var rdeZoom = null;

if (document.addEventListener)
{
	document.addEventListener("DOMContentLoaded", iniciaZoom, false);
}
else if (document.attachEvent)
{
	document.attachEvent("onreadystatechange", compruebaDOMCargado);
}

function compruebaDOMCargado()
{
	if (document.readyState == "complete")
	{
			iniciaZoom();
	}
}

// Función de inicio del Zoom
function iniciaZoom()
{
	if (navigator.userAgent.indexOf("Safari") == -1)
	{
		var oBody = document.getElementsByTagName("BODY")[0];
		var oDivImg = document.getElementById("RDEZoom");
		//alert(oDivImg.attributes["url"].value);
		rdeZoom = new CRDEZoom();
	}
}

function CRDEZoom()
{
	var self = this;
	var timer = null;
	var oDivImg;
	var oImg;
	var oCuadroZoom;
	var oGuiaZoom;
	var ultimaPosicion;
	var posImg;
	var scroll;

// Métodos públicos	
	this.setImagenPequenya = function(src)
	{
		oDivImg.src = src;
	};

	this.setImagenGrande = function(src)
	{
		oCuadroZoom.estableceFuente(src);
	};

	this.estableceScroll = function(event)
	{
		scroll[0] = window.event.offsetX - window.event.clientX + document.body.offsetLeft;
		scroll[1] = window.event.offsetY - window.event.clientY + document.body.offsetTop;
		self.procesaMovimiento();
	}

	this.onTeclaPulsada = function(event)
	{
		oMascara = document.createElement("DIV");
		oMascara.id = "RDEZoom_mascara";
		oMascara.style.position = "absolute";
		oMascara.style.left = "0px";
		oMascara.style.top = "0px";
		oMascara.style.width = "100%";
		oMascara.style.left = "100%";
		oMascara.style.background = "#000000";
		oMascara.style.zIndex = "0";
		document.body.appendChild(oMascara);
	//window.status = "Presionada una tecla: ";
	}

	this.onTeclaLiberada = function(event)
	{
		oMascara = document.getElementById("RDEZoom_mascara");
		if (oMascara)
		{
			oBody = document.body.removeChild(oMascara);
		}
	//window.status = "Liberada la tecla: ";
	}

	this.procesaMovimiento = function(event)
	{
		var xGuia, yGuia, xScrollCuadro, yScrollCuadro;
		var posCursorX, posCursorY;
		if (event)
		{
			if (event.clientX)
			{
				posCursorX = event.clientX;
				posCursorY = event.clientY;
			}
		}
		else if (window.event)
		{
			if (window.event.clientX)
			{
				posCursorX = window.event.clientX;
				posCursorY = window.event.clientY;
			}
		}
		var diffX = 0;
		var diffY = 0;
		posCursorX = (posCursorX) ? posCursorX : ultimaPosicion[0];
		posCursorY = (posCursorY) ? posCursorY : ultimaPosicion[1];

		posImg = obtenPosicion(oImg);
		//window.status = posImg[0];
		if (!document.all)
		{
			scroll[0] = window.pageXOffset;
			scroll[1] = window.pageYOffset;
		}
		else
		{
			scroll[0] = window.event.offsetX - window.event.clientX + document.body.offsetLeft;
			scroll[1] = window.event.offsetY - window.event.clientY + document.body.offsetTop;
		}
		scroll = getScrollXY();
//		posImg[0] = posImg[0] - scroll[0];
		if (document.all)
		{
			posImg[1] = posImg[1] - scroll[1];
		}


		// Verificamos si está dentro de los límites de la imagen
		var estaEnX = false;
		var estaEnY = false;
		if (oImg != null)
		{
			estaEnX = eval((posCursorX >= posImg[0]) && (posCursorX <= eval(parseFloat(posImg[0]) + parseFloat(oImg.width))));
			estaEnY = eval((posCursorY >= posImg[1]) && (posCursorY <= eval(parseFloat(posImg[1]) + parseFloat(oImg.height))));
		}

		//window.status += "," + posCursorX + ": " + posImg[0] + ", " + eval(parseFloat(posImg[0]) + parseFloat(oImg.width)) + "["+ eval(estaEnX) + ".." + eval(estaEnY)+"]";

		if (estaEnX && estaEnY)
		{
			// Calculamos la posicion en la guía
			var dimGuia = oGuiaZoom.getDimensiones();
			var xPaddingGuia = dimGuia[0] / 2;
			var yPaddingGuia = dimGuia[1] / 2;
			xGuia = posCursorX - xPaddingGuia;
			yGuia = posCursorY - yPaddingGuia;

			// Controlamos que no se salga de los límites
			xGuia = (parseFloat(xGuia) < posImg[0]) ? posImg[0] : xGuia;
			xGuia = (parseInt(parseFloat(xGuia) + parseFloat(dimGuia[0])) > eval(posImg[0] + oImg.width)) ? posImg[0] + oImg.width - dimGuia[0] : xGuia;
			yGuia = (parseFloat(yGuia) < parseFloat(posImg[1])) ? posImg[1] : yGuia;
			yGuia = (parseInt(parseFloat(yGuia) + parseFloat(dimGuia[1])) > eval(posImg[1] + oImg.height)) ? posImg[1] + oImg.height - dimGuia[1] : yGuia;
			oGuiaZoom.setPosicion(xGuia + scroll[0], yGuia + scroll[1]);
			
//		window.status = xGuia+","+yGuia;

			// Calculamos la posicion dentro de la imagen
			var xPosCursorEnImg = xGuia - posImg[0];
			var yPosCursorEnImg = yGuia - posImg[1];

			xScrollCuadro = xPosCursorEnImg / oImg.width;
			yScrollCuadro = yPosCursorEnImg / oImg.height;

			oCuadroZoom.mueveImagen(xScrollCuadro, yScrollCuadro);
			oGuiaZoom.mueve();
			ultimaPosicion[0] = posCursorX;
			ultimaPosicion[1] = posCursorY;

			oCuadroZoom.muestra();
			oGuiaZoom.muestra();
		}
		else
		{
			oCuadroZoom.oculta();
			oGuiaZoom.oculta();
		}
	};

	function onLoadImagenGra()
	{
		var dimGuia = calculaDimensionesGuia();
		oGuiaZoom.setDimensiones(dimGuia[0], dimGuia[1]);
	}
	
	function iniciaMotor(event)
	{
		oGuiaZoom.muestra();
		oCuadroZoom.muestra();
	}

	function finalizaMotor()
	{
		oGuiaZoom.oculta();
		oCuadroZoom.oculta();
	}

	function calculaDimensionesGuia()
	{
		// Obtenemos las dimensiones del div que enmarca la imagen ampliada
		var areaVisible = oCuadroZoom.areaVisible;
		// Obtenemos las dimensiones de la imagen ampliada
		var dimImgGra = oCuadroZoom.getDimensionesImagen();
		// Obtenemos la proporcion del area visible respecto al tamaño de la imagen en cada dimensión
		var proporcionX = areaVisible[0] / dimImgGra[0];
		var proporcionY = areaVisible[1] / dimImgGra[1];
		
		// Las dimensiones de la guía deben tener las mismas proporciones que el área de visualización respecto a sus respectivas imágenes
		var anchoGuia = oImg.width * proporcionX;
		var altoGuia = oImg.height * proporcionY;

		return new Array(anchoGuia, altoGuia);
	}

// Código del constructor
	ultimaPosicion = [0, 0];
	scroll = [0, 0];
	oDivImg = document.getElementById("RDEZoom");
	if (oDivImg && document.all)
	{
		oImg = oDivImg.firstChild;
	}
	else
	{
		if ((oDivImg != null) && (oDivImg.getElementsByTagName("img") != null))
		{
			oImg = oDivImg.getElementsByTagName("img")[0];
		}
	}
	// Obtenemos la posición de la imagen
	posImg = obtenPosicion(oImg);
	oCuadroZoom = new CCuadroZoom(oDivImg);
	oCuadroZoom.addOnLoadCallback(onLoadImagenGra);

	oGuiaZoom = new CGuiaZoom(oDivImg);
	
	registraEvento(document, "mousemove", self.procesaMovimiento);
	registraEvento(document.body, "scroll", self.estableceScroll);
	registraEvento(document.body, "keyup", self.onTeclaLiberada);
	registraEvento(document.body, "keydown", self.onTeclaPulsada);

	var srcBig = null;
	if (oImg != null)
	{
		if (oImg.longdesc)
		{
			srcBig = oImg.longdesc;
		}
		else
		{
			srcBig = oImg.longdesc;//.getAttribute("longdesc");
		}
	}
	oCuadroZoom.estableceFuente(srcBig);
}

function CCuadroZoom(oDivPrincipal)
{
// Atributos públicos
	this.areaVisible;

// Atributos privados
	var self = this;
	var oDiv = null;
	var oImg = null;
	var callbacks = new Array();
	
// Métodos públicos
	this.estableceFuente = function(src)
	{
		oImg.src = src;
	};

	this.muestra = function()
	{
		if (oDiv.style.visibility == "hidden")
		{
			oDiv.style.visibility = "visible";
		}
	};

	this.oculta = function()
	{
		if (oDiv.style.visibility == "visible")
		{
			oDiv.style.visibility = "hidden";
		}
	};

	this.addOnLoadCallback = function(callback)
	{
		if  (oImg.addEventListener)
		{
			oImg.addEventListener("load", callback, false);
		}
		else
		{
			oImg.attachEvent("onload", callback);
		}
	};

	this.mueveImagen = function(x, y)
	{
		var scrLeft = x * oImg.width;
		var scrTop = y * oImg.height;
		oDiv.scrollLeft = scrLeft;
		oDiv.scrollTop = scrTop;
	};

	this.getDimensionesImagen = function()
	{
		return [oImg.width, oImg.height];
	};

// Métodos privados
	function setDimensiones()
	{
		self.dimensionesImagen = [oImg.width, oImg.height];
	}

// Código del constructor
	oDiv = document.createElement("DIV");
	oDiv.className = "cuadroRDEZoom";
	oDiv.style.visibility = "hidden";
	oDiv.style.overflow = "hidden";

	oImg = document.createElement("IMG");
	oDiv.appendChild(oImg);
	
	if (oDivPrincipal != null)
	{
		oDivPrincipal.appendChild(oDiv);
	}

	this.addOnLoadCallback(setDimensiones);
	// Obtenemos el área visible
	var width, height;
	if (document.defaultView)
	{
		// FF no recoge el valor del css de un fichero. Hay que hacerlo como sigue
		width = document.defaultView.getComputedStyle(oDiv, "").getPropertyValue("width");
		height = document.defaultView.getComputedStyle(oDiv, "").getPropertyValue("height");
	}
	else
	{
		width = oDiv.currentStyle.width;
		height = oDiv.currentStyle.height;
	}
	var pixelWidth = parseInt(width.substr(0, width.length - 2));
	var pixelHeight = parseInt(height.substr(0, width.length - 2));
	this.areaVisible = [pixelWidth, pixelHeight];
}


function CGuiaZoom(oImg)
{
	// Atributos públicos

	// Atributos privados
	var self = this;
	var oDiv = null;
	var posX = 0;
	var posY = 0;

	this.setDimensiones = function(w, h)
	{
		oDiv.style.width = w + "px";
		oDiv.style.height = h + "px";
		paddLeft = parseInt(w) / 2;
		paddTop = parseInt(h) / 2;
	};
	this.getDimensiones = function()
	{
		var w = oDiv.style.width;
		var h = oDiv.style.height;
		return [w.substr(0, w.length - 2), h.substr(0, h.length - 2)];
	};
	this.setPosicion = function(x, y)
	{
		posX = x;
		posY = y;
	};

	this.muestra = function()
	{
		if (oDiv.style.visibility == "hidden")
		{
//			oDiv.style.visibility = "visible";
		}
	};

	this.oculta = function()
	{
		if (oDiv.style.visibility == "visible")
		{
			oDiv.style.visibility = "hidden";
		}
	};

	this.mueve = function()
	{
		oDiv.style.left = parseInt(posX) + "px";
		oDiv.style.top = parseInt(posY) + "px";
	}

	// Código del constructor
	inicializa();

	function inicializa()
	{
		oDiv = document.createElement("div");
		oDiv.className = "guiaRDEZoom";
		oDiv.style.visibility = "hidden";
		oDiv.style.left = posX + "px";
		oDiv.style.top = posY + "px";
		oDiv.style.width = 60 + "px";
		oDiv.style.height = 60 + "px";
		document.getElementsByTagName("BODY")[0].appendChild(oDiv);
	}
}

/**
 * Clase que representa a un Nodo dentro de la jerarquía DOM
 */
function obtenPosicion(nodo)
{
	var left = 0;
	var top = 0;

	// Partimos del nodo
	var obj = nodo;

	// Si hay un objeto padre
	if ((obj != null) && obj.offsetParent)
	{
		do
		{
			left += obj.offsetLeft + obj.scrollLeft;
			top += obj.offsetTop + obj.scrollTop;
		} while (obj = obj.offsetParent);
	}
	// Añadimos el scroll del documento
	var scroll = getScrollXY();
	left -= scroll[0];
	top -= scroll[1];
	return [left, top];
}

function getScrollXY()
{
	var scrOfX = 0, scrOfY = 0;
	if( typeof( window.pageYOffset ) == 'number' )
	{
		//Netscape compliant
		scrOfY = window.pageYOffset;
		scrOfX = window.pageXOffset;
	}
	else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) )
	{
		//DOM compliant
		scrOfY = document.body.scrollTop;
		scrOfX = document.body.scrollLeft;
	}
	else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) )
	{
		//IE6 standards compliant mode
		scrOfY = document.documentElement.scrollTop;
		scrOfX = document.documentElement.scrollLeft;
	};
	return [ scrOfX, scrOfY ];
};

function registraEvento(obj, nombre, funcion)
{
	if  (obj.addEventListener)
	{
		obj.addEventListener(nombre, funcion, false);
	}
	else
	{
		obj.attachEvent("on"+nombre, funcion);
	}
}

