/** 
* @author   $Author: martijn $
* @revision $Revision: 2 $
* @date     $Date: 2009-02-11 15:58:55 +0100 (Wed, 11 Feb 2009) $
*
* this fotofader class can be used to fade images in and out
* it works with a div and an image inside it.
* - the div this.as the back and has a image as background, from now on called : back
* - the image in it works like the front, from now on called : front
*
* the back never fades in or out, only the front fades in and out.
* when the front is 100% visible, the back is not visible (because the front is overlapping it), thus the back image can be changed without notice 
* other way around, when the front is 0% visible (thus hidden), the back is shown and the front can be changed without notice
*/


/**
* fotoFader class
*/
fotoFader = function()
{
	
	// This is a workaround for an error in the ECMAScript Language Specification which causes this to be set incorrectly for inner functions.
	var self = this;

	this.fotoFaderBack         = 'carousel_image1'; // todo make this configurable/settable 
	this.fotoFaderFront        = 'carousel_image2'; // todo make this configurable/settable
	this.imageCollection;                           // array which holds the images which will fade
	this.aLinks										// array which holds the links for the images
	this.imageCollectionSize;                       // will be filled automatically
	this.imageToDisplay        = 0;                 // holds the image to fade in/out. the initial displayed image is 0
	this.imageAlpha            = 100;               // the initial alhpa value of initial image
	this.displayTime           = 5000;              // nr of millisecs that a image is displayed before fading. todo make this publicaly configurable/settable
	this.fadeSpeed             = 50;                // the smaller the faster the fading. todo make this publicaly configurable/settable

	this.showFadePosition      = false;             // create "buttons" to show and override the current position
	this.fadeButtonClassActive = "buttonactive";    // which class must the buttons have when it is highlighted
	this.addFadeButtonsTo      = "buttonholder";    // ID of the object in which the buttons should be placed

	this.oTimeout;
	this.overRideTo;

	/**
	* Sets the image collection to fade in/out
	*/
	this.setImages = function(images)
	{
		this.imageCollection     = images;
		this.imageCollectionSize = this.imageCollection.length;
	}

	this.setLinks = function(aLinks)
	{
		this.aLinks = aLinks;
	}
	
	/**
	* Does some inital testing and setting up
	*/
	this.initFotoFader = function()
	{
		// object to place images in is not found - exiting
		if(!document.getElementById(this.fotoFaderBack)) return;

		// are there more then 1 image?
		if(this.imageCollectionSize <= 1) 
		{
			// no, there is just 1 image, don't do anything
			return;
		}

		// build the buttons for the different slides
		if(this.showFadePosition == true)
		{
			oButtonContainer = document.getElementById(this.addFadeButtonsTo);

			for(i = 0; i < this.imageCollectionSize; i++)
			{
				var tag = document.createElement("div");
				tag.className = this.fadeButtonClass;
				tag.id = "carouselbutton_" + i;
				tag.onclick = function () { fotoFader.overrideFader(this.id); }
				tag.innerHTML = (i + 1);

				oButtonContainer.appendChild(tag);
			}
		}


		// there is more then 1 image, assume there already is a front image, so start with fading out		
		// start with fading in, but because the front alpha already is 100, 
		// a new back will be loaded and fading the front out will start after display time
		fotoFader.fadeInFront();
	}
	
	/**
	* Sets the back, background image expect urls without spaces
	*/
	this.setBack = function(backImageUrl)
	{
		document.getElementById(this.fotoFaderBack).style.backgroundImage = 'url(' + backImageUrl + ')';
	}
	
	/**
	* Set the front, front image
	*/
	this.setFront = function (frontImageUrl)
	{
		// set a nwe background image into the front
		document.getElementById(this.fotoFaderFront).style.backgroundImage = 'url(' + frontImageUrl + ')';
	}
	
	
	/**
	* Handles the fading in of the front (from 0 to 100%)
	* Sets a new back image and starts the fading out (again)
	*/
	this.fadeInFront = function() 
	{
		// increase the alpha of the front image
		this.imageAlpha += 5;
		this.setFrontOpacity(this.imageAlpha);
		
		if(this.imageAlpha >= 100)
		{
			// when fading in is 100% done, load the next photo into the back


			if(this.showFadePosition == true)
			{
				// when using buttons to show the current fade position, highlight the current button
				this.delightButtons();
				oButtonObject = document.getElementById("carouselbutton_" + this.imageToDisplay);
				oButtonObject.className = this.fadeButtonClassActive;
			}

			// increment the image to display
			this.imageToDisplay++;

			if(this.imageToDisplay >= this.imageCollectionSize) 
			{
				// when there is no more next image restart
				this.imageToDisplay = 0;
			}
		

			this.setBack(this.imageCollection[this.imageToDisplay])
			
			// start fading out the front after dipslay time
			this.oTimeout = setTimeout( function() { fotoFader.fadeOutFront(); }, this.displayTime);
			
		}
		else
		{
			// continue fading in
			setTimeout( function() { fotoFader.fadeInFront(); }, this.fadeSpeed);
			
		}
	}
	
	/**
	* Handles the fading out of the front image (from 100 to 0)
	* Sets a new front image and starts the fading in (again)
	*/
	this.fadeOutFront = function()
	{
		// decrease the alpha for the front image
		this.imageAlpha -= 5;
		this.setFrontOpacity(this.imageAlpha);
		
		if(this.imageAlpha <= 0)
		{
			// when the front image is invisible, set a new front image


			if(this.showFadePosition == true)
			{
				// when using buttons to show the current fade position, highlight the current button
				this.delightButtons();
				oButtonObject = document.getElementById("carouselbutton_" + this.imageToDisplay);
				oButtonObject.className = this.fadeButtonClassActive;
			}

			// increment image to display
			this.imageToDisplay++;

			if(this.imageToDisplay >= this.imageCollectionSize) 
			{
				// when there is no more next image restart
				this.imageToDisplay = 0;
			}
	
			// set the next image into the front
			this.setFront(this.imageCollection[this.imageToDisplay]);
			
			// start fading in after display time
			this.oTimeout = setTimeout( function() { fotoFader.fadeInFront(); }, this.displayTime);
		}
		else
		{
			// continue fading out
			setTimeout( function() { fotoFader.fadeOutFront() }, this.fadeSpeed);
		}
	}
	
	/**
	* Sets the opacity of the front
	*/
	this.setFrontOpacity = function(iAlpha)
	{
		//alert('setFrontOpacity(' + iAlpha + ')');
		
		oObject = document.getElementById(this.fotoFaderFront);
		oObject.style.filter = 'alpha(opacity = ' + iAlpha + ')'; // for IE
		oObject.style.MozOpacity = (iAlpha / 100);                // for firefox
		oObject.style.opacity = (iAlpha / 100);                   // for opera
	}

	/**
	* delights all buttons, when using buttons to display the current image
	*/
	this.delightButtons = function()
	{
		for(i = 0; i < this.imageCollectionSize; i++)
		{
			oCurrentButton = document.getElementById("carouselbutton_" + i);
			oCurrentButton.className = '';
		}
	}

	/**
	* manually overrides the current position
	*/
	this.overrideFader = function(sFadeTo)
	{
		// need to call the fotoFader object, instead of this, because it is called from outside the object (by onclick)

		iFadeTo = sFadeTo.replace("carouselbutton_", "");
		fotoFader.imageToDisplay = iFadeTo;
		// stop fading
		clearTimeout(fotoFader.oTimeout);

		if(fotoFader.imageAlpha >= 100 || fotoFader.imageAlpha <= 0)
		{
			// currently not fading, safe to load new image
			if(fotoFader.imageAlpha >= 100)
			{
				// front is being displayed, load back image and start fading
				fotoFader.setBack(fotoFader.imageCollection[iFadeTo]);
				// wait 250ms to load the image
				setTimeout( function() { fotoFader.fadeOutFront(); }, 250);
			}
			else
			{
				// background is being displayed, load front image and start fading
				fotoFader.setFront(fotoFader.imageCollection[iFadeTo]);
				// wait 250ms to load the image
				setTimeout( function() { fotoFader.fadeInFront(); }, 250);
			}
		}
		else
		{
			// currenty in the process of fading, calculate the maximum time it will take to finish, and try again
			if(fotoFader.imageAlpha >= 50)
				iMaxStepsRemaining = (fotoFader.imageAlpha / 5);
			else
				iMaxStepsRemaining = ((100 - fotoFader.imageAlpha) / 5);

			iTimeToWait = (iMaxStepsRemaining * fotoFader.fadeSpeed);
			setTimeout( function() { fotoFader.overrideFader(sFadeTo); }, iMaxStepsRemaining);
		}
	}


	this.click = function()
	{
		iLink = (this.imageToDisplay - 1);
		if(iLink == -1) iLink = (this.imageCollectionSize - 1);

		if(typeof(this.aLinks[iLink]) == "string") window.location = this.aLinks[iLink];
	}
}

