/**
	An object that manages a slideshow with control buttons.
	
	This class supports jQuery animation for fade in and out effects, but it is optional. 
	If the jQuery animation class is included it will be used, otherwise it will not. 
	
	This class does not require jQuery to work, it is an option. Without jQuery it will not fade in and out, 
	but everything will still work.
	
	Control links allow jumping to a slide directly, and stop the show.
	
	parameters
	slides: html elements of all the slides
	controlLinks: html elements of control links that allow going to a slide directly
	timeout: ms between slides
	
**/

function SlideShow(slides, timeout, fadeSpeed, controlLinks) {
	var t = this;
	
	// ------- functions -------------
	/** 
	load a slide using fade-out + fade-in animation 
	This method fades out the current slide and then fades in the new slide
	buy registering a listener to the end of the fade out.
	**/
	t.load = function (index) {
		var t = this;
		//log ('shw_load: '+ index);
		// first change the style of the control links for immediate user feedback
		if (t.controlLinks){
			for (var i = 0; i < t.controlLinks.length; i++)
				SL.util.removeClass(t.controlLinks[i], 'selected');
			SL.util.addClass(t.controlLinks[index], 'selected');
		}
		if (window.jQuery){
			// has jQuery, we can animate
			if (t.animation){
				// there is animation running, kill immediately and do not fade out
				//t.animation.killed = true;
				t.animation.stop(true,false);
				t.animation = null;
				//log ('shw_load: killed animation, calling finished '+ index);
				// go straight to the next slide without fadeout
				t.finished(index);
			}else{
				// fade out animation
				// callback to fade in the next slide
				var callback = function() {
					t.animation = null;
					t.finished(index);
				};
				t.animation = jQuery(t.slides[t.selected]);
				// start
				t.animation.animate({opacity: 0}, t.speed,'', callback);
			}
		}else
			//log ('calling finished no jQuery');
			t.finished(index);
		
		return false; 
	}
	
	/** Called on this object by control links after a click **/
	t.click = function (index) {
		if (index != t.selected){
			// stop slide show on click
			t.stopLoop();
			// load next slide
			t.load(index)
		}
	};

	/** 
	Called after removing the current slide to show the next.
	This is normally called when the animation finished fading out a slide, to fade in a new slide.
	**/
	
	t.finished = function (index) {
		var t = this;
		//log ('finished: '+ index +' '+ t.selected);
		
		// optional: fade in animation
		if (window.jQuery){
			var callback = function() {
				// IE bug: Font rendering problems with opacity. During animation we 
				// still see that problem, but we can get rid of it at the end.
				t.slides[index].style['filter'] = '';
				if (t.animation != null)
					t.animation.stop(true,false);
				t.animation = null;
			}
			// fade in
			t.animation = jQuery(t.slides[index]);
			t.animation.css('opacity', 0);
			// swap slides
			t.showSlide(index);
			t.animation.animate({opacity: 1}, t.speed,'', callback);
			// make new slide visible.
			// show asynch to avoid flashing (YUI starts after this method finishes, so opacity is 1 initially and visible)
			//window.setTimeout(function(){ t.showSlide(index); }, 1);
		}
		else{
			// no jQuery, just show
			t.showSlide(index);
		}
	};

	/** Jump to a single slide and make it visible immediatly **/
	t.showSlide = function (index){
		//var t = this;
		SL.util.addClass(t.slides[t.selected], 'hidden');
		SL.util.removeClass(t.slides[index], 'hidden');
		t.selected = index;
	};
	
	/** 
		Called by the animation thread to roll the next slide.
		Rotates all slides, and then stop at the first.
	**/
	t.loop = function(){
		var i = t.selected + 1;
		if (i < t.slides.length)
			// has more slides, animate next
			t.load(i);
		else{
			// end of loop, remove loop object to stop animation
			t.stopLoop();
			// load first slide again
			t.load(0);
		}
	};
	
	/** Stop the automatic play **/
	t.stopLoop = function(){
		if(t.sched){
			window.clearInterval(t.sched);
			t.sched = null;
			t.loop = null;
		};
	}
	
	// ------- values -------------
	t.slides = slides;
	t.controlLinks = controlLinks;
	t.selected = 0;
	t.speed = fadeSpeed;
	
	// ------- Constructor code -------------
	// hook up events to control links
	if (controlLinks)
		for (var i=0; i<t.controlLinks.length; i++)
		{
			// set the slide index on the link object
			controlLinks[i].viewIndex = i;
			// 'this' is that case is the link object, this object (SlideShow) is the passed reference 't'
			controlLinks[i].onclick = function(){ t.click(this.viewIndex); return false; };
		}

	// start animation thread
	t.sched = window.setInterval(function(){ t.loop(); }, timeout);
}

/** 
	A utility method that creates the slideshow object.
	This is optional, the object can be created directly by the page.	
**/
function slideShowFactory(slidesExpr, clicksExpr, timeout){
	// splitting the expression to two seems to run a lot less code.
	// The single expression traverses the whole dom tree ???
	var slides = jQuery(slidesExpr);
	if (!slides || slides.length <= 1)
		return;
	var links = jQuery(clicksExpr); 
	if (!timeout) timeout = 3000;	
	return new SlideShow(slides, timeout, 600, links);
}
// loggin code for debugging
/*
var log_i = 0;
function log (str){
	var lg = document.getElementById('log');
	//if (!lg){
	//	var body = document.getElementsByTagName('body')[0];
	//	body.innerHTML = "<div id='log' style='position:absolute; background-color: yellow'></div>" + body.innerHTML;
	//	lg = document.getElementById('log');
	//}
	
	lg.innerHTML = lg.innerHTML + '<p>' +(log_i++) + '. ' + str + '</p>'; 
}
*/