/*
//*******
//
//	filename: slideshow.js
//	author: Zack Brown
//	date: 1st April 2011
//
//*******
*/

var $j = jQuery.noConflict();

//declare slideshow plugin
function Slideshow(id, options)
{
	//slideshow element
	this.element = null;
	
	//timer
	this.timer = null;
	
	//slideshow options
	this.options = {};
	
	//array of slides
	this.slides = [];
	
	//array of models
	this.models = [];
	
	//current slide index
	this.slide = 1;
	
	//animating flag
	this.animating = false;
	
	//initialize self
	this.initialize(id, options);
}

//initialise self
Slideshow.prototype.initialize = function(id, options)
{
	//gather slideshow element
	this.element = $j("#slideshow_" + id);
	
	//check element is valid
	if(this.element.length > 0)
	{
		//merge array of options
		this.options = $j.extend({controls: false, delay_speed: 10, transition_speed: 1, transition_type: "fade"}, options);
		
		//gather slides models elements
		this.slides = jQuery("#slideshow_slides_" + id).children();
		this.models = jQuery("#slideshow_models_" + id).children();
		
		//check slide wrapper is valid
		if(this.slides.length > 0)
		{
			//loop through slides
			$j.each(this.slides, function(key, value)
			{
				//check transition type
				if(options.transition_type == "fade")
				{
					//ignore first slide
					if(key > 0)
					{
						//hide slide
						$j(value).hide();
					}
				}
				else
				{
					//calculate offset
					var offset = (key == 0 ? 0 : (key * parseInt($j(value).css("width"))));
					
					//set model offset
					$j(value).css("left", offset + "px");
				}
			});
		}
		
		//check model wrapper is valid
		if(this.models.length > 0)
		{
			//loop through models
			$j.each(this.models, function(key, value)
			{
				//check transition type
				if(options.transition_type == "fade")
				{
					//ignore first slide
					if(key > 0)
					{
						//hide model
						$j(value).hide();
					}
				}
				else
				{
					//calculate offset
					var offset = (key == 0 ? 0 : (20 + (key * parseInt($j(value).css("width")))));
					
					//set model offset
					$j(value).css("left", offset + "px");
				}
			});
		}
		
		//check control options
		if(this.options.controls === true)
		{
			//gather control element
			var control_previous = $j("#slideshow_control_previous_" + id);
			var control_next = $j("#slideshow_control_next_" + id);
			
			//save self as parent
			var parent = this;
			
			//check previous control element is valid
			if(control_previous.length > 0)
			{
				//observe click events
				$j(control_previous).click(function()
				{
					//invoke parent method
					parent.previous();
				});
			}
			
			//check next control element is valid
			if(control_next.length > 0)
			{
				//observe click events
				control_next.click(function()
				{
					//invoke parent method
					parent.next();
				});
			}
		}
		
		//start slideshow
		this.start();
	}
}

//start slideshow
Slideshow.prototype.start = function()
{
	//check timer is valid
	if(this.timer === null)
	{
		//save self as parent
		var parent = this;
		
		//create a new timer
		this.timer = setTimeout(function()
		{
			//invoke parent method
			parent.timedEvent();
			
		}, (this.options.delay_speed * 1000));
	}
}

//stop slideshow
Slideshow.prototype.stop = function()
{
	//check timer is valid
	if(this.timer != null)
	{
		//invalidate timer
		clearTimeout(this.timer);
	}
	
	//invalidate timer
	this.timer = null;
}

//handle timed events
Slideshow.prototype.timedEvent = function()
{
	//rotate slideshow to next slide
	this.next();
}

//slide to specified item
Slideshow.prototype.slideTo = function(next, previous)
{
	//set animating flag
	this.animating = true;
	
	//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)];
		
		//gather next and previous models
		var model_previous = this.models[(previous - 1)];
		var model_next = this.models[(next - 1)];
		
		//fade previous model and slide out
		$j(slide_previous).fadeOut((this.options.transition_speed * 1000));
		$j(model_previous).fadeOut((this.options.transition_speed * 1000));
		
		//fade next model and slide in
		$j(slide_next).fadeIn((this.options.transition_speed * 1000));
		$j(model_next).fadeIn((this.options.transition_speed * 1000));
	}
	else
	{
		//determine distance to move slides
		var distance = parseInt($j(this.slides[(previous - 1)]).css("width"));
		
		//save self as parent
		var parent = this;
		
		//loop through slides
		$j.each(this.slides, function(key, value)
		{
			//calculate multiplier
			var multiplier = (key - (next - 1));
			
			//create animation
			var animation = {left: (distance * multiplier) + "px"};
			
			//animate slide
			$j(value).animate(animation, (parent.options.transition_speed * 1000));
		});
		
		//loop through models
		$j.each(this.models, function(key, value)
		{
			//calculate multiplier
			var multiplier = (key - (next - 1));
			
			//create animation
			var animation = {left: (distance * multiplier) + "px"};
			
			//animate model
			$j(value).animate(animation, (parent.options.transition_speed * 1000));
		});
	}
	
	//set animating flag
	this.animating = false;
}

//rotate slideshow to previous slide
Slideshow.prototype.previous = function()
{
	//check animating flag
	if(this.animating === true)
	{
		//return
		return;
	}
	
	//stop slideshow
	this.stop();
	
	//save current slide id
	var current = this.slide;
	
	//determine previous slide id
	this.slide = (this.slide > 1 ? (this.slide - 1) : this.slides.length);
	
	//slide to specified item
	this.slideTo(this.slide, current);
	
	//start slideshow
	this.start();
}

//rotate slideshow to next slide
Slideshow.prototype.next = function()
{
	//check animating flag
	if(this.animating === true)
	{
		//return
		return;
	}
	
	//stop slideshow
	this.stop();
	
	//save current slide id
	var current = this.slide;
	
	//determine next slide id
	this.slide = (this.slide < this.slides.length ? (this.slide + 1) : 1);
	
	//slide to specified item
	this.slideTo(this.slide, current);
	
	//start slideshow
	this.start();
}
