
/**
 * Slideshow component that will create a slideshow of images out of an element with the following structure:
 *	<div id="SlideshowContainer">
 * 		<ul id="SlideshowControls">
 * 			<li>[slide number]</li>
 * 			<li>[slide number]</li>
 * 			...
 *		</ul>
 * 
 * 		<div style="display: none;"><img src="[src]" /></div>
 * 		<div style="display: none;"><img src="[src]" /></div>
 * 		...
 * 	</div>
 */
var Slideshow = Class.create({
							 
	/** constructor */
	initialize: function() {
		
		this.current = 0;
		this.effect = null;
		this.timer = null;
		this.activeColor = "#E22624";
		this.inactiveColor = "#FFFFFF"
		
		this.controls = $$("#SlideshowControls li");
		this.slides = $$("#SlideshowContainer div");
		
		//wire up the slide numbers to be able to click to go to that slide
		this.controls.each(function(control, i) {
			control.observe("click", this.show.bindAsEventListener(this, i));
		}.bind(this));

		//show the first slide
		this.show(null, 0);
	},
	
	/** crossfades the current and next slide */
	crossfade: function() {
		var next = this.current + 1;
		
		if (next == this.slides.length)
		{
			next = 0;
		}
				
		this.effect = new Effect.Parallel([
				new Effect.Fade(this.slides[this.current], { sync: true}), 
				new Effect.Appear(this.slides[next], { sync: true})
			], { 
				duration: 2.0,
				beforeStart: function() {
					this.controls.invoke("setStyle", { backgroundColor: this.inactiveColor });
					this.controls[next].setStyle({ backgroundColor: this.activeColor });
				}.bind(this),
				afterFinish: function() {
					this.current = next;
				}.bind(this)
			}
		);
	},
	
	/** shows the slide at the given index (i) */
	show: function(event, i) {
		
		//kill the timer so another effect doesn't start
		if (this.timer)
		{
			this.timer.stop();
			this.timer = null;
		}
		
		//finish off the effect if it's running before we change slides
		if (this.effect)
		{
			this.effect.options['afterFinish'] = this._show.bind(this).curry(i);
			this.effect.finish();
			this.effect = null;
		}
		else
		{
			this._show(i);
		}
	},
	
	/** internally used by show() to actually change to a different slide (i) */
	_show: function(i) {
		
		//update what slide we're on
		this.current = i;
		
		//mark the proper slide number as active
		this.controls.invoke("setStyle", { backgroundColor: this.inactiveColor });
		this.controls[this.current].setStyle({ backgroundColor: this.activeColor });
		
		//show the right image
		this.slides.invoke("hide");
		this.slides[this.current].show();
		
		//kick off another crossfade
		this.timer = new PeriodicalExecuter(this.crossfade.bind(this), 4);
	}
});
