var Etalage = Class.create(
{
	Version				: "1.0",
	aItems				: [],
	iNumBlocks			: null,
	iNumTotalItems		: null,
	iNumItemsPerBlock	: 5,
	iCurrentImageID		: 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){
				// Fixed: the old JSON object was limited in kb size, that's why we get now back the response as 
				// plain text and folowing parse the json text object.
				oJson = transport.responseText.evalJSON();
				
				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 if minimun 1 element is found.
				if(oEtalage.aItems.length > 0)
				{
					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()
	{
		$('carousel_balk').style.display = 'block';
		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=1; 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.
		this.showBlock(0);
		
		// Mouseover/out events handlers for the 2 buttons
		this.ButtonsObserve('btn_next');
		this.ButtonsObserve('btn_prev');
		
		// Reel initialization
		var sReturn 	= setTimeout( 'oEtalage.initializeReelBalk()' , 2000 );
	},
	
	/**
	* Setting the slidedown/slideup for the images-reel with
	* mouseouver / mouseout on the etalage block window.
	* @return void
	*/
	initializeReelBalk: function()
	{
		var oEtalage = this;
		
		// Combination of efects to simulate a slidedown with hide effect for the image-reel.
		new Effect.SlideUp('carousel_balk', {
			duration: 1.0
		});
		new Effect.Move('carousel_balk', {
			x: 0,
			y: 85,
			mode: 'absolute',
			duration: 1.0
		});
		
		
		this.setImageReelShow(false);
		
		$('body').observe('mousemove', oEtalage.moveMouseXY );
		return true;
	},
	
	moveMouseXY: function(event)
	{
		var aCoordinates = {
			x : event.clientX,
			y : event.clientY
		};
		//console.log('waar observer aan is toegevoegd', event.currentTarget.id);
		//console.log('waar mouseout op plaatsvond', event.target.id);
		
		var lx;
		var ly = 90;
		if(!document.all)
		{
			lx = eval( ($('etalage').getStyle('left')).sub('px', '' ));
		}
		else
		{
			var iDeltaW = document.viewport.getWidth();
			if(iDeltaW > 900)
			{
				lx = (iDeltaW-900)/2;
			}
			else
			{
				lx = 0;
			}
		}
		
		// Calculating the block width-height of the etalage where trigger the mouseover.
		// IE and FF calculate the left margin in different way, that's why this compensation.
		var Dx,Dy;
		if(document.all)
		{
			Dx = lx + 648;
		}
		else
		{
			Dx = lx + 635;
		}
		
		Dy = 90 + 360;
		
		if( (aCoordinates.x >= lx) && (aCoordinates.x <= Dx) &&
			(aCoordinates.y >= ly) && (aCoordinates.y <= Dy)  )
		{
			if(oEtalage.getImageReelShow() == false)
			{
				//oEtalage.showReelbalk();
				oEtalage.showHideReelBalk();
				oEtalage.pause();
			}
		}
		else
		{
			if(oEtalage.getImageReelShow() == true)
			{
				oEtalage.showHideReelBalk();
				oEtalage.start(oEtalage.iInterval, oEtalage.bRandom);
				//oEtalage.setImageReelShow(false);
			}
		}
		
		return false;
	},
	
	/**
	 * Setter function for bImageReelShow
	 * @param boolean bStatus
	 */
	setImageReelShow: function(bStatus)
	{
		this.bImageReelShow = bStatus;
	},
	
	/**
	 * Getter function for bImageReelShow
	 * @return boolean
	 */
	getImageReelShow: function()
	{
		return this.bImageReelShow;
	},
	
	/**
	* Slide down the image reel.
	*/
	showHideReelBalk: function()
	{
		if(this.getImageReelShow() == true)
		{
			
			// Resetting the queue of eventual not jet executed effects
			Effect.Queue.each(function(e) { e.cancel() });
			
			// Combination of efects to simulate a slidedown with hide effect for the image-reel.
			new Effect.SlideUp('carousel_balk', {
				duration: 0.3
			});
			new Effect.Move('carousel_balk', {
				x: 0,
				y: 85,
				mode: 'absolute',
				duration: 0.3,
				afterFinish: function()
				{
				}
			});
			oEtalage.setImageReelShow(false);
			//var ret = setTimeout('return true', 100);
		}
		else
		{
			// Resetting the queue of eventual not jet executed effects
			Effect.Queue.each(function(e) { e.cancel() });
			
			$('carousel_balk').style.left = '0px';
			$('carousel_balk').style.top = '0px';
			$('carousel_balk').style.height = '85px';
			$('carousel_balk').style.display = 'block';
			oEtalage.setImageReelShow(true);
		}
	},
	
	reduceHeight: function()
	{
		$('carousel_balk').style.height = ($('carousel_balk').style.height -10 )+'px';
	},
	
	/**
	* Slideup the image reel.
	*/
	showReelbalk: function()
	{
		if(this.getImageReelShow() == false)
		{
			$('carousel_balk').style.left = '0px';
			$('carousel_balk').style.top = '0px';
			$('carousel_balk').style.height = '85px';
			$('carousel_balk').style.display = 'block';
		}
	},
	
	
	/**
	* 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 oReference = this;
		Event.observe(
			$('imageItem_'+iImageID),
			'mouseover',
			function()
			{
				// Increment image ID
				var iNewImageID = iImageID;
				oReference.selectAction(iNewImageID, oReference.iCurrentImageID);
			}
		);
		
		Event.observe(
			$('imageItem_'+iImageID),
			'mouseout',
			function()
			{
				oReference.start(oReference.iInterval, oReference.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); } );
	},
	
	/**
	 * 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 });
	},
	
	/**
	 * Select an image (will scroll to it's block if necessary)
	 * @param int Image ID 
	 * @return int selected Image ID
	 */
	selectImage: function(iImageID)
	{
		//alert(iImageID+'-'+this.iNumTotalItems);
		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(this.aItems[ 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(oNewImage);
			}
			
			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.select.Prev
	* @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);
		// Appear the new actual item
		this.onSelectImage(this.aItems[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(oElement)
	{
		if(this.iCurrentImageID == null)
		{
			this.iCurrentImageID = 0;
		}
		if(!oElement)
		{
			oElement = this.aItems[ this.iCurrentImageID ];
		}
		
		var oInfo = this.aItems[ this.iCurrentImageID ];
		var innerContentText = '<div class="inner_etalage_content_text">';
		
		if(oInfo.readmore)
		{
			innerContentText += '<a class="read_more" ' + oInfo.readmore + '">';
		}
		innerContentText += '<h3>' + oInfo.title + '</h3>';
		if(oInfo.readmore)
		{
			innerContentText += '</a>';
		}
		innerContentText += oInfo.content;
		/*
		if(oInfo.readmore)
		{
			innerContentText += '<a class="read_more" ' + oInfo.readmore + '"><img src="/images/arrow-rx.png" alt="Lees meer" /></a>';
		}
		*/
		innerContentText += '</div>';
		
		$('etalage_content_text').innerHTML = innerContentText;
		if(oInfo.bigPicture != "")
		{
			$('carousel_background').innerHTML = '<img src="'+ oInfo.bigPicture + '" alt="" />';
		}
		else
		{
			$('carousel_background').innerHTML = "";
		}
		
		$('imageItem_'+this.iCurrentImageID).style.opacity = 1;
		$('imageItem_'+this.iCurrentImageID).style.filter = "alpha(opacity=100)";
	},
	
	/**
	 * Called when oElement is deselected in the Etalage.
	 
	 * @param object Prototype bject of the element item
	 * @return void
	 */
	onDeselectImage: function(iInt)
	{
		if(iInt != null)
		{
			$('imageItem_'+iInt).style.opacity = 30 / 100;
			$('imageItem_'+iInt).style.filter = "alpha(opacity=30)";
		}
	},
	
	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();
