/***************************************************************************
 *
 * Copyright (C) 2006 by Korgault Studios
 * http://www.kgstudios.net
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 **************************************************************************/

/**
 * Controlador de marquesinas
 *
 * @package	phppr0.Shared.plugins.Marquee
 * @class Marquee
 * @author Korvus
 * @date 01-01-2007
 * @version 1.0
 */

function Marquee( sMarqueeId, sMarqueeContent, nMarqueeWidth, nMarqueeHeight )
{
 
	// ==================== Atributos ========================
 
 	/**
	 * Identificativo del objeto
	 * @var id ( String )
	 * @access public
	 */
 
 	this.id						=			new String( sMarqueeId );
	
	/**
	 * Contenido de texto plano / html de la marquesina
	 *
	 * @var _content ( String )
	 * @access private
	 */
	
	this._content				=			new String( sMarqueeContent );
	
	/**
	 * Nodo relacionado con el objeto actual
	 *
	 * @var _node ( Object )
	 * @access private
	 */
	
	this._node					=			null;
	
	/**
	 * Atributos del nodo superior
	 *
	 * @var _attributes ( Array )
	 * @access private
	 */
	
	this._attributes			=			new Array();
	
	/**
	 * Listado asociativo de direcciones disponibles y su configuración interna
	 *
	 * @var _directions ( Object )
	 * @access private
	 */
	
	this._directions			=			new Object();
	
	/**
	 * Retardo de la marquesina para efectuar el siguiente desplazamiento
	 *
	 * @var _scrollDelay ( Number )
	 * @access private
	 */
	
 	this._scrollDelay			=			50;
	
	/**
	 * Cantidad recorrida de píxeles por cada desplazamiento
	 *
	 * @var _scrollAmmount ( Number )
	 * @access private
	 */
	
	this._scrollAmmount			=			1;
	
	/**
	 * Dirección hacia la que se mueve el contenido de la marquesina
	 *
	 * @var scrollDirection ( Number )
	 * @access private
	 */
	
	this._scrollDirection		=			1;
 
	// ================== Métodos SET ========================
 
 	/**
	 * Modifica el contenido de la marquesina
	 *
	 * @function setContent
	 * @access public
	 * @param sContent ( String )
	 * @return ( void )
	 */
 
 	this.setContent = function( sContent )
	{ 
	 this._content = new String( sContent );
	 this._node.firstChild.innerHTML = "<nobr>" + this._content + "</nobr>"; 
	}
 
 	/**
	 * Inicializa el valor de un atributo
	 *
	 * @function setAttribute
	 * @access public
	 * @param sAttributeName ( String )
	 * @param sAttributeValue ( String )
	 * @return ( void )
	 */
 
 	this.setAttribute = function( sAttributeName, sAttributeValue )
	{ this._attributes[ sAttributeName ] = sAttributeValue; }
 
 	/**
	 * Cambia el intervalo entre cada desplazamiento
	 *
	 * @function setScrollDelay
	 * @access public
	 * @param nScrollDealy ( Number ) Tiempo en milisegundos
	 * @return ( void )
	 */
 
	this.setScrollDelay = function( nScrollDelay )
	{
	 if( isNaN( nScrollDelay ) == false && nScrollDelay > 0 )
	 {
	  this._scrollDelay = nScrollDelay;
	  this.stop(); this.play();
	 }
	};
	
	/**
	 * Modifica la cantidad de píxeles por cada desplazamiento
	 *
	 * @function setScrollAmmount
	 * @access public
	 * @param nScrollAmmount ( Number ) Cantidad en píxeles
	 * @return ( void )
	 */
	
	this.setScrollAmmount = function( nScrollAmmount )
	{
	 if( isNaN( nScrollAmmount ) == false && nScrollAmmount > 0 )
	  this._scrollAmmount = nScrollAmmount;
	};
	
	/**
	 * Cambia la dirección hacia la que se desplaza el contenido de la marquesina
	 * Los posibles valores para el primer parámetro son 'up', 'down', 'left' y 'right'
	 *
	 * @function setScrollDirection
	 * @access public
	 * @param sScrollDirection ( String )
	 */
	
	this.setScrollDirection = function( sScrollDirection )
	{
	 if( typeof( this._directions[ sScrollDirection ] ) == "object" )
	  this._scrollDirection = sScrollDirection;
	};
	
	// ================== Métodos GET ========================
	
	/**
	 * Devuelve el valor de un atributo
	 *
	 * @function getAttribute
	 * @access public
	 * @param sAttributeName ( String )
	 * @return ( String )
	 */
	
	this.getAttribute = function( sAttributeName )
	{ return( this._attributes[ sAttributeName ] ); }
	
	/**
	 * Devuelve el intervalo en milisegundos entre cada desplazamiento
	 *
	 * @function getScrollDelay
	 * @access public
	 * @return ( Number )
	 */
	
	this.getScrollDelay = function()
	{ return( this._scrollDelay ); };
	
	/**
	 * Devuelve la cantidad de píxeles por cada desplazamiento
	 *
	 * @function getScrollAmmount
	 * @access public
	 * @return ( Number )	 
	 */
	
	this.getScrollAmmount = function()
	{ return( this._scrollAmmount ); };
	
	/**
	 * Devuelve la dirección hacia la que se desplaza el contenido de la marquesina
	 *
	 * @function getScrollDirection
	 * @access public
	 * @return ( String )
	 */
	
	this.getScrollDirection = function()
	{ return( this._scrollDirection ); };
	
	// ================ Otros métodos ========================
	
	/**
	 * Inicia el movimiento de la marquesina
	 *
	 * @function play
	 * @access public
	 * @return ( void )
	 */
	
	this.play = function()
	{
	 /**
	  * Lanza un error si no ha encontrado el nodo al que pertenece la marquesina
	  * @see phppr0.Shared.plugins.Marquee.Marquee :: toString
	  */
	 
	 if( typeof( this._node = document.getElementById( this.id ) ) != "object" )
	  throw new Error( "Marquee :: play(): Node not found. Call 'toString' method first" );
	 
	 /**
	  * Inicia el intervalo que generará el movimiento de la marquesina
	  */

	 if( this._node != null )
	 {
	  this.restore(); this.setContent( this._content );
	  this._interval = window.setInterval( "getObject( '" + this.id + "' ).move()", this.getScrollDelay() ); 
	 }
	}
	
	/**
	 * Detiene el movimiento de la marquesina
	 *
	 * @function stop
	 * @access public
	 * @return ( void )
	 */
	
	this.stop = function()
	{ window.clearInterval( this._interval ); }
	
	/**
	 * Mueve el contenido de la marquesina
	 *
	 * @function move
	 * @access public
	 * @return ( void )
	 */
	
	this.move = function()
	{
	 /**
	  * Información necesaria para efectuar el desplazamiento
	  * @var oDirectionInfo ( Object )
	  */
	 
	 var oDirectionInfo = this._directions[ this.getScrollDirection() ];
	 var oContentNodeInfo = this._node.firstChild.style;
	 
	 /**
	  * Evalúa las siguientes sentencias en base a la configuración estipulada en 'oDirectionInfo'
	  * 1.- Mueve el contenido hacia la dirección indicada la cantidad de píxeles determinada por 'this.getScrollAmmount()'
	  * 2.- Comprueba que el contenido se halle dentro de los limites, de lo contrario lo reposiciona
	  */
	 
	 eval( 'oContentNodeInfo[ "' + oDirectionInfo[ "position" ] + '" ] = ( parseInt( oContentNodeInfo[ "' + oDirectionInfo[ "position" ] + '" ] ) ' + oDirectionInfo[ "operator" ] + ' this.getScrollAmmount() ) + "px";' );	 
	 eval( 'if( parseInt( oContentNodeInfo[ "' + oDirectionInfo[ "position" ] + '" ] ) ' + oDirectionInfo[ "comparator" ] + ' parseInt( ' + oDirectionInfo[ "max" ] + ' ) ' + oDirectionInfo[ "operator" ] + ' this.getScrollAmmount() ){ this.restore( "min" ); }' );
	}
	
	/**
	 * Posiciona el contenido de la marquesina en la posición inicial
	 * Los posibles valores para el primer parámetro son 'min' ( inicio ) y 'max' ( fin )
	 *
	 * @function restore
	 * @param [ sIndex ] ( String )
	 * @return ( void )
	 */
	
	this.restore = function( sIndex )
	{
	 /**
	  * Valor predeterminado del primer parámetro
	  */
		
	 if( typeof( sIndex ) == "undefined" || [ "min", "max" ].indexOf( sIndex ) == -1 )
	  sIndex = "min";
		
	 /**
	  * Posiciona el contenido en la posición inicial del eje X
	  */
	  
	 if( this._directions[ this.getScrollDirection() ][ "position" ] == "left" )
	  eval( 'this._node.firstChild.style.left = ' + this._directions[ this.getScrollDirection() ][ sIndex ] + ';' );

	 /**
	  * Posiciona el contenido en la posición inicial del eje Y
	  */

	 if( this._directions[ this.getScrollDirection() ][ "position" ] == "top" )
	  eval( 'this._node.firstChild.style.top = ' + this._directions[ this.getScrollDirection() ][ sIndex ] + ';' );
	}
	
	/**
	 * Devuelve el código completo de la marquesina
	 *
	 * @function toString
	 * @access public
	 * @return ( String )
	 */
	
	this.toString = function()
	{
	 var oMarqueeContent = new Array();
	 
	 oMarqueeContent.push( '<div id="' + this.id + '" style="' + this._attributes.ajoin( ':', ';' ) + '">' );
	 oMarqueeContent.push( '<span style="position: relative; left: 0px; top: 0px;"><nobr>' + this._content + '</nobr></span>' );
	 oMarqueeContent.push( '</div>' );
	
	 return( oMarqueeContent.join( "" ) );
	};
	
	/**
	 * Inicializa la configuración de las direcciones que puede adoptar el movimiento de la marquesina
	 */
	 
	this._directions[ "up" ] = { position: "top", operator: "-", comparator: "<", min: "this.getAttribute( 'height' )", max: "parseInt( this._node.firstChild.offsetHeight ) * -1" };
	this._directions[ "down" ] = { position: "top", operator: "+", comparator: ">", min: "parseInt( this._node.firstChild.offsetHeight ) * -1", max: "this.getAttribute( 'height' )" };
	this._directions[ "left" ] = { position: "left", operator: "-", comparator: "<", min: "this.getAttribute( 'width' )", max: "parseInt( this._node.firstChild.offsetWidth ) * -1" };
	this._directions[ "right" ] = { position: "left", operator: "+", comparator: ">", min: "parseInt( this._node.firstChild.offsetWidth ) * -1", max: "this.getAttribute( 'width' )" };	
	
	/**
	 * Valores predeterminados de los estilos de la capa contenedora
	 */
	 
	this.setAttribute( "position", "relative" );
	this.setAttribute( "overflow", "hidden" );
	this.setAttribute( "width", parseInt( nMarqueeWidth ) + "px" );
	this.setAttribute( "height", parseInt( nMarqueeHeight ) + "px" );
 
}