//<script language="javascript">

///////////////////////////////////////////////////////////////////////////////
// Constructor for class which supports automatic scrolling area of items
// Usage: var	oScroll = new CAutoScroll("oScroll", 200, 200, 5, 20, 10);
//				oScroll.ScrollLeft(1);
///////////////////////////////////////////////////////////////////////////////
function CAutoScroll( 
						sName, // Object name should be same as ref
						nMaskWidth, // Width of scroll control
						nMaskHeight, // Height of scroll control
						nScrollTime, // Time interval between auto scroll
						nScrollAmount, // Amount to scroll on each scroll operation (i.e. width of item in the list)
						nMaxScrollCount // Number of scroll operations supported (i.e. number of items in the list)
					)
{
	//
	// Private Member values
	//	
	m_Ref = this; // Reference required by private members to call public members
	m_sName = sName; // Object name 
	m_nMaskX = 0; // Start y position of mask  
	m_nMaskY = 0; // Start x position of mask  
	m_nMaskWidth = nMaskWidth; // Width of scroll area window (m_nMaskY)
	m_nMaskHeight = nMaskHeight;// Height of scroll area window (m_nMaskY)
	m_oDiv = new CObject("div" + m_sName ); // Reference to scrolling layer
	m_nLayerY = m_oDiv.GetAbsouluteYPosition(); // Current Y Position of scrolling DIV area that is masked
	m_nLayerX = m_oDiv.GetAbsouluteXPosition(); // Current X Position of scrolling DIV area that is masked
	m_nAcceleration = 0.3; //Acceleration Rate		
	m_nScrollTime = nScrollTime; // Scroll interval		
	m_nTimeOut = -1; // Unique identifier of timer for scroll interval. 
	m_nScrollAmount = nScrollAmount; // Amount to scroll on each scroll action.	
	m_nScrollIndex = 0; // Current scroll index. Will be incremented 1 for each scroll action until nMaxScrollCount
	m_nMaxScrollCount = nMaxScrollCount; // Total number of scroll feature items, used to limit number of scroll actions 		
						
	//
	// Private Constants 
	//
	SCROLL_UP = 0;
	SCROLL_DOWN = 1;
	SCROLL_LEFT = 2;
	SCROLL_RIGHT = 3;
	
	//
	// Public methods
	//		
	this.ScrollStop = CAutoScroll_ScrollStop; // Prevent any further scrolling clear the timer	
	this.ScrollLeft = CAutoScroll_ScrollLeft; // Scroll in the specified driection
	this.ScrollRight = CAutoScroll_ScrollRight; // Scroll in the specified driection
	this.ScrollUp = CAutoScroll_ScrollUp; // Scroll in the specified driection
	this.ScrollDown = CAutoScroll_ScrollDown; // Scroll in the specified driection
	this.ScrollToPosition = CAutoScroll_ScrollToPosition; // Must be public se we can call it via timer, Scroll to specified position.	
	this.SetXpos = CAutoScroll_SetXpos;
	this.SetYpos = CAutoScroll_SetYpos;
	
	//
	// Public Accessors
	//
	this.GetMaxScrollIndex = CAutoScroll_GetMaxScrollIndex; // Get max scroll index value
	this.GetCurrentScrollIndex = CAutoScroll_GetCurrentScrollIndex; // Get scroll index value
	
				
	////////////////////////////////////////////////////////////////////////////////
	// PUBLIC MEMBER FUNCTIONS 
	////////////////////////////////////////////////////////////////////////////////
					
	// Stop the scrolling operation, clear the scroll timer.	
	function CAutoScroll_ScrollStop( )
	{
		clearTimeout( m_nTimeOut );
	}
		 
	// Scroll Left pnCount times
	function CAutoScroll_ScrollLeft( pnCount )
	{
		Scroll(SCROLL_LEFT, pnCount);
	}						
		 
	// Scroll Right pnCount times
	function CAutoScroll_ScrollRight( pnCount )
	{
		Scroll(SCROLL_RIGHT, pnCount);
	}						
		 
	// Scroll Up pnCount times
	function CAutoScroll_ScrollUp( pnCount )
	{
		Scroll(SCROLL_UP, pnCount);
	}						
		 
	// Scroll Down pnCount times
	function CAutoScroll_ScrollDown( pnCount )
	{
		Scroll(SCROLL_DOWN, pnCount);
	}						
										
	// Scroll in specified direction to a specified index position
	// Must be public so can be called via timer which has global scope.
	// Call recursively to implement acceleration algorithm
	function CAutoScroll_ScrollToPosition( p_nScroll, p_nPosition )
	{												
		var nScrollSpeed = 0;
		
		// Stop the scroll timer .. 
		// Note call through member variable for reference to this object
		this.ScrollStop();	
												
		// Calculate scroll amount considering acceleration
		switch(p_nScroll )
		{
			case SCROLL_LEFT:
				nScrollSpeed = Math.floor( (( p_nPosition - m_nMaskX ) ) * m_nAcceleration );																																																					
				break;
			case SCROLL_RIGHT:
				nScrollSpeed = Math.floor( (( p_nPosition - m_nMaskX ) ) * m_nAcceleration ) * -1;																																																					
				break;
			case SCROLL_UP:
				nScrollSpeed = Math.floor( ( p_nPosition - m_nMaskY ) * m_nAcceleration );					
				break;				
			case SCROLL_DOWN:
				nScrollSpeed = Math.floor( ( p_nPosition - m_nMaskY ) * m_nAcceleration ) * -1;					
				break;
		}		
							
		// Check we have not yet reached the stop point							
		if(nScrollSpeed > 0)
		{
			// Set layer positions
			SetSpeed( p_nScroll, nScrollSpeed );								
					
			// Move the layers and clip window
			SetPosition();								
					
			// Recurse on timer to scroll
			m_nTimeOut = setTimeout( m_sName + ".ScrollToPosition( " + p_nScroll + ", " + p_nPosition + " )", m_nScrollTime );							
		}
	}
		
	////////////////////////////////////////////////////////////////////////////////
	// PUBLIC VARIABLE ACCESSORS
	////////////////////////////////////////////////////////////////////////////////
		
	// Return current scroll location index	
	function CAutoScroll_GetCurrentScrollIndex()
	{
		return m_nScrollIndex;
	}
		
	// Return max scroll location index	
	function CAutoScroll_GetMaxScrollIndex()
	{
		return m_nMaxScrollCount;
	}
	
	// Set the scroll layer position
	function CAutoScroll_SetXpos( nXpos )
	{
		m_nLayerX = nXpos;
	}
	
	// Set the scroll layer position
	function CAutoScroll_SetYpos( nYpos )
	{
		m_nLayerY = nYpos;
	}	
	
	////////////////////////////////////////////////////////////////////////////////
	// PRIVATE CLASS MEMBER FUNCTIONS 
	////////////////////////////////////////////////////////////////////////////////
		
	// Scroll the area in specified direction
	// pnDirection is any of the Scroll Constants	
	function Scroll( 
						p_nDirection, // Direction to scroll ... pass constant
						p_nScrollCount // Number of scroll operation to perform
					)
	{	
		// Default scroll count to 1 if not specified
		if(typeof(p_nScrollCount)=="undefined" || p_nScrollCount==null)
		{
			p_nScrollCount = 1;
		}							
									
		// Check if not already at the end of scroll area
		if( ValidateScrollIndex(p_nDirection) )
		{																												
			// Increment/Decrement Scroll Index
			UpdateScrollIndex(p_nDirection);						
																												
			// Perform Scroll of required amount			
			m_Ref.ScrollToPosition( p_nDirection, ( m_nScrollIndex * m_nScrollAmount ) );						
									 						
			// For multiple scrolls .. recurse
			if(p_nScrollCount > 1)
			{
				Scroll(p_nDirection, --p_nScrollCount);				
			}
		}					
	}
					
	// Private function to increment/decrement scroll index based on direction of scroll	
	function UpdateScrollIndex( p_nDirection )
	{
		// Increment current index
		if( p_nDirection==SCROLL_LEFT || p_nDirection==SCROLL_UP )
		{
			// Increase the current scroll index
			m_nScrollIndex++;
		}
		else
		{
			// Decrease the current scroll index
			m_nScrollIndex--;
		}				
	}		
		
	// Set position of layers and reset clip area on scroll area reposition.
	// This is the real action of moving the layers!	
	function SetPosition(  )
	{																											
			// Move the layer			
			m_oDiv.SetYpos( m_nLayerY );
			m_oDiv.SetXpos( m_nLayerX );	
	
			// Move the clip
			m_oDiv.SetClip( m_nMaskX, m_nMaskY, m_nMaskWidth + m_nMaskX, m_nMaskHeight + m_nMaskY );
	}
		
	// Private function to validate if scroll direction specified is valid for another scroll
	// in the specified direction
	// i.e. returns false if at end points of scroll	
	function ValidateScrollIndex( p_nDirection )
	{										
		// Scrolling towards max scroll
		if( p_nDirection == SCROLL_LEFT || p_nDirection == SCROLL_UP )
		{						
			// Check we are under max scroll count
			if(m_nScrollIndex < m_nMaxScrollCount)
			{								
				return true;
			}
		}
		else 
		{
			// Check we are past 0 start position
			if(m_nScrollIndex > 0)
			{				
				return true;
			}
		}				
		
		// At the edge so have to stop scroll
		return false;
	}		
		
	// Set new scroll layer positions based on calculated scroll speed and direction
	function SetSpeed( p_nScroll, p_nScrollSpeed )
	{		
		switch( p_nScroll )
		{
			case SCROLL_DOWN:
				m_nMaskY += p_nScrollSpeed;				
				m_nLayerY -= p_nScrollSpeed;	
			break;
			case SCROLL_UP:
				m_nMaskY -= p_nScrollSpeed;				
				m_nLayerY += p_nScrollSpeed;	
			break;
			case SCROLL_LEFT:				
				m_nMaskX += p_nScrollSpeed;								
				m_nLayerX -= p_nScrollSpeed;					
			break;
			case SCROLL_RIGHT:				
				m_nMaskX -= p_nScrollSpeed;								
				m_nLayerX += p_nScrollSpeed;				
			break;												
		}							
	}		
}

//</script>