var imageslideshowEngine = function()
{
	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);
	};
};
