/**
 * A slideshow.
 * (c) 2008 Mikko Mensonen
 * Released into the public domain, use as you please :)
 */
SlideshowOptions = Object.extend({
	containerId: "slideshowContainer",
	frameInterval: 2,
	effectDuration: 4,
	loop: true,
	zoom: false,
	zoomLevel: 200,
	zoomSpeed: 2
}, window.SlideshowOptions || {});

var Slideshow = Class.create();

Slideshow.prototype = {
	initialize : function(container, imglist, options)
	{
		this.options = Object.extend(SlideshowOptions, options || {});
		this.imgCount = 0;
		this.timeOut = null;
		this.playing = false;
		this.imgStack = new Array();
		this.prevStack = new Array();
		$(container).appendChild(Builder.node('div', {
			'id' : this.options.containerId
		}));
		this.container = $(this.options.containerId);
		this.container.setStyle({
			position: 'relative',
			overflow: 'hidden',
			width: '100%',
			height: '100%'
		});
		imglist.each(function(i) {
			this.imgStack.push(new Slide(i, this));
		}, this);
	},
	next : function()
	{
		if (this.playing) return;
		
		this.playing = true;

		if (this.prevStack.last()) {
			if (!this.imgStack.first() && this.options.loop) {
				this.imgStack = this.prevStack;
				var resetprev = true;
			}
			if (this.imgStack.first().isZoomed()) {
				this.imgStack.first().revert();
			}
			if (!this.imgStack.first().loaded) {
				this.playing = false;
				return;
			}
			new Effect.Parallel([
				new Effect.Fade(this.prevStack.last().get(), {sync: true, duration: this.options.effectDuration}),
				new Effect.Appear(this.imgStack.first().get(), {sync: true, duration: this.options.effectDuration})
			], {
				duration: this.options.effectDuration,
				afterFinish : this.afterComplete.bind(this)
			});
			if (resetprev)
				this.prevStack = new Array();
		} else {
			if (!this.imgStack.first() || !this.imgStack.first().loaded) {
				this.playing = false;
				return;
			}
			new Effect.Appear(this.imgStack.first().get(), {
				duration: this.options.effectDuration,
				afterFinish : this.afterComplete.bind(this)
			});
		}
	},
	afterComplete : function()
	{
		this.prevStack.push(this.imgStack.shift());
		this.playing = false;
		if (this.options.zoom) {
			new Effect.Scale(this.prevStack.last().get(), this.options.zoomLevel, {
				fps: 30,
				scaleContent: false,
				delay: this.options.frameInterval,
				duration: this.options.zoomSpeed,
				scaleFromCenter: true,
				afterFinish: this.next.bind(this)
			});
			this.prevStack.last().setZoomed(true);
		} else {
			this.timeOut = window.setTimeout(function() { this.next() }.bind(this), this.options.frameInterval*1000);
		}
	}
}

var Slide = Class.create();

Slide.prototype = {
	initialize : function(imgsrc, parent)
	{
		parent.imgCount++;
		this.zoomed = false;
		this.count = parent.imgCount;
		this.src = imgsrc;
		this.loaded = false;
		this.container = parent.container;
		var imgPreloader = new Image();
		imgPreloader.onload = (function() {
			this.loaded = true;
			parent.next();
		}).bind(this);
		imgPreloader.src = this.src;
	},
	get : function()
	{
		if (!$('slide'+this.count)) {
			this.container.appendChild(Builder.node('img', {
				'id':'slide'+this.count
			}));
			$('slide'+this.count).setStyle({
				position: 'absolute'
			});
			$('slide'+this.count).hide();
			$('slide'+this.count).writeAttribute('src', this.src);
			this.originalDimensions = $('slide'+this.count).getDimensions();
		}
		return $('slide'+this.count);
	},
	setZoomed : function (zoomstate)
	{
		this.zoomed = zoomstate;
	},
	isZoomed : function()
	{
		return this.zoomed;
	},
	revert : function()
	{
		$('slide'+this.count).hide();
		$('slide'+this.count).setStyle({
			width : this.originalDimensions.width+'px',
			height : this.originalDimensions.height+'px',
			top: 0,
			left: 0
		});
	}
}
