/**
 * WhSlideshow
 * (c) 2010 Hexon BV -- www.hexon.cx
 */

var MSIE = document.all ? true : false;

function WhSlideshow(el, options) {
	this.images			= [];
	this.currentImage	= 0;

	this.outerContainer	= null;
	this.container		= null;

	this.options = {
		// Image source
		'images':	[],

		// Layout options
		'width':			80,
		'height':			80,
		'enlargeImages':	true,
		'centerImages':		true,
		'showCaptions':		false,
		'containerIdBase':	'WhSlideshowImageContainer',
		'containerClass':	'WhSlideshowImageContainer',
		'imageIdBase':		'WhSlideshowImage',
		'imageClass':		'WhSlideshowImage',
		'captionIdBase':	'WhSlideshowCaption',
		'captionClass':		'WhSlideshowCaption',

		// Animation options
		'advanceDelay':	3000,
		'fadeDelay':	50,
		'fadeStep':		0.05,

		// Other options
		'showCaptions':		false,
		'addLinks':			true,
		'pauseOnMouseOver':	false
	};

	try {
		this.setOptions(options);
		this.setContainer(el);
	} catch(e) {
		this.handleError(e);
	}
}

WhSlideshow.prototype.setContainer = function(el) {
	if(typeof(el) == 'string') {
		el = document.getElementById(el);
	}

	if(el) {
		this.outerContainer	= el;

		this.container		= document.createElement('DIV');
		this.container.style.position	= 'absolute';
		this.container.style.width		= this.options.width + 'px';
		this.container.style.height		= this.options.height + 'px';
		this.container.style.overflow	= 'hidden';

		this.outerContainer.appendChild(this.container);
	} else {
		throw('Invalid container');
	}
}

WhSlideshow.prototype.setOptions = function(options) {
	if(typeof(options) == 'undefined') {
		return;
	}

	if(typeof(options) != 'object') {
		throw('Invalid options');
	}

	for(var key in options) {
		this.options[key] = options[key];
	}
}

WhSlideshow.prototype.loadImages = function(images) {
	switch(images.constructor) {
		case Array:
			for(var i in images) {
				this.buildImage(images[i]);
			}
			break;

		case Object:
			for(var i in images) {
				this.buildImage(i, images[i]);
			}
			break;

		default:
			throw('Invalid image type');
	}
}

WhSlideshow.prototype.buildImage = function(src, options) {
	var container		= document.createElement('DIV');

	container.id		= this.options.containerIdBase + this.images.length;
	container.className	= this.options.containerClass;

	container.style.position	= 'absolute';
	container.style.width		= '100%';
	container.style.height		= '100%';

	if(MSIE) {
		container.style.filter	= 'alpha(opacity=0)';
	} else {
		container.style.opacity	= 0;
	}

	container.WhSlideshow				= {};
	container.WhSlideshow.obj			= this;
	container.WhSlideshow.index			= this.images.length;
	container.WhSlideshow.currentOpacity	= 0;
	container.WhSlideshow.targetOpacity	= 0;
	container.WhSlideshow.fadeTimer		= null;

	var img			= document.createElement('IMG');

	img.id			= this.options.imageIdBase + this.images.length;
	img.className	= this.options.imageClass;
	img.src			= src;

	img.container	= container;
	img.onload		= function() { this.container.WhSlideshow.obj.fixImage(this); }.bind(img);

	if(this.options.pauseOnMouseOver) {
		container.onmouseover	= function() { this.WhSlideshow.obj.stop(); }.bind(container);
		container.onmouseout	= function() { this.WhSlideshow.obj.start(); }.bind(container);
	}

	if(this.options.addLinks && options && options.link) {
		container.onclick		= function() { this.WhSlideshow.obj.stop(); window.location = this.WhSlideshow.link; }.bind(container);
		container.WhSlideshow.link	= options.link;
		container.style.cursor	= 'pointer';
	}

	if(this.options.showCaptions && options && options.caption) {
		var caption			= document.createElement('DIV');

		caption.id			= this.options.captionIdBase + this.images.length;
		caption.className	= this.options.captionClass;
		caption.innerHTML	= options.caption;

		caption.style.position	= 'absolute';
		caption.style.width		= '100%';

		container.appendChild(caption);
	}

	container.appendChild(img);
	this.container.appendChild(container);
	this.images.push(container);
}

WhSlideshow.prototype.fixImage = function(img) {
	var width	= parseInt(img.clientWidth);
	var height	= parseInt(img.clientHeight);

	img.container.style.display	= 'none';

	var scale			= (width / height);
	var containerScale	= (this.options.width / this.options.height);

	if((width < this.options.width) && (height < this.options.height)) {
		if(!this.options.enlargeImages) {
			return;
		}
	}

	if(scale > containerScale) {
		var newWidth		= this.options.width;
		var newHeight		= newWidth / scale;

		img.style.width		= newWidth + 'px';
		img.style.height	= Math.floor(newHeight) + 'px';

		if(this.options.centerImages) {
			img.style.marginTop		= Math.floor((this.options.height - newHeight) / 2) + 'px';
		}
	} else {
		var newHeight		= this.options.height;
		var newWidth		= newHeight * scale;

		img.style.width		= Math.floor(newWidth) + 'px';
		img.style.height	= newHeight + 'px';

		if(this.options.centerImages) {
			img.style.marginLeft	= Math.floor((this.options.width - newWidth) / 2) + 'px';
		}
	}

}

WhSlideshow.prototype.start = function() {
	if(this.images.length > 0) {
		this.showImage(this.images[this.currentImage]);
		this.advanceTimer = setInterval(function(){ this.next(); }.bind(this), this.options.advanceDelay);
	}
}

WhSlideshow.prototype.stop = function() {
	clearInterval(this.advanceTimer);
}

WhSlideshow.prototype.next = function() {
	this.hideImage(this.images[this.currentImage]);
	this.currentImage = (this.currentImage + 1) % this.images.length;
	this.showImage(this.images[this.currentImage]);
}

WhSlideshow.prototype.hideImage = function(img) {
	this.fadeTo(img, 0);
}

WhSlideshow.prototype.showImage = function(img) {
	this.fadeTo(img, 1);
}

WhSlideshow.prototype.fadeTo = function(img, opacity) {
	if(img.WhSlideshow.fadeTimer) {
		clearInterval(img.WhSlideshow.fadeTimer);
	}

	img.WhSlideshow.targetOpacity = opacity;
	img.WhSlideshow.fadeTimer = setInterval(function(){ this.WhSlideshow.obj.fadeStep(this); }.bind(img), this.options.fadeDelay);
}

WhSlideshow.prototype.fadeStep = function(img) {
	var step = img.WhSlideshow.obj.options.fadeStep;
	var diff = Math.abs(img.WhSlideshow.targetOpacity - img.WhSlideshow.currentOpacity);

	img.style.display = 'block';

	if(diff <= step) {
		clearInterval(img.WhSlideshow.fadeTimer);
		var newOpacity = img.WhSlideshow.targetOpacity;

		if(img.WhSlideshow.targetOpacity == 0) {
			img.style.display = 'none';
		}
	} else if(img.WhSlideshow.currentOpacity < img.WhSlideshow.targetOpacity) {
		var newOpacity = img.WhSlideshow.currentOpacity + step;
	} else {
		var newOpacity = img.WhSlideshow.currentOpacity - step;
	}

	if(MSIE) {
		img.style.filter = 'alpha(opacity=' + (newOpacity * 100) + ')';
	} else {
		img.style.opacity = newOpacity;
	}

	img.WhSlideshow.currentOpacity = newOpacity;
}

WhSlideshow.prototype.init = function() {
	try {
		this.loadImages(this.options.images);
		this.start();
	} catch(e) {
		this.handleError(e);
	}
}

WhSlideshow.prototype.handleError = function(e) {
}

Function.prototype.bind = function(obj, args) {
	var self = this;

	args = args || [];

	return function() {
		return self.apply(obj, args);
	}
}
