// -----------------------------------------------------------------------------------
//
//	Lightbox v2.04
//	par Lokesh Dhakar - http://www.lokeshdhakar.com
//	Dernière modification : 2/9/08
//
//	Pour plus de détails, voir:
//	http://lokeshdhakar.com/projects/lightbox2/
//
//	Diffusée sous license Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
//  	- Libre de droits pour usages personel et commercial
//		- Toute utilisation nécessite cepterminerant le maintien du nom de l'auteur, d'un lien vers son site et des informations de license.
//	
//  Remerciements à : Scott Upton(uptonic.com), Peter-Paul Koch(quirksmode.com), & Thomas Fuchs(mir.aculo.us) pour leurs idées, leurs bibliothèques et autres lignes de code
//  		Artemy Tregubenko (arty.name) pour les mises à jour nécessitées par les changements de version de Prototype et Scriptaculo.us.
//
// Cette adaptation française est de Jean-Luc Lemonnier : www.bureau-des-latitudes.com
// Dernière modification : 13 juillet 2009
// -----------------------------------------------------------------------------------
/*

   Sommaire
    -----------------

    Déclaration de la classe Lightbox
    - initialize()
    - dresserListeImages()
    - demarrer()
    - changerImage()
    - ajusterTailleConteneur()
    - afficherImage()
    - changerDetails()
    - changerNav()
    - permettreNavClavier()
    - empecherNavClavier()
    - detecterTouche()
    - chargerImgVoisines()
    - terminer()
    
    Appels de fonction :
    - document.observe()
   
*/
// -----------------------------------------------------------------------------------

//
//  Préparation
//
optionsLightbox = Object.extend({
    imgAttente:	'img/lightbox_fr_img/patience.gif', //lien relatif vers l'image d'attente lors d'un chargement  
    imgFermerConteneur: 'img/lightbox_fr_img/fermer.png', //lien relatif vers image de fermeture de la galerie
	// Attention : ces liens sont insérés dans le fichier html et ne sont donc PAS relatifs au fichier lightbox.js

    opaciteVoile: 0.9,   

    tailleProgressive: true,         // bascule en dimensionnement dynamique / statique du conteneur
    ajustementVitesse: 9,        // contrôle la rapidité du dimensionnement (1=lent and 10=rapide)

    tailleBordure: 15,

	// Pour les groupes d'images: afficher "Image # / #".
	appellationImage: "Image",
	appellationSur: "/"
}, window.optionsLightbox || {});

// -----------------------------------------------------------------------------------
var Lightbox = Class.create({

    collectionImages: [],
    imageEnCours: undefined,
    
    // initialiser()
    // Ce constructeur démarre une fois le DOM chargé. A l'appel de dresserListeImages, la fonction
    // insère du code html au bas de la page,pour afficher le voile opaque et le conteneur d'image 
    initialize: function() {    
		this.dresserListeImages();
        
        this.detecterTouche = this.detecterTouche.bindAsEventListener(this);

        if (optionsLightbox.ajustementVitesse > 10) optionsLightbox.ajustementVitesse = 10;
        if (optionsLightbox.ajustementVitesse < 1)  optionsLightbox.ajustementVitesse = 1;

		//durée de l'ajustement de taille du conteneur mise à zéro si pas d'ajustement progressif
	    this.dureeAjustementTaille = optionsLightbox.tailleProgressive ? ((11 - optionsLightbox.ajustementVitesse) * 0.15) : 0;
	    this.dureeOpacification = optionsLightbox.tailleProgressive ? 0.2 : 0;  // idem pour la mise en place du voile opaque

        // Taille de départ du conteneur réduite à 1 px au départ si pas d'ajustement progressif
        var taille = (optionsLightbox.tailleProgressive ? 250 : 1) + 'px';
        

        // Allure du code html inséré
        //
        //  <div id="voile"></div>
        //  <div id="lightbox">
        //      <div id="conteneur_externe_img">
        //          <div id="conteneur_img">
        //              <img id="image_lightbox">
        //              <div style="" id="surcouche_nav">
        //                  <a href="#" id="vers_precedent"></a>
        //                  <a href="#" id="vers_suivant"></a>
        //              </div>
        //              <div id="chargement">
        //                  <a href="#" id="lien_chargement">
        //                      <img src="images/patience.gif">
        //                  </a>
        //              </div>
        //          </div>
        //      </div>
        //      <div id="conteneur_externe_details">
        //          <div id="conteneur_details">
        //              <div id="details_img">
        //                  <span id="legende"></span>
        //                  <span id="affichageNumero"></span>
        //              </div>
        //              <div id="nav_bas">
        //                  <a href="#" id="fermeture">
        //                      <img src="images/fermer.gif">
        //                  </a>
        //              </div>
        //          </div>
        //      </div>
        //  </div>

		var objetBody = $$('body')[0];
		objetBody.appendChild(Builder.node('div',{id:'voile'}));
        objetBody.appendChild(Builder.node('div',{id:'lightbox'}, [
            Builder.node('div',{id:'conteneur_externe_img'}, 
                Builder.node('div',{id:'conteneur_img'}, [
                    Builder.node('img',{id:'image_lightbox'}), 
                    Builder.node('div',{id:'surcouche_nav'}, [
                        Builder.node('a',{id:'vers_precedent', href: '#' }),
                        Builder.node('a',{id:'vers_suivant', href: '#' })
                    ]),
                    Builder.node('div',{id:'chargement'}, 
                        Builder.node('a',{id:'lien_chargement', href: '#' }, 
                            Builder.node('img', {src: optionsLightbox.imgAttente})
                        )
                    )
                ])
            ),
            Builder.node('div', {id:'conteneur_externe_details'},
                Builder.node('div',{id:'conteneur_details'}, [
                    Builder.node('div',{id:'details_img'}, [
                        Builder.node('span',{id:'legende'}),
                        Builder.node('span',{id:'affichageNumero'})
                    ]),
                    Builder.node('div',{id:'nav_bas'},
                        Builder.node('a',{id:'fermeture', href: '#' },
                            Builder.node('img', { src: optionsLightbox.imgFermerConteneur })
                        )
                    )
                ])
            )
        ]));


		$('voile').hide().observe('click', (function() { this.terminer(); }).bind(this));
		$('lightbox').hide().observe('click', (function(event) { if (event.element().id == 'lightbox') this.terminer(); }).bind(this));
		$('conteneur_externe_img').setStyle({ width: taille, height: taille });
		$('vers_precedent').observe('click', (function(event) { event.stop(); this.changerImage(this.imageEnCours - 1); }).bindAsEventListener(this));
		$('vers_suivant').observe('click', (function(event) { event.stop(); this.changerImage(this.imageEnCours + 1); }).bindAsEventListener(this));
		$('lien_chargement').observe('click', (function(event) { event.stop(); this.terminer(); }).bind(this));
		$('fermeture').observe('click', (function(event) { event.stop(); this.terminer(); }).bind(this));

        var th = this;
        (function(){
            var ids = 
                'voile lightbox conteneur_externe_img conteneur_img image_lightbox surcouche_nav vers_precedent vers_suivant chargement lien_chargement ' + 
                'conteneur_externe_details conteneur_details details_img legende affichageNumero nav_bas fermeture';   
            $w(ids).each(function(id){ th[id] = $(id); });
        }).defer();
    },

    //
    // dresserListeImages()
	// Parcourt les balises <a> à la rechercher de références (rel) à Lightbox pour y appliquer les écouteurs d'événements CLIC
	// Relancer si mise à jour Ajax de la liste des images
    dresserListeImages: function() {   
        this.dresserListeImages = Prototype.emptyFunction;
        document.observe('click', (function(event){
            var cible = event.findElement('a[rel^=lightbox]') || event.findElement('area[rel^=lightbox]');
            if (cible) {
                event.stop();
                this.demarrer(cible);
            }
        }).bind(this));
    },
    
    //  demarrer()
    demarrer: function(ceLienImage) {    
		//on se débarrasse de tout ce qui bouge ;-)), les balises select,object, embed sont cachées
        $$('select', 'object', 'embed').each(function(cetObjet){ cetObjet.style.visibility = 'hidden' });

        // le voile occupe touta la page...
        var dimensionsPage = this.lireDimPage();
        $('voile').setStyle({ width: dimensionsPage[0] + 'px', height: dimensionsPage[1] + 'px' });

        new Effect.Appear(this.voile, { duration: this.dureeOpacification, from: 0.0, to: optionsLightbox.opaciteVoile });

        this.collectionImages = [];
        var imageNum = 0;       

        if ((ceLienImage.rel == 'lightbox')){
            // si l'image n'est PAS incluse dans un groupe, on ajoute une seule image au tableau collectionImages
            this.collectionImages.push([ceLienImage.href, ceLienImage.title]);         
        } else {
            // mais si l'image appartient à une liste, on ajoute une portion de tableau à collectionImages
			
			this.collectionImages = 
				$$(ceLienImage.tagName + '[href][rel="' + ceLienImage.rel + '"]').
				collect(function(ceLien){ return [ceLien.href, ceLien.title]; }).
				uniq();
            while (this.collectionImages[imageNum][0] != ceLienImage.href) { imageNum++; }
        }
        // positionnement du conteneur dans page
        var defilementsPage = document.viewport.getScrollOffsets();
        var lightboxTop = defilementsPage[1] + (document.viewport.getHeight() / 10);
        var lightboxLeft = defilementsPage[0];
        this.lightbox.setStyle({ top: lightboxTop + 'px', left: lightboxLeft + 'px' }).show();
        
        this.changerImage(imageNum);
    },

    //
    //  changerImage()
    changerImage: function(imageNum) {   
        
        this.imageEnCours = imageNum; // met à jour la variable globale

        // cache certains éléments durant la transition
        if (optionsLightbox.tailleProgressive) this.chargement.show();
        this.image_lightbox.hide();
        this.surcouche_nav.hide();
        this.vers_precedent.hide();
        this.vers_suivant.hide();
		// HACK: Opera9 ne prend pas en charge les effets scriptaculous opacity et appear
        this.conteneur_externe_details.setStyle({opacity: .0001});
        this.affichageNumero.hide();      
        
        var imgEnChargement = new Image();
        
        // une fois l'image chargée, on réajuste les dimensions du conteneur


        imgEnChargement.onload = (function(){
            this.image_lightbox.src = this.collectionImages[this.imageEnCours][0];
            this.ajusterTailleConteneur(imgEnChargement.width, imgEnChargement.height);
        }).bind(this);
        imgEnChargement.src = this.collectionImages[this.imageEnCours][0];
    },

    //
    //  ajusterTailleConteneur()
    //
    ajusterTailleConteneur: function(cetteLargeur, cetteHauteur) {

        var largeurCourante  = this.conteneur_externe_img.getWidth();
        var heightCurrent = this.conteneur_externe_img.getHeight();

        var nouvelleLargeur  = (cetteLargeur  + optionsLightbox.tailleBordure * 2);
        var nouvelleHauteur = (cetteHauteur + optionsLightbox.tailleBordure * 2);

        // rapport d'homothétie
        var echelleX = (nouvelleLargeur  / largeurCourante)  * 100;
        var echelleY = (nouvelleHauteur / heightCurrent) * 100;

        var differenceLargeur = largeurCourante - nouvelleLargeur;
        var differenceHauteur = heightCurrent - nouvelleHauteur;

        if (differenceHauteur != 0) new Effect.Scale(this.conteneur_externe_img, echelleY, {scaleX: false, duration: this.dureeAjustementTaille, queue: 'front'}); 
        if (differenceLargeur != 0) new Effect.Scale(this.conteneur_externe_img, echelleX, {scaleY: false, duration: this.dureeAjustementTaille, delay: this.dureeAjustementTaille}); 

        // pour les images consécutives ayant mêmes dimensions
        // on programme une courte pause pour éviter un papillottement
        var timeout = 0;
        if ((differenceHauteur == 0) && (differenceLargeur == 0)){
            timeout = 100;
            if (Prototype.Browser.IE) timeout = 250;   
        }

        (function(){
            this.vers_precedent.setStyle({ height: cetteHauteur + 'px' });
            this.vers_suivant.setStyle({ height: cetteHauteur + 'px' });
            this.conteneur_externe_details.setStyle({ width: nouvelleLargeur + 'px' });

            this.afficherImage();
        }).bind(this).delay(timeout / 1000);
    },
    
    //
    //  afficherImage()
    afficherImage: function(){
        this.chargement.hide();
        new Effect.Appear(this.image_lightbox, { 
            duration: this.dureeAjustementTaille, 
            queue: 'terminer', 
            afterFinish: (function(){ this.changerDetails(); }).bind(this) 
        });
        this.chargerImgVoisines();
    },

    //
    //  changerDetails()
    changerDetails: function() {
        // présence / absence de légende
        if (this.collectionImages[this.imageEnCours][1] != ""){
            this.legende.update(this.collectionImages[this.imageEnCours][1]).show();
        } else {
			this.legende.update('').show();
        }	
        
        // pour une image partie d'un groupe
        if (this.collectionImages.length > 1){
            this.affichageNumero.update( optionsLightbox.appellationImage + ' ' + (this.imageEnCours + 1) + ' ' + optionsLightbox.appellationSur + '  ' + this.collectionImages.length).show();
        }

        new Effect.Parallel(
            [ 
                new Effect.SlideDown(this.conteneur_externe_details, { sync: true, duration: this.dureeAjustementTaille, from: 0.0, to: 1.0 }), 
                new Effect.Appear(this.conteneur_externe_details, { sync: true, duration: this.dureeAjustementTaille }) 
            ], 
            { 
                duration: this.dureeAjustementTaille, 
                afterFinish: (function() {
	                // on ajuste la taille du voile
	                var dimensionsPage = this.lireDimPage();
	                this.voile.setStyle({ height: dimensionsPage[1] + 'px' });
	                this.changerNav();
                }).bind(this)
            } 
        );
    },

    //
    //  changerNav()
    changerNav: function() {

        this.surcouche_nav.show();               

        // si l'image n'est pas la première, on affiche l'élément de navigation arrière
        if (this.imageEnCours > 0) this.vers_precedent.show();

        // si l'image n'est pas la dernière, on affiche l'élément de navigation avant
        if (this.imageEnCours < (this.collectionImages.length - 1)) this.vers_suivant.show();
        
        this.permettreNavClavier();
    },

    //
    //  permettreNavClavier()
    //
    permettreNavClavier: function() {
        document.observe('keydown', this.detecterTouche); 
    },

    //
    //  empecherNavClavier()
    //
    empecherNavClavier: function() {
        document.stopObserving('keydown', this.detecterTouche); 
    },

    //
    //  detecterTouche()
    //
    detecterTouche: function(event) {
        var codeTouche = event.keyCode;
        var toucheEchapp;
        if (event.DOM_VK_ESCAPE) {  // mozilla
            toucheEchapp = event.DOM_VK_ESCAPE;
        } else { // ie
            toucheEchapp = 27;
        }

        var touche = String.fromCharCode(codeTouche).toLowerCase();
        
        if (touche.match(/x|o|c/) || (codeTouche == toucheEchapp)){ 
            this.terminer();
        } else if ((touche == 'p') || (codeTouche == 37)){ // image précedente
            if (this.imageEnCours != 0){
                this.empecherNavClavier();
                this.changerImage(this.imageEnCours - 1);
            }
        } else if ((touche == 's') || (codeTouche == 39)){ // image suivante
            if (this.imageEnCours != (this.collectionImages.length - 1)){
                this.empecherNavClavier();
                this.changerImage(this.imageEnCours + 1);
            }
        }
    },

	//  chargerImgVoisines()
    chargerImgVoisines: function(){
        var imgSuivPrechargee, imgPrecPrechargee;
        if (this.collectionImages.length > this.imageEnCours + 1){
            imgSuivPrechargee = new Image();
            imgSuivPrechargee.src = this.collectionImages[this.imageEnCours + 1][0];
        }
        if (this.imageEnCours > 0){
            imgPrecPrechargee = new Image();
            imgPrecPrechargee.src = this.collectionImages[this.imageEnCours - 1][0];
        }
    
    },

    //
    //  terminer()
    //
    terminer: function() {
        this.empecherNavClavier();
        this.lightbox.hide();
        new Effect.Fade(this.voile, { duration: this.dureeOpacification });
        $$('select', 'object', 'embed').each(function(cetObjet){ cetObjet.style.visibility = 'visible' });
    },

    lireDimPage: function() {
	        
	     var xScroll, yScroll;
		
		if (window.innerHeight && window.scrollMaxY) {	
			xScroll = window.innerWidth + window.scrollMaxX;
			yScroll = window.innerHeight + window.scrollMaxY;
		} else if (document.body.scrollHeight > document.body.offsetHeight){ // pour tout sauf Explorer Mac
			xScroll = document.body.scrollWidth;
			yScroll = document.body.scrollHeight;
		} else { // Explorer Mac...et aussi Explorer 6 Strict, Mozilla et Safari
			xScroll = document.body.offsetWidth;
			yScroll = document.body.offsetHeight;
		}
		
		var largeurFenetre, hauteurFenetre;
		
		if (self.innerHeight) {	// all except Explorer
			if(document.documentElement.clientWidth){
				largeurFenetre = document.documentElement.clientWidth; 
			} else {
				largeurFenetre = self.innerWidth;
			}
			hauteurFenetre = self.innerHeight;
		} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Mode Strict
			largeurFenetre = document.documentElement.clientWidth;
			hauteurFenetre = document.documentElement.clientHeight;
		} else if (document.body) { // autres Explorers
			largeurFenetre = document.body.clientWidth;
			hauteurFenetre = document.body.clientHeight;
		}	
		
		// 
		if(yScroll < hauteurFenetre){
			pageHeight = hauteurFenetre;
		} else { 
			pageHeight = yScroll;
		}
	
		if(xScroll < largeurFenetre){	
			pageWidth = xScroll;		
		} else {
			pageWidth = largeurFenetre;
		}

		return [pageWidth,pageHeight];
	}
});

document.observe("dom:loaded", function() {new Lightbox(); });

