/*====================================*\
|| ################################## ||
|| # iDeal 2.0 Ajax Core            # ||
|| # ------------------------------ # ||
|| # Copyright ©2008 MediaPulse     # ||
|| # ------------------------------ # ||
|| # Revision Alpha                 # ||
|| ################################## ||
\*====================================*/

/**
 * Slides controller.
 */
iDeal.Slides = Class.create({
	/**
	 * Is the mouse currently over the slide
	 *
	 * @var boolean
	 * @access protected
	 */
	_over: false,
	
	/**
	 * The element that contains the collection of slides
	 *
	 * @var element
	 * @access protected
	 */
	_slideList: null,
	
	/**
	 * The slides.
	 *
	 * @var array,
	 * @access protected
	 */
	_slides: null,
	
	/**
	 * Index of the current slide
	 *
	 * @var integer
	 * @access protected
	 */
	_index: 0,
	
	
	/**
	 * Amount of time in seconds to wait between slides.
	 *
	 * @var float
	 * @access protected
	 */
	_timeOut: 5,
	
	/**
	 * Duration of the appearance effect.
	 *
	 * @var float
	 * @access protected
	 */
	_fadeIn: 1,
	
	/**
	 * Duration of the fade out effect
	 * 
	 * @var float
	 * @access protected
	 */
	_fadeOut: 1,
	
	/**
	 * Type of effect used to appear the slide
	 * See scriptaclous Library for a complete list of values.
	 *
	 * @var string
	 * @access protected
	 */
	_enterTween: 'Appear',

	/**
	 * Type of effect used to exit the slide.
	 * See scriptaclous Library for a complete list of values.
	 *
	 * @var string
	 * @access protected
	 */
	_exitTween: 'Fade',
		
	/**
	 * Flag to show that we are animating the slide. We ignore
	 * all events when this is set true.
	 */
	_transitionInProgress: false,
		
	/**
	 * Cache for the bound mouseOver function.
	 *
	 * @var bound function object
	 * @access public
	 */
	mouseOver: null,
	
	/**
	 * Cache for the bound mouseOut function
	 *
	 * @var bound function object
	 * @access public 
	 */
	mouseOut: null,
	
	/**
	 * Initialize the popup controller.
	 *
	 * @param hash {
	 *		target - target div of the controller REQUIRED
	 *		fadeIn - time in seconds to fade in
	 *		fadeOut - time in seconds to fade out
	 *		timeOut - time in seconds to wait before fade out after mouse out
	 *		enterTween - effect used for appearances
	 *		exitTween - effect used for exits.
	 *	}
	 * @return  void
	 * @access public (constructor)
	 * @throws missingRequiredParam
	 */
	initialize: function ( params ) {
		
		if (!(this._slideList = $(params.target)))
		{
			throw missingRequiredParam;
		}
				
		// Attach parameters
		this._fadeIn = (params.fadeIn) ? params.fadeIn : this._fadeIn;
		this._fadeOut = (params.fadeOut) ? params.fadeOut : this._fadeOut;
		this._timeOut = (params.timeOut) ? params.timeOut : this._timeOut;
		this._enterTween = (params.enterTween) ? params.enterTween : this._enterTween;
		this._exitTween = (params.exitTween) ? params.exitTween : this._exitTween;

		// Now get the slides.
		this._slides = this._slideList.select('li');
		
		// Set all but first hidden.
		this._slides.invoke('hide');
		this._slides[0].show();
	
		// Create the bound copies of the event functions
		this.mouseOver = this._mouseOver.bindAsEventListener(this);
		this.mouseOut = this._mouseOut.bindAsEventListener(this);
		
		// Register them to the page elements they are to control	
		Event.observe( this._slideList, 'mouseover', this.mouseOver );
		Event.observe( this._slideList, 'mouseout', this.mouseOut );
		
		// Start up the rotation
		setTimeout( this._doTimeOut.bindAsEventListener(this), this._timeOut * 1000 );
		
		if (iDeal.debug)
		{
			iDeal.console.log('Slide List Registered.');
		}
	},
	
	/**
	 * Primitive mouseover function.
	 *
	 * @param event
	 * @return void
	 * @access protected
	 */
	_mouseOver: function ()
	{
		this._over = true;
	},
	
	/**
	 * Primitive mouseout function
	 * 
	 * @param event
	 * @return void
	 * @access protected
	 */
	_mouseOut: function ()
	{
		this._over = false;		
		setTimeout( this._doTimeOut.bindAsEventListener(this), this._timeOut * 1000 );
	},
	
	/**
	 * Resolve the timeout of a mouseout
	 *
	 * @param void
	 * @return void
	 * @access protected
	 */
	_doTimeOut: function ()
	{
		if (!this._over )
		{
			this._hide();	
		}
	},
	
	/**
	 * Appear the popup Function
	 * 
	 * @param void
	 * @return void
	 * @access private
	 */
	_appear: function()
	{
		if (!this._transitionInProgress)
		{
			if (this._index >= this._slides.length)
			{
				this._index = 0;
			}
			
			this._transitionInProgress = true;

			new Effect[this._enterTween]( this._slides[this._index], {duration: this._fadeIn, afterFinish: function(){ 
				this._transitionInProgress = false 
				setTimeout( this._doTimeOut.bindAsEventListener(this), this._timeOut * 1000 );
			}.bindAsEventListener(this) } );
		}
	},
	
	/**
	 * Fade the popup Function
	 * 
	 * @param void
	 * @return void
	 * @access private
	 */
	_hide: function()
	{
		if(!this._transitionInProgress)
		{
			this._transitionInProgress = true;
			
			new Effect[this._exitTween]( this._slides[this._index], {duration: this._fadeOut, afterFinish: function(){ 
				this._transitionInProgress = false;
				this._index++;
				this._appear();
			}.bindAsEventListener(this) } );
		}
	}

});