function slideshow( dataNode, pfad_images, mainElement ){

    this.imagesData = dataNode;
    this.actualImage = 0;
    this.totalImages = 0;
    this.pfadImages = pfad_images;
    this.slideIsRunning = false;  // number if slideshow is running (value returned by setInterval)
    this.mainElement = mainElement;
    
    // selektory jQuery do wybierania elementów struktury
    // w razie potrzeby można je zmodyfikować nadpisując w implementacji klienta
    this.selNaviFirst = '#zurueck_2';
    this.selNaviPrev = '#zurueck_1';
    this.selNaviNext = '#vor_1';
    this.selNaviLast = '#vor_2';
    this.selNaviImg = '#hotelbild';
    this.selNaviSpareImg = '#spare';
    this.selNaviSubline = '#subline';
    this.selNaviCounter = '#bildvon';
    this.selNaviAuto = '#auto';
    this.selNaviResize = '#resize';
    this.selMainElement = '#divImg';

    // inne zmienne konfiguracyjne
    this.tplAuto = ['AUTO','STOP'];
    this.tplAutoTitles = ['uruchom automatyczną zmianę zdjęć','zatrzymaj automatyczną zmianę zdjęć'];
    this.tplResize = ['<img src="'+this.pfadImages+'hib/lupe.png" alt=""/>','<img src="'+this.pfadImages+'hib/lupe.png" alt=""/>','<img src="'+this.pfadImages+'hib/lupe_minus.png" alt=""/>']
    this.cfgAllowAuto = true;
    this.cfgAllowResize = true;
    this.currentResize = (hib.config.slideshowInitialSize)?hib.config.slideshowInitialSize:0; // allowed 0(low), 1(middle), 2(normal)
    this.cfgAutoInterval = 4000;
    this.counterTpl = 'Zdjęcie {actual} / {total}';
	this.imagesAlreadyInHTML = false; // 2010.03.29 - 'true' gdy zdjęcia są już załadowane w kodzie np. przez PHP

    
    this.refreshCounter = function(){
        var actualImage= this.projector.getCurrentImageIndex();        
        // wpisanie do template licznika wartości
        var tmp = this.counterTpl.replace( /\{actual\}/, actualImage + 1 );
        tmp = tmp.replace( /\{total\}/, this.totalImages );
        // wyświetlenie zaktualizowanej wartości
        $( this.selNaviCounter, this.mainElement ).html( tmp );
        
        $( this.selNaviSubline, this.mainElement ).html( this.imagesData[ actualImage ].subline )

        this.refreshNavi();

    }

    this.refreshNavi = function(){
        
        var actualImage= this.projector.getCurrentImageIndex();
        
        $(this.selNaviFirst, this.mainElement ).attr('src', this.pfadImages+'hib/zurueck_2'+(actualImage==0?'_off':'')+'.gif').get(0).slideObj=(actualImage>0?this:null);
        $(this.selNaviPrev, this.mainElement ).attr('src', this.pfadImages+'hib/zurueck_1'+(actualImage==0?'_off':'')+'.gif').get(0).slideObj=(actualImage>0?this:null);
        $(this.selNaviNext, this.mainElement ).attr('src', this.pfadImages+'hib/vor_1'+(actualImage<this.totalImages-1?'':'_off')+'.gif').get(0).slideObj=(actualImage<this.totalImages-1?this:null);
        $(this.selNaviLast, this.mainElement ).attr('src', this.pfadImages+'hib/vor_2'+(actualImage<this.totalImages-1?'':'_off')+'.gif').get(0).slideObj=(actualImage<this.totalImages-1?this:null);
        with( $(this.selNaviAuto, this.mainElement ) ){
            get(0).slideObj=this;
            if (this.cfgAllowAuto) show(); else hide();
            html( this.tplAuto[ this.slideIsRunning?1:0 ] );
            attr('title', this.tplAutoTitles[ this.slideIsRunning?1:0 ])
        }
        with( $(this.selNaviResize, this.mainElement ) ){
            get(0).slideObj=this;
            html( this.tplResize[ this.currentResize ] );
            if (this.cfgAllowResize) show(); else hide();
        }
    }
    
    this.showNext = function(){
        this.projector.showNext();
        this.projector.preloadNext()
        this.refreshCounter();
      
    }
    this.showPrev = function(){
        this.projector.showPrev();
        this.refreshCounter();        
    }
    this.showLast = function(){
        this.projector.showLast();
        this.refreshCounter();        
    }
    this.showFirst = function(){
        this.projector.showFirst();
        this.refreshCounter();        
    }
    
    this.autoStepNext = function(){ 
        if (hib.slide.slideIsRunning) {
            if ($(hib.slide.selMainElement,hib.slide.mainElement).length==0) return;
            setTimeout(hib.slide.autoStepNext, hib.slide.cfgAutoInterval);
            hib.slide.showNext();
        }
    }
    
    this.auto = function(){
        if (this.slideIsRunning==false) { 
            this.slideIsRunning = true;
            this.autoStepNext()
        } else {
            this.slideIsRunning = false;
            this.refreshCounter()
        }
    }

    this.noImagesToDisplay = function(){
        $(this.selMainElement, this.mainElement ).hide();
        hib.fitHeight();
    }    


    // inicjalizacja

    this.init = function(){
        if (dataNode.length==0) {
            this.noImagesToDisplay();
            return;
        } else {

           $( this.selMainElement, this.mainElement).removeClass('zoom0 zoom1 zoom2').addClass('zoom'+this.currentResize);
    
            this.projector = new projector();
            with (this.projector) {
                setMainElement($(this.selMainElement, mainElement));
    
                //setDisplayMode('center');
					 //setDisplayMode('fitParentHeightWidth');
					 setDisplayMode(hib.config.displayModeForSlideShow);
                //setCssClassForImages('varHeight');
            }
        
            for (var n in dataNode ) {
                    
                var imageData = dataNode[ n ];
      
                if (!this.cfgAllowResize) {
                    var image = imageData.name
                } else if (this.cfgAllowResize && !imageData.name) {
                    
                    switch (this.currentResize) {
                        case 2 : var image = imageData.nameSizeHigh;
                            break
        
                        case 1 : var image = imageData.nameSizeMiddle;
                            break
        
                        default : var image = imageData.nameSizeLow;
                    }
                    
                } else if (this.cfgAllowResize && imageData.name){
                    var tmp = imageData.name;
                    tmp = tmp.replace( /\/middle\// ,'/{x}/' );
                    tmp = tmp.replace( /\/low\// ,'/{x}/' );
                    tmp = tmp.replace( /\/high\// ,'/{x}/' );
                    
                    switch (this.currentResize) {
                        case 2  : var image = tmp.replace ( /\/{x}\// ,'/high/' );
                            break
        
                        case 1  : var image = tmp.replace ( /\/{x}\// ,'/middle/' );
                            break
        
                        default : var image = tmp.replace ( /\/{x}\// ,'/low/' );
                    }
                    
                } else {
                    alert('#img error');
                }
                //this.projector.add( [image] );
                
				if(!this.imagesAlreadyInHTML) {
					$(this.selMainElement,mainElement).append('<img src="'+image+'"  style="display:none">');
				}
				
				this.totalImages++;
                
            }
			this.projector.addImagesFromElement( $(this.selMainElement,mainElement)  );
            this.showFirst();
        }   
    }
    
/*    
    this.showImage = function(){
        if (this.imagesData.length==0) return false;
        var imageData = this.imagesData[ this.actualImage ];
        // zmiana obrazka na aktualnie wybrany

        if (!this.cfgAllowResize) {
            var image = imageData.name
        } else if (this.cfgAllowResize && !imageData.name) {
            
            switch (this.currentResize) {
                case 2    : var image = imageData.nameSizeHigh;
                    break

                case 1    : var image = imageData.nameSizeMiddle;
                    break

                default     : var image = imageData.nameSizeLow;
            }
            
        } else if (this.cfgAllowResize && imageData.name){
            var tmp = imageData.name;
            tmp = tmp.replace( /\/middle\// ,'/{x}/' );
            tmp = tmp.replace( /\/low\// ,'/{x}/' );
            tmp = tmp.replace( /\/high\// ,'/{x}/' );
            
            switch (this.currentResize) {
                case 2  : var image = tmp.replace ( /\/{x}\// ,'/high/' );
                    break

                case 1  : var image = tmp.replace ( /\/{x}\// ,'/middle/' );
                    break

                default : var image = tmp.replace ( /\/{x}\// ,'/low/' );
            }
            
        } else {
            alert('#img error');
        }

        $( this.selNaviImg, this.mainElement ).get(0).slideObj=this;
        $( this.selNaviImg, this.mainElement ).load( 
        // po załadowaniu obrazka przez przeglądarkę zostaje zmieniony podpis
            function(){
                with (this.slideObj){
                    
                    centerImage($(this, this.mainElement));
                    //centerImage();

                    $(this, this.mainElement).fadeIn( 1200, function(){
                        
                         $(this.slideObj.selNaviSpareImg, this.mainElement)
                             .attr('src',$(this, this.mainElement).attr('src'))
                             .css({
                                 left:$(this, this.mainElement).css('left'),
                                 top:$(this, this.mainElement).css('top')
                             })
                             .load(function(){$(this, this.mainElement).show()});
                         });
                    
                    $(selNaviSpareImg,this.mainElement).fadeOut( 1200 );

                    $( selNaviSubline, this.mainElement ).html( imagesData[ actualImage ].subline )

                    // odświeżenie licznika
                    refreshCounter();
                }
        }).attr('src', image ).hide();
        
        $( '#divImg' , this.mainElement).removeClass('zoom0 zoom1 zoom2').addClass('zoom'+this.currentResize);

        
        this.refreshNavi();
    }
    
    this.centerImage = function( i ){
        i.parent().css({position:'relative',left:0,top:0});        
        i.css({
            position:'absolute',
            left: (i.parent().width()-i.width())/2+'px',
            top: (i.parent().height()-i.height())/2+'px'
        })
    }
        
    this.auto = function(){
        // funkcja wywoływana po kliknięciu na przycisk "auto"
        
        
        if (this.slideIsRunning!=false){ // pokaz slajdów działa

            timer.remAction('slideshow');
            this.slideIsRunning = false;
            this.refreshNavi();            

        } else { //pokaz slajdów nie działa

            timer.addAction('slideshow', this.stepNext, this );
            this.slideIsRunning = true;
            this.stepNext();

        }
    }
    
    this.stepNext = function(){
 //       var tmp = this.slideshow.context;
//        if (this.slideIsRunning==false) return false;
        if(this.actualImage<this.totalImages)
            this.showNext();
        else
            this.showFirst();    
    }
    
    this.resize = function(){
        this.currentResize++;
        if (this.currentResize==3) this.currentResize=0;
        
        this.showImage();
    }

    
    this.refreshCounter = function(){
        // wpisanie do template licznika wartości
        var tmp = this.counterTpl.replace( /\{actual\}/, this.actualImage + 1 );
        tmp = tmp.replace( /\{total\}/, this.totalImages + 1 );
        // wyświetlenie zaktualizowanej wartości
        $( this.selNaviCounter, this.mainElement ).html( tmp );

    }

    this.refreshNavi = function(){
        $(this.selNaviFirst, this.mainElement ).attr('src', this.pfadImages+'hib/zurueck_2'+(this.actualImage==0?'_off':'')+'.gif').get(0).slideObj=this;
        $(this.selNaviPrev, this.mainElement ).attr('src', this.pfadImages+'hib/zurueck_1'+(this.actualImage==0?'_off':'')+'.gif').get(0).slideObj=this;
        $(this.selNaviNext, this.mainElement ).attr('src', this.pfadImages+'hib/vor_1'+(this.actualImage<this.totalImages?'':'_off')+'.gif').get(0).slideObj=this;
        $(this.selNaviLast, this.mainElement ).attr('src', this.pfadImages+'hib/vor_2'+(this.actualImage<this.totalImages?'':'_off')+'.gif').get(0).slideObj=this;
        with( $(this.selNaviAuto, this.mainElement ) ){
            get(0).slideObj=this;
            if (this.cfgAllowAuto) show(); else hide();
            html( this.tplAuto[ this.slideIsRunning?1:0 ] );
            attr('title', this.tplAutoTitles[ this.slideIsRunning?1:0 ])
        }
        with( $(this.selNaviResize, this.mainElement ) ){
            get(0).slideObj=this;
            html( this.tplResize[ this.currentResize ] );
            if (this.cfgAllowResize) show(); else hide();
        }
    }

    this.showFirst = function(){
        if (this.actualImage!=0){
            this.actualImage = 0
            this.showImage();
        }
    }

    this.showPrev = function(){
        if (this.actualImage > 0){
            this.actualImage--;
            this.showImage();
        }        
    }
    this.showNext = function(){
        if (this.actualImage < this.totalImages){
            this.actualImage++;
            this.showImage();
        }          
    }
    this.showLast = function(){
        if (this.actualImage < this.totalImages){
            this.actualImage = this.totalImages;
            this.showImage();
        }           
    }
    
    this.noImagesToDisplay = function(){
//        $(this.selMainElement, this.mainElement ).slideUp('slow',function(){ hib.fitHeight() });
        $(this.selMainElement, this.mainElement ).hide();
        hib.fitHeight();
    }

    if (dataNode.length==0) {
        this.noImagesToDisplay();
        return;
    }
    
    timer = new timeManager( this.cfgAutoInterval );
    
    $(this.selNaviSpareImg, this.mainElement).attr('src',this.pfadImages+'ajax-loader.gif').css( 'z-index','1' );
    $(this.selNaviImg, this.mainElement).css( 'z-index','2' );
    this.centerImage( $(this.selNaviSpareImg, this.mainElement) );
                                                */
}
