/** rotatingMessagePanel.js ********************************************
 * JavaScript functions for controlling a JavaScript carousel which
 * stops at either end.
 *
 * Makes use of the MooTools Fx tweens to slide the carousel along.
 *
 * Created:		CM - 20110422
 * Edited:		CM - 20110422
 * Version:		1.1
 *
 * DESCRIPTION ***************************************** CM - 20110422 *
 * Small JS library that creates a scrolling window that moves along a
 * range of items held within it with fixed widths.  Usage is as
 * follows:
 *
 *	1	A div is set up to hold the carousel and all element are added
 *		to that, contols are set outside this div.
 *	2	The carousel should be initialised with the initCarousel()
 *		method, passing in the id, number of items, width of each item,
 *		the number of items to scroll at a time, the id of the left
 *		control and the id of the right control.	
 *	3	Interaction is added to the carousel by adding onclick/onhover	
 *		calls to the controllers, scrollCarouselLeft() or
 *		scrollCarouselRight().
 *	
 *	Makes use of MooTools Fx tweens: http://mootools.net/
 *
 * CH-CH-CHANGES *******************************************************
 * 20100308		Updated the carousel to allow the scrolling window size
 * V1.1 CM		to be different from the viewing window size.
 *
 * 20100305		Created the JS widget and set up all the required  
 * V1.0 CM		functions to deal with scrolling and updating the
 * 				controls.
 ****************************************************** CM - 20100305 */

var rotatingMessagePanel	= new Class( {
	_carousel:			null,
	_carouselWidth:		0,
	_itemWidth:			0,
	_itemsToScroll:		0,
	_itemsToShow:		0,
	_leftValue:			0,
	_autoScrolling:		null,
	_periodical:		0,
	_wait:				5000,
	_duration:			800,
	_fx:				null,
	_navSelector:		null,
	
	
	
	
	/* initialize ******************************************************
	 * The constructor method to create an instance of a
	 * rotatingMessagePanel.  Takes a list of options, most of which
	 * are required to set up and start the rotator.
	 *
	 * Syntax **********************************************************
	 * new rotatingMessagePanel( options );
	 * 
	 * Arguments *******************************************************
	 * options	a properties list containing:
	 *			 - carouselID:		ID of the element containing the
	 *								carousel items.
	 *			 - totalItems:		Count of the number of items in the
	 *								carousel.
	 *			 - itemsToShow:		How many items are shown in the
	 *								viewport at one time.
	 *			 - itemWidth:		The width of an individual item in
	 *								the carousel.
	 *			 - itemsToScroll:	The number of items to scroll the
	 *								viewport by.
	 *			 - wait:			The duration to wait between
	 *								tweening to the next carousel item.
	 *			 - duration:		The duration of the tween between
	 *								carousel items.
	 *			 - navSelector:		Class/ID used to identify the
	 *								navigation for the carousel.
	 *			 - navOnClass:		Class used to identify the active
	 *								navigation items.
	 *
	 ******************************************************************/
	initialize: function( options ) {
		this._carousel			= $( options.carouselID );
		this._carouselWidth		= options.totalItems * options.itemWidth;
		this._itemWidth			= options.itemWidth;
		this._itemsToScroll		= ( options.itemsToScroll <= options.itemsToShow ) ? options.itemsToScroll : options.itemsToShow;
		this._itemsToShow		= options.itemsToShow;
		this._autoScrolling		= ( options.itemsToShow < options.totalItems ) ? "right" : "none";
		this._navSelector		= options.navSelector;
		this._navOnClass		= options.navOnClass;
		
		if( options.duration != null && options.duration > 0 ) {
			this._duration		= options.duration;
		}

		if( options.wait != null && options.wait > 0 ) {
			this._wait		= ( options.wait > this._duration ) ? options.wait : this._duration;
		}
		
		
		// Set the width of the carousel in case it's not set properly
		this._carousel.setStyle( "width", options.totalItems * this._itemWidth + "px" );
		this._carousel.setStyle( "position", "relative" );
		
		$$( "."+this._navSelector ).removeClass( this._navOnClass );
		$( this._navSelector+"-"+( ( this._leftValue / ( this._itemsToShow * this._itemWidth ) ) + 1 ) ).addClass( this._navOnClass );

	},

	
	/* scrollPanelLeft *************************************************
	 * Scroll the message panel to the left by the number of items
	 * specified in the options initially passed.
	 *
	 * Syntax **********************************************************
	 * rotatingMessagePanel.scrollPanelLeft();
	 * 
	 ******************************************************************/
	scrollPanelLeft: function() {
		var scrollBy		= this._itemsToScroll;
		var newLeftValue	= this._leftValue - ( scrollBy * this._itemWidth );
		
		// Change the left value to the width of the carousel less the width
		// of the items shown
		if( newLeftValue < 0 ) {
			newLeftValue	= ( this._carouselWidth - ( this._itemsToShow * this._itemWidth ) );
			leftValueString	= "-" + newLeftValue + "px";
		} else {
			leftValueString	= "-" + newLeftValue + "px";
		}
	
		$$( "."+this._navSelector ).removeClass( this._navOnClass )
		$( this._navSelector+"-"+( ( newLeftValue / ( this._itemsToShow * this._itemWidth ) ) + 1 ) ).addClass( this._navOnClass );
	
		var myFx	= new Fx.Tween( this._carousel, { duration: this._duration } );
		myFx.start( 'left', leftValueString );
		this._leftValue	= newLeftValue;
	},

	
	/* scrollPanelRight ************************************************
	 * Scroll the message panel to the right by the number of items
	 * specified in the options initially passed.
	 *
	 * Syntax **********************************************************
	 * rotatingMessagePanel.scrollPanelRight();
	 * 
	 ******************************************************************/
	scrollPanelRight: function() {
		var scrollBy		= this._itemsToScroll;
		var newLeftValue	= this._leftValue + ( scrollBy * this._itemWidth );
		
		// Change the left value to the width of the carousel less the width
		// of the items shown
		if( newLeftValue > ( this._carouselWidth - ( this._itemsToShow * this._itemWidth ) ) ) {
			newLeftValue	= 0;
			leftValueString	= newLeftValue + "px";
		} else {
			leftValueString	= "-" + newLeftValue + "px";
		}
	
	
		$$( "."+this._navSelector ).removeClass( this._navOnClass )
		$( this._navSelector+"-"+( ( newLeftValue / ( this._itemsToShow * this._itemWidth ) ) + 1 ) ).addClass( this._navOnClass );
	
		var myFx	= new Fx.Tween( this._carousel, { duration: this._duration } );
		myFx.start( 'left', leftValueString );
		this._leftValue	= newLeftValue;
	},

	
	/* scrollToPanel ***************************************************
	 * Scroll the message panel to the specified viewport window.
	 *
	 * Syntax **********************************************************
	 * rotatingMessagePanel.scrollToPanel( panelNo );
	 * 
	 * Arguments *******************************************************
	 * panelNo	the panel number to jump to.
	 ******************************************************************/
	scrollToPanel: function( panelNo ) {
		var newLeftValue	= ( panelNo - 1 ) * this._itemsToScroll * this._itemWidth;
		
		// Change the left value to the width of the carousel less the width
		// of the items shown
		if( newLeftValue < 0 ) {
			newLeftValue	= ( this._carouselWidth - ( this._itemsToShow * this._itemWidth ) );
			var leftValueString	= "-" + newLeftValue + "px";
		} else {
			var leftValueString	= "-" + newLeftValue + "px";
		}
	
		$$( "."+this._navSelector ).removeClass( this._navOnClass );
		$( this._navSelector+"-"+( ( newLeftValue / ( this._itemsToShow * this._itemWidth ) ) + 1 ) ).addClass( this._navOnClass );
	
		var myFx	= new Fx.Tween( this._carousel, { duration: this._duration } );
		myFx.start( 'left', leftValueString );
		this._leftValue	= newLeftValue;
	},

	
	/* startScrollingPanels ********************************************
	 * Start the automatic scrolling of panels from left to right with
	 * the wait that was specified on initialization.
	 *
	 * Syntax **********************************************************
	 * rotatingMessagePanel.startScrollingPanels();
	 * 
	 ******************************************************************/
	startScrollingPanels: function() {
		this._periodical	= this.scrollPanelRight.periodical( this._wait, this );
	},

	
	/* stopScrollingPanels *********************************************
	 * Stop the automatic scrolling of panels.
	 *
	 * Syntax **********************************************************
	 * rotatingMessagePanel.stopScrollingPanels();
	 * 
	 ******************************************************************/
	stopScrollingPanels: function() {
		clearInterval( this._periodical );
	}
	
} );
