PhotoZoom = new Class(
{
    Implements: [Chain, Events, Options],

    options:
	{
	    rootPath: "/photo_zoom",
	    bigContainer: null,
	    smallContainer: null,
	    openButton: null,
	    prevButton: null,
	    nextButton: null,
	    loadingCaption: "Chargement de l'image en cours..."
	},

    initialize: function(options)
	{
        this.id = $time();
        this.index = 0;
        this.active = false;

        this.setOptions(options);

        this.overlay = new Overlay({ container: document.body, onClick: this.close.bind(this) });

        this.container = new Element("div", { "class": "photozoom-container" });

        // affectation d'un evenement click sur le bouton openButton, si present
        if ($(this.options.openButton) != null)
		{
            $(this.options.openButton).addEvent("click", this.open.bindWithEvent(this.index, this));
        }
        this.closeButton = new Element("a", { "href": "javascript:void(0)", "class": "photozoom-close", "title": "fermer" });

        // affectation d'un evenement click sur le bouton prevButton, si present
        if ($(this.options.prevButton) != null)
		{
            $(this.options.prevButton).addEvent("click", this.bigger.bind(this, [-1, -1]));
        }

        // affectation d'un evenement click sur le bouton nextButton, si present
        if ($(this.options.nextButton) != null) {
            $(this.options.nextButton).addEvent("click", this.bigger.bind(this, [-1, 1]));
        }

        this.loader = new Element("div", { "class": "photozoom-loader" });
        this.iframe = new Element("iframe", { "class": "photozoom-iframe" });
        this.thumbs = new Element("ul", { "class": "photozoom-thumbs" });

        this.iframe.setAttribute("scrolling", "no");
        this.iframe.setAttribute("border", "0");
        this.iframe.setAttribute("frameBorder", "0");
        this.iframe.addEvent("load", this.loaded.bindWithEvent(this));
        this.iframe.inject(this.container);

        this.emptyIframe = new Element("div", { "class": "photozoom-iframe" });
        this.emptyIframe.setStyle("display", "none");
        this.emptyIframe.inject(this.container);

        this.thumbs.setStyle("display", "none");
        this.thumbs.inject(this.container);

        this.container.setStyle("visibility", "hidden");
        
        this.container.inject(document.body);

		this.originalTop = parseInt(this.container.getStyle("top").replace("px", ""));

        this.closeButton.setStyles({ top: 0, right: 0 });
        this.closeButton.addEvent("click", this.close.bind(this));
        this.closeButton.inject(this.container);


        // affectation des styles pour le loader
        this.loader.setStyles(
		{
		    display: "none",
		    top: 0,
		    left: 0,
		    opacity: 0.5
		});
        this.loader.inject(this.container);
        this.loader.set("html", this.options.loadingCaption);


        // creation d'un tableau pour accueillir tous les chemins vers les photos en version BIG
        this.photos = new Array();


        // affectation d'un evenement click sur tous les liens appartenant au container bigContainer
        // => remplissage du table this.photos avec les chemins d'acces vers les photos
        this.links = $(this.options.bigContainer).getElements("a");
        for (var i = 0; i < this.links.length; i++)
		{
            // obliger de passer (i+1), il semblerait que passer une valeur egale a 0 fasse merder :)
            this.links[i].addEvent("click", this.open.bindWithEvent(i + 1, this));

            var photoPath = this.links[i].href.replace("http://", "");
            if (this.links[i].href.indexOf("javascript:") != -1)
			{
                photoPath = unscramble(this.links[i].href).replace("http://", "");
            }

            photoPath = photoPath.substr(photoPath.indexOf("/"), photoPath.length - photoPath.indexOf("/"));
            photoPath = appDirectory + this.options.rootPath + photoPath;

            this.photos[i] = photoPath;
        }

        // affectation  d'un evenement click sur tous les liens appartenant au container smallContainer
        // => permet de changer l'affichage de la version "bigger" en cours
		var resized = false;
        if ($(this.options.smallContainer) != null)
		{
            var smallLinks = $(this.options.smallContainer).getElements("a");
            var totalWidth = 0;
            for (var i = 0; i < smallLinks.length; i++) {
                //smallLinks[i].addEvent("click", this.bigger.bind(this, [i]));
                smallLinks[i].addEvent("click", this.open.bindWithEvent(i + 1, this));

                var linkImg = smallLinks[i].getElement("img");

                var thumbItem = new Element("li", { "class": "zoomThumb" });

                var thumbImg = new Element("img", { "id": "thumb-" + this.id + "-" + i, "src": linkImg.src });
                thumbImg.addEvent("click", this.thumbClick.bindWithEvent(i + 1, this));
                thumbImg.setStyle("opacity", 0.5);
                thumbImg.inject(thumbItem);

                thumbItem.inject(this.thumbs);

                var thumbWidth = parseInt(thumbImg.getStyle("width")) + parseInt(thumbImg.getStyle("padding-left")) + parseInt(thumbImg.getStyle("padding-right"));
                totalWidth += thumbWidth;

                // permet d'adapter la hauteur du container quand le nombre de thumbs est trop important tenir sur une seule ligne
                if (totalWidth + thumbWidth > parseInt(this.container.getStyle("width")) && !resized)
				{
					resized = true;
                    this.container.setStyle("height", parseInt(this.container.getStyle("height")) + parseInt(thumbItem.getStyle("height")));
                }
            }
        }

        // ajout d'un evenement keydown pour intercepter les touches d'actions speciales
        // (i.e. : esc, left, right, ...)
        document.addEvent("keydown", this.keyboardListener.bindWithEvent(this));

        this.activeLink = this.links[0];
    },

    open: function(e, instance) 
    {
        e.stop();

        // on fait disparaitre d'eventuelles anim flash
        var tagName = (Browser.Engine.trident) ? "object" : "embed";
        var flashObjects = $(document.body).getElements(tagName);

        flashObjects.each(function(el)
		{
            try
			{
                el.setStyle("visibility", "hidden");
            }
            catch (e)
			{
                //
            }
        });

        instance.overlay.show();

        instance.active = true;

        // dans le cas ou l'appel de "open" s'est fait a partir
        // d'un click sur le bouton this.openButton
        if (!isNaN(this))
		{
            instance.index = this - 1;

            //instance.bigger(this - 1, -1);
        }

        // on vide le contenu de l'iframe
        instance.emptyIframe.setStyle("display", "block");
        instance.iframe.setStyle("display", "none");
        instance.iframe.contentWindow.document.location.replace("about:blank");

        // centrage horizontal de la fenetre
        var leftPos = (window.getWidth() - instance.container.getStyle("width").toInt()) / 2;
        instance.container.setStyle("left", leftPos + "px");

		// positionnement vertical par rapport à un eventuel scrolling dans la page
		var topPos = instance.originalTop + window.getScrollTop();
		instance.container.setStyle("top", topPos + "px");

        // affichage de la fenetre et du loader
        instance.container.setStyle("visibility", "visible");

        // affichage des miniatures
        instance.thumbs.setStyle("display", "block");
        instance.setThumb(true);

        // affichage de la photo
        instance.show();
    },

    bigger: function(index, offset)
	{
        if (index != -1)
		{
            this.index = index;
        }
        else
		{
            this.index += offset;
        }

        this.checkIndex();

        for (var i = 0; i < this.links.length; i++)
		{
            if (this.links[i].getStyle("display") == "inline")
			{
                this.links[i].setStyle("display", "none");
                this.links[this.index].setStyle("display", "inline");

                break;
            }
        }
    },

    thumbClick: function(e, instance)
	{
        instance.setThumb(false);

        instance.index = this - 1;

        instance.show();

        instance.setThumb(true);
    },

    setThumb: function(active)
	{
        var thumbImg = $("thumb-" + this.id + "-" + this.index);

        if (thumbImg)
		{
            thumbImg.setStyle("opacity", (active == true) ? 1 : 0.5);

            if (active == true)
			{
                thumbImg.addClass("active");
            }
            else
			{
                thumbImg.removeClass("active");
            }
        }
    },

    navigate: function(offset)
	{
        this.setThumb(false);

        // si le type d'offset est egal a "click"
        // => il s'agit d'un appel realisé a partir de l'iframe
        // => on positionne la valeur de l'offset sur 1
        if (offset.type == "click") offset = 1;

        this.index += offset;

        this.checkIndex();

        this.setThumb(true);

        this.show();
    },

    checkIndex: function()
	{
        if (this.index > this.photos.length - 1)
		{
            this.index = 0;
        }
        if (this.index < 0)
		{
            this.index = this.photos.length - 1;
        }
    },

    show: function()
	{
        // affichage du loader
        this.loader.setStyle("display", "block");

        // affectation du bon source a l'iframe
        this.iframe.contentWindow.document.location.replace(this.photos[this.index] + "?" + $time());
    },

    close: function()
	{
        // on masque les elements de la fenetre
        this.container.setStyle("visibility", "hidden");
        this.loader.setStyle("display", "none");
        this.thumbs.setStyle("display", "none");

        this.setThumb(false);

        // on cache l'overlay
        this.overlay.hide();

        this.active = false;

        // on refait apparaitre les anim flash qui ont pu etre precedemment masquees
        var tagName = (Browser.Engine.trident) ? "object" : "embed";
        var flashObjects = $(document.body).getElements(tagName);

        flashObjects.each(function(el) 
		{
            try
			{
                el.setStyle("visibility", "visible");
            }
            catch (e)
			{
                //
            }
        });
    },

    keyboardListener: function(e)
	{
        if (!this.active) return;

        // on desactive l'appui sur les touches tab & alt
        // (qui foutent un peu le boxon :))
        if (e.code == 9 || e.code == 18)
		{
            e.stopPropagation();
            return;
        }

        switch (e.key)
		{
            case "esc":
                this.close();
                break;

            case "right":
                this.navigate(1);
                break;

            case "left":
                this.navigate(-1);
                break;
        }
    },

    loaded: function()
	{
        if (this.loader) {
            this.loader.setStyle("display", "none");

            // on cache l'objet emptyIframe et on affiche notre iframe avec la photo
            if (this.emptyIframe.getStyle("display") == "block")
			{
                this.emptyIframe.setStyle("display", "none");
                this.iframe.setStyle("display", "block");
            }

            // permet de gerer les evenements clavier a partir de l'iframe
            if (this.iframe.contentWindow.document.location.href != "about:blank")
			{
                var iframeDoc = this.iframe.contentWindow.document;

                iframeDoc.addEvent("keydown", this.keyboardListener.bindWithEvent(this));

                var iframeImg = iframeDoc.getElement("img[class=photozoom]");
                if ($defined(iframeImg))
				{
                    iframeImg.addEvent("click", this.navigate.bind(this));
                }
            }
        }
    }
});