var imageslideshowEngine = function()
{
	/*
	author:Giuseppe
	date: 20/08/2007
	notes:
	This function is to fade in and out the images and linkboxes.
	 
	Revised and modified by Matt for Roccoforte Angleterre adding JQuery functionality, pause, play and image jump
	Revised by Giuseppe 17/09/2008 fixed minor naming problem
	Revised by Matt 19/09/2008
	- corrected the year in Giuseppe's previous revision date ;)
	- added optional this.fadeSpeed, and made interval optional as well
	- added optional callback parameter, which should be a function expecting a single object:
	{ from: i, to: j },  where i and j are the image indices
	 
	NOTE: Requires JQuery
	*/
	this.name = 'imageslideshowEngine';
	this.currentIndex = 0;
	//initializing to [] so later on the a.length function will not fail if either the images or linkboxes are not available
	this.images = [];
	this.linkboxes = [];
	this.pairs = [];
	this.fadeClock = null;
	this.linkboxMaxHeight = 0;

	this.init = function(interval, fadeSpeed, callback)
	{
		var i;
		this.interval = interval || 3000;
		this.fadeSpeed = fadeSpeed || 1000;
		this.callback = callback;

		for (i = 1; i < this.images.length; i++)
		{
			this.initElement(this.images[i]);
		}
		for (i = 1; i < this.linkboxes.length; i++)
		{
			this.initElement(this.linkboxes[i]);
		}
		this.associateImagesToLinkboxes();
		this.currentIndex = 0;

		// trigger initial callback as if transitioning to the first item
		if (callback)
		{
			callback({
				to: this.currentIndex
			});
		}

		var slideshowengine = this;
		this.fadeClock = setInterval(function()
		{
			slideshowengine.fadeEngine();
		}, this.interval);
	};

	this.doFade = function(fromIndex, toIndex)
	{
		if (this.pairs === undefined || this.pairs.length <= 1)
		{
			return;
		}

		var pairout = this.pairs[fromIndex];
		var pairin = this.pairs[toIndex];

		// only fade out if we're actually swapping to a new item
		if (pairout.image != pairin.image)
		{
			this.fadeOut(pairout.image);
		}
		if (pairout.linkbox != pairin.linkbox)
		{
			this.fadeOut(pairout.linkbox);
		}

		this.fadeIn(pairin.image);
		this.fadeIn(pairin.linkbox);

		if (this.callback)
		{
			this.callback({
				from: fromIndex,
				to: toIndex
			});
		}

		this.currentIndex = toIndex;
	};

	this.fadeEngine = function()
	{
		var outIndex = this.currentIndex;
		var inIndex = (this.currentIndex === undefined) ? 0 : (++(this.currentIndex) >= this.pairs.length) ? 0 : this.currentIndex;

		this.doFade(outIndex, inIndex);
	};


	this.jumpToPair = function(toIndex, pause)
	{
		if (pause)
		{
			this.pauseEngine();
		}
		this.doFade(this.currentIndex, toIndex);
	};

	this.pauseEngine = function()
	{
		clearInterval(this.fadeClock);
	};

	this.unpauseEngine = function()
	{
		var slideshowengine = this;
		this.fadeClock = setInterval(function()
		{
			slideshowengine.fadeEngine();
		}, this.interval);
	};

	this.getLinkboxMaxHeight = function()
	{
		for (var i = 0; i < this.linkboxes.length; i++)
		{
			this.linkboxMaxHeight = Math.max(this.linkboxMaxHeight, this.linkboxes[i].offsetHeight);
		}
		return this.linkboxMaxHeight;
	};

	this.associateImagesToLinkboxes = function()
	{
		var i, o;
		var maxindex = (this.images.length > this.linkboxes.length) ? this.images.length : this.linkboxes.length;

		for (i = 0; i < maxindex; i++)
		{
			o = {
				image: this.images[i] || (this.images.length > 0 ? this.images[this.images.length - 1] : null),
				linkbox: this.linkboxes[i] || (this.linkboxes.length > 0 ? this.linkboxes[this.linkboxes.length - 1] : null)
			};
			this.pairs.push(o);
		}
	};

	this.initElement = function(el)
	{
		el.style.position = 'absolute';
		el.style.display = 'none';
		//jQuery(el).css({ 'position': 'absolute' });
		//jQuery(el).hide();
	};

	this.fadeIn = function(el)
	{
		jQuery(el).fadeIn(this.fadeSpeed);
	};

	this.fadeOut = function(el)
	{
		jQuery(el).fadeOut(this.fadeSpeed);
	};
};
