/*
//*******
//
//	filename: slideshow.js
//	author: Zack Brown
//	date: 21st July 2010
//
//*******
*/

//declare Slideshow class
var Slideshow = Class.create();

//declate the Slideshow prototype
Slideshow.prototype = {

	//slideshow element
	element: null,
	
	//slideshow options
	options: {},

	//periodical executer
	pe: null,
	
	//array of slides
	slides: [],
	
	//array of models
	models: [],
	
	//current slide index
	slide: 1,
	
	//animating flag
	animating: false,

	//wrapper function for init
	initialize: function(id, options)
	{
		//gather slideshow element
		this.element = $("slideshow_" + id);
		
		//merge array of options
		this.options = (options != undefined ? options : {controls: false, delay_speed: 10, transition_speed: 1, transition_type: "fade"});
		
		//check element is valid
		if(this.element != undefined)
		{
			//gather slides
			this.slides = $("slideshow_slides_" + id);
			
			//gather models
			this.models = $("slideshow_models_" + id);
			
			//check slides are valid
			if(this.slides != undefined)
			{
				//gather children
				this.slides = this.slides.childElements();
				
				//loop index
				var index = 0;
				
				//loop through array of slides
				this.slides.each(function(slide)
				{
					//check index for first slide
					if(index == 0)
					{
						//check transition type
						if(this.options.transition_type == "fade")
						{
							//set slide style
							slide.setStyle({opacity: 1.0});
						}
						else
						{
							//set slide style
							slide.setStyle({left: 0 + "px"});
						}
					}
					else
					{
						//check transition type
						if(this.options.transition_type == "fade")
						{
							//set slide style
							slide.setStyle({opacity: 0.0});
						}
						else
						{
							//set slide style
							slide.setStyle({left: (index * this.element.getDimensions().width) + "px"});
						}
					}
					
					//increment index
					++index;
				}.bind(this));
			}
			
			//check models are valid
			if(this.models != undefined)
			{
				//gather children
				this.models = this.models.childElements();
				
				//loop through array of models
				this.models.without(this.models.first()).each(function(model)
				{
					//set model style
					model.setStyle({display: "none"});
				});
			}
			
			//check controls option
			if(this.options.controls)
			{
				//gather control elements
				var control_previous = $("slideshow_control_previous_" + id);
				var control_next = $("slideshow_control_next_" + id);
				
				//check control is valid
				if(control_previous != undefined)
				{
					//observe click events
					Event.observe(control_previous, "click", this.previous.bind(this));
				}
				
				//check control is valid
				if(control_next != undefined)
				{
					//observe click events
					Event.observe(control_next, "click", this.next.bind(this));
				}
			}
			
			//start slideshow
			this.start();
		}
	},
	
	//start slideshow
	start: function()
	{
		//create a new periodical executer
		this.pe = new PeriodicalExecuter(this.next.bind(this), this.options.delay_speed);
	},
	
	//end slideshow
	stop: function()
	{
		//stop periodical executer
		this.pe.stop();
	},
	
	//slide to specifed item
	slideTo: function(next, previous)
	{
		//check transition type
		if(this.options.transition_type == "fade")
		{
			//gather next and previous slides
			var slide_previous = this.slides[(previous - 1)];
			var slide_next = this.slides[(next - 1)];
			
			//fade previous slide out
			slide_previous.fade({duration: this.options.transition_speed});
			
			//fade next slide in
			slide_next.appear({duration: this.options.transition_speed});
		}
		else
		{
			//determine movement distance
			var distance = this.element.getDimensions().width;
			
			//array of animations
			var animations = [];
			
			//loop index
			var index = 0;
			
			//loop through array of slides
			this.slides.each(function(slide)
			{
				//calculate multiplier
				var multiplier = index - (next - 1);
				
				//create a new animation effect and append to array of animations
				animations.push(new Effect.Move($(slide), {mode: "absolute", x: distance * multiplier, y: 0}));
				
				//increment loop index
				++index;
			});
			
			//animate
			new Effect.Parallel(animations, {	duration: this.options.transition_speed,
												beforeStart: function()
												{
													//set animating flag
													this.animating = true;
													
												}.bind(this),
												afterFinish: function()
												{
													//set animating flag
													this.animating = false;
													
												}.bind(this)});
		}
		
		//gather next and previous models
		var model_previous = this.models[(previous - 1)];
		var model_next = this.models[(next - 1)];
		
		//fade previous model out
		model_previous.fade({duration: this.options.transition_speed});
		
		//fade next model in
		model_next.appear({duration: this.options.transition_speed});
	},
	
	//move to previous slide
	previous: function()
	{
		//check animating flag
		if(this.animating)
		{
			//return
			return;
		}
		//stop slideshow
		this.stop();
		
		//save current slide id
		var current = this.slide;
		
		//determine slide id
		this.slide = (this.slide > 1 ? (this.slide - 1) : this.slides.length);
		
		//slide to specified slide
		this.slideTo(this.slide, current);
		
		//start slideshow
		this.start();
	},
	
	//move to next slide
	next: function()
	{
		//check animating flag
		if(this.animating)
		{
			//return
			return;
		}
		
		//stop slideshow
		this.stop();
		
		//save current slide id
		var current = this.slide;
		
		//determine slide id
		this.slide = (this.slide < this.slides.length ? (this.slide + 1) : 1);
		
		//slide to specified slide
		this.slideTo(this.slide, current);
		
		//start slideshow
		this.start();
	}
};
