/**
 * Viewer
 *
 * Visionneuse d'image en superposition
 * @see	http://script.aculo.us/
 *
 * @author	Anthony Terrien	<terrien@benchmark.fr>
 *
 * Impératif :
 *	Alias /html_include_bibliotheque/  "/data/inetpub/cgiroot/bibliotheque/html_include/"
 */

function Viewer() {
	// Path includes bibliotheque
	this.racine = "/html_include_bibliotheque/objimagecentralisee/visionneuse";

	// Declaration
	// Multiple
	this.imageArray		= new Array; // Tableau d'images
	this.imageSrcArray	= new Array; // Tableau d'images src

	this.idImage = 0;

	// Preparation de l'affichage
	this.divFond = document.createElement('div');
	this.divFond.className = 'divFond';

	// Preparation du cadre
	this.divCadre = document.createElement('div');

	// Image div
	this.currentImage = document.createElement('img');

	// Image vide en supersposition
	this.imageSecu = document.createElement('img');

	// Titre de l'image
	this.divCadreTitre = document.createElement('div');
	this.divCadreTitre.className = 'divCadreTitre';
}

/**
 * preload
 *
 * Gestion du préchargement de l'image
 */
Viewer.prototype.preload = function(element, cle_image, id_image, ext_image) {
	// Si pas deja charge
	if (!this.imageSrcArray.inArray(id_image)) {
	//if (this.imageSrc != fichier) {
		// url de l'image agrandie
		var regFormat	= new RegExp("{format}", "g");
		var regCle		= new RegExp("{cle_image}", "g");
		var regId		= new RegExp("{id_image}", "g");
		var regExt		= new RegExp("{ext_image}", "g");

		var url = this.maskSrc;
		url = url.replace(regFormat, this.format);
		url = url.replace(regCle, cle_image);
		url = url.replace(regId, id_image);
		url = url.replace(regExt, ext_image);

		Debugger.debug("Charge : " + url);
		this.imagePreloader = new ImagePreloader(this, [url],
			onPreload = function (unViewer, images, nimages) {
				Debugger.debug("Charge : succes=" + url);

				unViewer.imageArray[unViewer.idImage]	= images[0];
				unViewer.imageSrcArray[unViewer.idImage]	= id_image;

				unViewer.image	= images[0];
				unViewer.imageSrc	= id_image;

				// attente charge
				unViewer.setCurrentImage(images[0]);

				unViewer.idImage++;
			}
		);
	}
};

Viewer.prototype.setCurrentImage = function(image) {
	// Détermine largeur et hauteur disponible de la fenêtre courante
	var windowWidth		= typeof window.innerWidth	!= 'undefined' ? window.innerWidth	: document.documentElement.clientWidth;
	var windowHeight	= typeof window.innerHeight	!= 'undefined' ? window.innerHeight : document.documentElement.clientHeight;
	var windowScrollX	= typeof window.pageXOffset	!= 'undefined' ? window.pageXOffset : document.documentElement.scrollLeft;
	var windowScrollY	= typeof window.pageYOffset	!= 'undefined' ? window.pageYOffset : document.documentElement.scrollTop;

	// Image courante
	this.currentImage.src		= image.src;
	this.currentImage.width		= image.width;
	this.currentImage.height	= image.height;
	this.currentImage.className	= "imageBeforeEffect";
	Debugger.debug("Source de l'image à afficher : "+this.currentImage.src);

	var positionX = 0;
	var positionY = 0;
	var tailleX = 0;
	var tailleY = 0;

	// Dimensionnement du cadre d'affichage de la photo
	tailleX	= image.width + 20;
	tailleY	= image.height + 60;

	// Positionement du cadre d'affichage de la photo
	positionX	= windowScrollX + (windowWidth - tailleX) / 2;
	positionY	= windowScrollY + (windowHeight - tailleY) / 2;
	positionX	= positionX < 0 ? 0 : positionX;
	positionY	= positionY < 0 ? 0 : positionY;

	this.divCadre.style.left	= positionX + 'px';
	this.divCadre.style.top		= positionY + 'px';
	this.divCadre.style.width	= tailleX + 'px';
	this.divCadre.style.height	= tailleY + 'px';

	// Image vide en superposition
	this.imageSecu.style.left	= '10px';
	this.imageSecu.style.top	= '10px';
	this.imageSecu.style.width	= image.width + 'px';
	this.imageSecu.style.height	= image.height + 'px';
};

/**
 * showIcon
 *
 * Affichage du bouton permettant l'agrandissmeent
 */
Viewer.prototype.showIcon = function(element, image, titre) {
	if (typeof this.viewerIndicateur == "undefined") {
		// On n'affiche l'image si le curseur de la souris survole element
		// On ne recré pas d'indicateur si on est en survol de l'indicateur lui-même
		if (!((Mouse.x >= getLeft(element)	+ element.width - 33)
			&& (Mouse.y >= getTop(element)	+ element.height - 33)
			&& (Mouse.x <= getLeft(element)	+ element.width - 7)
			&& (Mouse.y <= getTop(element)	+ element.height - 7))) {

			var bodyElement = document.getElementsByTagName("body");
			if (bodyElement.length) {
				bodyElement = bodyElement[0];
			}
			Debugger.debug(Mouse.x + "/" + Mouse.y);

			// Indicateur du viewer
			this.viewerIndicateur = document.createElement('img');
			this.viewerIndicateur.setAttribute('id', 'viewerIndicateur');
			this.viewerIndicateur.setAttribute('alt', 'Agrandir la photo');
			this.viewerIndicateur.setAttribute('title', 'Agrandir la photo');
			this.viewerIndicateur.style.position	= 'absolute';
			this.viewerIndicateur.style.zIndex		= 1000;
			this.viewerIndicateur.style.top			= (getTop(element) + element.height - 32) + 'px';
			this.viewerIndicateur.style.left		= (getLeft(element) + element.width - 32) + 'px';
			this.viewerIndicateur.style.width		= '24px';
			this.viewerIndicateur.style.height		= '24px';
			this.viewerIndicateur.src				= this.racine + "/image/viewerindicateur.gif";

			var viewerIndicateur = this.viewerIndicateur; // global
			function viewerIndicateurOnMouseOver() {
				viewerIndicateur.style.cursor = 'pointer';
			}

			if (typeof this.viewerIndicateur != "undefined") {
				if (this.viewerIndicateur.addEventListener) {//FireFox
					this.viewerIndicateur.addEventListener('mouseover', viewerIndicateurOnMouseOver, false);
				} else {
					this.viewerIndicateur.attachEvent('onmouseover', viewerIndicateurOnMouseOver);
				}
			}

			// Event pour ouverture
			function viewerIndicateurOnClick() {
				Viewer.openViewer(element, image, titre);
				removeElement("viewerIndicateur");
				Viewer.viewerIndicateur = undefined;
			}

			if (typeof this.viewerIndicateur != "undefined") {
				if (this.viewerIndicateur.addEventListener) {//FireFox
					this.viewerIndicateur.addEventListener('click', viewerIndicateurOnClick, false);
				} else { // IE
					this.viewerIndicateur.attachEvent('onclick', viewerIndicateurOnClick);
				}
			}

			function elementOnMouseOut() {
				Debugger.debug("1" + (Mouse.x < getLeft(element) + element.width - 32));
				Debugger.debug("2" + (Mouse.x > getLeft(element) + element.width - 4) + "|" + Mouse.x + ">" + (getLeft(element) + element.width - 4));
				Debugger.debug("3" + (Mouse.y < getTop(element) + element.height - 32));
				Debugger.debug("3" + (Mouse.y > getTop(element) + element.height - 4));
				if (((Mouse.x < getLeft(element))
					|| (Mouse.y < getTop(element))
					|| (Mouse.x > getLeft(element) + element.width)
					|| (Mouse.y > getTop(element) + element.height))) {
					if (typeof viewerIndicateur != "undefined") {
						removeElement("viewerIndicateur");
						Viewer.viewerIndicateur = undefined;
					}
				}
			}

			if (element.addEventListener) {//FireFox
				element.addEventListener('mouseout', elementOnMouseOut, false);
			} else {
				element.attachEvent('onmouseout', elementOnMouseOut);
			}
		}
	}

	// Div racine
	if (bodyElement) {
		bodyElement.appendChild(this.viewerIndicateur);
	}
};

/**
 * init
 *
 * Initialisation de la visionneuse
 *
 * Il suffit d'ajouter l'event onmouseover="Viewer.init(...)" sur un element img
 * pour activer la visionneuse
 */
Viewer.prototype.init = function(element, racine, largeur, hauteur, cle_image, id_image, ext_image, titre) {
	// Masque d'url de la photo
	this.maskSrc = racine + "/{format}/{cle_image}/{id_image}.{ext_image}";

	// Taille originale de l'image
	this.imageLargeurOriginal = largeur;
	this.imageHauteurOriginal = hauteur;
	this.imageRacine = racine;

	if (this.agrandissable(element)) {
		// Affiche l'icone
//		this.showIcon(element, image, titre);
		// Internet Explorer
		if (window.navigator.appName == 'Microsoft Internet Explorer') {
			element.style.cursor = "url(/image/photo/zoom.ico), pointer";
		} else if (window.navigator.product == 'Gecko') {
			// Moteur Gecko (Netscape, Mozilla, SeaMonkey, Firefox, Camino, Flock, etc.)
			if (window.navigator.userAgent.indexOf('KHTML') < 0) {
				element.style.cursor = "url(/image/photo/zoom.png) 7 7, pointer";
			// Moteur KHTML (Safari, Konqueror)
			} else {
				element.style.cursor = "pointer";
			}
		// Autres navigateurs (Opera)
		} else {
			element.style.cursor = "pointer";
		}

		// lance le préchargement
		Viewer.preload(element, cle_image, id_image, ext_image);
	} else {
		element.style.cursor = "";
	}
};


Viewer.prototype.agrandissable = function(element) {
	// determine le format optimum en fonction de la fenêtre
	this.format = this.getImageFormat();
	return (this.format > Math.max(element.clientWidth, element.clientHeight));
};

/**
 * openViewer
 *
 * Ouvre la visionneuse
 */
Viewer.prototype.openViewer = function(element, image, titre) {
	Debugger.debug("Ouverture : "+image);
	if (!this.agrandissable(element)) {
		return false;
	}

	// Div racine de la visionneuse
	if (!this.viewerDiv) {
		var bodyElement = document.getElementsByTagName("body")[0];
		if (bodyElement) {
			this.viewerDiv = document.createElement("div");
			bodyElement.appendChild(this.viewerDiv);
		}
	}
	this.setAllWMode('opaque');
	this.setZIndexByTagName('object', 0);

	// Cadre de l'image
	// on le créé à la volée
	// lors de la fermeture passe par un removeChild
	if (typeof this.divCadre == "undefined") {
		this.divCadre = document.createElement('div');
	}
	this.divCadre.setAttribute('id', 'divCadre');

	if (this.divCadre.addEventListener) { // FireFox
		this.divCadre.addEventListener('click', divCadreClick, false);
	} else { // IE
		this.divCadre.attachEvent('onclick', divCadreClick);
	}
	this.viewerDiv.appendChild(this.divCadre);

	// Détermine largeur et hauteur disponible de la fenêtre courante
	var windowWidth		= typeof window.innerWidth	!= 'undefined' ? window.innerWidth	: document.documentElement.clientWidth;
	var windowHeight	= typeof window.innerHeight	!= 'undefined' ? window.innerHeight : document.documentElement.clientHeight;
	var documentHeight	= typeof document.height	!= 'undefined' ? document.height	: document.documentElement.scrollHeight;
	var windowScrollX	= typeof window.pageXOffset	!= 'undefined' ? window.pageXOffset : document.documentElement.scrollLeft;
	var windowScrollY	= typeof window.pageYOffset	!= 'undefined' ? window.pageYOffset : document.documentElement.scrollTop;

	var positionX = 0;
	var positionY = 0;
	var tailleX = 0;
	var tailleY = 0;

	// Fond
	this.divFond.className		= "divFond";
	this.divFond.style.height	= documentHeight + 'px';
	this.divFond.style.filter	= "alpha(opacity=50)";
	this.viewerDiv.appendChild(this.divFond);
	this.divFond.style.background	= "#333"; // ! placé après appendChild = permet d'éviter un bug sous IE7

	// cle de l'image courante si plusieurs image agrandissable sur la page
	// Multiple
	Debugger.debug("Recuperation de l'image chargée : "+image);
	this.currentImageId = this.imageSrcArray.key(image);

	// Dimensionnement du cadre d'affichage de la photo
	if (this.currentImageId != null) {
		tailleX	= this.imageArray[this.currentImageId].width + 20;
		tailleY	= this.imageArray[this.currentImageId].height + 60;
	} else {
		tailleX		= 200;
		tailleY		= 50;
	}

	// Positionement du cadre d'affichage de la photo
	positionX	= windowScrollX + (windowWidth - tailleX) / 2;
	positionY	= windowScrollY + (windowHeight - tailleY) / 2;
	positionX	= positionX < 0 ? 0 : positionX;
	positionY	= positionY < 0 ? 0 : positionY;

	this.divCadre.style.left	= positionX + 'px';
	this.divCadre.style.top		= positionY + 'px';
	this.divCadre.style.width	= tailleX + 'px';
	this.divCadre.style.height	= tailleY + 'px';


	// Titre
	this.divCadreTitre.appendChild(document.createTextNode(titre));

	//Multiple
	if (this.currentImageId != null) {
		// Multiple
		this.currentImage.width		= this.imageArray[this.currentImageId].width;
		this.currentImage.height	= this.imageArray[this.currentImageId].height;
		this.currentImage.src		= this.imageArray[this.currentImageId].src;
	} else {
		this.currentImage.width		= 16;
		this.currentImage.height	= 16;
		this.currentImage.src		= this.racine + "/image/chargement.gif";
	}

	Debugger.debug("Ouverture : source="+this.currentImage.src);
	this.currentImage.setAttribute('alt', 'Cliquez pour fermer ce cadre');
	this.currentImage.setAttribute('title', 'Cliquez pour fermer ce cadre');
	this.divCadre.appendChild(this.currentImage);

	this.imageSecu.src = this.racine + "/image/pixel.gif";
	this.imageSecu.setAttribute('alt', 'Cliquez pour fermer ce cadre');
	this.imageSecu.setAttribute('title', 'Cliquez pour fermer ce cadre');
	this.imageSecu.className = "imageBloquante";
	//this.divCadre.appendChild(this.imageSecu);

	// Titre
	this.divCadre.appendChild(this.divCadreTitre);

	// Effet d'opacité progressif
	Debugger.debug("Ouverture : démarrage de la transition");
	new Effect.Opacity('divCadre', {
			duration:0.3,
			from:0,
			to:1
		}
	);

	return true;
};

/**
 * getImageFormat
 *
 * Permet d'estimer le meilleur format de visualisation grande taille
 */
Viewer.prototype.getImageFormat = function() {
	var formats = new Array(750, 540, 450, 425, 400, 352, 350, 300, 270, 265, 240, 180, 160, 150, 140, 130, 115, 100, 95, 90, 80, 77, 75, 72, 70, 66, 63, 62, 60, 50, 40, 30, 26);

	// Détermine le format optimum pour la window
	var largeurMax = Math.min(this.imageLargeurOriginal, document.documentElement.clientWidth);
	var hauteurMax = Math.min(this.imageHauteurOriginal, document.documentElement.clientHeight);
	var ratio = this.imageLargeurOriginal / this.imageHauteurOriginal;

	for (var i = 0; i < formats.length; i++) {
		// SI on est en mode paysage, formats[i] sera la largeur
		// SINON formats[i] sera la hauteur
		var largeur = ratio > 1 ? formats[i] : formats[i] * ratio;
		var hauteur = ratio > 1 ? formats[i] / ratio : formats[i];

		// On ajoute les dimensions du cadre à celles de la photo
		if ((largeur + 20) < largeurMax && (hauteur + 60) < hauteurMax) {
			return formats[i];
		}
	}

	return 0;
};


/**
 * closeViewer
 *
 * Ferme la visionneuse
 */
Viewer.prototype.closeViewer = function() {
	if (this.divCadre.addEventListener) { // FireFox
		this.divCadre.removeEventListener('click', divCadreClick, false);
	} else { // IE
		this.divCadre.detachEvent('onclick', divCadreClick);
	}

	new Effect.Opacity('divCadre', {
			afterFinish:function() {
				// Div cadre, on vide
				Viewer.divCadre.innerHTML		= "";
				Viewer.divCadreTitre.innerHTML	= "";
	   			Viewer.divFond.className		= "displayNone";
				Viewer.viewerDiv.removeChild(Viewer.divCadre);
			},
   			duration:0.3,
			from:1,
   			to:0
		}
	);
};

// Redéfinit le Window Mode des animations flash.
Viewer.prototype.setAllWMode = function(mode) {
	var objects = document.getElementsByTagName('object');
	for (var i = 0; i < objects.length; i++) {
		// Recherche la liste des paramètres (balises <param>)
		var params = objects[i].getElementsByTagName('param');
		// Indique si on a trouvé un wmode
		var wModeTrouve = false;

		// Pour tous les paramètres trouvés...
		for (var j = 0; j < params.length; j++) {
			if (params[j].getAttribute('name') == 'wmode') {
				// On redéfinie les attributs
				params[j].setAttribute('value', mode);
				// On signale qu'on a trouvé un attribut WMode
				wModeTrouve = true;
			}
		}

		// On recherche la (ou les) balises embed
		// Note : Si on en trouve pas, c'est pas grave !
		var embeds = objects[i].getElementsByTagName('embed');
		for (var j = 0; j < embeds.length; j++) {
			// Ca donne un <embed [...] wmode="mode">
			embeds[j].setAttribute('wmode', mode);
		}

		// Si aucun parametre wmode n'a été trouvé, on en crée un.
		if (!wModeTrouve) {
			var param = document.createElement('param');
			param.setAttribute('name', 'wmode');
			param.setAttribute('value', mode);

			if (embeds.length) {
				objects[i].insertBefore(param, embeds[0]);
			} else {
				objects[i].appendChild(param);
			}
		}
	}
};

// Redéfinit les zIndex de toutes les balises object et select
Viewer.prototype.setZIndexByTagName = function(name, zIndex) {
	var objects = document.getElementsByTagName(name);
	for (var i = 0; i < objects.length; i++) {
		objects[i].style.zIndex = zIndex;
	}
};

/**
 * Initialisation du Viewer
 **/
Viewer = new Viewer();

/**
 * Function global pour add/remove Listener
 */
function divCadreClick() {
	Viewer.closeViewer();
}

/**
 * Prototypage Mouse
 **/
function Mouse() {
}

Mouse.prototype.x		= 0;
Mouse.prototype.y		= 0;
Mouse.prototype.setX = function(x) {
	this.x = x
}
Mouse.prototype.setY = function(y) {
	this.y = y
}

Mouse = new Mouse();

if (window.addEventListener) {
	window.addEventListener('mousemove', getMouseXY, false);
} else if (window.attachEvent) {
	window.attachEvent('onmousemove', getMouseXY);
}

// Temporary variables to hold mouse x-y pos.s
var tempX = 0;
var tempY = 0;

// Main function to retrieve mouse x-y pos.s
function getMouseXY(e) {
	if (e.pageX != null) { // grab the x-y pos.s if browser is NS
		tempX = e.pageX;
		tempY = e.pageY;
	} else {	 // grab the x-y pos.s if browser is IE
		tempX = event.clientX + document.body.scrollLeft;
		tempY = event.clientY + document.body.scrollTop;
	}

	// catch possible negative values in NS4
	if (tempX < 0) {
		tempX = 0;
	}

	if (tempY < 0) {
		tempY = 0;
	}

	Mouse.setX(tempX);
	Mouse.setY(tempY);

	return 1;
}


/**
 * Positions sur la page
 */
function getLeft(obj) {
	/*if (obj.x) return obj.x;*/
	var ret = 0;
	while (obj.offsetParent) {
		ret += obj.offsetLeft;
		obj = obj.offsetParent;
	}
	return ret;
}

function getTop(obj) {
	/*if (obj.y)return obj.y;*/
	var ret = 0;
	while (obj.offsetParent) {
		ret += obj.offsetTop;
		obj = obj.offsetParent;
	}
	return ret;
}

/**
 * setOpacity d'un objet tous navigateur
 */
function setOpacity(obj, opacity) {
	opacity = (opacity == 100) ? 99.999 : opacity;

	// IE/Win
	obj.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + opacity + ");";

	// Safari < 1.2, Konqueror
	obj.style.KHTMLOpacity = opacity / 100;

	// Older Mozilla and Firefox
	obj.style.MozOpacity = opacity / 100;

	// Safari 1.2, newer Firefox and Mozilla, CSS3
	obj.style.opacity = opacity / 100;
}


/**
 * removeElement
 *
 * Permet de supprimer un noeud du document
 */
function removeElement(id) {
	var node = document.getElementById(id);
	if (node) {
		node.parentNode.removeChild(node);
	}
}
