/**
 * Copyright (c) 2005. Divisa iT S.A.
 * 
 * $Log: scroll-list.js,v $
 * Revision 1.1.2.3.4.3.10.2  2008/10/23 12:32:55  java104
 * Se ha cambiado el comportamiento de los listados en modo scrolling:
 * - se han añadido dos iconos para detener y reanudar el listado.
 *
 * Revision 1.1.2.3.4.3.10.1  2008/08/28 08:17:26  rruano
 * Merge con la rama de accesibilidad
 *
 * Revision 1.1.2.3.4.3.8.2  2008/06/16 08:28:42  java104
 * Se ha modificado el scroll para que se pueda controlar su funcionamiento con los siguientes eventos:
 * - onmouseover acelera el scroll hasta que el elemento activo llegue al principio del contenedor y para el scroll
 * - onmouseout reinicia el scroll
 *
 * Revision 1.1.2.3.4.3.8.1  2008/06/05 11:01:39  java104
 * El listado de los contenidos de scroll se pintan mediante listas (ul, li) y no cajas (div).
 *
 * Revision 1.1.2.3.4.3  2007/06/01 13:07:25  drodriguez
 * Incluida nueva funcionalidad de soporte para los contenidos relacionados,
 * funciona correctamente en modificación, pero no así en creación, hay que
 * revisar este caso concreto
 *
 * Revision 1.1.2.3.4.2  2007/05/18 13:11:45  drodriguez
 * Se ha incluido en el Javascript de recursos, ficheros e imagenes la
 * invocación a una llamada de callback para que el wizard este notificado
 * de los cambios realizados si es que los hay.
 * La carga de la CSS del wizard se ha pasado al método de inicialización
 * del wizard en lugar de tenerla precargada
 * Se ha modificado el scroll-list.js con el objeto de que auto-genere el
 * nombre del Scroll (el ID de la capa contenedora), para intentar evitar
 * que puedan existir duplicados con los consiguientes problemas asociados
 *
 * Revision 1.1.2.3.4.1  2007/05/17 17:40:11  drodriguez
 * Realizados una serie de cambios que tienen por objeto solucionar una
 * serie de bugs en el modo WIZARD.
 *
 * a) Se ha incluido el soporte para los conetnidos enlazados dentro del
 * texto que ya se encontraba presente en administración
 * b) Se ha redefinido el mapping images dentro del módulo WIZARD para
 * que utilice la versión de acceso directo sin pasar por caché, control
 * de permisos, etc.
 * c) Se controla que los botones de edición y creación de contenidos no
 * se habilitan hasta que todo el JavaScript ha sido cargado.
 * d) Se fuerza a que el estilo de los A sea blue independientemente del
 * resto de hojas de estilo cargadas... Es que si no, no hay quien vea nada.
 *
 * Con todo esto quedan pendientes todavía las siguientes operaciones:
 * 1. Almacenar en BBDD los datos relativos a los contenidos enlazados por
 * datos.
 * 2) Información relacionada
 * 3) Opciones avanzadas: habilitación, no habilitación, modo de mostrar los hijos,
 * 4) Control de ciertos errores en IExplorer cuando se mandan nombres de ficheros que contienen < o > (por el tema de los IFRAME)
 * 5) Incluir un mecanismo de validación de la plantilla de edición auto-generada.
 *
 * Revision 1.1.2.3  2005/10/19 06:38:41  drodriguez
 * Cambio para que sólo rote si hay más de un elemento en la lista
 *
 * Revision 1.1.2.2  2005/07/13 12:04:04  drodriguez
 * Arreglados bugs que ocasionaban un funcionamiento incorrecto cuando
 * estaban en uso unidades relativas.
 *
 *
 * @author $Author: java104 $
 * @version $Revision: 1.1.2.3.4.3.10.2 $
 * @since Proxia CMS 4.6
 */
    var allScrolls = new Array();
	
    /**
     * Método que se encarga de detener todos los scrolls.
     */
    function stopScrolls() {
        for(var i=0;i<allScrolls.length;i++) {
            allScrolls[i].stopped = true;		
            clearTimeout(allScrolls[i].timeout);
        }
	
    }
	
	/** 
	 * Método que se encarga de detener el scroll que contiene el elemento 
	 * desde donde se invoca la función
	 */
	 function stopScroll(el) {
		 //retrieve the main container div
		 var mcDiv = el.parentNode.parentNode;
		 var ulTag;
		 for(var i=0; i<mcDiv.childNodes.length; i++) {
			 if(mcDiv.childNodes[i].tagName == 'UL') {
				 //scroll list found
				 ulTag = mcDiv.childNodes[i];
			 }
		 }
		 if(ulTag) {
			 for(i=0; i<allScrolls.length; i++) {
				 if(allScrolls[i].name == ulTag.id) {
					 //hemos encontrado nuestro scroll, vamos a pararlo y a mostrar el icono para reiniciar
					 allScrolls[i].stopped = true;
					 clearTimeout(allScrolls[i].timeout);
					 el.style.display = 'none';
					 document.getElementById('cmPlayScroll_'+i).style.display='block';
				 }
			 }
		 }
		 return ;
	 }

	 /** 
	 * Método que se encarda de continuar el funcionamiento del scroll que contiene el elemento 
	 * desde donde se invoca la función
	 */
	 function startScroll(el) {
		 //retrieve the main container div
		 var mcDiv = el.parentNode.parentNode;
		 var ulTag;
		 for(var i=0; i<mcDiv.childNodes.length; i++) {
			 if(mcDiv.childNodes[i].tagName == 'UL') {
				 //scroll list found
				 ulTag = mcDiv.childNodes[i];
			 }
		 }
		 if(ulTag) {
			 for(i=0; i<allScrolls.length; i++) {
				 if(allScrolls[i].name == ulTag.id) {
					 //hemos encontrado nuestro scroll, vamos a pararlo y a mostrar el icono para reiniciar
					 if(allScrolls[i].stopped && allScrolls[i].items.length>1) {
						 allScrolls[i].stopped = false;
						 
						 var _tmpHeight = allScrolls[i].innerHeight;
						 if(allScrolls[i].dimension != 'px') {
							 _tmpHeight *= 10;
						 }
						 
						 if(allScrolls[i].scrollCount == _tmpHeight) {
							for(var j=0; j<allScrolls[i].items.length; j++) {
								allScrolls[i].resetElement(document.getElementById('c_'+allScrolls[i].name+'_'+j));
							}
							//empezamos el scroll del nuevo elemento en seguida
							allScrolls[i].timeout = setTimeout(allScrolls[i].obj+'.scroll()',allScrolls[i].innerInterval);     
						 } else {
							 allScrolls[i].timeout = setTimeout(allScrolls[i].obj+'.innerScroll()',allScrolls[i].innerInterval);
						 }
						 el.style.display = 'none';
						 document.getElementById('cmPauseScroll_'+i).style.display='block';
					 }
				 }
			 }
		 }
		 return ;
	 }
 
    /**
     * Generador de la clase, que recibe como parámetro el nombre del scroll
     * y la altura correspondiente al mismo.
     *
     * @param   scrollClass  La clase CSS asociada a la caja global de scrolling
     */
    function ScrollList(scrollClass) {
		// Vamos a recuperar todos los elementos que sean de tipo scroll
		var allScrollsUl = document.getElementsByTagName('UL');
		var maxIndex = 0;
		for(var i=0;i<allScrollsUl.length;i++) {
			if(allScrollsUl[i].id && allScrollsUl[i].id.indexOf('cmScroll')!=-1) {
				var currIndex = parseInt(allScrollsUl[i].id.substring(8));
				if(currIndex > maxIndex) {
					maxIndex = currIndex;
				}
			}
		}
	
        this.name = 'cmScroll'+(maxIndex+1);
        this.scrollClass = scrollClass;
        this.items = new Array();
        this.scrollCount = 0;
        this.timeout = false;
        this.stopped = false;

        // Inicializamos unas variables objetos por defecto...
        this.scrollWidth = '200px';
        this.scrollHeight = '90px';

        this.interval = 5000;
        this.innerInterval = 10;

        this.addElement = addElement;
        this.paintScroll = paintScroll;
        this.resetElement = resetElement;
        this.shiftElement = shiftElement;
        this.scroll = scroll;
        this.innerScroll = innerScroll;
        this.init = init;
        this.obj = this.name + "Object";
        eval(this.obj + "=this");
        allScrolls[allScrolls.length] = this;
    }


    /**
     * Añade un elemento a la lista de scrolling, 
     *
     * @param  text   El texto que compone la lista de scroll.
     */
    function addElement(text) {
        var _pos = this.items.length;
        this.items[_pos] = new Object();
        this.items[_pos].text = text;
    }

    /**
     * Pinta el scroll y activa el intervalo para el dibujado periódico de todos los
     * elementos del mismo.
     *
     * @param   interval       El intervalo de actividad del scroll (tiempo tras el cual
     *                         se efectua un scroll).
     */
    function paintScroll(interval) {
        // Creamos la capa contenedora.
        document.write('<ul id="'+this.name+'" class="'+this.scrollClass+'" style="overflow: hidden; position: relative;"></ul>\n');
		
        this.interval = parseInt(interval);
        this.innerInterval = this.interval / 200;
        if(!this.stopped) {
            this.timeout = setTimeout(this.obj+'.init()',500);
        }
    }
    
    /**
     * Este método permite inicializar el objeto de scroll para la presentación
     * de información, no puede hacerse dentro del paintScroll, puesto que
     * no da tiempo a inicializar las capas.
     */
    function init() {
        var containerUl = document.getElementById(this.name);
		
		//definimos los estilos para que el UL se comporte como un DIV
		containerUl.style.margin = 0;
		containerUl.style.padding = 0;
		containerUl.style.listStyle = 'none';
		containerUl.style.display = 'block'
		
        // Ahora extractar la altura, anchura, etc. de la capa.
        if(document.defaultView) {
            if(document.defaultView.getComputedStyle(containerUl,'').width) {
                this.scrollWidth = document.defaultView.getComputedStyle(containerUl,'').width;
            }

            if(document.defaultView.getComputedStyle(containerUl,'').height) {
                this.scrollHeight = document.defaultView.getComputedStyle(containerUl,'').height;
            }

        } else {
            if(containerUl.currentStyle) {
                this.scrollWidth = containerUl.currentStyle.width;
                this.scrollHeight = containerUl.currentStyle.height;                
            } else {
                if(containerUl.clientHeight) {
                    this.scrollHeight = containerUl.clientHeight+'px';
                }

                if(containerUl.clientWidth) {
                    this.scrollWidth = containerUl.clientWidth+'px';
                }
            }
        }

        // Generamos la altura interna de la capa utilizando.
        this.innerHeight = Math.round(parseFloat(this.scrollHeight));
        this.dimension = 'px';

        innerHeightAsStr = parseFloat(this.scrollHeight)+'';
        if(innerHeightAsStr.length != this.scrollHeight.length) {
            this.dimension = this.scrollHeight.substring(innerHeightAsStr.length);
        }

        // Tenemos computadas anchura y altura, lo único que tenemos que hacer es generar todos 
        // los nodos hijos.
        for(i=0;i<this.items.length;i++) {
            var _currentTop = i*this.innerHeight+''+this.dimension;
            var currentLi = document.createElement('LI');
            currentLi._innerTop = _currentTop;
            currentLi.id = 'c_'+this.name+'_'+i;
            currentLi.style.top = _currentTop;
            currentLi.style.overflow = 'hidden';
            currentLi.style.position = 'absolute';
            currentLi.style.width = this.scrollWidth;
            currentLi.style.height = this.scrollHeight;
            currentLi.style.margin = 0;
            currentLi.style.padding = 0;
            currentLi.style.listStyle = 'none';
            currentLi.style.display = 'block';

            // Rellenamos el html
            currentLi.innerHTML = this.items[i].text;
            containerUl.appendChild(currentLi);
        }

        if(this.items.length > 1 && !this.stopped) {
            this.timeout = setTimeout(this.obj+'.scroll()',this.interval);
        }
    }

    /**
     * Esta función realiza la llamada al scroll principal.
     */
    function scroll() {
        this.scrollCount = 0;
        if(!this.stopped) {
            this.timeout = setTimeout(this.obj+'.innerScroll()',this.innerInterval);
        }
    }

    /**
     * Realiza el scroll real de elementos en la lista.
     */
    function innerScroll() {
        // Los desplazamos todos hacia abajo...
        var _shift = 1;
        if(this.dimension != 'px') {
            _shift = 0.1;
        }
        for(i=0;i<this.items.length;i++) {
           this.shiftElement(document.getElementById('c_'+this.name+'_'+i),_shift);
        }

        this.scrollCount++;
        var _tmpHeight = this.innerHeight;
        
        // Si no tenemos pixeles nos desplazamos de 0.1 en 0.1
        if(this.dimension != 'px') {
            _tmpHeight = _tmpHeight * 10;
        }
        
		if(this.scrollCount != _tmpHeight) {
            if(!this.stopped) {
                this.timeout = setTimeout(this.obj+'.innerScroll()',this.innerInterval);
            }
        } else {
            for(i=0;i<this.items.length;i++) {
                this.resetElement(document.getElementById('c_'+this.name+'_'+i));
            }
            if(!this.stopped) {
                this.timeout = setTimeout(this.obj+'.scroll()',this.interval);     
            }
        }
    }

    /**
     * Esta función permite reubicar un elemento en la lista, si ha superado la altura
     * máxima se le reubica hacia arriba.
     * 
     * @param   element   El elemento a reubicar.
     */
    function resetElement(element) {
        // Recuperamos como una cadena la posición top.
		var strTop = element._innerTop;
		var _top = Math.round(parseFloat(strTop));
        if(_top+this.innerHeight == 0) {
            element._innerTop = (this.items.length-1)*this.innerHeight+this.dimension;        
            element.style.top = element._innerTop;
        }
    }

    /**
     * Esta función permite desplazar un elemento hacia arriba.
     *
     * @param   element    El elemento a desplazar.
     * @param   shift      El desplazamiento.
     */
    function shiftElement(element, shift, dimension, innerHeight) {
        // Recuperamos como una cadena la posición top.
        var strTop = element._innerTop;
        // Extraemos la parte entera.
        var _top = parseFloat(strTop);
        // Intentamos recalcular la dimensión...
        _top -= shift;
		element.style.top = _top+this.dimension;
		element._innerTop = _top+this.dimension;
    }
	
	/**
	* Esta función pinta los iconos para parar y reanudar el scroll.
	*
	* @param	imgSrc		El atributo src de la imagen
	* @param	title		El título del enlace
	* @param	cssClass	La clase CSS a usar
	*/
	function paintActionIcon(imgSrc, title, cssClass) {
		//obtenemos el id del enlace
		var allScrollsUl = document.getElementsByTagName('UL');
		var maxIndex = 0;
		for(var i=0;i<allScrollsUl.length;i++) {
			if(allScrollsUl[i].id && allScrollsUl[i].id.indexOf('cmScroll')!=-1) {
				var currIndex = parseInt(allScrollsUl[i].id.substring(8));
				if(currIndex > maxIndex) {
					maxIndex = currIndex;
				}
			}
		}
		var iconId = cssClass + "_" + maxIndex;
		
		//creamos el enlace
		var icon = '<a href="javascript:void(0);" id="'+iconId+'" class="'+cssClass+'" title="'+title+'"';
		if(cssClass == 'cmPauseScroll') {
			icon += ' onclick="stopScroll(this);">';
		} else {
			icon += ' onclick="startScroll(this);" style="display: none;">';
		}
		
		//añadimos el icono y cerramos el enlace
		icon += '<img src="'+imgSrc+'" alt=""></a>';
		
		//pintamos el icono generado
		document.write(icon);
	}


