//<!-- All material on this site, including web pages, JavaScript, graphics and other content
//	 is Copyright (c)2008 Internet Exposure -->
// $Revision: 52 $

//
// class ImageCycler
//
//	Parameters:
//		sThisVariableName	The name of the variable assigned to this object. This string is used when generating IMG names and the
//							event strings for the mouse events. It must match this object's name.
//		nInterval			Interval in milliseconds.
//		sTitleElementId		Id of DIV element whose title shall be updated when changing image groups. Specify null to disable.
//		asTitleElementHTML	Array of title HTML strings to update the sTitleElementId DIV. Use null if not required.
//		aasImageCodes		2-dimensional array of image code strings. These are converted to URLs by calling fnImageCodeToURL.
//		anGroupRepeats		Array of integers specifying how many times each group of images should repeat before moving to the next group.
//		fnImageCodeToURL	Function that converts image code strings to actual image URLs. The function should take a string parameter
//							and return a string. If image URLs were actually specified in aasImageCodes, then this function could simply
//							return the string parameter. I.e. use   function(s){ return s; }   as the fnImageCodeToURL parameter.
//		fnImageClicked		Function called when an image is clicked. Pass null if no action is required. The function must accept a
//							string parameter which is the image code as specified in the aasImageCodes array, and an integer identifying
//							which group is currently displayed.
//
function ImageCycler(sThisVariableName, nInterval, sTitleElementId, asTitleElementHTML, aasImageCodes, anGroupRepeats, fnImageCodeToURL, fnImageClicked)
{
	var FRAMES_PER_PHOTO = 20;
	var BATCH_STAGGER_FRAMES = 5;
	var MS_PER_FRAME = 35;

	this.sThisName = sThisVariableName;	
	this.nInterval = nInterval;
	this.sTitleElementId = sTitleElementId;
	this.asTitleElementHTML = asTitleElementHTML;
	this.aasImageCodes = aasImageCodes;
	this.anGroupCount = anGroupRepeats;
	this.fnImageCodeToURL = fnImageCodeToURL;
	this.fnImageClicked = fnImageClicked;
	
	this.aaImages = new Array(anGroupRepeats.length);
	for (var i = 0; i < anGroupRepeats.length; ++i)
	{
		this.anGroupCount[i] *= this.aasImageCodes[i].length;
		this.aaImages[i] = new Array(aasImageCodes[i].length);
	}
	
	this.nPositions = 0;
	
	this.nGroup = 0;
	this.nGroupImageCount = 0;
	this.nDisplayedGroup = this.nGroup;
	this.bGroupChange = true;
	this.nCurrentImage = 0;
	
	this.nFrame = 0;
	this.nSeqPosition = 0;//Always 0 in batch mode.
	this.bBatch = false;
	this.nPauseState = 0;
	
	this.asCurrentCode = new Array();
	
	this.GetNextImgElement = function()
	{
		var i = this.nPositions;
		var s = this.GetURL(this.nCurrentImage);
		this.asCurrentCode[i] = this.aasImageCodes[this.nGroup][i];
		++this.nPositions;
		this.nCurrentImage = (this.nCurrentImage + 1) % this.aasImageCodes[this.nGroup].length;
		++this.nGroupImageCount;
		return '<img alt="Patisserie" name="' + this.sThisName + "Image" + i + '" src="' + s + '" border=0 width=240 height=200 style="opacity:1.0;filter:alpha(opacity=100)" onclick="return ' + this.sThisName + '.Click(' + i + ');" onmouseover="' + this.sThisName + '.MouseEnter(' + i + ');" onmouseout="' + this.sThisName + '.MouseLeave(' + i + ');" onload="" onerror="">';
	}
	this.UpdateTitleHTML = function()
	{
		if (this.sTitleElementId != null)
			document.getElementById(this.sTitleElementId).innerHTML = this.asTitleElementHTML[this.nGroup];
	}
	this.GetURL = function(n)
	{
		return this.fnImageCodeToURL(this.aasImageCodes[this.nGroup][n]);
	};
	this.StartSequential = function()
	{
		this.bBatch = false;
		this.Prepare();
	}
	this.StartBatch = function()
	{
		this.bBatch = true;
		this.Prepare();
	}
	this.Click = function(nPosition)
	{
		if (this.fnImageClicked != null)
		{
			this.fnImageClicked(this.asCurrentCode[nPosition], this.nDisplayedGroup);
			return false;
		}
		return true;
	}
	this.MouseEnter = function(nPosition)
	{
		this.nPauseState = 1;
	}
	this.MouseLeave = function(nPosition)
	{
		if (this.nPauseState == 2)
			this.StartTimer();
		this.nPauseState = 0;
	}
	this.Prepare = function()
	{
		if (this.nGroupImageCount >= this.anGroupCount[this.nGroup])
		{
			this.nGroup = (this.nGroup + 1) % this.anGroupCount.length;
			this.nGroupImageCount = 0;
			this.nCurrentImage = 0;
			this.bGroupChange = true;
		}
		var i;
		var n;
		var iLimit = this.bBatch ? this.nPositions : 1;
		for (i = 0; i < iLimit; ++i)
		{
			n = (this.nCurrentImage + i) % this.aasImageCodes[this.nGroup].length;
			if (this.aaImages[this.nGroup][n] == null)
			{
				this.aaImages[this.nGroup][n] = new Image();
				this.aaImages[this.nGroup][n].src = this.GetURL(n);
			}
		}
		if (this.nPauseState == 0)
			this.StartTimer();
		else
			this.nPauseState = 2;
	}
	this.StartTimer = function()
	{
		this.nFrame = 0;
		var me = this;
		this.TimerId = setTimeout(function(){ me.OnTimeout() }, this.nInterval);
	}
	this.OnTimeout = function()
	{
		if (this.nFrame == 0 && this.nPauseState != 0)
		{
			this.nPauseState = 2;
			return;
		}
		if (this.bGroupChange)
		{
			this.UpdateTitleHTML();
			this.nDisplayedGroup = this.nGroup;
			this.bGroupChange = false;
		}
		var i = 0;
		var f;
		var n;
		var iLimit = this.bBatch ? this.nPositions : 1;
		for (i = 0; i < iLimit; ++i)
		{
			n = this.nFrame - (i * BATCH_STAGGER_FRAMES) - (FRAMES_PER_PHOTO - 1);
			if (n > -FRAMES_PER_PHOTO && n <= FRAMES_PER_PHOTO)
			{
				f = Math.abs(n / FRAMES_PER_PHOTO);
				//Note: this.nSeqPosition is always 0 in batch mode.
				var elt = document[this.sThisName + "Image" + (i + this.nSeqPosition)];
				elt.style.opacity = f;
				if (elt.filters != null)
					elt.filters.alpha.opacity = f * 100;
					
				if (n == 0)
				{
					elt.src = this.aaImages[this.nGroup][this.nCurrentImage].src;
					this.asCurrentCode[i + this.nSeqPosition] = this.aasImageCodes[this.nGroup][this.nCurrentImage];
					this.nCurrentImage = (this.nCurrentImage + 1) % this.aasImageCodes[this.nGroup].length;
					++this.nGroupImageCount;
				}
			}
		}
		
		if (n == FRAMES_PER_PHOTO)
		{
			if (!this.bBatch)
				this.nSeqPosition = (this.nSeqPosition + 1) % this.nPositions;
			this.Prepare();
		}
		else
		{
			++this.nFrame;
			var me = this;
			setTimeout(function(){ me.OnTimeout() }, MS_PER_FRAME);
		}
	}
}

