// ===================================================================================
// Funciones JavaScript relacionadas con DHTML.
//
// Partes del código incluidos de:
//    DHTMLapi.js custom API for cross-platform object positioning by Danny Goodman 
//    (http://www.dannyg.com). Release 2.0. Supports IE and W3C DOMs.
// ===================================================================================

// Devuelve el índice de "valor" dentro de "array", o -1 si no se encuentra
function indice(array, valor)
{
	for (var i = 0; i < array.length; ++i) {
		if (array[i][0] == valor) return i;
	}
	return -1;
}

// Variables globales...
var esCSS, esW3C, esIE4, esIE6CSS;
// ...inicializadas usando el siguiente código:
esW3C = (document.getElementById) ? true : false;
esIE4 = (document.all) ? true : false;
esCSS = esW3C || esIE4;
esIE6CSS = (document.compatMode && document.compatMode.indexOf("CSS1") >= 0) ? true : false;

// Convierte un nombre o referencia de un objeto en una referencia de objeto válida
function obtenerObjeto(nombreOReferenciaObjeto) {
	var objeto;
	if (typeof nombreOReferenciaObjeto == "string") {
		if (esW3C) {
			objeto = document.getElementById(nombreOReferenciaObjeto);
		} else if (esIE4) {
			objeto = document.all(nombreOReferenciaObjeto);
		}
	} else {
		// devolver tal cual la referencia recibida
		objeto = nombreOReferenciaObjeto;
	}
	return objeto;
}

// Convierte un nombre o referencia de un objeto en una referencia válida al estilo del objeto
function obtenerEstiloObjeto(nombreOReferenciaObjeto) {
	var objeto = obtenerObjeto(nombreOReferenciaObjeto);
	if (objeto && esCSS) {
		objeto = objeto.style;
	}
	return objeto;
}

// Situar el objeto en la posición (en píxeles) indicada
function situar(nombreOReferenciaObjeto, x, y) {
	var objeto = obtenerEstiloObjeto(nombreOReferenciaObjeto);
	if (objeto) {
		if (esCSS) {
			// Prevenir error por tipo numérico (incorrecto) de la propiedad "left" en algunos navegadores
			var unidades = (typeof objeto.left == "string") ? "px" : 0;
			objeto.left = x + unidades;
			objeto.top = y + unidades;
		}
	}
}
function situarX(nombreOReferenciaObjeto, x) {
	var objeto = obtenerEstiloObjeto(nombreOReferenciaObjeto);
	if (objeto) {
		if (esCSS) {
			var unidades = (typeof objeto.left == "string") ? "px" : 0;
			objeto.left = x + unidades;
		}
	}
}
function situarY(nombreOReferenciaObjeto, x) {
	var objeto = obtenerEstiloObjeto(nombreOReferenciaObjeto);
	if (objeto) {
		if (esCSS) {
			var unidades = (typeof objeto.left == "string") ? "px" : 0;
			objeto.top = y + unidades;
		}
	}
}

// Mover el objeto el número de píxeles especificado respecto a su posición actual
function desplazar(nombreOReferenciaObjeto, deltaX, deltaY) {
	var objeto = obtenerEstiloObjeto(nombreOReferenciaObjeto);
	if (objeto) {
		if (esCSS) {
			// Prevenir error por tipo numérico (incorrecto) de la propiedad "left" en algunos navegadores
			var unidades = (typeof objeto.left == "string") ? "px" : 0;
			objeto.left = posicionIzquierda(nombreOReferenciaObjeto) + deltaX + unidades;
			objeto.top = posicionSuperior(nombreOReferenciaObjeto) + deltaY + unidades;
		}
	}
}

// Fijar el orden Z del objeto
function fijarIndiceZ(nombreOReferenciaObjeto, zOrder) {
	var objeto = obtenerEstiloObjeto(nombreOReferenciaObjeto);
	if (objeto) {
		objeto.zIndex = zOrder;
	}
}

// Fijar el color de fondo del objeto
function fijarColorFondo(nombreOReferenciaObjeto, color) {
	var objeto = obtenerEstiloObjeto(nombreOReferenciaObjeto);
	if (objeto) {
		if (esCSS) {
			objeto.backgroundColor = color;
		}
	}
}

// Fijar la visibilidad del objeto a visible
function mostrar(nombreOReferenciaObjeto) {
	var objeto = obtenerEstiloObjeto(nombreOReferenciaObjeto);
	if (objeto) {
		objeto.visibility = "visible";
	}
}

// Fijar la visibilidad del objeto a oculto
function ocultar(nombreOReferenciaObjeto) {
	var objeto = obtenerEstiloObjeto(nombreOReferenciaObjeto);
	if (objeto) {
		objeto.visibility = "hidden";
	}
}

// Devuelve la coordenada X del objeto (posicionable)
function posicionIzquierda(nombreOReferenciaObjeto)  {
	var elemento = obtenerObjeto(nombreOReferenciaObjeto);
	var resultado = 0;
	if (document.defaultView) {
		var style = document.defaultView;
		var cssDecl = style.getComputedStyle(elemento, "");
		resultado = cssDecl.getPropertyValue("left");
	} else if (elemento.currentStyle) {
		resultado = elemento.currentStyle.left;
	} else if (elemento.style) {
		resultado = elemento.style.left;
	}
	return parseInt(resultado);
}

// Devuelve la coordenada Y del objeto (posicionable)
function posicionSuperior(nombreOReferenciaObjeto)  {
	var elemento = obtenerObjeto(nombreOReferenciaObjeto);
	var resultado = 0;
	if (document.defaultView) {
		var style = document.defaultView;
		var cssDecl = style.getComputedStyle(elemento, "");
		resultado = cssDecl.getPropertyValue("top");
	} else if (elemento.currentStyle) {
		resultado = elemento.currentStyle.top;
	} else if (elemento.style) {
		resultado = elemento.style.top;
	}
	return parseInt(resultado);
}

// Devuelve la anchura con que se ha dibujado el objeto
function ancho(nombreOReferenciaObjeto)  {
	var elemento = obtenerObjeto(nombreOReferenciaObjeto);
	var resultado = 0;
	if (elemento.offsetWidth) {
		resultado = elemento.offsetWidth;
	} else if (elemento.style.width) {
		resultado = elemento.style.width;
	} else if (elemento.clip && elemento.clip.width) {
		resultado = elemento.clip.width;
	} else if (elemento.style && elemento.style.pixelWidth) {
		resultado = elemento.style.pixelWidth;
	}
	return parseInt(resultado);
}

// Devuelve la altura con que se ha dibujado el objeto
function alto(nombreOReferenciaObjeto)  {
	var elemento = obtenerObjeto(nombreOReferenciaObjeto);
	var resultado = 0;
	if (elemento.offsetHeight) {
		resultado = elemento.offsetHeight;
	} else if (elemento.clip && elemento.clip.height) {
		resultado = elemento.clip.height;
	} else if (elemento.style && elemento.style.pixelHeight) {
		resultado = elemento.style.pixelHeight;
	}
	return parseInt(resultado);
}

// Devuelve la anchura disponible en la ventana del navegador para el contenido
function anchoInteriorVentana() {
	if (window.innerWidth) {
		return window.innerWidth;
	} else if (esIE6CSS) {
		return document.body.parentElement.clientWidth;	// ancho del objeto html
	} else if (document.body && document.body.clientWidth) {
		return document.body.clientWidth;
	}
	return 0;
}

// Devuelve la altura disponible en la ventana del navegador para el contenido
function altoInteriorVentana() {
	if (window.innerHeight) {
		return window.innerHeight;
	} else if (esIE6CSS) {
		return document.body.parentElement.clientHeight;	// alto del objeto html
	} else if (document.body && document.body.clientHeight) {
		return document.body.clientHeight;
	}
	return 0;
}

// "Corrector" global para IE/Mac (que indica un valor inicial incorrecto para la propiedad offsetTop del elemento); 
// no afecta a otros navegadores.
var factorCorreccion = {top:-1, left:-1};

// Centrar en la ventana y hacer visible el elemento posicionable "nombreCapa". Si no se especifica el segundo
// parámetro, o se deja a false, se centra sólo en horizontal. Si no se especifica el tercer parámetro, o se
// deja a true, se hace visible.
function centrarObjeto(nombreCapa, centrarVertical, hacerVisible) {
	var objeto = obtenerObjeto(nombreCapa);
	// No hacer nada si el objeto no existe, o es más ancho que la ventana
	if (objeto == null) {
		return;
	}
	// Hacer visible el objeto: debería hacerse al final, después de centrar, pero si se mueve una capa con listbox cuando es todavía invisible, al hacerse visible se quedan los listbox en el lugar original
	if (arguments.length < 3 || hacerVisible) {
		mostrar(objeto);
	}
	// fijar factorCorrecion solo la primera vez (o sea, cuando tiene el valor inicial -1)
	if (factorCorreccion.top == -1) {
		if ((typeof objeto.offsetTop == "number") && objeto.offsetTop > 0) {
			factorCorreccion.top = objeto.offsetTop;
			factorCorreccion.left = objeto.offsetLeft;
		} else {
			factorCorreccion.top = 0;
			factorCorreccion.left = 0;
		}
		if (objeto.offsetWidth && objeto.scrollWidth) {
			if (objeto.offsetWidth != objeto.scrollWidth) {
				objeto.style.width = objeto.scrollWidth;    
			}
		}
	}
	var x = Math.round((anchoInteriorVentana() / 2) - (ancho(objeto) / 2));
	x = (x < 0) ? 0 : x;
	var y = Math.round((altoInteriorVentana() / 2) - (alto(objeto) / 2));
	y = (y < 0) ? 0 : y;
	if (centrarVertical) {
		situar(objeto, x - factorCorreccion.left, y - factorCorreccion.top);
	} else {
		situarX(objeto, x - factorCorreccion.left);
	}
}

// Muestra en pantalla un mensaje que se cierra automáticamente
function mensaje_autocierre(mensaje, titulo)
{
	var ventana = window.open('/include/mensaje.html', 'mensaje', 'width=400, height=100');
	ventana.focus();
	var contenido = ventana.document.createTextNode(mensaje);
	ventana.document.getElementById('mensaje').appendChild(contenido);
	if (arguments.length > 1) {
		ventana.document.title = titulo;
	}
}

// Cambia la propiedad "propiedad" del estilo "nombre_estilo", asignándole el valor "valor"
function cambiar_estilo(nombre_estilo, propiedad, valor)
{
	for (var i = 0; i < document.styleSheets.length; ++i) {
		// IE 5.5 usa un nombre no estándar para el array de estilos
		if (esIE4) {
			var estilos = document.styleSheets[i].rules;
		}
		else {
			var estilos = document.styleSheets[i].cssRules;
		}
		for (var j = 0; j < estilos.length; ++j) {
			if (estilos[j].selectorText == nombre_estilo) {
				eval('estilos[j].style.' + propiedad + '="' + valor + '"');
				return;
			}
		}
	}
}

// Busca en 'formulario' un campo oculto con el nombre 'nombreCampo' y le asigna el valor 'nuevoValor'
function cambiarCampoOculto(formulario, nombreCampo, nuevoValor) 
{
	for (var i = 0; i < formulario.elements.length; ++i) {
		if (formulario.elements[i].name == nombreCampo && formulario.elements[i].type=="hidden") {
			formulario.elements[i].value = nuevoValor;
			return;
		}
	}
}

// Añade a 'formulario' un campo oculto con el nombre y valor indicados
function crearCampoOculto(formulario, nombre, valor)
{
	var nuevo_control = document.createElement('input');
	nuevo_control.setAttribute('type', 'hidden');
	nuevo_control.setAttribute('name', nombre);
	nuevo_control.setAttribute('value', valor);
	formulario.appendChild(nuevo_control);
}

// Quita de 'formulario' un campo oculto con el nombre indicado, si existe; si no, no hace nada
function eliminarCampoOculto(formulario, nombre)
{
	for (var i = 0; i < formulario.elements.length; ++i) {
		if (formulario.elements[i].name == nombre && formulario.elements[i].type=="hidden") {
			formulario.removeChild(formulario.elements[i]);
			return;
		}
	}
}

function encadenar_codigo_evento(objeto, nombre_evento, codigo)
{
	var evento = eval(nombre_evento);
	if (typeof(evento) == "function") {
		var codigo_existente = evento.toString(); 
		codigo_existente = codigo_existente.substring(codigo_existente.indexOf("{") + 1, codigo_existente.length - 1) + codigo; 
		eval(nombre_evento + '=new Function(codigo_existente)');
	} 
	else {
		eval(nombre_evento + '=new Function(codigo)');
	}
}
