"use strict";
/// IMGZOOMER
///
/// Implementa a mostra de imagens ampliadas sobre um fundo translúcido.
///
function ImgZoomer () {}
ImgZoomer.prototype = {
///
///
/// PROPRIEDADES
///
extract : function (x) {	return x.href	},
///
///
/// EVENTOS
///
onZoom		: NOP,
onLoadError	: function () {	this._waiting (0)	},
onClose		: NOP,
///
///
/// MÉTODOS
///
// Carrega a imagem indicada por A.
load : function (a) {
	var me = this, img, x, d, f;
	if (a) {
		// Inicializar.
		if (!me._diafana) {
			me._diafana = d = $("diafana");
			me._img = img = me._getFocusImage (me._foco = x = d.nextSibling);
			on (img, "load", me._onImgLoaded.bind (me));
			img.onerror = me.onLoadError.bind (me);
			on (d, "click", f = me._show.bind (me, 0));
			if (x = me._getCloseButton (x)) x.onclick = f
		}
		// Carregar a imagem.
		x = me.extract (a);
		if (me._prevImgURI !== x) {
			me._prev = a;
			me._prevImgURI = x;
			me._curImgURI || me._waiting (1);
			me._getFocusImage (me._foco).src = me._curImgURI = x
		}
		else me._show (1)
	}
},

// Implementa o pré-carregamento.
preload : function (container, optEl) {
	var me = this, c = container.getElementsByTagName ("img"), ndx = 0, i, a, x;
	if (c.length) {
		c = AP.slice.call (c, 0);
		// Determinar a posição do último elemento referenciado.
		x = optEl || me._prev;
		for (i = c.length; i;) {
			a = c [--i].parentNode;
			if (a === x) ndx = i;
			c [i] = me.extract (a)
		}
		// Delegar o carregamento.
		defer (function () {	var pl = new ImgPreloader; pl.load (c, ndx)	}, ".ImgPreloader")
	}

	return c
},
///
///
/// MÉTODOS REDEFINÍVEIS
///
// Retorna a imagem para mostrar a ampliação.
_getFocusImage : function (box) {	return box.childNodes [1]	},

// Retorna o elemento que constitui o botão de fecho.
_getCloseButton : function (box) {	return box.firstChild	},

// Posiciona o foco e a imagem.
_position : function (img) {
	var me = this, foco = me._foco, fw = foco.offsetWidth, fh = foco.offsetHeight, t, l;
	// Não avançar se não tiver havido mudança no tamanho do foco.
	if (me._fw === fw && me._fh === fh) return;
	me._fw = fw;
	me._fh = fh;
	// Centrar o foco.
	t = Math.round ((screen.availHeight - fh) / 2) - 60;
	l = Math.round ((screen.availWidth - fw) / 2);
	if (t < 0) t = 0;
	if (l < 0) l = 0;
	fw = foco.style;
	fw.top = t + "px";
	fw.left = l + "px"
},

// Sinaliza o início ou fim de um período de espera.
_waiting : function (b) {},
///
///
/// MÉTODOS INTERNOS
///
// Disparado logo após o fim do carregamento da imagem grande.
_onImgLoaded : function (ev) {
	var me = this, img = ev.target, x, i = 0;
	if (me._curImgURI !== img.src) return;
	me._show (1);
	me._waiting (0);
	me._curImgURI = ""
},

// Mostra ou esconde a diáfana.
_show : function (b) {
	var me = this, img = me._img, a = me._prev, foco = me._foco, st1 = me._diafana.style, st2 = foco.style, H = "hidden", V = "visible", N = "none";
	if (b) {
		st2.visibility = H;
		st1.display = st2.display = "block";
		me._position (img);
	   	me.onZoom (img, foco, a);
		st2.visibility = "visible"
	} else {
		st1.display = st2.display = N;
	   	me.onClose (img, foco)
	}
},
///
///
/// VARIÁVEIS
///
_diafana	: 0,
_foco		: 0,
_img		: 0,
_prev		: 0,
_prevImgURI	: 0,
_curImgURI	: "",
_fw			: -1,
_fh			: -1

};


Im (".ImgZoomer")

