/*
 * imgtransition v0.2
 *
 * Script para hacer transiciones entre capas.
 * El script va mostrando alternativamente, dentro
 * de un contenedor especificado, el contenido de
 * una serie de capas indicadas.
 *
 * Modo de uso:
 *
 * 1.	Crear el objeto: var miobjeto = new presentacion(nombreContenedor,ancho,alto,atributoContenedor(opc),autoStart(opc))
 *		(Los parametros marcados con (opc) son opcionales)
 * 2.	Establecer los parametros: espera, intervalo, duracion, noparar, filtro, w, h
 * 3.	Añadir las capas:
 *		2.1 miobjeto.addImagen(URLimagen,URLenlace) // aniade una imagen
 *		2.2 miobjeto.nuevaCapa('idcapa',0)			// aniade una capa con el ID especificado
 *		2.3 miobjeto.nuevasCapas('atributo')		// aniade todas las capas con un atributo contenedor igual a atributo
 * 4.	OPCIONAL: Montar la primera capa: miobjeto.montar()
 * 5.	OPCIONAL: Iniciar las transiciones: miobjeto.iniciar()
 * Not:	para aniadir las capas e iniciar la transicion debemos asegurarnos de que las capas existen previamente
 * 
 * Otros metodos (funcionalidades)
 *
 * miobjeto.parar(): detiene las transiciones
 * miobjeto.iniciar(): inicia o reanuda las transiciones
 * miobjeto.siguiente(): pone la siguiente capa (las transiciones deben estar paradas)
 * miobjeto.anterior(): pone la capa anterior (las transiciones deben estar paradas
 *
 * Ejemplos
 *
 * Bitacora de cambios
 *
 * Bugs
 * - Si se pone la capa contenedora dentro de una tabla o un DIV centrado no aparecen las capas de las transiciones
 *   Se puede evitar metiendo el contenedor en una tabla y centrando dicha tabla
 */

var transiciones = new Array()
transiciones[0] = "progid:DXImageTransform.Microsoft.RandomDissolve(Enabled=false)"
transiciones[1] = "progid:DXImageTransform.Microsoft.Iris(irisStyle='star', motion='out', Enabled=false)"
transiciones[2] = "progid:DXImageTransform.Microsoft.Iris(irisStyle='diamond', motion='in', Enabled=false)"
transiciones[3] = "progid:DXImageTransform.Microsoft.Iris(irisStyle='cross', motion='out', Enabled=false)"
transiciones[4] = "progid:DXImageTransform.Microsoft.Iris(irisStyle='circle', motion='in', Enabled=false)"
transiciones[5] = "progid:DXImageTransform.Microsoft.Iris(irisStyle='square', motion='out', Enabled=false)"
transiciones[6] = "progid:DXImageTransform.Microsoft.Iris(irisStyle='plus', motion='in', Enabled=false)"
transiciones[7] = "progid:DXImageTransform.Microsoft.Barn(orientation='vertial' motion='in', Enabled=false)"
transiciones[8] = "progid:DXImageTransform.Microsoft.Barn(orientation='vertial' motion='out', Enabled=false)"
transiciones[9] = "progid:DXImageTransform.Microsoft.Barn(orientation='horizontal' motion='in', Enabled=false)"
transiciones[10] = "progid:DXImageTransform.Microsoft.Barn(orientation='horizontal' motion='out', Enabled=false)"
transiciones[11] = "progid:DXImageTransform.Microsoft.Pixelate(Enabled=false)"
transiciones[12] = "progid:DXImageTransform.Microsoft.Inset(Enabled=false)"
transiciones[13] = "progid:DXImageTransform.Microsoft.Checkerboard(Direction='left', Enabled=false)"
transiciones[14] = "progid:DXImageTransform.Microsoft.Checkerboard(Direction='right', Enabled=false)"
transiciones[15] = "progid:DXImageTransform.Microsoft.Checkerboard(Direction='down', Enabled=false)"
transiciones[16] = "progid:DXImageTransform.Microsoft.Checkerboard(Direction='up', Enabled=false)"
transiciones[17] = "progid:DXImageTransform.Microsoft.RandomBars(motion='horizontal', Enabled=false)"
transiciones[18] = "progid:DXImageTransform.Microsoft.RandomBars(motion='vertical', Enabled=false)"
transiciones[19] = "progid:DXImageTransform.Microsoft.Slide(bands=5, slideStyle='push', Enabled=false)"
transiciones[20] = "progid:DXImageTransform.Microsoft.Slide(bands=5, slidestyle='swap', Enabled=false)"
transiciones[21] = "progid:DXImageTransform.Microsoft.Slide(bands=5, slidestyle='hide', Enabled=false)"
transiciones[22] = "progid:DXImageTransform.Microsoft.Spiral(Enabled=false)"
transiciones[23] = "progid:DXImageTransform.Microsoft.Stretch(stretchStyle='push', Enabled=false)"
transiciones[24] = "progid:DXImageTransform.Microsoft.Blinds(bands=10, Enabled=false)"
transiciones[25] = "progid:DXImageTransform.Microsoft.Fade(Enabled=false)"

function presentacion(contenedor,width,height,capas,autostart)
{
	this.nombre = contenedor
	this.obj = this.nombre + "Object"
	eval(this.obj + "=this")
	this.w = width
	this.h = height
	this.contenedor = new Object()			// La capa (DIV) que contiene a los elementos
	this.espera = 1							// Espera desde carga página hasta primer cambio en segundos
	this.nav = new presentBrowserCheck()

	this.intervalo = 5						// Espera entre cambios en segundos
	this.duracion = 1						// Durancion de la transicion (segundos)
	this.noparar = 0						// Para decidir si cambiamos indefinidamente o nos paramos al final

	this.tout = new Object()				// El temporizador para las transiciones
	this.estado	= 0							// 0: parado, 1: automatico, 2: manual
	this.cambiando = 0						// A 1 mientras se está haciendo una transicion

	this.numCapas = 0						// Cuantos elementos hay para intercambiar
	this.capa = new Object()				// El elemento que se muestra (DIV)
	this.capas = new Array()				// Cuales son esos elementos
	this.capasVistas = new Array()			// Que capas hemos mostrado
	this.capasNoVistas = new Array()		// Que capas no hemos mostrado
	this.capaPrimeraMontada = 0				// Indica si se ha colocado la primera capa
	this.ordenCapas = 'secuencial'			// Mostrar las capas secuencial o aleatoriamente
	this.numCapasMostradas = 1				// Cuantas capas hemos mostrado
	this.capaActiva = 0						// Elemento activo en cada instante
	this.capaSiguiente = 0					// Siguiente elemento en la lista
	this.cambio = 'individual'		// Secuencial, Aleatorio o Individual
	this.filtro = 0							// El filtro a utilizar (en Mozilla siempre fundido)

	this.dentrofuera = 0					// Controla el modo de funcionamiento del filtro de opacidad
	this.opac = 100							// Controla la opacidad del filtro de opacidad

	if (capas && capas != "")
	{
		this.nuevasCapas(capas)
		this.montar()
	}

	if (autostart && autostart == 1)
	{
		this.iniciar()
	}
}

// Pone en la capa de las transiciones la primera capa a mostrar
function presentMontarPrimeraCapa()
{
	// La capa contenedora situada en la pagina HTML
	this.contenedor = document.getElementById(this.nombre)
	if (!this.contenedor)
	{
		//alert('Error al obtener el contenedor '+this.nombre+' para la transición entre capas')
		return null
	}
	this.contenedor.style.width = this.w
	this.contenedor.style.height = this.h
	this.contenedor.style.overflow = 'hidden'

	// Creamos una capa que tendra definidos los filtros y almacenara
	// las capas de las transiciones
	this.capa = document.createElement('DIV')
	this.capa.id = this.nombre+'CapaFiltros'
	this.capa.style.width = this.w
	this.capa.style.height = this.h
	//this.capa.style.position = 'absolute'
	this.capa.style.overflow = 'hidden'
	this.capa.style.clip = 'rect(auto,auto,auto,auto)'
	this.capa.style.display = 'block'
	this.capa.style.visible = 'show'
	if (this.nav.ie&&!this.nav.ie50)
	{
		// Nada...
	}
	else if (this.ns||this.nav.ie50)
	{
		this.capa.style.MozOpacity = 1
	}
	this.contenedor.appendChild(this.capa)

	// Me aseguro de que hay una capa que montar
	if (!(this.numCapas > 0))
	{
		//alert('Debes llamar al método \'montar()\' después de haber añadido las capas')
		return false
	}

	// Selecciono la primera capa
	switch (this.ordenCapas)
	{
		case 'aleatorio':
			if (!(this.numCapas > 0))
			{
				return false
			}
			this.capaActiva = Math.floor(Math.random() * this.numCapas)
		break;
		default:
			this.capaActiva = 0
		break
	}
	this.capa.appendChild(this.capas[this.capaActiva])
	this.capaPrimeraMontada = 1
}

function presentIniciarTransiciones()
{
	// Si no hay capas no iniciamos nada
	if (!(this.numCapas > 0))
	{
		//alert('El elemento '+this.nombre+' no tiene capas con las que hacer transiciones')
		return false
	}

	// Si ya estamos en marcha paramos aqui
	if (this.estado == 1)
		return false	// Para que no cargue el enlace del onClick

	// Si no se monto la capa inicial lo hago ahora (compatibilidad con versiones viejas)
	if (!this.capaPrimeraMontada)
	{
		this.montar()
	}

	// Comienzan las transiciones entre las capas
	this.estado = 1
	this.tout = setTimeout(this.obj+".cambia()",this.espera * 1000)

	return false	// Para que no cargue el enlace del onClick
}

function presentPararTransiciones()
{
	// Solo paro si estabamos en marcha (podemos estar en modo manual)
	if (this.estado != 1)
		return false

	this.estado = 0
	clearTimeout(this.tout)

	return false    // Para que no cargue el enlace del onClick
}


function presentNuevaImagen(imgSrc,imgEnlace)
{
	var capaImagen = document.createElement('DIV')

	var unaImagen = new Image()
	unaImagen.src = imgSrc
	unaImagen.style.border = 0
	unaImagen.style.width = this.w
	unaImagen.style.height = this.h


	if (imgEnlace && imgEnlace != '')
	{
		var unEnlace = document.createElement('A')
		unEnlace.href = imgEnlace
		unEnlace.appendChild(unaImagen)
		capaImagen.appendChild(unEnlace)
	}
	else
	{
		capaImagen.appendChild(unaImagen)
	}

	this.nuevaCapa(capaImagen,1)
}

// modo: 0 ID, 1 Objeto
function presentNuevaCapa(capa,modo)
{
	if (modo != 1)
	{
		var tmp = document.getElementById(capa)
		this.capas[this.numCapas] = tmp.cloneNode(true)
		if (!this.capas[this.numCapas])
		{
			//alert('Error al obtener la capa '+capa+'. Aseguresé de que la página contiene una capa con ese identificador')
			return null
		}
	}
	else
	{
		this.capas[this.numCapas] = capa.cloneNode(true)
		// Para evitar que nuevasCapas(contenedor) de otro objeto
		// pueda pillar las capas (clonadas) de este objeto
		this.capas[this.numCapas].setAttribute('contenedor','clon')
	}

	this.capas[this.numCapas].id = this.nombre+'C'+this.numCapas
	this.capas[this.numCapas].style.display = 'block'
	this.capas[this.numCapas].style.position = 'absolute'
	this.capas[this.numCapas].style.width = this.w
	this.capas[this.numCapas].style.height = this.h
	this.capas[this.numCapas].style.clip = 'rect(auto,auto,auto,auto)'
	this.numCapas++
}

function presentNuevasCapas(contenedor)
{
	capas = document.getElementsByTagName('DIV')
	for (i=0; i<capas.length; i++)
	{
		atributo = capas[i].getAttribute('contenedor')
		if (atributo == contenedor)
		{
			capas[i].style.display = 'none'
			this.nuevaCapa(capas[i],1)
		}
	}
}


function presentCambia()
{
	// Si no ha montado antes el objeto: miobjeto.montar() lo hacemos ahora
	if (this.capaPrimeraMontada != 1)
	{
		this.montar()
	}

	// Si estamos parados no hacemos nada
	if (this.estado == 0)
		return true

	// Si solo hay una capa no hacemos nada
	if (this.numCapas <= 1)
		return true

	// Si ya estamos cambiando no hacemos nada
	if (this.cambiando == 1)
		return true

	// Si estamos en modo automatico calculo la siguiente capa
	if (this.estado == 1)
		this.setCapaSiguiente()

	switch(this.cambio)
	{
		case 'secuencial':
			this.filtro = (this.filtro + 1) % transiciones.length
		break;
		case 'aleatorio':
			this.filtro = Math.floor(Math.random() * transiciones.length)
		break;
	}

	this.cambiaFiltrando()

	// Cuando hayamos dado una vuelta completa a las imágenes decidimos
	// si continuamos o no
	if (this.numCapasMostradas == this.numCapas && this.noparar == 0)
		return true; 

	// Si estamos en marcha (modo automático) activo el temporizador
	if (this.estado == 1)
		setTimeout(this.obj+".cambia()",this.intervalo * 1000)
}

// Mantiene los arrays de capas vistas y capas no vistas
// para evitar que una capa salga dos veces en la secuencia
function presentActualizaCapasVistas()
{
	var i,j,k,capaVista

	// Si la transicion no se detiene no me importa que una
	// capa salga dos veces (de hecho saldra varias veces)
	if (this.noparar)
	{
		this.capasVistas = new Array()
		this.capasNoVistas = new Array()
		for (i=0;i<this.capas.length;i++)
			this.capasNoVistas[i] = i
		return true
	}
		
	this.capasVistas = new Array()

	// Anoto la capa que se acaba de mostrar (la capa activa)
	this.capasVistas[this.capasVistas.length] = this.capaActiva

	// Actualizo el array de capas no vistas
	k = 0
	for (i=0;i<this.capas.length;i++)
	{
		capaVista = 0
		for (j=0;j<this.capasVistas.length;j++)
		{
			if (this.capas[i] == this.capasVistas[j])
				capaVista = 1
		}
		if (capaVista == 0)
		{
			this.capasNoVistas[k++] = i
		}
	}
}

// Pasa a la siguiente capa activa. El cambio real se hace en
// cambiaSimple, donde se activa la capa que se indica aqui
function presentSetCapaSiguiente()
{
	// Calculo cual sera la siguiente capa que se activara
	switch(this.ordenCapas)
	{
		case 'secuencial':
			this.capaSiguiente = (this.capaActiva + 1) % this.numCapas
		break;
		case 'aleatorio':
			this.actualizaCapasVistas()
			this.capaSiguiente = this.capasNoVistas[Math.floor(Math.random() * this.capasNoVistas.length)]
		break;
	}
	
	// Intento evitar que la capa siguiente sea la misma que la actual
	if (this.capaActiva == this.capaSiguiente)
	{
		this.capaSiguiente = (this.capaActiva + 1) % this.numCapas
	}
	this.capaActiva = this.capaSiguiente

	this.numCapasMostradas++
}

// Muestra la siguiente capa en la secuencia
function presentCapaSiguiente()
{
	if (this.estado == 1)
	{
		//alert('Debe detener la presentación antes de pasar al modo manual')
		return false
	}

	this.estado = 2
	this.capaActiva = (this.capaActiva + 1) % this.numCapas
	this.cambia()	

	return false	// Para que no cargue el enlace del onClick
}

// Muestra la anterior capa en la secuencia
function presentCapaAnterior()
{
	if (this.estado == 1)
	{
		//alert('Debe detener la presentación antes de pasar al modo manual')
		return false
	}

	this.estado = 2
	this.capaActiva = (this.capaActiva - 1)
	if (this.capaActiva < 0)
		this.capaActiva = this.capas.length -1
	this.cambia()

	return false	// Para que no cargue el enlace del onClick
}

function presentCambiaFiltrando()
{
			// En el Mozilla la única transición que hago es un fundido
			if (!this.nav.ie||this.nav.ie50)
			{
				this.cambiaFundiendo()
				return
			}

			this.cambiando = 1

			this.capa.style.filter = transiciones[this.filtro]
			this.capa.filters.item(0).Duration = this.duracion
			this.capa.filters[0].apply()
			this.cambiaSimple()
			this.capa.filters[0].play()

			this.cambiando = 0
}

function presentCambiaFundiendo()
{
	var npasos = 25
	var delta = 100 / npasos 
	var tout = (this.duracion / (npasos * 2)) * 1000

	// Empezamos difuminando, al llegar a OPAC=0 cambiamos, al llegar a OPAC=100 volvemos
	// al modo difuminando para la siguiente ejecución
	if (this.opac <= 1) 
	{
		this.cambiaSimple()
		this.dentrofuera = 1
		this.opac=0;	// Realmente nos quedamos en 99 pero el script funciona partiendo de 100
				// así que lo corrijo aquí
	}
	else if (this.opac >= 99)
	{
		this.dentrofuera = 0
		this.opac=100;	// Realmente nos quedamos en 99 pero el script funciona partiendo de 100
				// así que lo corrijo aquí
		// Si llego a OPAC=99 y estaba cambiando es que ya he terminado el cambio
		if (this.cambiando == 1)
		{
			this.cambiando = 0
			return true
		}
	}

	this.cambiando = 1
	// De 99 a 1
	if (this.dentrofuera == 0)
	{
		if (this.opac > delta)
		{
			this.opac -= delta // Si lo hago en un sólo paso (this.capa.opac-=0.1) no funciona bien
		}
		else
		{
			this.opac -= (delta-1) // Para no llegar a 0
		}
		if (this.ns) this.capa.style.MozOpacity = this.opac / 100
		else if (this.nav.ie&&!this.nav.ie50) this.capa.filters.item("DXImageTransform.Microsoft.Alpha").opacity = this.opac
		setTimeout(this.obj+'.cambiaFundiendo()',tout)
	}	
	else
	{
		if (this.opac < 100-delta)
		{
			this.opac += delta
		}
		else {
			this.opac += (delta-1)	// Para no llegar a 100
		}
		if (this.ns) this.capa.style.MozOpacity = this.opac / 100
		else if (this.nav.ie&&!this.nav.ie50) this.capa.filters.item("DXImageTransform.Microsoft.Alpha").opacity = this.opac
		setTimeout(this.obj+'.cambiaFundiendo()',tout)
	}
}

function presentCambiaSimple()
{
	this.capa.removeChild(this.capa.firstChild)
	this.capa.appendChild(this.capas[this.capaActiva])
}

function presentBrowserCheck() {
        var b = navigator.appName
        if (b=="Netscape") this.b = "ns"
        else if (b=="Microsoft Internet Explorer"||b=="Opera") this.b = "ie"
        else this.b = b
        this.version = navigator.appVersion
        this.v = parseInt(this.version)
        this.ns = (this.b=="ns" && this.v>=4)
        this.ns4 = (this.b=="ns" && this.v==4)
        this.ns5 = (this.b=="ns" && this.v==5)
        this.ie = (this.b=="ie" && this.v>=4)
        this.ie4 = (this.version.indexOf('MSIE 4')>0)
        this.ie5 = (this.version.indexOf('MSIE 5')>0)
        this.ie50 = (this.version.indexOf('MSIE 5.0')>0)
        this.min = (this.ns||this.ie)
}

presentacion.prototype.init = presentIniciarTransiciones
presentacion.prototype.inicio = presentIniciarTransiciones
presentacion.prototype.iniciar = presentIniciarTransiciones
presentacion.prototype.parar = presentPararTransiciones
presentacion.prototype.build = presentMontarPrimeraCapa
presentacion.prototype.montar = presentMontarPrimeraCapa
presentacion.prototype.addImage = presentNuevaImagen
presentacion.prototype.nuevaImagen = presentNuevaImagen
presentacion.prototype.nuevaCapa = presentNuevaCapa
presentacion.prototype.nuevasCapas = presentNuevasCapas
presentacion.prototype.actualizaCapasVistas = presentActualizaCapasVistas
presentacion.prototype.setCapaSiguiente = presentSetCapaSiguiente
presentacion.prototype.anterior = presentCapaAnterior
presentacion.prototype.siguiente = presentCapaSiguiente
presentacion.prototype.cambia = presentCambia
presentacion.prototype.cambiaFiltrando = presentCambiaFiltrando
presentacion.prototype.cambiaFundiendo = presentCambiaFundiendo
presentacion.prototype.cambiaSimple = presentCambiaSimple


function isEmpty(s)
{   return ((s == null) || (s.length == 0))
}

function isDigit(c)
{   return ((c >= "0") && (c <= "9"))
}

function isNumber(s)
{
   var i;
    if (isEmpty(s))
       if (isNumber.arguments.length == 1) return defaultEmptyOK;
       else return (isNumber.arguments[1] == true);

    for (i = 0; i < s.length; i++)
    {
        var c = s.charAt(i);
        if( i != 0 ) {
            if (!isDigit(c)) return false;
        } else {
            if (!isDigit(c) && (c != "-") || (c == "+")) return false;
        }
    }
    return true;
}


