/*
	Klasse:			ImageSwitcher
	Beschreibung:	Ein kleiner Controller fuer eine animierte Einzelbildershow.
	Autor:			Dominic Meier, ThreeWay AG
	Datum:			26.11.2009
	WICHTIG:		Funktioniert nur zusammen mit dem jQuery-Framework (http://jquery.com/)
*/

var ImageSwitcher = function(container_element) {
	
	// Konstruktor
	
	var _self = this;
	var root = $(container_element);
	var scope = root.find(".scope");
	var scope_bar = root.find(".scope_bar");
	var arrow_left = root.find(".arrow_left");
	var arrow_right = root.find(".arrow_right");
	var loading = root.find(".loading");
	
	var size = {
		width: scope.width(),
		height: scope.height()
	};
	
	var index_current_image = 0;
	var is_waiting = false;
	var image_list = [];
	var cyclic = false;
	var speed = "slow";
	
	// Private Methoden --------------------------------------------------------------------
	
	var preloadNeighbors = function(middle_index)
	{
		index = middle_index - 1;
		if (index < 0) index = image_list.length - 1;
		(new Image()).src = image_list[index];
		index = middle_index + 1;
		if (index == image_list.length) index = 0;
		(new Image()).src = image_list[index];
	};
	
	var prepareNextImage = function(index_next_image, dir)
	{
		if (is_waiting) return;
		is_waiting = true;
		loading.show();
		var next_image = new Image();
		next_image.onload = function() {
			loading.hide();
			preloadNeighbors(index_next_image);
			showNextImage(index_next_image, dir);
		};
		next_image.src = image_list[index_next_image];
	};
	
	var showNextImage = function(index_next_image, dir)
	{
		var img = getImage(image_list[index_next_image]);
		var new_left_value = scope_bar.position().left;
		if (dir == 1)
		{
			new_left_value -= size.width;
			scope_bar.append(img);
		}
		else
		{
			new_left_value = 0;
			scope_bar.css("left", "-" + size.width + "px");
			scope_bar.prepend(img);
		}
		scope_bar.animate({left: new_left_value}, speed, function() {
			is_waiting = false;
			if (dir == 1)
				scope_bar.find(":first-child").remove();
			else
				scope_bar.find(":last-child").remove();
			
			scope_bar.css("left", "0px");
			index_current_image = index_next_image;
		});
	};
	
	var getImage = function(image_src)
	{
		return $("<img src=\"" + image_src + "\" alt=\"\" width=\"" + size.width + "\" height=\"" + size.height + "\" />");
	};
	
	// oeffentliche Methoden --------------------------------------------------------------------
	
	this.start = function()
	{
		// Zeigt das erste Bild an und initialisiert den Controller.
		if (!image_list.length || scope_bar.children().length) return;
		scope_bar.width(size.width * 2);
		scope_bar.append(getImage(image_list[index_current_image]));
		arrow_right.bind("click", function(e){e.preventDefault(); _self.goRight();});
		arrow_left.bind("click", function(e){e.preventDefault(); _self.goLeft();});
	};
	
	this.randomStart = function()
	{
		// Startet den ImageSwitcher mit einem zufällig gewählten Bild
		index_current_image = Math.floor(Math.random()*image_list.length);
		this.start();
	};
	
	this.appendImage = function(image_url)
	{
		// Fuegt vorgaengig oder zur Laufzeit ein weiteres Bild am Ende hinzu.
		image_list.push(image_url);
	};
	
	this.prependImage = function(image_url)
	{
		// Fuegt vorgaengig oder zur Laufzeit ein weiteres Bild am Anfang hinzu.
		image_list.unshift(image_url);
	};
	
	this.setImageList = function(arr_images)
	{
		// Setzt alle Bilder auf einmal.
		image_list = [];
		for (var i = 0; i < arr_images.length; i++)
		{
			if (arr_images[i]) {
				this.appendImage(arr_images[i]);
			}
		}
	};	
	
	this.setCyclic = function(boolean)
	{
		// Bestimmt, ob wieder das erste Bild angezeigt wird, wenn das Ende erreicht ist (und umgekehrt).
		cyclic = boolean;
	};
	
	this.setSpeed = function(new_speed)
	{
		// Setzt das Tempo des Bilderwechsels.
		speed = new_speed;
	};
	
	this.goRight = function()
	{
		// Zeigt das naechste Bild an.
		if (index_current_image < image_list.length - 1)
			prepareNextImage(index_current_image + 1, 1);
		else if (cyclic)
			prepareNextImage(0, 1);
	};
	
	this.goLeft = function()
	{
		// Zeigt das vorherige Bild an.
		if (index_current_image > 0)
			prepareNextImage(index_current_image - 1, 0);
		else if (cyclic)
			prepareNextImage(image_list.length - 1, 0);
	};
	
	this.goTo = function(new_index)
	{
		// Zeigt das Bild an einer bestimmten Stelle an.
		if (new_index >= 0 && new_index < image_list.length)
			prepareNextImage(new_index, 1);
	};
};
