//
//	The script assumes the following
//	In the container the only ELEMENT element child is the scrollable content, so you have to have this in mind
//	effectively the parent of the scrollable content is the container
//
//

cContentScroller = function( sId )
{
	this.sId = sId;
	this.hMoveConstraints = { bLeft: true, bRight: true, bTop: true, bBottom: true };
	this.bScrolling = false;
	this.nScrollingDirection = 0;
	this.hScrollLinksIds = {};
	this.onLinksUpdate = new MO.Event.customEvent( 'onLinksUpdate', this );
	this.onScrollEnd = new MO.Event.customEvent( 'onScrollEnd', this );
}

cContentScroller.CN_SCROLL_LEFT = 0x01;
cContentScroller.CN_SCROLL_RIGHT = 0x02;
cContentScroller.CN_SCROLL_UP = 0x04;
cContentScroller.CN_SCROLL_DOWN = 0x08;


cContentScroller.bReverseUpDown = true;
cContentScroller.nSteps = 9;
cContentScroller.nSpeed = 30;
cContentScroller.nDist = 160;	

cContentScroller.CB_FADE = false;

cContentScroller.CS_ENABLED_LINK_CLASS = 'scrollEnabled';
cContentScroller.CS_DISABLED_LINK_CLASS = 'scrollDisabled';

cContentScroller.scrollUp = function( hContainer, nDistance )
{
	cContentScroller.scroll( hContainer, { deltaX : null, deltaY: -cContentScroller.getDistance( hContainer, nDistance, 'up' ) }, cContentScroller.CN_SCROLL_UP );
}

cContentScroller.scrollDown = function( hContainer, nDistance )
{
	cContentScroller.scroll( hContainer, { deltaX : null, deltaY: cContentScroller.getDistance( hContainer, nDistance, 'down' ) }, cContentScroller.CN_SCROLL_DOWN );
}

cContentScroller.scrollLeft = function( hContainer, nDistance )
{
	cContentScroller.scroll( hContainer, { deltaX : -cContentScroller.getDistance( hContainer, nDistance, 'left' ), deltaY : null }, cContentScroller.CN_SCROLL_LEFT );
}


cContentScroller.scrollRight = function( hContainer, nDistance )
{
	cContentScroller.scroll( hContainer, { deltaX : cContentScroller.getDistance( hContainer, nDistance, 'right' ), deltaY : null }, cContentScroller.CN_SCROLL_RIGHT );
}

cContentScroller.getContent = function( hContainer )
{
	var nI = 0;
	var hContent = null;
	while( hContainer.childNodes[ nI ].nodeType != document.ELEMENT_NODE )
	{
		nI++;
	}
	if( hContainer.childNodes[ nI ].nodeType == document.ELEMENT_NODE );
	{
		hContent = hContainer.childNodes[ nI ];
	}
	return hContent;
}

cContentScroller.getDistance = function( hContainer, nDistance, sScrollType )
{
	var hContent = cContentScroller.getContent( hContainer );

	hContent.style.width = hContent.scrollWidth + 'px';
	hContent.style.height = hContent.scrollHeight + 'px';

	var hContainerPos = MO.Dom.getXY( hContainer );
	var hContainerSize = MO.Dom.getSize( hContainer );
	var hContentPos = MO.Dom.getXY( hContent );
	var hContentSize = MO.Dom.getSize( hContent );

	var nContainerHeight = hContainerSize[ 1 ] - MO.DomExt.getBorderWidth( hContainer, "tb" ) - MO.DomExt.getPaddingWidth( hContainer, "tb" );
	//var nHeight = hContentSize[ 1 ];
	var nTop = hContent.offsetTop + MO.DomExt.getBorderWidth( hContainer, "t" );
	//var nTop = hContentPos[ 1 ] - hContainerPos[ 1 ];
	var nHeight = hContent.offsetHeight;

	var nContainerWidth = hContainerSize[ 0 ] - MO.DomExt.getBorderWidth( hContainer, "lr" ) - MO.DomExt.getPaddingWidth( hContainer, "lr" );;
	//var nWidth = hContentSize[ 0 ];
	var nLeft = hContent.offsetLeft + MO.DomExt.getBorderWidth( hContainer, "l" );
	//var nLeft = hContentPos[ 0 ] - hContainerPos[ 0 ];
	var nWidth = hContent.offsetWidth;
	
	if( !nDistance )
	{
		nDistance = cContentScroller.nDist;
	}
	
	switch( sScrollType )
	{
		case 'up'		:	if( nTop <= ( nContainerHeight - nHeight ) )
							{
								return false;
							}
							else
							{
								nDistance = ( nHeight + nTop - nContainerHeight ) < nDistance ? Math.abs( nHeight + nTop - nContainerHeight ) : nDistance;
							}
						break;
		case 'down'	:	if( nTop >= 0 )
						{
							return false;
						}
						else
						{
							nDistance = Math.abs( nTop ) < nDistance ? Math.abs( nTop ) : nDistance;
						}
						break;
		case 'left'		:	if( nLeft <= ( nContainerWidth - nWidth ) )
							{
								return false;
							}
							else
							{
								nDistance = ( nWidth + nLeft - nContainerWidth ) < nDistance ? Math.abs( nWidth + nLeft - nContainerWidth ) : nDistance;
							}
						break;
		case 'right'	:	if( nLeft >= 0 )
							{
								return false;
							}
							else
							{
								nDistance = Math.abs( nLeft ) < nDistance ? Math.abs( nLeft ) : nDistance;
							}
						break;
	}
	
	return nDistance;
}

cContentScroller.scroll = function( hContainer, aDistance, nDirection )
{
	var hContent = cContentScroller.getContent( hContainer );
	if( cContentScroller.CB_FADE )
	{
		hE = new cMoEffects.cFade( hContent, 100, 20, {nSteps:5, nDuration:100} );
	}
	cContentScroller.setScrolling( hContainer, true, nDirection );
	var hE = new cMoEffects.cMover( hContent, null, null, aDistance.deltaX, aDistance.deltaY, cMoEffects.cMover.CN_MOVE_GLIDEFAST, true, {nSteps:8, nDuration:200, onFinish:function(){ var hE; if( cContentScroller.CB_FADE ) { hE = new cMoEffects.cFade( this.sId, 20, 100, {nSteps:5, nDuration:100} ) }; cContentScroller.updateConstraints( MO.Dom.get( this.sId ).parentNode ); MO.Dom.get( this.sId ).parentNode.contentScroller.onScrollEnd.fire(); cContentScroller.setScrolling( MO.Dom.get( this.sId ).parentNode, false ) }} );
}

cContentScroller.onScrollLinkClick = function( e )
{
	var hContainer;
	var nDistance = this.getAttribute( 'distance' ) ? parseInt( this.getAttribute( 'distance' ) ) : null;

	if( MO.Dom.hasClass( this, 'scrollUpButton' ) )
	{
		hContainer = document.getElementById( this.id.substring( 0, this.id.length - 2 ) );
		if( hContainer.contentScroller.bScrolling )
		{
			return;
		}
		if( hContainer )
		{
			if( cContentScroller.bReverseUpDown )
			{
				cContentScroller.scrollDown( hContainer, nDistance );
			}
			else
			{
				cContentScroller.scrollUp( hContainer, nDistance );
			}
		}
	}
	if( MO.Dom.hasClass( this, 'scrollDownButton' ) )
	{
		hContainer = document.getElementById( this.id.substr( 0, this.id.length - 4 ) );
		if( hContainer.contentScroller.bScrolling )
		{
			return;
		}
		if( hContainer )
		{
			if( cContentScroller.bReverseUpDown )
			{
				cContentScroller.scrollUp( hContainer, nDistance );
			}
			else
			{
				cContentScroller.scrollDown( hContainer, nDistance );
			}
		}
	}
	if( MO.Dom.hasClass( this, 'scrollLeftButton' ) )
	{
		hContainer = document.getElementById( this.id.substring( 0, this.id.length - 4 ) );
		if( hContainer.contentScroller.bScrolling )
		{
			return;
		}
		if( hContainer )
		{
			cContentScroller.scrollLeft( hContainer, nDistance );
		}
	}
	if( MO.Dom.hasClass( this, 'scrollRightButton' ) )
	{
		hContainer = document.getElementById( this.id.substr( 0, this.id.length - 5 ) );
		if( hContainer.contentScroller.bScrolling )
		{
			return;
		}
		if( hContainer )
		{
			cContentScroller.scrollRight( hContainer, nDistance );
		}
	}

	MO.Event.cancelEvent( e )
	return false
}

cContentScroller.onContainerKeyUp = function( e )
{
	var hContainer = MO.Dom.getParentBy( this, 'className', 'contentScrollable' );
	var hEvent = MO.Event.getEvent( e );
	switch( hEvent.key )
	{
		case	38				:	if( hContainer.contentScroller.bScrolling )
									{
										return;
									}
									if( hContainer )
									{
										cContentScroller.scrollUp( hContainer );
									}
									break
		case	40				:	if( hContainer.contentScroller.bScrolling )
									{
										return;
									}
									if( hContainer )
									{
										cContentScroller.scrollDown( hContainer );
									}
									break
		case	37				:	if( hContainer.contentScroller.bScrolling )
									{
										return;
									}
									if( hContainer )
									{
										cContentScroller.scrollLeft( hContainer );
									}
									break
		case	39				:	if( hContainer.contentScroller.bScrolling )
									{
										return;
									}
									if( hContainer )
									{
										cContentScroller.scrollRight( hContainer );
									}
									break
	}
}

cContentScroller.initScrollLinks = function( hLink )
{
	if( hLink )
	{
		hLink.className += ' ';
		MO.Event.addEvent( hLink, 'click', cContentScroller.onScrollLinkClick );

		if( MO.Dom.hasClass( hLink, 'scrollUpButton' ) )
		{
			this.hScrollLinksIds[ 'Top' ] = hLink.id;
		}
		if( MO.Dom.hasClass( hLink, 'scrollDownButton' ) )
		{
			this.hScrollLinksIds[ 'Bottom' ] = hLink.id;
		}
		if( MO.Dom.hasClass( hLink, 'scrollLeftButton' ) )
		{
			this.hScrollLinksIds[ 'Left' ] = hLink.id;
		}
		if( MO.Dom.hasClass( hLink, 'scrollRightButton' ) )
		{
			this.hScrollLinksIds[ 'Right' ] = hLink.id;
		}
	}
}

cContentScroller.setScrolling = function( hContainer, bScrolling, nDirection )
{	
	if( typeof nDirection == 'undefined' || bScrolling == false )
	{
		nDirection = 0;
	}

	hContainer = MO.Dom.get( hContainer );
	hContainer.contentScroller.bScrolling = bScrolling;

	hContainer.contentScroller.nScrollingDirection = nDirection;
}

cContentScroller.updateConstraints = function( hContainer )
{	
	hContainer = MO.Dom.get( hContainer );
	var nI = 0;
	while( hContainer.childNodes[ nI ].nodeType != document.ELEMENT_NODE )
	{
		nI++;
	}
	if( hContainer.childNodes[ nI ].nodeType == document.ELEMENT_NODE )
	{
		hContent = hContainer.childNodes[ nI ];
	}

	var hContainerPos = MO.Dom.getXY( hContainer );
	var hContainerSize = MO.Dom.getSize( hContainer );
	var hContentPos = MO.Dom.getXY( hContent );
	var hContentSize = MO.Dom.getSize( hContent );

	var nContainerHeight = hContainerSize[ 1 ] - MO.DomExt.getBorderWidth( hContainer, "tb" ) - MO.DomExt.getPaddingWidth( hContainer, "tb" );
	//var nHeight = hContentSize[ 1 ];
	var nTop = hContent.offsetTop + MO.DomExt.getBorderWidth( hContainer, "t" );
	//var nTop = hContentPos[ 1 ] - hContainerPos[ 1 ];
	var nHeight = hContent.offsetHeight;

	var nContainerWidth = hContainerSize[ 0 ] - MO.DomExt.getBorderWidth( hContainer, "lr" ) - MO.DomExt.getPaddingWidth( hContainer, "lr" );;
	//var nWidth = hContentSize[ 0 ];
	var nLeft = hContent.offsetLeft + MO.DomExt.getBorderWidth( hContainer, "l" );
	//var nLeft = hContentPos[ 0 ] - hContainerPos[ 0 ];
	var nWidth = hContent.offsetWidth;

	if( nLeft >= 0 )
	{
		hContainer.contentScroller.hMoveConstraints.bRight = true;
		hContainer.contentScroller.hMoveConstraints.Right = true;
	}
	else
	{
		hContainer.contentScroller.hMoveConstraints.bRight = false;
		hContainer.contentScroller.hMoveConstraints.Right = false;
	}

	if( nLeft <= ( nContainerWidth - nWidth ) )
	{
		hContainer.contentScroller.hMoveConstraints.bLeft = true;
		hContainer.contentScroller.hMoveConstraints.Left = true;
	}
	else
	{
		hContainer.contentScroller.hMoveConstraints.bLeft = false;
		hContainer.contentScroller.hMoveConstraints.Left = false;
	}

	if( nTop >= 0 )
	{
		hContainer.contentScroller.hMoveConstraints.bBottom = true;
		hContainer.contentScroller.hMoveConstraints.Bottom = true;
	}
	else
	{
		hContainer.contentScroller.hMoveConstraints.bBottom = false;
		hContainer.contentScroller.hMoveConstraints.Bottom = false;
	}
	
	if( nTop <= ( nContainerHeight - nHeight ) )
	{
		hContainer.contentScroller.hMoveConstraints.bTop = true;
		hContainer.contentScroller.hMoveConstraints.Top = true;
	}
	else
	{
		hContainer.contentScroller.hMoveConstraints.bTop = false;
		hContainer.contentScroller.hMoveConstraints.Top = false;
	}

	for( var hI in hContainer.contentScroller.hMoveConstraints )
	{
		if( hI.charAt( 0 ) != 'b' )
		{
			if( hContainer.contentScroller.hMoveConstraints[ hI ] )
			{
				MO.Dom.removeClass( MO.Dom.get( hContainer.contentScroller.hScrollLinksIds[ hI ] ), 'scrollEnabled' );
				MO.Dom.addClass( MO.Dom.get( hContainer.contentScroller.hScrollLinksIds[ hI ] ), 'scrollDisabled' );
			}
			else
			{
				MO.Dom.addClass( MO.Dom.get( hContainer.contentScroller.hScrollLinksIds[ hI ] ), 'scrollEnabled' );
				MO.Dom.removeClass( MO.Dom.get( hContainer.contentScroller.hScrollLinksIds[ hI ] ), 'scrollDisabled' );
			}
		}
	}
	hContainer.contentScroller.onLinksUpdate.fire( hContainer.contentScroller );
}

cContentScroller.init = function( hContainer )
{
	var nI = 0;
	var hContent = null;
	while( hContainer.childNodes[ nI ].nodeType != document.ELEMENT_NODE )
	{
		nI++;
	}
	if( hContainer.childNodes[ nI ].nodeType == document.ELEMENT_NODE );
	{
		hContent = hContainer.childNodes[ nI ];
	}

	hContainer.contentScroller = new cContentScroller( hContainer.id );

	if( hContent )
	{
		cContentScroller.initScrollLinks.call( hContainer.contentScroller, document.getElementById( hContainer.id + 'Up' ) );
		cContentScroller.initScrollLinks.call( hContainer.contentScroller, document.getElementById( hContainer.id + 'Down' ) );
		cContentScroller.initScrollLinks.call( hContainer.contentScroller, document.getElementById( hContainer.id + 'Left' ) );
		cContentScroller.initScrollLinks.call( hContainer.contentScroller, document.getElementById( hContainer.id + 'Right' ) );

		MO.Event.addEvent( hContainer, 'keyup', cContentScroller.onContainerKeyUp );
	}

	/*
	hContent.style.width = hContent.scrollWidth + 'px';
	hContent.style.height = hContent.scrollHeight + 'px';
	*/

	cContentScroller.updateConstraints( hContainer );
}

cContentScroller.initContainers = function()
{
	MO.Dom.getElementsBySelector( "div[class*=contentScrollable]" ).apply( cContentScroller.init );
}

MO.Event.DomLoaded.load( cContentScroller.initContainers );