/*
	Class:			Slideshow
	Author:			Tom Kentell
	Version:		0.3
	Date:			07/01/2010
	Note:			This should be called in an on load event not dom ready to allow webkit to work out heights of images, otherwise you need to set this manually and remove JS for working the heights out.
*/

var Slideshow = new Class({
	Implements: [Options],

	options: {
		slideTarget: '.slideshow',
		slideItems: '.slideshow_items',
		slideDuration: 3000, /* miliseconds 1000 = 1 second */
		currentIndex: 0,
		autoplay: true,
		pauseOnHover: true,
		btnPlayPause: '.slideshow_control',
		pauseText: 'Pause',
		playText: 'Play',
		hasButtons: false,
		buttonsTarget: '.slideshow_buttons'
	},

	initialize: function(options) {
		this.setOptions(options);
		this.options.images = this.options.slideTarget.getElements('img');
		$(this.options.slideTarget).setStyle('display','block');

		/* opacity and fade */
		this.options.images.each(function(img,i) {
			if(i > 0) img.getParent('li').set('opacity',0);

			/* Get height of biggest image */
			if(this.options.slideshowHeight == null || this.options.slideshowHeight < img.getSize().y) this.options.slideshowHeight = img.getSize().y;
		}.bind(this));

		/* Set height of container as images are positioned absolute */
		this.options.slideTarget.getElement(this.options.slideItems).setStyle('height',this.options.slideshowHeight);

		/* If autoplay = true then start slideshow */
		if(this.options.autoplay) this.start();
			else this.options.paused = true;

		if(this.options.pauseOnHover) {
			/* If slideshow already paused then we don't want to restart it on mouseleave */
			var wasPaused = false;

			$$(this.options.images).getParent('li').addEvents({
				'mouseenter': function() {
					if(this.options.paused) wasPaused = true;
						else wasPaused = false;
					this.stop();
				}.bind(this),
				'mouseleave': function() {
					if(!wasPaused) this.start();
				}.bind(this)
			});
		}

		/* If slideshow has buttons eg: 1, 2, 3, 4, 5 then do this */
		if(this.options.hasButtons) {
			/* add class of current to first button */
			this.options.theButtons = this.options.slideTarget.getElements('.slideshow_buttons li');
			this.options.theButtons[0].addClass('current');

			/* bind click events using relay method to buttons */
			this.options.theButtons.each(function(e,i) {
				e.addEvent('click', function(e) {
					this.slideTo(i);
					e.stop();
				}.bind(this));
			}, this);
		}

		/* If slideshow has play/pause button then set this up */
		if($defined(this.options.slideTarget.getElements(this.options.btnPlayPause))) {
			var playPause = this.options.slideTarget.getElements(this.options.btnPlayPause);

			playPause.addEvent('click', function(e) {
				if(playPause[0].hasClass('paused')) this.start();
					else this.stop();
				e.stop();
			}.bind(this));
		}
	},

	slideTo: function(here) { /* here [optional] = position to slide/transition to in the collection of pictures */
		var slideShow = this; /* maintain a reference for when /this/ is out of scope */
		var images = this.options.images;

		/* Sort out the indexes and maintain a reference to previous index for fading */
		var previousIndex = this.options.currentIndex;
		if($defined(here)) this.options.currentIndex = here;

		/* Fade out previous image and fade in new one, if here is set then number has been clicked so pause */
		images[previousIndex]
			.getParent('li').fade('out')
			.removeClass('current');

		if(!$defined(here)) this.options.currentIndex++;
			else this.stop();

		images[this.options.currentIndex %= images.length]
			.getParent('li').fade('in')
			.addClass('current');

		/* If slideshow has buttons eg: 1, 2, 3, 4, 5 then do this */
		if(this.options.hasButtons) {
			this.options.theButtons.removeClass('current');
			this.options.theButtons[this.options.currentIndex].addClass('current');
		}
	},

	start: function() {
		this.options.interval = this.slideTo.periodical(this.options.slideDuration, this);
		this.options.paused = false;

		/* Update Play/Pause button if one exists */
		if($defined($$(this.options.btnPlayPause)[0])) {
			this.options.slideTarget.getElements(this.options.btnPlayPause)
				.removeClass('paused')
				.set('html', this.options.pauseText);
		}
	},

	stop: function() {
		clearInterval(this.options.interval);
		this.options.paused = true;

		/* Update Play/Pause button if one exists */
		if($defined($$(this.options.btnPlayPause)[0])) {
			this.options.slideTarget.getElements(this.options.btnPlayPause)
				.addClass('paused')
				.set('html', this.options.playText);
		}
	}
});
