/**
* Public abstract class Presentation
* Base for different presentation types
*/
var Presentation = new Class({

    Implements: Options,
    
    // Class options
    options: {

        transitionDuration: 1000,
        transitionInterval: 5000,
        transitionType: Fx.Transitions.Quad.easeOut,
        autoSwap: true
    },

    /**
    * function initialize
    * Constructor.
    *
    * @param id String ID attribute of the element that contains a presentation
    * @param options Object Class options: transitionType, transitionDuration,
    *                       transitionInterval.
    */
    initialize: function(id, options) {
    
        this.setOptions(options);
        
        // Vet the options!
        if(this.options.transitionDuration > this.options.transitionInterval) {
        
            this.options.transitionInterval = this.options.transitionDuration;
        }
    
        this.presentation = $(id);
        
        if(this.presentation) {
        
            // Grab the slides in this presentation
            this.slides = this.presentation.getElements('.presentation-slide');
            this.slideIndex = 0;
            
            //console.log(this.slides);
            
            // Remove the other slides from the DOM
            for(var i = 1; i < this.slides.length; i++) {
            
                this.slides[i].dispose();
            }
        
            // Setup any presentation tabs
            this.tabs = $$('.presentation-tab');
            
            this.tabs.each(function(tab, index) {

                tab.addEvent('click', this.tabClickListener.bindWithEvent(this, index));
            
            }, this);
            
            // Setup any presentation navigation
            this.navs = this.presentation.getElements('.presentation-nav');
            
            this.navs.each(function(nav, index) {

                nav.addEvent('click', this.navigationClickListener.bindWithEvent(this, index));
            
            }, this);
            
            
            // Select the first tab
            this.selectTab(0, 0);
            
            // Setup the automatic slide swappage
            this.autoSwap.delay(this.options.transitionInterval, this);
            
            this.swapping = false;
        }
    },
    
    tabClickListener: function(evt, index) {
    
        if(!this.swapping) {
    
            this.options.autoSwap = false;
        
            var tab = $(evt.target);
            
            if(this.slideIndex != index) {
    
                this.selectTab(index, this.slideIndex);
            
                this.swap(this.slides[this.slideIndex], this.slides[index]);
                this.slideIndex = index;
            }
        }
        
        return false;
    },
    
    navigationClickListener: function(evt, index) {
    	evt.preventDefault();
        if(!this.swapping) {
    
            this.options.autoSwap = false;
        
            var nav = $(evt.target);
			//console.log(nav);
            
			//console.log('current slide is ' + this.slideIndex);
			
			// if index is 0, then this is the back button, so next slide = this.slideIndex - 1
			// if index is 1, then this is the forward button, so next slide = this.slideIndex + 1
			
			if (index == 0){
				var nextSlide = this.slideIndex -1;
				
			}else{
				var nextSlide = this.slideIndex +1;
			}
			
			// check we are not at the beginning or end of the presentation
			
			if (nextSlide < 0) {
				nextSlide = this.slides.length - 1;
			}
			if (nextSlide > (this.slides.length - 1)){
				nextSlide = 0;
			}
			
			//console.log('next slide is '+nextSlide);
				
			this.swap(this.slides[this.slideIndex], this.slides[nextSlide]);
            this.slideIndex = nextSlide;
			
            /*if(this.slideIndex != index) {
    
                this.selectTab(index, this.slideIndex);
            
                this.swap(this.slides[this.slideIndex], this.slides[index]);
                this.slideIndex = index;
            }*/
        }
        
        return false;
    },

    
    selectTab: function(index, selectedTabIndex) {
    	if(this.tabs[selectedTabIndex]) {
       	 	this.tabs[selectedTabIndex].removeClass('presentation-tab-on');
        	this.tabs[index].addClass('presentation-tab-on');
		}
    },
    
    /**
    * Protected abstract function swap
    * Swaps one slide with another 
    *
    * @param oldSlide Element The slide element that should disappear
    * @param newSlide Element The slide element that should appear
    */
    swap: function(oldSlide, newSlide) {
    },
    
    autoSwap: function() {

        if(!this.swapping) {
    
            if(this.options.autoSwap) {
        
                // Find next index
                var index = this.slideIndex + 1;
                
                if(index >= this.slides.length) {
                
                    index = 0;
                }
                
                this.selectTab(index, this.slideIndex);
                
                this.swap(this.slides[this.slideIndex], this.slides[index]);
                this.slideIndex = index;
            }
        }
        
        this.autoSwap.delay(this.options.transitionInterval, this);
    },
    
    /**
    * Protected abstract function swapCompleteListener
    * For cleanup after swap
    *
    * @param slide Element The slide element that is no longer being viewed
    */
    swapCompleteListener: function(slide) {
    
        // Remove the old slide from the DOM
        slide.dispose();
        
        this.swapping = false;
    }

});



var CrossFadingPresentation = new Class({

    Extends: Presentation,

    // Assumes slides are positioned absolutely within the presentation
    swap: function(oldSlide, newSlide) {
    
        this.swapping = true;
    
        // Position newSlide under oldslide
        newSlide.setStyle('z-index', 0);
        oldSlide.setStyle('z-index', 1);
        
        // Add newSlide to the DOM
        newSlide.inject(this.presentation);
        
        var newSlideFx = newSlide.retrieve('fx', null);
          
        if(!newSlideFx) {
  
            newSlideFx = new Fx.Tween(newSlide, {duration: this.options.transitionDuration,
                                                 transition: this.options.transitionType});
                                                 
            newSlideFx.addEvent('complete', this.swapCompleteListener.bind(this));
            
            newSlide.store('fx', newSlideFx);
        }
        
        // Create fx object if not exists
        var oldSlideFx = oldSlide.retrieve('fx', null);
        
        if(!oldSlideFx) {
        
            oldSlideFx = new Fx.Tween(oldSlide, {duration: this.options.transitionDuration,
                                                 transition: this.options.transitionType});

            oldSlideFx.addEvent('complete', this.swapCompleteListener.bind(this));
            
            oldSlide.store('fx', oldSlideFx);
        }
        
        // Start the fx
        newSlideFx.set('opacity', 1);
        oldSlideFx.start('opacity', 1, 0);
    }
});


var SlidingPresentation = new Class({

    Extends: Presentation,

    // Assumes slides are positioned absolutely within the presentation
    swap: function(oldSlide, newSlide) {
    
        this.swapping = true;

         var slideWidth = oldSlide.getCoordinates().width;
      
          newSlide.setStyle('left', slideWidth);
          
          // Add newSlide to the DOM
          newSlide.inject(this.presentation);
          
          var newSlideFx = newSlide.retrieve('fx', null);
          
          if(!newSlideFx) {
  
              newSlideFx = new Fx.Tween(newSlide, {duration: this.options.transitionDuration,
                                                   transition: this.options.transitionType});
              newSlide.store('fx', newSlideFx);
          }
          
          var oldSlideFx = oldSlide.retrieve('fx', null);
          
          if(!oldSlideFx) {
  
              oldSlideFx = new Fx.Tween(oldSlide, {duration: this.options.transitionDuration,
                                                   transition: this.options.transitionType});
              oldSlide.store('fx', oldSlideFx);
          }
          
          // Remove any old swap complete events from these objects
          newSlideFx.removeEvents('complete');
          oldSlideFx.removeEvents('complete');
          
          // Trigger swap complete listener for oldSlide
          oldSlideFx.addEvent('complete', this.swapCompleteListener.bind(this));

          // Start the fx
          newSlideFx.start('left', slideWidth - 5, 0);
          oldSlideFx.start('left', 0, 0 - slideWidth);
    }
});
