/**
 * Etalage class to animate on front page. 
 * Based on NBo's Carrousel.
 * @author JMutsaerts <jmutsaerts@zigwebsoftware.nl>
 * @version 1.0
 * @since 30 mrt 2010 10:09:52 
 * @copyright Copyright (c) 2010, Zig Websoftware
 * @package SSW_JS
 */	
Etalage = function(aItems)
{
	// Elements	
	this.sImageReel				= 'imageReel';
	this.sImageReelSlider		= 'imageReelSlider';
	this.sNextButton			= 'btn_next';
	this.sPrevButton			= 'btn_prev';
	
	// Items	
	this.aItems					= $(this.sImageReelSlider).childElements();
	this.iNumTotalItems			= this.aItems.length;
	this.iItemWidth				= this.aItems[0].getWidth();		
	this.iNumItemsPerBlock		= 5;
	this.iNumBlocks				= Math.ceil(this.iNumTotalItems / this.iNumItemsPerBlock);
	this.iBlockWidth			= this.iNumItemsPerBlock * this.iItemWidth;
	
	/**
	 * @var int
	 * @access private
	 */
	this.iCurrentImageID		= 0;
	
	/**
	 * @var int
	 * @access private
	 */
	this.iCurrentBlockID		= 0;
	
	// ANIMATION
	
	/**
	 * Has interval started/stopped?
	 * @var bool
	 */
	this.bPaused				= true;
	
	/**
	 * Is Etalage scrolling a block?
	 * If this is true, changing an image will be ignored (useful when clicking next/prev too fast)
	 * @var bool
	 * @access private
	 */
	this.bScrolling				= false;
	
	/**
	 * Amount of ms between intervals
	 * @var int
	 * @access private
	 */
	this.iInterval				= 1000;
	
	/**
	 * Identifier of currently set interval
	 * @var int
	 * @access private
	 */
	this.iIntervalID			= null;
	
	/**
	 * Do the items change randomly or in ascending order?
	 * @var bool
	 * @access private
	 */
	this.bRandom				= false;
	
	// OPTIONAL HANDLERS
	
	/**
	 * Called when an image is selected
	 * @var Function
	 * @access public
	 */
	this.onSelectImage			= null;
	
	/**
	 * Called when an image is deselected
	 * @var Function
	 * @access public
	 */
	this.onDeselectImage		= null;
	
	// Init
	$(this.sImageReel).style.width	= this.iBlockWidth * this.iNumBlocks + 'px';

	/**
	 * Select next image
	 * @return int
	 */
	this.selectNext = function()
	{
		// Increment image ID
		var iReturn = this.selectImage(this.iCurrentImageID + 1);
		this.onSelectImage(this.getSelectedImage);
		return iReturn;
	}
	
	/**
	 * Select previous image
	 * @return int
	 */
	this.selectPrev = function()
	{
		// Decrement image ID
		var iReturn = this.selectImage(this.iCurrentImageID - 1);
		this.onSelectImage(this.getSelectedImage);
		return iReturn;
	}
	
	/**
	 * Start animation (if not started or before)
	 * @return void
	 */
	this.play = function(iInterval, bRandom)
	{
		if(this.bPaused)
		{
			if(iInterval)
			{
				this.iInterval = iInterval;
			}
			if(bRandom)
			{
				this.bRandom = bRandom;
			}
		
			// Create a reference to this Etalage instance to pass to the interval handler (using 'this' would reference the window)
			var oRefInstance = this;
			// Create interval handler
			var fnIntervalHandler = function()
			{
				// Handler for interval: select next image on each interval
				var iLastImageID	= oRefInstance.iCurrentImageID;
				var iNewImageID		= iLastImageID;	// Make the first while loop return true;
				
				if(oRefInstance.bRandom)
				{
					while(iNewImageID == iLastImageID)
					{
						iNewImageID = Math.floor(Math.random() * oRefInstance.iNumTotalItems);
					}
					iNewImageID		= oRefInstance.selectImage(iNewImageID);
				}
				else
				{
					iNewImageID		= oRefInstance.selectNext();							
				}						
				
				var oLastImage	= oRefInstance.aItems[ iLastImageID ];
				var oNewImage	= oRefInstance.aItems[ iNewImageID ];
				
				// Call handler if set
				if(oRefInstance.onDeselectImage instanceof Function)
				{
					oRefInstance.onDeselectImage(oLastImage);
				}
				
				// Call handler if set
				if(oRefInstance.onSelectImage instanceof Function)
				{
					oRefInstance.onSelectImage(oNewImage);
				}
				
										
			}
			
			this.iIntervalID = setInterval(fnIntervalHandler, this.iInterval);								
			//fnIntervalHandler();				
			this.bPaused = false;
		}
	}
	
	/**
	 * Pause animation
	 * @return void
	 */
	this.pause = function()
	{
		clearInterval(this.iIntervalID);
		this.iIntervalID = null;
		this.bPaused = true;
	}
	
	/**
	 * Stop animation
	 * @return void
	 *
	 */
	this.stop = function()
	{
		this.pause();
		// Reset identifiers
		this.selectImage(0);
	}
	
	/**
	 * Select an image (will scroll to it's block if necessary)
	 * @param int Image ID 
	 * @return int selected Image ID
	 */
	this.selectImage = function(iImageID)
	{
		if(iImageID >= this.iNumTotalItems)
		{
			// New image ID is passed the total, so go to 0
			iImageID = 0;
		}
		else if(iImageID < 0)
		{
			// There are no negative image ID's, so select the last
			iImageID = this.iNumTotalItems - 1;
		}
			
		if(!this.bScrolling)
		{			
			// Get the block on which the next image is on
			var iNextBlockID = this.getBlockID(iImageID);
			
			// Scroll the difference if necessary
			if(iNextBlockID != this.iCurrentBlockID)
			{
				this.scrollToBlock(iNextBlockID);
			}		
			
			// Call handler if set
			if(this.onDeselectImage instanceof Function)
			{
				this.onDeselectImage(this.aItems[ this.iCurrentImageID ]);
			}		
			// Call handler if set
			if(this.onSelectImage instanceof Function)
			{
				this.onSelectImage(this.aItems[ iImageID ]);
			}
			
			// Set the new properties
			this.iCurrentImageID = iImageID;
			this.iCurrentBlockID = iNextBlockID;
		}
		return this.iCurrentImageID;
	}
	
	/**
	 * 
	 */
	this.selectElement = function(oElement)
	{
		var iID = this.aItems.indexOf(oElement);
		
		if(iID >= 0)
		{
			this.selectImage(iID);
		}
	}
	
	/**
	 * @access private
	 * @param int	
	 * @return void
	 */
	this.scrollToBlock = function(iNewBlockID)
	{		
		if(iNewBlockID >= this.iNumBlocks)
		{
			// New block ID is passed the total, so go to 0
			iNewBlockID = 0;
		}
		else if(iNewBlockID < 0)
		{
			// There are no negative Block ID's, so select the last
			iNewBlockID = this.iNumBlocks - 1;
		}
		
		var iNumBlocks = (iNewBlockID - this.iCurrentBlockID) * -1;
		
		// 'lock for scrolling'
		this.bScrolling = true;
		var oRefInstance = this;
		new Effect.Move
		(
				this.sImageReelSlider,
				{
					x: this.iBlockWidth * iNumBlocks,
					y: 0,
					mode: 'relative',
					afterFinish: function()
					{
						// 'unlock for scrolling'
						oRefInstance.bScrolling = false;
					}
				}
		);
		

		
		this.iCurrentBlockID = iNewBlockID;
		return this.iCurrentBlockID;
	}
	
	/**
	 * Get the block ID for an image
	 * @param int	iImageID	ID of the image to get the block ID for
	 * @return int				ID of the block on which the image is on
	 */
	this.getBlockID = function(iImageID)
	{
		return Math.ceil((iImageID + 1) / this.iNumItemsPerBlock) - 1;
	}	
	
	/**
	 * Get the currently selected item
	 * @return object
	 */
	this.getSelectedItem = function()
	{
		return this.aItems[ this.iCurrentID ];
	}
	
}

// INSTANTIATION
// Declare oEtalage out of scope for easier manipulation
var oEtalage;
var aEtalageItems = [];
// Settigns
var iEtalageInterval;
var bEtalageRandom;
// Whether to use an effect
var bEtalageUseEffect = true;
// Type of effect 
var sEtalageTypeEffect = 'Vervagen';
// Duration of the effect (if applicable)
var iEtalageTimeEffect = 0.5;

// Wait for dom to be ready to use all elements
document.observe('dom:loaded', onDomLoaded);

/**
 * 
 * @return
 */
function onDomLoaded()
{
	oEtalage = new Etalage();		
	oEtalage.onSelectImage = onSelectImage;
	oEtalage.onDeselectImage = onDeselectImage;			
	var iOpacity = 30;
	for(var i = 0; i < oEtalage.aItems.length; i++)
	{
		// Display items transparent bij default
		onDeselectImage(oEtalage.aItems[i]);
		
		// Set mouse over/out handlers
		oEtalage.aItems[i].observe
		(
				'mouseover',
				function()
				{
					oEtalage.selectElement(this, true);
					onSelectImage(this);
					// Deselect all but the selected
					for(var i = 0; i < oEtalage.aItems.length; i++)
					{
						if(oEtalage.aItems[i] != this)
						{							
							onDeselectImage(oEtalage.aItems[i]);
						}
					}
					oEtalage.pause();
				}
		);
		oEtalage.aItems[i].observe
		(
				'mouseout',
				function()
				{
					oEtalage.play(iEtalageInterval, bEtalageRandom);
				}
		);
	}
	
	oEtalage.selectImage(0);
	oEtalage.play(iEtalageInterval, bEtalageRandom);
}


/**
 * Called from template
 * @param sImageURL
 * @param sContent
 * @return
 */
function addEtalageItem(sImageURL, sTitle, sContent, sReadmore)
{
	aEtalageItems.push
	(
			{
				title: sTitle,
				content: sContent,
				imageURL: sImageURL, 
				readmore: sReadmore
			}
	);
}

/**
 * Called from template to set admin settings
 * @param sImageURL
 * @param sContent
 * @return
 */
function setEtalageSettings(iInterval, bRandom, bUseEffect, sTypeEffect, iTimeEffect)
{
	iEtalageInterval = iInterval;
	bEtalageRandom = bRandom;
	bEtalageUseEffect = bUseEffect;
	sEtalageTypeEffect = sTypeEffect;	
	iEtalageTimeEffect = iTimeEffect;
}

/**
 * Called when oElement is selected in the Etalage
 * @param oElement	The newly selected element
 * @param bSkipEffect	Whether to skip the effects if set (i.e. when a button is hovered)
 * @return void
 */
var iTimeout
function onSelectImage(oElement, bSkipEffect)
{
	var oInfo = aEtalageItems[ oEtalage.iCurrentImageID ];
	if(!oElement)
	{
		oElement = oEtalage.aItems[ oEtalage.iCurrentImageID ];
	}
	
	$('etalage_content_text').innerHTML = '<h3>' + oInfo.title + '</h3>' + oInfo.content;
	if(iTimeout)
	{
		clearTimeout(iTimeout);
	}
	if(bEtalageUseEffect && !bSkipEffect)
	{
		
		$('etalage_transition').hide();
		$('etalage_transition').style.backgroundImage = "url('"+ oInfo.imageURL +"')";
		iTimeout = setTimeout
		(
			function()
			{
				$('etalage_transition').hide();
				$('sectionnavbar').style.backgroundImage = "url('"+ oInfo.imageURL +"')";			
			},
			iEtalageTimeEffect * 1000
		)
		var oOptions = { duration: iEtalageTimeEffect };
		
		switch (sEtalageTypeEffect.toUpperCase())
		{
			case 'VERVAGEN':
				Effect.Appear('etalage_transition', oOptions);				
				break;
	
			default:
				break;
		}
	}
	else
	{
		$('sectionnavbar').style.backgroundImage = "url('"+ oInfo.imageURL +"')";	
	}
	
	
	if(oInfo.readmore)
	{
		$('etalage_content_text').innerHTML += '&nbsp;<a ' + oInfo.readmore + '>Lees meer...</a>';
	}
	
	var iOpacity = 100;
	oElement.style.opacity = iOpacity / 100;
	oElement.style.filter = "alpha(opacity=" + iOpacity + ")";	
}


/**
 * Called when oElement is deselected in the Etalage
 * @param oElement	The previously selected element
 * @return void
 */
function onDeselectImage(oElement)
{
	var iOpacity = 30;
	oElement.style.opacity = iOpacity / 100;
	oElement.style.filter = "alpha(opacity=" + iOpacity + ")";
	
}

