/**
 * Common javascript class to fade between x images with controls.
 *
 * @author John Severinson / Egmont Tidskrifter
 *
 * Usage instructions:
 * 1) Create:
 * 	- a container with an id attribute
 * 	- In it, create item nodes with id attributes
 * 	- Optional: Create control nodes
 *
 * 	Note: If you don't use default DOM IDs you need to set the base id names yourself.
 *
 * 2) Do sf = new SwapFade();
 *
 * 3) Use sf.Set*() to set settings
 *
 * 4) Use sf.Initialize() to start swap fader.
 */
function SwapFade()
{
	/**
	 * Options
	 */
	this.timeout = 5000;
	this.itemContainerId = "feature_items";
	this.itemBaseId = "feature_item_";
	this.controlBaseId = "feature_control_";
	this.controlActiveClass = "active";
	
	this.itemCount = 5;
	this.startIndex = 0;

	/**
	 * Running parameters
 	 */
	this.runItems = [];
	this.runInterval = null;
	this.runCurrentIndex = 0;

	/**
	 * Methods
	 */
	this.Initialize = function()
	{
		var tmp;
		var obj = this;
		
		// Set current index
		if( this.startIndex < 0 )
			this.runCurrentIndex = 0;
		else
			this.runCurrentIndex = this.startIndex;

		// Initialize items
		for( var i=0; i<this.itemCount; i++ )
		{
			// Make sure element exists
			tmp = jQuery( '#' + this.itemBaseId + i );
			if( tmp.length <= 0 )
			{
				alert( "Element med id '" + this.itemBaseId + i + "' saknas. Kan inte initialisera swapfade." );
				return null;
			}
			this.runItems.push( tmp );
		}

		// Initialize pause event trigger if container can be located
		jQuery( '#' + this.itemContainerId ).hover(
			function(){
				obj.Pause();
			},
			function(){
				obj.Unpause();
			}
		);

		// Initialize click events on numbered controls
		for( var j=0; j<this.itemCount; j++ )
		{
			jQuery( '#' + this.controlBaseId + j ).click( function(){
				obj.Pause();
				obj.SwitchToItem( this.id.substr( obj.controlBaseId.length ) );
			});
		}

		// Initialize click events on prev and next (if exists)
		jQuery( '#' + this.controlBaseId + "prev" ).click( function(){
			obj.Pause();
			obj.Prev();
		});
		jQuery( '#' + this.controlBaseId + "next" ).click( function(){
			obj.Pause();
			obj.Next();
		});

		// Initialize interval by unpausing
		this.Unpause();
	};

	/**
	 * Switch to specified item.
	 *
	 * @param i		Item index.
	 */
	this.SwitchToItem = function( i )
	{
		// Temporarily store previous item
		var tmpCurrent = this.runCurrentIndex;

		// Set current item
		this.runCurrentIndex = Number( i );

		// Fadeswitch
		if( this.runCurrentIndex != tmpCurrent )
		{
			jQuery( this.runItems[this.runCurrentIndex] ).fadeIn();
			jQuery( this.runItems[tmpCurrent] ).fadeOut();

			if( this.controlActiveClass != null )
			{
				jQuery( '#' + this.controlBaseId + this.runCurrentIndex ).addClass( this.controlActiveClass );
				jQuery( '#' + this.controlBaseId + tmpCurrent ).removeClass( this.controlActiveClass );
			}
		}
	};

	/**
	 * Switch to next item.
	 */
	this.Next = function()
	{
			// Cycle around?
			if( ( this.runCurrentIndex + 1 ) >= this.itemCount )
				this.SwitchToItem( 0 );
			else
				this.SwitchToItem( this.runCurrentIndex + 1 );
	};

	/**
	 * Switch to previous item.
	 */
	this.Prev = function()
	{
			// Cycle around?
			if( this.runCurrentIndex <= 0 )
				this.SwitchToItem( this.itemCount - 1 );
			else
				this.SwitchToItem( this.runCurrentIndex - 1 );
	};

	/**
	 * Pause cycle.
	 */
	this.Pause = function()
	{
		// Remove interval
		if( this.runInterval > 0 )
			clearInterval( this.runInterval );
		this.runInterval = 0;
	};

	/**
	 * Unpause (or startup) cycle.
	 */
	this.Unpause = function()
	{
		var obj = this;

		// Set interval
		if( this.runInterval <= 0 )
			this.runInterval = setInterval( function(){
				obj.Next();
			}, this.timeout );
	};

	/**
	 * Getters and setters
	 */

	/**
	 * Set delay between each cycle.
	 *
	 * @param value		Delay in milliseconds.
	 */
	this.SetTimeout = function( value )
	{
		this.timeout = Number( value );
	};

	/**
	 * Specify the name of the DOM ID used for the item container.
	 *
	 * @param value 		Name of container.
	 */
	this.SetItemContainerId = function( value )
	{
		this.itemContainerId = String( value );
	};

	/**
	 * Specify the name base of the DOM ID used for items (cycled).
	 *
	 * @param value 		Name base of items. Index is appended to these.
	 */
	this.SetItemBaseId = function( value )
	{
		this.itemBaseId = String( value );
	};

	/**
	 * Specify the name base of the DOM ID used for controls.
	 *
	 * @param value 		Name base of controls. Index is appended to these.
	 */
	this.SetControlBaseId = function( value )
	{
		this.controlBaseId = String( value );
	};

	/**
	 * Specify name of class that should be set on active control. Set to null to disable.
	 *
	 * @param value		CSS class name.
	 */
	this.SetControlActiveClass = function( value )
	{
		this.controlActiveClass = String( value );	
	};

	/**
	 * Set number of items to cycle through.
	 * 
	 * @param value		Number of items.
	 */
	this.SetItemCount = function( value )
	{
		this.itemCount = Number( value );
	};

	/**
	 * Set index that should be started. This is merely so that next step is handled correctly.
	 * Initial visibility should be set by initial rendering.
	 *
	 * @param value		Starting index.
	 */
	this.SetStartIndex = function( value )
	{
		this.startIndex = Number( value );
	}
}
