
/**
 * Fornece as funcionalidades para implementar e gerenciar um Scroller.
 * @author Márcio Pimentel Espósito [marcioesposito@edglobo.com.br]
 * @version 1.0
 * @since 20/12/2008
 */
function Scroller()
{
	/**
	 * Tipo de Scroller horizontal.
	 * @property TYPE_HORIZONTAL
	 * @type {String}
	 * @public
	 */
	var TYPE_HORIZONTAL = "horizontal";
	Scroller.prototype.TYPE_HORIZONTAL = TYPE_HORIZONTAL;

	/**
	 * Tipo de Scroller vertical.
	 * @property TYPE_VERTICAL
	 * @type {String}
	 * @public
	 */
	var TYPE_VERTICAL = "vertical";
	Scroller.prototype.TYPE_VERTICAL = TYPE_VERTICAL;

	/**
	 * Direção próxima, indica que o Scroller irá se mover para a frente, do menor item para o maior,
	 * conforme a ordem de criação dos elementos HTML.
	 * @property DIRECTION_NEXT
	 * @type {String}
	 * @public
	 */
	var DIRECTION_NEXT = "next";
	Scroller.prototype.DIRECTION_NEXT = DIRECTION_NEXT;

	/**
	 * Direção anterior, indica que o Scroller irá se mover para trás, do maoir item para o menor,
	 * conforme a ordem de criação dos elementos HTML.
	 * @property DIRECTION_PREVIOUS
	 * @type {String}
	 * @public
	 */
	var DIRECTION_PREVIOUS = "previous";
	Scroller.prototype.DIRECTION_PREVIOUS = DIRECTION_PREVIOUS;

	/**
	 * Id do intervalo de tempo zerado (window.clearInterval()).
	 * @property INTERVAL_ID_CLEAR
	 * @type {Number}
	 * @private
	 */
	var INTERVAL_ID_CLEAR = -1

	/**
	 * Status do movimento iniciado.
	 * @property STATUS_MOVE_STARTED
	 * @type {String}
	 * @private
	 */
	var STATUS_MOVE_STARTED = "started"

	/**
	 * Status do movimento parado.
	 * @property STATUS_MOVE_STOPPED
	 * @type {String}
	 * @private
	 */
	var STATUS_MOVE_STOPPED = "stopped";

	/**
	 * Divisor padrão do tempo de movimento do Scroller.
	 * @property MOVE_DIVISOR
	 * @type {Number}
	 * @private
	 */
	var MOVE_DIVISOR = 5;

	/**
	 * Calcula o índice do elemento
	 * @method calcElementIndex
	 * @param {Object} scroller
	 * @param {Number} index
	 * @return {Number}
	 * @private
	 */
	function calcElementIndex( scroller, index )
	{
		var count = 0;

		for ( var i = 0; i < scroller.childNodes.length; i ++ )
		{
			if (( typeof scroller.childNodes[i].nodeName == "string" ) &&
				( scroller.childNodes[i].nodeName != "#text" ) &&
				( scroller.childNodes[i].nodeName != "#comment" ))
			{
				if ( index == count )
				{
					return i;
				}

				count ++;
			}
		}
	}

	/**
	 * Calcula o índice de um determinado item, conforme sua posição de exibição.
	 * @method calcItemIndex
	 * @param {Object} scroller
	 * @param {String} direction
	 * @param {Number} position
	 * @return {Number}
	 * @private
	 */
	function calcItemIndex( scroller, direction, position )
	{
		if ( direction == DIRECTION_NEXT )
		{
			if (( getFirstItem( scroller ) + position ) >= getLength( scroller ))
			{
				return ( getFirstItem( scroller ) + position ) - getLength( scroller );
			}
			else
			{
				return getFirstItem( scroller ) + position;
			}
		}
		else
		{
			if (( getLastItem( scroller ) - position ) < 0 )
			{
				return ( getLastItem( scroller ) - position ) + getLength( scroller );
			}
			else
			{
				return getLastItem( scroller ) - position;
			}
		}
	}

	/**
	 * Calcula o left de um determinado item, com base em seu índice, sua posição de exibição
	 * e a direção que o Scroller está se movendo.
	 * @method calcItemLeft
	 * @param {Object} scroller
	 * @param {Number} index
	 * @param {Number} position
	 * @param {String} direction
	 * @return {Number}
	 * @private
	 */
	function calcItemLeft( scroller, index, position, direction )
	{
		if (( getType( scroller ) == TYPE_HORIZONTAL ) && ( typeof getItemsWidth( scroller ) != "undefined" ))
		{
			var i = calcElementIndex( scroller, index );

			if ( scroller.childNodes[i].style.left.length > 0 )
			{
				var positionHelp = 1;
				var positionHelpRange = 0;
				var left = parseInt( scroller.childNodes[i].style.left );
				var leftPart = parseInt( getItemsWidth( scroller ) / calcMoveDivisor( scroller ));
				var leftHelp = -1;
				var leftLast = ( getItemsWidth( scroller ) * ( position + positionHelp )) +
					(( leftPart * calcMoveDivisor( scroller )) * leftHelp );

				if ( direction == DIRECTION_PREVIOUS )
				{
					positionHelp = -1;
					positionHelpRange = -1;
					leftHelp = 1;
				}

				if (( left < ( getItemsWidth( scroller ) * ( position + positionHelpRange ))) ||
					( left > ( getItemsWidth( scroller ) * (( position + positionHelpRange ) + 1 ))))
				{
					left = getItemsWidth( scroller ) * ( position + positionHelp );
				}

				if (((( left + ( leftPart * leftHelp )) > leftLast ) && direction == DIRECTION_NEXT ) ||
					((( left + ( leftPart * leftHelp )) < leftLast ) && direction == DIRECTION_PREVIOUS ))  
				{
					return left + ( leftPart * leftHelp );
				}
			}

			return getItemsWidth( scroller ) * position;
		}
		else
		{
			return 0;
		}
	}

	/**
	 * Calcula a posição de exibição de um determinado item. 
	 * @method calcItemPosition
	 * @param {Object} scroller
	 * @param {Number} position
	 * @return {Number}
	 * @private
	 */
	function calcItemPosition( scroller, position )
	{
		if ( position < -1 )
		{
			return -1;
		}
		else if ( position > getDisplayItems( scroller ))
		{
			return getDisplayItems( scroller );
		}
		else
		{
			return position;
		}
	}

	/**
	 * Calcula o top de um determinado item, com base em seu índice, sua posição de exibição
	 * e a direção que o Scroller está se movendo.
	 * @method calcItemTop
	 * @param {Object} scroller
	 * @param {Number} index
	 * @param {Number} position
	 * @param {String} direction
	 * @return {Number}
	 * @private
	 */
	function calcItemTop( scroller, index, position, direction )
	{
		if (( getType( scroller ) == TYPE_VERTICAL ) && ( typeof getItemsHeight( scroller ) != "undefined" ))
		{
			var i = calcElementIndex( scroller, index );

			if ( scroller.childNodes[i].style.top.length > 0 )
			{
				var positionHelp = 1;
				var positionHelpRange = 0;
				var top = parseInt( scroller.childNodes[i].style.top );
				var topPart = parseInt( getItemsHeight( scroller ) / calcMoveDivisor( scroller ));
				var topHelp = -1;
				var topLast = ( getItemsHeight( scroller ) * ( position + positionHelp )) +
					(( topPart * calcMoveDivisor( scroller )) * topHelp );

				if ( direction == DIRECTION_PREVIOUS )
				{
					positionHelp = -1;
					positionHelpRange = -1;
					topHelp = 1;
				}

				if (( top < ( getItemsHeight( scroller ) * ( position + positionHelpRange ))) ||
					( top > ( getItemsHeight( scroller ) * (( position + positionHelpRange ) + 1 ))))
				{
					top = getItemsHeight( scroller ) * ( position + positionHelp );
				}

				if (((( top + ( topPart * topHelp )) > topLast ) && direction == DIRECTION_NEXT ) ||
					((( top + ( topPart * topHelp )) < topLast ) && direction == DIRECTION_PREVIOUS ))  
				{
					return top + ( topPart * topHelp );
				}
			}

			return getItemsHeight( scroller ) * position;
		}
		else
		{
			return 0;
		}
	}

	/**
	 * Calcula a altura do Scroller.
	 * @method calcScrollerHeight
	 * @param {Object} scroller
	 * @return {Number}
	 * @private
	 */
	function calcScrollerHeight( scroller )
	{
		if (( typeof getItemsHeight( scroller ) != "undefined" ) &&
			( typeof getDisplayItems( scroller ) != "undefined" ))
		{
			if ( getType( scroller ) == TYPE_VERTICAL  )
			{
				return getItemsHeight( scroller ) * getDisplayItems( scroller );
			}
			else
			{
				return getItemsHeight( scroller );
			}
		}
		else
		{
			return 0;
		}
	}

	/**
	 * Calcula a largura do Scroller.
	 * @method calcScrollerHeight
	 * @param {Object} scroller
	 * @return {Number}
	 * @private
	 */
	function calcScrollerWidth( scroller )
	{
		if (( typeof getItemsWidth( scroller ) != "undefined" ) &&
			( typeof getDisplayItems( scroller ) != "undefined" ))
		{
			if ( getType( scroller ) == TYPE_HORIZONTAL  )
			{
				return getItemsWidth( scroller ) * getDisplayItems( scroller );
			}
			else
			{
				return getItemsWidth( scroller );
			}
		}
		else
		{
			return 0;
		}
	}

	/**
	 * Calcula o divisor de movimento do Scroller.
	 * @method calcMoveDivisor
	 * @param {Object} scroller
	 * @return {Number}
	 * @private
	 */
	function calcMoveDivisor( scroller )
	{
		if ( getType( scroller ) == TYPE_HORIZONTAL )
		{
			if ( getItemsWidth( scroller ).length > 3 )
			{
				return ( getItemsWidth( scroller ).length - 2 ) * MOVE_DIVISOR;
			}
			else
			{
				return MOVE_DIVISOR;
			}
		}
		else
		{
			if ( getItemsHeight( scroller ).length > 3 )
			{
				return ( getItemsHeight( scroller ).length - 2 ) * MOVE_DIVISOR;
			}
			else
			{
				return MOVE_DIVISOR;
			}
		}
	}

	/**
	 * Obtem a quantidade de itens a serem exibidos no Scroller.
	 * @method getDisplayItems
	 * @param {Object} scroller
	 * @return {Number}
	 * @public
	 */
	function getDisplayItems( scroller )
	{
		if ( typeof scroller != "object" )
		{
			window.alert( "Error" );
		}
		else
		{
			if ( scroller.getAttribute( "displayItems" ) != null )
			{
				return parseInt( scroller.getAttribute( "displayItems" ));
			}
			else
			{
				return undefined;
			}
		}
	}
	Scroller.prototype.getDisplayItems = getDisplayItems;

	/**
	 * Seta a quantidade de itens a serem exibidos no Scroller.
	 * @method setDisplayItems
	 * @param {Object} scroller
	 * @param {Number} displayItems
	 * @public
	 */
	function setDisplayItems( scroller, displayItems )
	{
		if ( typeof scroller != "object" )
		{
			window.alert( "Error" );
		}
		else if ( typeof displayItems != "number" )
		{
			window.alert( "Error" );
		}
		else
		{
			var count = 0;
			scroller.setAttribute( "displayItems", displayItems );
			scroller.setAttribute( "height", calcScrollerHeight( scroller ));
			scroller.setAttribute( "width", calcScrollerWidth( scroller ));
			scroller.style.height = calcScrollerHeight( scroller ) + "px";
			scroller.style.width = calcScrollerWidth( scroller ) + "px";

			for ( var i = 0; i < scroller.childNodes.length; i ++ )
			{
				if (( typeof scroller.childNodes[i].nodeName == "string" ) &&
					( scroller.childNodes[i].nodeName != "#text" ) &&
					( scroller.childNodes[i].nodeName != "#comment" ))
				{
					scroller.childNodes[i].style.position = "absolute";
					scroller.childNodes[i].style.left = "";
					scroller.childNodes[i].style.top = "";

					scroller.childNodes[i].style.left = calcItemLeft(
						scroller,
						count,
						calcItemPosition( scroller, count ),
						DIRECTION_NEXT ) + "px";

					scroller.childNodes[i].style.top = calcItemTop(
						scroller,
						count,
						calcItemPosition( scroller, count ),
						DIRECTION_NEXT ) + "px";

					count ++;

					if ( count < getDisplayItems( scroller ))
					{
						setLastItem( scroller, count );
					}
				}
			}
		}
	}
	Scroller.prototype.setDisplayItems = setDisplayItems;

	/**
	 * Obtem o índice do primeiro item em exibição no Scroller.
	 * @method getFirstItem 
	 * @param {Object} scroller
 	 * @return {Number}
	 * @private
	 */
	function getFirstItem( scroller )
	{
		return parseInt( scroller.getAttribute( "firstItem" ));
	}

	/**
	 * Seta o índice do primeiro item em exibição no Scroller.
	 * @method setFirstItem
	 * @param {Object} scroller
	 * @param {Number} firstItem
	 * @private
	 */
	function setFirstItem( scroller, firstItem )
	{
		scroller.setAttribute( "firstItem", firstItem );
	}

	/**
	 * Obtem o índice do último item em exibição no Scroller.
	 * @method getLastItem
	 * @param {Object} scroller
	 * @return {Number}
	 * @private
	 */
	function getLastItem( scroller )
	{
		return parseInt( scroller.getAttribute( "lastItem" ));
	}

	/**
	 * Seta o índice do último item em exibição no Scroller.
	 * @method setLastItem
	 * @param {Object} scroller
	 * @param {Number} lastItem
	 * @private
	 */
	function setLastItem( scroller, lastItem )
	{
		scroller.setAttribute( "lastItem", lastItem );
	}

	/**
	 * Obtem o id do intervalo de tempo.
	 * @method getIntervalId
	 * @param {Object} scroller
	 * @return {Number}
	 * @private
	 */
	function getIntervalId( scroller )
	{
		return parseInt( scroller.getAttribute( "intervalId" ));
	}

	/**
	 * Seta o id do intevalo de tempo.
	 * @method setIntervalId
	 * @param {Object} scroller
	 * @param {Number} intervalId
	 * @private
	 */
	function setIntervalId( scroller, intervalId )
	{
		scroller.setAttribute( "intervalId", intervalId );
	}

	/**
	 * Obtem a quantidade de itens do Scroller.
	 * @method getLength
	 * @param {Object} scroller
	 * @return {Number}
	 * @private
	 */
	function getLength( scroller )
	{
		return parseInt( scroller.getAttribute( "length" ));
	}

	/**
	 * Seta a quantidade de itens do Scroller.
	 * @method setLength
	 * @param {Object} scroller
	 * @param {Number} length
	 * @private
	 */
	function setLength( scroller, length )
	{
		scroller.setAttribute( "length", length );
	}

	/**
	 * Obtem a altura dos itens do Scroller.
	 * @method getItemsHeight
	 * @param {Object} scroller
	 * @return {Number}
	 * @public
	 */
	function getItemsHeight( scroller )
	{
		if ( typeof scroller != "object" )
		{
			window.alert( "Error" );
		}
		else
		{
			if ( scroller.getAttribute( "itemsHeight" ) != null )
			{
				return parseInt( scroller.getAttribute( "itemsHeight" ));
			}
			else
			{
				return undefined;
			}
		}
	}
	Scroller.prototype.getItemsHeight = getItemsHeight;

	/**
	 * Seta a altura dos itens do Scroller.
	 * @method setItemsHeight
	 * @param {Object} scroller
	 * @param {Number} itemsHeight
	 * @public
	 */
	function setItemsHeight( scroller, itemsHeight )
	{
		if ( typeof scroller != "object" )
		{
			window.alert( "Error" );
		}
		else if ( typeof itemsHeight != "number" )
		{
			window.alert( "Error" );
		}
		else
		{
			var count = 0;
			scroller.setAttribute( "itemsHeight", itemsHeight );
			scroller.setAttribute( "height", calcScrollerHeight( scroller ));
			scroller.style.height = calcScrollerHeight( scroller ) + "px";

			for ( var i = 0; i < scroller.childNodes.length; i ++ )
			{
				if (( typeof scroller.childNodes[i].nodeName == "string" ) &&
					( scroller.childNodes[i].nodeName != "#text" ) &&
					( scroller.childNodes[i].nodeName != "#comment" ))
				{
					scroller.childNodes[i].setAttribute( "height", itemsHeight );
					scroller.childNodes[i].style.height = itemsHeight + "px";
					scroller.childNodes[i].style.position = "absolute";
					scroller.childNodes[i].style.top = "";
					scroller.childNodes[i].style.top = calcItemTop(
						scroller,
						count,
						calcItemPosition( scroller, count ),
						DIRECTION_NEXT ) + "px";

					count ++;
				}
			}
		}
	}
	Scroller.prototype.setItemsHeight = setItemsHeight;

	/**
	 * Obtem a largura dos itens do Scroller.
	 * @method getItemsWidth
	 * @param {Object} scroller
	 * @return {Number}
	 * @public
	 */
	function getItemsWidth( scroller )
	{
		if ( typeof scroller != "object" )
		{
			window.alert( "Error" );
		}
		else
		{
			if ( scroller.getAttribute( "itemsWidth" ) != null )
			{
				return parseInt( scroller.getAttribute( "itemsWidth" ));
			}
			else
			{
				return undefined;
			}
		}
	}
	Scroller.prototype.getItemsWidth = getItemsWidth;

	/**
	 * Seta a largura dos itens do Scroller.
	 * @method setItemsWidth
	 * @param {Object} scroller
	 * @param {Number} itemsWidth
	 * @public
	 */
	function setItemsWidth( scroller, itemsWidth )
	{
		if ( typeof scroller != "object" )
		{
			window.alert( "Error" );
		}
		else if ( typeof itemsWidth != "number" )
		{
			window.alert( "Error" );
		}
		else
		{
			var count = 0;
			scroller.setAttribute( "itemsWidth", itemsWidth );
			scroller.setAttribute( "width", calcScrollerWidth( scroller ));
			scroller.style.width = calcScrollerWidth( scroller ) + "px";

			for ( var i = 0; i < scroller.childNodes.length; i ++ )
			{
				if (( typeof scroller.childNodes[i].nodeName == "string" ) &&
					( scroller.childNodes[i].nodeName != "#text" ) &&
					( scroller.childNodes[i].nodeName != "#comment" ))
				{
					scroller.childNodes[i].setAttribute( "width", itemsWidth );
					scroller.childNodes[i].style.width = itemsWidth + "px";
					scroller.childNodes[i].style.position = "absolute";
					scroller.childNodes[i].style.left = "";
					scroller.childNodes[i].style.left = calcItemLeft(
						scroller,
						count,
						calcItemPosition( scroller, count ),
						DIRECTION_NEXT ) + "px";

					count ++;
				}
			}
		}
	}
	Scroller.prototype.setItemsWidth = setItemsWidth;

	/**
	 * Obtem o tempo (segundos) de movimento do Scroller.
	 * @method getTimeMove
	 * @param {Object} scroller
	 * @return {Number}
	 * @public
	 */
	function getTimeMove( scroller )
	{
		if ( typeof scroller != "object" )
		{
			window.alert( "Error" );
		}
		else
		{
			if ( scroller.getAttribute( "timeMove" ) != null )
			{
				return parseFloat( scroller.getAttribute( "timeMove" ));
			}
			else
			{
				return undefined;
			}
		}
	}
	Scroller.prototype.getTimeMove = getTimeMove;

	/**
	 * Seta o tempo (segundos) de movimento do Scroller.
	 * @method setTimeMove
	 * @param {Object} scroller
	 * @param {Number} timeMove
	 * @public
	 */
	function setTimeMove( scroller, timeMove )
	{
		if ( typeof scroller != "object" )
		{
			window.alert( "Error" );
		}
		else if ( typeof timeMove != "number" )
		{
			window.alert( "Error" );
		}
		else
		{
			scroller.setAttribute( "timeMove", timeMove );
		}
	}
	Scroller.prototype.setTimeMove = setTimeMove;

	/**
	 * Obtem o tipo do Scroller, definido conforme as constantes TYPE_HORIZONTAL ou TYPE_VERTICAL.
	 * @method getType
	 * @param {Object} scroller
	 * @return {String}
	 * @public
	 */
	function getType( scroller )
	{
		if ( typeof scroller != "object" )
		{
			window.alert( "Error" );
		}
		else
		{
			if ( scroller.getAttribute( "type" ) != null )
			{
				return scroller.getAttribute( "type" );
			}
			else
			{
				return undefined;
			}
		}
	}
	Scroller.prototype.getType = getType;

	/**
	 * Seta o tipo do Scroller, conforme as constantes TYPE_HORIZONTAL ou TYPE_VERTICAL.
	 * @method setType
	 * @param {Object} scroller
	 * @param {String} type
	 * @public
	 */
	function setType( scroller, type )
	{
		if ( typeof scroller != "object" )
		{
			window.alert( "Error" );
		}
		else if ( typeof type != "string" )
		{
			window.alert( "Error" );
		}
		else if (( type != TYPE_HORIZONTAL ) && ( type != TYPE_VERTICAL ))
		{
			window.alert( "Error" );
		}
		else
		{
			var count = 0;
			scroller.setAttribute( "type", type );
			scroller.setAttribute( "height", calcScrollerHeight( scroller ));
			scroller.setAttribute( "width", calcScrollerWidth( scroller ));
			scroller.style.height = calcScrollerHeight( scroller ) + "px";
			scroller.style.width = calcScrollerWidth( scroller ) + "px";

			for ( var i = 0; i < scroller.childNodes.length; i ++ )
			{
				if (( typeof scroller.childNodes[i].nodeName == "string" ) &&
					( scroller.childNodes[i].nodeName != "#text" ) &&
					( scroller.childNodes[i].nodeName != "#comment" ))
				{
					scroller.childNodes[i].style.position = "absolute";
					scroller.childNodes[i].style.left = "";
					scroller.childNodes[i].style.top = "";

					scroller.childNodes[i].style.left = calcItemLeft(
						scroller,
						count,
						calcItemPosition( scroller, count ),
						DIRECTION_NEXT ) + "px";

					scroller.childNodes[i].style.top = calcItemTop(
						scroller,
						count,
						calcItemPosition( scroller, count ),
						DIRECTION_NEXT ) + "px";

					count ++;
				}
			}
		}
	}
	Scroller.prototype.setType = setType;

	/**
	 * Seta o status de movimento do Scroller, conforme as constantes STATUS_MOVE_STARTED ou STATUS_MOVE_STOPPED.
	 * @method setStatusMove
	 * @param {Object} scroller
	 * @param {String} statusMove
	 * @private
	 */
	function setStatusMove( scroller, statusMove )
	{
		scroller.setAttribute( "statusMove", statusMove );
	}

	/**
	 * Verifica se o Scroller está em movimento.
	 * @method isMoving
	 * @param {Object} scroller
	 * @return {Boolean}
	 * @private
	 */
	function isMoving( scroller )
	{
		return ( scroller.getAttribute( "statusMove" ) == STATUS_MOVE_STARTED ? true : false );
	}

	/**
	 * Constroi um Scroller a partir de um elemento HTML.
	 * @method build
	 * @param {Object} element
	 * @return {Object}
	 * @public
	 */
	function build( element )
	{
		if ( typeof element != "object" )
		{
			window.alert( "Error" );
		}
		else
		{
			setDisplayItems( element, 4 );
			setLength( element, 0 );
			setIntervalId( element, INTERVAL_ID_CLEAR );
			setItemsHeight( element, 70 );
			setItemsWidth( element, 150 );
			setTimeMove( element, 1 );
			setType( element, TYPE_HORIZONTAL );
			setStatusMove( element, STATUS_MOVE_STOPPED );

			element.style.position = "relative";
			element.style.overflow = "hidden";

			for ( var i = 0; i < element.childNodes.length; i ++ )
			{
				if (( typeof element.childNodes[i].nodeName == "string" ) &&
					( element.childNodes[i].nodeName != "#text" ) &&
					( element.childNodes[i].nodeName != "#comment" ))
				{
					if ( getLength( element ) == 0 )
					{
						setFirstItem( element, getLength( element ));						
					}

					if ( getLength( element ) < getDisplayItems( element ))
					{
						setLastItem( element, getLength( element ));
					}

					setLength( element, getLength( element ) + 1 );
					element.childNodes[i].style.overflow = "hidden";
				}
			}

			return element;
		}
	}
	Scroller.prototype.build = build;

	/**
	 * Move o Scroller conforme as direções definidas pelas constantes DIRECTION_NEXT ou DIRECTION_PREVIOUS.
	 * @method move
	 * @param {Object} scroller
	 * @param {String} direction
	 * @public
	 */
	function move( scroller, direction )
	{
		if ( typeof scroller != "object" )
		{
			window.alert( "Error" );
		}
		else if ( typeof direction != "string" )
		{
			window.alert( "Error" );
		}
		else if (( direction != DIRECTION_NEXT ) && ( direction != DIRECTION_PREVIOUS ))
		{
			window.alert( "Error" );
		}
		else
		{
			if ( getLength( scroller ) > getDisplayItems( scroller ))
			{
				setStatusMove( scroller, STATUS_MOVE_STARTED );

				var positionInit = -1;
				var positionMult = 1;
				var firstItem = calcItemIndex( scroller, direction, 1 );
				var lastItem = calcItemIndex( scroller, direction, getDisplayItems( scroller ));
				var lastMove = false;

				if ( direction == DIRECTION_PREVIOUS )
				{
					positionInit = getDisplayItems( scroller );
					positionMult = -1;
					firstItem = calcItemIndex( scroller, direction, getDisplayItems( scroller ));
					lastItem = calcItemIndex( scroller, direction, 1 );
				}

				for ( var i = 0; i <= getDisplayItems( scroller ); i ++ )
				{
					var position = positionInit + ( i * positionMult );
					var index = calcItemIndex( scroller, direction, i );
					var left = calcItemLeft( scroller, index, position, direction );
					var top = calcItemTop( scroller, index, position, direction );
					var j = calcElementIndex( scroller, index );

					scroller.childNodes[j].style.left = left + "px";
					scroller.childNodes[j].style.top = top + "px";

					if (( left == 0 ) && ( top == 0  ) && ( position == 0 )) 
					{
						lastMove = true; 
					}
				}

				if ( lastMove )
				{
					window.clearInterval( getIntervalId( scroller ));
					setFirstItem( scroller, firstItem );
					setIntervalId( scroller, INTERVAL_ID_CLEAR );
					setLastItem( scroller, lastItem );
					setStatusMove( scroller, STATUS_MOVE_STOPPED );
				}
				else
				{
					if ( getIntervalId( scroller ) == INTERVAL_ID_CLEAR )
					{
						setIntervalId( scroller, window.setInterval(
							"Scroller.prototype.move( document.getElementById('" + scroller.getAttribute( "id" )+ "'), '" + direction + "')",
							((( getTimeMove( scroller ) * 1000 ) / ( getDisplayItems( scroller ) + 1 )) / calcMoveDivisor( scroller ))));
					}
				}
			}
		}
	}
	Scroller.prototype.move = move;

	/**
	 * Move o Scroller exibindo o próximo item. 
	 * @method nextItem
	 * @param {Object} scroller
	 * @public
	 */
	function nextItem( scroller )
	{
		if ( typeof scroller != "object" )
		{
			window.alert( "Error" );
		}
		else
		{
			if ( !isMoving( scroller ))
			{
				move( scroller, DIRECTION_NEXT );
			}
		}
	}
	Scroller.prototype.nextItem = nextItem;

	/**
	 * Move o Scroller exibindo o item anterior.
	 * @method previousItem
	 * @param {Object} scroller
	 * @public
	 */
	function previousItem( scroller )
	{
		if ( typeof scroller != "object" )
		{
			window.alert( "Error" );
		}
		else
		{
			if ( !isMoving( scroller ))
			{
				move( scroller, DIRECTION_PREVIOUS );
			}
		}
	}
	Scroller.prototype.previousItem = previousItem;

	/**
	 * Move o Scroller exibindo a próxima página.
	 * @method nextPage
	 * @param {Object} scroller
	 * @public
	 */
	function nextPage( scroller )
	{
		if ( typeof scroller != "object" )
		{
			window.alert( "Error" );
		}
		else
		{
			if ( !isMoving( scroller ))
			{
				move( scroller, DIRECTION_NEXT );
			}
		}
	}
	Scroller.prototype.nextPage = nextPage;

	/**
	 * Mover o Scroller exibindo a página anterior.
	 * @method previousPage
	 * @param {Object} scroller
	 * @public
	 */
	function previousPage( scroller )
	{
		if ( typeof scroller != "object" )
		{
			window.alert( "Error" );
		}
		else
		{
			if ( !isMoving( scroller ))
			{
				move( scroller, DIRECTION_PREVIOUS );
			}
		}
	}
	Scroller.prototype.previousPage = previousPage;
}

