/**
 *	A slide show is a number of pictures that have been segmented 
 *  into parts. It's slides through a part until the last elemetn
 *  of a segment. It then waits for a click.
 */
var SlideShow = {

	showIn : null,
	info : null,
	nImagesLoaded : 0,
	nImages : 0,
	images : {},
	slideTexts: [],
	
	segModel : [],
	
	slot : 0,
	segment : 0,
	nSegments : 0,
	inCycle : false,
	inside : false,

	timer : null,

	/**
	 *	Initialize the data-members and start loading the images
	 */
	__construct : function(showIn, info, slideTexts) {
	
		this.info = info;
		this.showIn = showIn;
	
		this.setupModel(info);
	
		// load images
		this.loadImages(info);
		
		//load textst
		this.loadSlideTexts();
		
		
	},
	
	/**
	 *	Setup the slot models
	 */
	setupModel : function(info) {
	
		var thiz = this;
		var segIdx = 0;
		
		// iterate over segments
		$(info).children("ul").each(function() {
			var slotContents = [];
			var slotIdx = 0;
			
			// iterate over slots
			$(this).children("li").each(function() {
				slotContents[slotIdx] = $.trim($(this).text());
				++slotIdx;
			});
			
			thiz.segModel[segIdx] = slotContents;
			++segIdx;
			
		});
		
		this.nSegments = segIdx;
		
	},


	/**
	 *	Preload the images
	 */
	loadImages : function(info) {
	
		var imageUrls = [];
		
		// extract image names
		$("li", info).each(function() {
			imageUrls.push($(this).text());
		});
		
		this.nImages = imageUrls.length;
		
		for (var idx in imageUrls) {
			var img = new Image();
			img.src = $.trim(imageUrls[idx]) + "?time=" + new Date().getTime();
			
			var thiz = this;
			$(img).load(function() {
				
				++thiz.nImagesLoaded;
				
				var src = $(this).attr("src").substr(0,$(this).attr("src").indexOf("?"));
				thiz.images[src] = $(this);

				if (thiz.nImages == thiz.nImagesLoaded) {
					thiz.startShow();
				}
			});
		}	
	},
	
	/**
	 *	Preload the textst placed on the images
	 */
	loadSlideTexts : function() {
		
		var thiz = this;
		// extract image names
		$("div.textHolder").each(function() {
			var element = $(this).clone();
			var vDiv = $(".visual", element);
			vDiv.removeClass("visual").attr("id", "visual");
			//.html makes nice string
			thiz.slideTexts.push(element.html());
		});
	},
	
	/**
	 *	all images were loaded, so show the arrow that can start
	 *  a segment cycle.
	 */
	startShow : function() {

		var thiz = this;
		
		this.insertFirstBehind();

	
		$("#animation_arrow")
			.fadeIn(250)
			.pulse({opacity:[0.6,1] },{duration:850, times:100})
			.click(function() {
				$(this).stop();

				$(".front", thiz.showIn)
					.stop(true, true)
					.animate({}, 100, function() {
						$(".behind", thiz.showIn).remove();
						$("#visual div:visible").fadeOut(200);
						thiz.startCycle();
					});
			});
	},
	
	
	/**
	 *	Start the cycle
	 */
	startCycle: function() {
		var thiz = this;
		this.inCycle = true;
		$("#animation_arrow").fadeOut(250, function() {
			thiz.timer = setInterval(function() {thiz.nextSlide();}, 1500);
		});
		$(".animation_textblock").remove();
	},
	

	/**
	 *	This method is called on interval and displays next slide
	 */	
	nextSlide : function() {

		var newImg = this.images[this.segModel[this.segment][this.slot]].clone();
		newImg.addClass("behind");

		var isLastSlot = this.segModel[this.segment].length - 1 == this.slot;

		var thiz = this;
		
		this.showIn.append(newImg);
		$(".front", this.showIn)
		.animate({ "left" : (!isLastSlot ? "+=50" : "+=0") , opacity: 0.0 }, 500,
			function() {
				newImg.addClass("front").removeClass("behind");
				$(this).remove();
				
				++thiz.slot;
		
				if (thiz.slot >= thiz.segModel[thiz.segment].length) {
					thiz.slot = 0;
					
					$(thiz.showIn).prepend(thiz.slideTexts[thiz.segment]);
					
					++thiz.segment;
			
					if (thiz.segment == thiz.segModel.length) {
						thiz.segment = 0;
					}
			
					thiz.stopCycle();
				}				
			}
		);

	},


	/**
	 *	Insert the first next behind image so the hover has something to show
	 */
	insertFirstBehind : function() {
	
		var backImg = this.images[$.trim(this.segModel[this.segment][0])].clone();
		backImg.addClass("behind");
		
		this.showIn.append(backImg);
		
	},
		

	/**
	 *	Stop the cycle and wait for user input to go to next slot
	 */
	stopCycle : function() {
		clearTimeout(this.timer);
	
		$("#animation_arrow")
			.css("opacity", "0")
			.show()
			.animate({"opacity": "1"}, 250);
		$("#animation_arrow").pulse({opacity:[0.6,1] },{duration:850, times:100})
		
		$("#visual div", this.showIn).css("z-index","11");
		
		
		this.inCycle = false;
		this.insertFirstBehind();
		
		if (this.segment === 0) {
			$("#visual div").fadeIn(100);
		}
		
	}

};


function create_slideshow(showin, info, slideTexts) {

	for (var idx in SlideShow) {
		this[idx] = SlideShow[idx];
	}
	
	this.__construct(showin, info, slideTexts);
	return this;
}

