var Etalage = Class.create(
{
	Version				: "2.0",
	aItems				: [],
	iNumBlocks			: null,
	iNumTotalItems		: null,
	iNumItemsPerBlock	: 4,
	iCurrentImageID		: 0,
	iLastImageID		: 0,
	iCurrentBlockID		: 0,
	bPaused				: true,
	bRandom				: false,
	iInterval			: 5,
	sNextButton			: 'button_next',
	sPrevButton			: 'buttonn_prev',
	sImageReel			: 'imageReel',
	sImageReelSlider	: 'imageReelSlider',
	bImageReelShow		: false,
	iBlockWidth			: null,
	oJson: {
		iEtalSpeed		: null,
		iEtalRandom		: null
	},
	slide_toggle: null,
	sActiveBlock		: null,
	
	/**
	 * Is Etalage scrolling a block?
	 * If this is true, changing an image will be ignored (useful when clicking next/prev too fast)
	 * @var bool
	 */
	bScrolling		: false,
	
	/**
	 * Standard prototype initialize contructor
	 */
	initialize: function()
	{
		var oEtalage = this;
		var iSpeed = this.iInterval;
		var bRandom = this.bRandom;
		
		new Ajax.Request('/output/json/etalage/0', {
			method: 'get',
			asynchronous : false,
			onSuccess: function(transport, oJson)
			{
				for(var i = 0; i < oJson.iCounterEtalItems; i++) {
					oEtalage.addEtalageItem(
						oJson['oEtalageItem'+i].sLittleImage,
						oJson['oEtalageItem'+i].sTitle,
						oJson['oEtalageItem'+i].sIntro,
						oJson['oEtalageItem'+i].meerInfo,
						oJson['oEtalageItem'+i].sBigImage
					);
				}
				
				oEtalage.setEtalageSettings(eval(oJson.iEtalSpeed), oJson.iEtalRandom);
				// Starting the etalage-machine
				Event.observe( window, 'load', function(){ oEtalage.domLoaded(); } );
			}
		});
		
		return true;
	},
	
	/**
	 * Add an element item to the main items-array
	 * @param string sImageURL URL where to find the image
	 * @param string sTitle			Title of the item
	 * @param string sShortTitle	Title of the item
	 * @param string sContent		Textcontent of the item
	 * @param string sReadmore		URL for the readmore link
	  * @param integer iID		Element ID
	 * @return
	 */
	addEtalageItem: function(sImageURL, sTitle, sContent, sReadmore, bigFoto)
	{
		this.aItems.push
		(
			{
				title: sTitle,
				content: sContent,
				imageURL: sImageURL, 
				readmore: sReadmore,
				bigPicture: bigFoto
			}
		);
		
		this.iNumTotalItems	= this.aItems.length;
		
	},
	
	setEtalageSettings: function(iInterval, bRandom)
	{
		this.iInterval = iInterval * 1000;
		this.bRandom = bRandom;
	},
	
	/**
	 * Trigger for the starting of rolling actions.
	 * @return
	 */
	domLoaded: function()
	{
		var oEtalage 	= this;
		
		this.iNumBlocks		= (Math.ceil(this.iNumTotalItems / this.iNumItemsPerBlock));
		
		// Initialize events when onloaded is ready.
		oEtalage.initializeOnLoaded(oEtalage);
		
		this.selectImage(0);
		this.start(this.iInterval, this.bRandom);
	},
	
	/**
	* Call observe event for buttons 'select precedent' and 'select next'
	* @return void
	*/
	initializeOnLoaded: function(oEtalage)
	{
		
		// The first time we let see only the first block
		for(var n = 0; n < this.iNumBlocks; n++)
		{
			$('block_'+ n ).style.display = 'none';
		}
		
		for(var i = 0; i < oEtalage.aItems.length; i++)
		{
			/* Display all items in transparent bij default */
			this.onDeselectImage(i);
			this.selectIfOver(i);
		}
		
		// The first time we want to show only the first block.
		$('imageReel').style.display = 'block';
		this.showBlock(0);
	},
	
	/**
	 * Setter function for bImageReelShow
	 * @param boolean bStatus
	 */
	setImageReelShow: function(bStatus)
	{
		this.bImageReelShow = bStatus;
	},
	
	/**
	 * Getter function for bImageReelShow
	 * @return boolean
	 */
	getImageReelShow: function()
	{
		return this.bImageReelShow;
	},
	
	reduceHeight: function()
	{
		$('carousel_balk').style.height = ($('carousel_balk').style.height -10 )+'px';
	},
	
	/**
	* Selection of an item as active when onmouseover event on a
	* single item is executed.
	* @param integer iImageID Array index of the item
	*/
	selectIfOver: function(iImageID)
	{
		var oEtalage = this;
		
		Event.observe(
			$('Item_'+iImageID),
			'mouseover',
			function()
			{
				// Increment image ID
				oEtalage.selectAction(iImageID, oEtalage.iCurrentImageID);
			}
		);
		
		Event.observe(
			$('Item_'+iImageID),
			'mouseout',
			function()
			{
				oEtalage.start(oEtalage.iInterval, oEtalage.bRandom);
			}
		);
		
		// Elabling "pause"/"start" with mouse over/out
		this.ButtonsObserve('imageItem_'+iImageID);
	},
	
	/**
	* Enable start/pause functions for $(sID) objects
	* @param string sID HTML object's ID
	*/
	ButtonsObserve: function(sID)
	{
		Event.observe( $(sID), 'mouseover', function(){ oEtalage.pause(); } );
		Event.observe( $(sID), 'mouseout', function(){ oEtalage.start(oEtalage.iInterval, oEtalage.bRandom); } );
		
		Event.observe( $('read_more_'+sID), 'mouseover', function(){ oEtalage.pause(); } );
		Event.observe( $('read_more_'+sID), 'mouseout', function(){ oEtalage.start(oEtalage.iInterval, oEtalage.bRandom); } );
	},
	
	/**
	 * Applies a APPEAR effect to the block with ID on blockwith id='block_'+iBlockID
	 *
	 * @param int iBlockID ID of the block to show.
	 * @return void
	 */
	showBlock: function(iBlockID)
	{
		Effect.Appear('block_'+iBlockID, { duration: 0.5 });
	},
	
	/**
	 * Applies a FADE effect to the block with ID on blockwith id='block_'+iBlockID
	 *
	 * @param int iBlockID ID of the block to show.
	 * @return void
	 */
	fadeBlock: function(iBlockID)
	{
		Effect.Fade('block_'+iBlockID, { duration: 1.0 });
		$('block_'+iBlockID).style.display = 'none';
	},
	
	/**
	 * Select an image (will scroll to it's block if necessary)
	 * @param int Image ID 
	 * @return int selected Image ID
	 */
	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.iCurrentImageID );
			}		
			// Call handler if set
			if(this.onSelectImage instanceof Function)
			{
				this.onSelectImage( iImageID );
			}
			
			// Set the new properties
			this.iCurrentImageID = iImageID;
			this.iCurrentBlockID = iNextBlockID;
		}
		return this.iCurrentImageID;
	},
	
	/**
	 * Select an item as active
	 * @param object oElement
	 * @return void
	 */
	selectElement: function(oElement)
	{
		var iID = this.aItems.indexOf(oElement);
		
		if(iID >= 0)
		{
			this.selectImage(iID);
		}
	},
	
	/**
	 * Start animation (if not started or before)
	 * @return void
	 */
	start: 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
				oRefInstance.onDeselectImage(iLastImageID);
				
				// Call handler if set
				oRefInstance.onSelectImage(iNewImageID);
			}
			
			this.iIntervalID = setInterval(fnIntervalHandler, this.iInterval);								
					
			this.bPaused = false;
		}
	},
	
	/**
	 * Select next image
	 * @return int
	 */
	selectNext: function()
	{
		// Increment image ID
		var iNewImageID = this.iCurrentImageID + 1;
		
		this.selectAction(iNewImageID, this.iCurrentImageID);
		
		return iNewImageID;
	},
	
	/**
	 * Select previous image
	 * @return int
	 */
	selectPrev: function()
	{
		// Decrement image ID
		var iNewImageID = this.iCurrentImageID - 1;
		
		this.selectAction(iNewImageID, this.iCurrentImageID);
	},
	
	/**
	* Common actions to this.selectNext and this.selectPrev
	* This function is initialized only onetime at the beginning
	* 
	* @param integer iNewImageID ID of the new to select image
	* @param integer iOldImageID ID of the still actual/old image to deselect
	*/
	selectAction: function(iNewImageID, iOldImageID)
	{
		this.selectImage(iNewImageID);
		
		// Fade the actual item and appear the new item
		this.onDeselectImage(iOldImageID);
		
		//Hide the last shown item when onMouseover is triggered
		//$('img-'+iOldImageID).style.display = 'none';
		new Effect.Fade('img-'+iOldImageID, { duration: 0.2} );
		
		// Clean the queue to leave javascript act faster when onMouseover is triggered
		// (all actions and settings are again initialized)
		Effect.Queue.each(function(e){e.cancel();})
		
		// Appear the new actual item
		this.onSelectImage(iNewImageID);
	},
	
	/**
	 * Pause animation
	 * @return void
	 */
	pause: function()
	{
		if(!this.bPaused)
		{
			clearInterval(this.iIntervalID);
			this.iIntervalID = null;
			this.bPaused = true;
		}
	},
	
	/**
	 * Stop animation
	 * @return void
	 *
	 */
	stop: function()
	{
		this.pause();
		// Reset identifiers
		this.selectImage(0);
	},
	
	/**
	 * 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
	 */
	getBlockID: function(iImageID)
	{
		return Math.ceil((iImageID + 1) / this.iNumItemsPerBlock) - 1;
	},
	
	/**
	 * @access private
	 * @param int	
	 * @return void
	 */
	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;
		}
		
		// We are still scrolling, thus the folling setting on true.
		this.bScrolling = true;
		
		var oRefInstance = this;
		
		new Effect.Fade(
			'block_'+this.iCurrentBlockID,
			{
				duration: 0.1,
				afterFinish: function()
				{
					// Scrolling is finished, thus the following setting on false.
					oRefInstance.bScrolling = false;
					oRefInstance.showBlock(iNewBlockID);
				}
			}
		);
		
		this.iCurrentBlockID = iNewBlockID;
		return this.iCurrentBlockID;
	},
	
	/**
	 * Called when oElement is selected in the Etalage
	 * @param oElement	The newly selected element
	 * @return void
	 */
	onSelectImage: function(iIDitem)
	{
		var oEtalage = this;
		
		if(this.iCurrentImageID == null)
		{
			this.iCurrentImageID = 0;
		}
		
		new Effect.Appear('img-'+ oEtalage.iCurrentImageID,
			{
				duration: 0.3,
				afterFinish: function()
				{
					if( ( oEtalage.iCurrentImageID == 0 ) && (oEtalage.iLastImageID == iIDitem )  )
					{
						// In this case we go from the last element to the first one (one cicle completed).
						for( var i = 0; i < iIDitem; i++)
						{
							new Effect.Fade('img-'+ i, { duration: 0.2} );
						}
					}
					else// if(iIDitem > 0)
					{
						// Standard we set the display property of the previous viewed element on 'none';
						new Effect.Fade('img-'+ oEtalage.iLastImageID, { duration: 0.2} );
						
					}
				}
			}
		);
		
		$('imageItem_'+this.iCurrentImageID).addClassName('reelBlock_active');
		$('Item_description_'+this.iCurrentImageID).addClassName('Item_description_active');
	},
	
	/**
	 * Called when oElement is deselected in the Etalage.
	 
	 * @param object Prototype bject of the element item
	 * @return void
	 */
	onDeselectImage: function(iInt)
	{
		this.iLastImageID = iInt;
		
		if(iInt != null)
		{
			$('imageItem_'+iInt).removeClassName('reelBlock_active');
			$('Item_description_'+iInt).removeClassName('Item_description_active');
		}
	},
	
	getBlockID: function(iImageID)
	{
		return Math.ceil((iImageID + 1) / this.iNumItemsPerBlock) - 1;
	},
	
	/**
	 * Get the currently selected item
	 * @return object
	 */
	getSelectedItem: function()
	{
		return this.aItems[ this.iCurrentID ];
	}
});

// Initializing Etalage object
var oEtalage = new Etalage();
