/**
 * Copyright (c) 2005. Divisa iT S.A.
 * 
 * $Log: scroll-list.js,v $
 * Revision 1.1  2010/05/06 14:53:35  cvarela
 * Carga Inicial cps v2.4
 *
 * 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: cvarela $
 * @version $Revision: 1.1 $
 * @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);
        }
	
    }
 

    /**
     * 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 allScrollsDiv = document.getElementsByTagName('DIV');
		var maxIndex = 0;
		for(var i=0;i<allScrollsDiv.length;i++) {
			if(allScrollsDiv[i].id && allScrollsDiv[i].id.indexOf('cmScroll')!=-1) {
				var currIndex = parseInt(allScrollsDiv[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('<div id="'+this.name+'" class="'+this.scrollClass+'" style="overflow: hidden; position: relative;"></div>\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 containerDiv = document.getElementById(this.name);

        // Ahora extractar la altura, anchura, etc. de la capa.
        if(document.defaultView) {
            if(document.defaultView.getComputedStyle(containerDiv,'').width) {
                this.scrollWidth = document.defaultView.getComputedStyle(containerDiv,'').width;
            }

            if(document.defaultView.getComputedStyle(containerDiv,'').height) {
                this.scrollHeight = document.defaultView.getComputedStyle(containerDiv,'').height;
            }

        } else {
            if(containerDiv.currentStyle) {
                this.scrollWidth = containerDiv.currentStyle.width;
                this.scrollHeight = containerDiv.currentStyle.height;                
            } else {
                if(containerDiv.clientHeight) {
                    this.scrollHeight = containerDiv.clientHeight+'px';
                }

                if(containerDiv.clientWidth) {
                    this.scrollWidth = containerDiv.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 currentDiv = document.createElement('DIV');
            currentDiv._innerTop = _currentTop;
            currentDiv.id = 'c_'+this.name+'_'+i;
            currentDiv.style.top = _currentTop;
            currentDiv.style.overflow = 'hidden';
            currentDiv.style.position = 'absolute';
            currentDiv.style.width = this.scrollWidth;
            currentDiv.style.height = this.scrollHeight;

            // Rellenamos el html
            currentDiv.innerHTML = this.items[i].text;
            containerDiv.appendChild(currentDiv);
        }

        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;
    }


