/** @package eFocus js lib */

/**
 * Slideshow Class - create slideshow of html elements
 *
 * @author Rocco Janse <rocco@efocus.nl>
 * @since 1.0, 13 aug, 2009
 * @copyright eFocus
 * @package eFocus js lib
 * @subpackage Slideshow
 * @uses MooTools 1.2.3 More <http://www.mootools.net>
 */

var Slideshow = new Class({

	Implements: Options,

	options: {
		'viewport': false,
		'slides': {},
		'transition': 'none',
		'mode': 'horizontal',
		'startslide': 0,
		'delay': 3
	},

	initialize: function(options) {

		this.setOptions(options);

		/** @var object viewport */
		this.viewport = this.options.viewport;
		if (!this.viewport) return;
		
		/** @var object slides */
		this.slides = this.options.slides;
		if (!this.slides.length) return;

		/** @var integer number of slides */
		this.totalSlides = this.slides.length;
		
		/** @var object optional navigation */
		this.navigation = this.options.navigation;

		/** @var string optional transition */
		this.transition = this.options.transition;
		
		/** @var string optional transition mode ('horizontal','vertical') */
		this.mode = this.options.mode;
		
		/** @var integer current slide number */
		this.current = this.options.startslide.toInt();

		/** @var integer delay in seconds */
		this.delay = this.options.delay.toInt();
		
		this.timer = false;

		this.initViewport();
		this.initSlides();
		
		if (this.delay) {
			this.startSlideshow();
		}
		
		this.slideFx = new Fx.Tween();
	},

	/**
	* initialises slideshow viewport
	*
	* @author Rocco Janse <rocco@efocus.nl>
	* @since 1.0, 13 aug, 2009
	* @return void
	*/
	
	initViewport: function() {
		
		// set viewport pos to relative, we need to place slides in it
		this.viewport.setStyle('position', 'relative');
	},	

	/**
	* initialises slides
	*
	* @author Rocco Janse <rocco@efocus.nl>
	* @since 1.0, 13 aug, 2009
	* @return void
	*/
	
	initSlides: function() {
		
		// hide all slides and place them in viewport
		this.slides.each(function(slide, index) {
			slide.setStyles({
				'position': 'absolute',
				'top': 0,
				'left': 0,
				'display': 'block',
				'opacity': 0
			});
			
			if (index == this.current) {
				slide.setStyle('opacity', 1);
			};
			
			if (this.delay) {			
				slide.addEvents({			
					'mouseenter': function() {
						this.pauseSlideshow();
					}.bind(this),
					
					'mouseleave': function() {
						this.startSlideshow();
					}.bind(this)
				});
			}
			
		}.bind(this));			
	},

	/**
	* shows requested slide based on transition
	*
	* @author Rocco Janse <rocco@efocus.nl>
	* @author Klaas Dieleman <klaas@efocus.nl>
	* @since 1.05, 1 oct, 2009
	* @return void
	*/

	showSlide: function(slidenumber) {
		
		this.requested = slidenumber;
		if (this.requested == this.current) return;

		// juggle z-indexes
		this.slides[this.current].setStyles({'z-index': 8});
		this.slides[this.requested].setStyles({'z-index': 10});
		
		switch(this.transition) {
			
			case 'fade': {
				// use the tween effect, chaining doesnt work with '.fade'
				this.slideFx.cancel();
				var otherSlides = this.slides.filter(function(item, index) {
					if(index != this.current) return item
				}.bind(this));
				
				otherSlides.each(function(item) {
					item.setOpacity(0);
				});
				this.slideFx = new Fx.Tween(this.slides[this.requested], {'duration': 800});
				this.slideFx.start('opacity', 1);
				this.current = this.requested;
				break;
			}
			case 'slide': {
				
				this.slides[this.requested].setStyle('opacity', 1);
				
				var slideFxIn = new Fx.Tween(this.slides[this.requested], {'duration': 800});
				var slideFxOut = new Fx.Tween(this.slides[this.current], {'duration': 800});
				
				switch(this.mode) {
					case 'horizontal': {
						var startPos = this.slides[this.requested].getWidth();
						var endPos = 0-this.slides[this.current].getWidth();	
						slideFxOut.start('left', 0, endPos);
						slideFxIn.start('left', startPos, 0);				
						break;
					}
					default: {
						var startPos = 0-this.slides[this.requested].getHeight();
						var endPos = this.slides[this.current].getHeight();	
						slideFxOut.start('top', 0, endPos);
						slideFxIn.start('top', startPos, 0);				
						break;
					}
				}

				this.current = this.requested;
				break;
			}
			default: {
				this.slides[this.requested].setStyle('opacity', 1);
				this.slides[this.current].setStyle('opacity', 0);
				this.current = this.requested;
				break;
			}
		};
	},

	/**
	* finds and activates next slide
	*
	* @author Rocco Janse <rocco@efocus.nl>
	* @since 1.0, 5 aug, 2009
	* @return void
	*/

	showNextSlide: function() {

		/** @var integer next slide to activate */
		var nextSlide = this.current + 1;

		// reset next slide to loop slideshow
		if (nextSlide >= this.totalSlides) {
			nextSlide = 0;
		}

		// execute
		this.showSlide(nextSlide);
	},

	/**
	* finds and activates previous slide
	*
	* @author Rocco Janse <rocco@efocus.nl>
	* @since 1.0, 5 aug, 2009
	* @return void
	*/

	showPreviousSlide: function() {

		/** @var integer previous slide to activate */
		var previousSlide = this.current - 1;

		// reset next slide to loop slideshow
		if (previousSlide < 0) {
			previousSlide = 0;
		}

		// execute
		this.showSlide(previousSlide);
	},

	/**
	* starts slideshow
	*
	* @author Rocco Janse <rocco@efocus.nl>
	* @since 1.0, 13 aug, 2009
	* @return void
	*/

	startSlideshow: function() {
		var delay = this.delay * 1000;
		this.timer = this.showNextSlide.periodical(delay, this);
	},
	
	/**
	* pauzes slideshow
	*
	* @author Rocco Janse <rocco@efocus.nl>
	* @since 1.0, 13 aug, 2009
	* @return void
	*/
		
	pauseSlideshow: function() {
		this.timer = $clear(this.timer);
	}
});