
ImageBox = function()
{
    this.addBoxHtml();
    this.shadowBox = $("shadowBox");
    this.zoomClose = $("zoomClose");
    this.zoomDiv = $("zoomDiv");
    this.zoomImage = $("zoomImage");
    this.zoomProgressImage = $("zoomProgressImage");
    this.zoomLeftNavigationArrowImage = $("zoomLeftNavigationArrowImage");
    this.zoomRightNavigationArrowImage = $("zoomRightNavigationArrowImage");
    this.zoomPlayNavigationImage = $("zoomPlayNavigationImage");
    this.zoomPauseNavigationImage = $("zoomPauseNavigationImage");
    this.zoomNavigationPanel = $("zoomNavigationPanel");
    this.addEvents();
};

ImageBox.prototype = 
{
    preloadingInProgress: false,
    zoomingInProgress: false,
    zoomStart: new Array(),
    zoomEnd: new Array(),
    zoomLast: null,
    shadowBox: null,
    zoomClose: null,
    zoomDiv: null,
    zoomImage: null,
    zoomCurrentStep: 0,
    zoomTotalSteps: 15,
    scroll: new Array(),
    page: new Array(),
    minBorder: 50,
    afterZoom: null,
    zoomTimerId: null,
    progressTimerId: null,
    progressBarActive: false,
    zoomTime: 30,
    alphaStart: 0,
    alphaEnd: 0,
    link: null,
    photos: null,
    currentPhotoIndex: 0,
    onImagePreloaded: null,
    templatesPath: "http://www.sale-weselne.pl/templates/default/img/imageBox/",
    isOpen: false,
    lastUrl: null,
    slideShowTimerId: null,
    slideShowInterval: 6,
    
    setPhotos: function(photos)
    {
        this.photos = photos;
    },

    addEvents: function()
    {
        var links = document.getElementsByTagName("a");

        for(i = 0; i < links.length; i++)
        {
            var link = links[i]
            var href = link.getAttribute("href");
            var rel = link.getAttribute("rel"); 

            if(href
            && href.search(/(.*)\.(jpg|jpeg|gif|png|bmp|tif|tiff)/gi) != -1
            && rel != "nozoom") 
            {
                $(link).addEvent("click", this.onSmallImageClick.handler(this));
                $(link).addEvent("mouseover", this.onSmallImageMouseOver.handler(this));
            }
        }
        
        this.zoomImage.addEvent("click", this.zoomOut.handler(this));
        this.zoomClose.addEvent("click", this.zoomOut.handler(this));
        this.zoomLeftNavigationArrowImage.addEvent("click", this.previousImage.handler(this));
        this.zoomRightNavigationArrowImage.addEvent("click", this.nextImage.handler(this));
        $(document).addEvent("keydown", this.onDocumentKeyDown.handler(this));
        $(document).addEvent("keypress", this.onDocumentKeyPress.handler(this));
        $(document).addEvent("mousemove", this.onDocumentMouseMove.handler(this));
        $(document).addEvent("click", this.onDocumentClick.handler(this));
        this.zoomPlayNavigationImage.addEvent("click", this.onPlayClick.handler(this));
        this.zoomPauseNavigationImage.addEvent("click", this.onPauseClick.handler(this));
        //this.zoomDiv.addEvent("mouseout", this.onBigImageMouseOut.handler(this));
    },
    
    onPauseClick: function(event)
    {
        event.preventDefault();
        this.pauseSlideShow();
    },
    
    onPlayClick: function(event)
    {
        event.preventDefault();
        this.startSlideShow();
    },
    
    startSlideShow: function(event)
    {
        this.zoomPlayNavigationImage.hide();
        this.zoomPauseNavigationImage.show();
        
        this.nextImage();
        this.slideShowTimerId = setInterval(this.nextImage.handler(this), this.slideShowInterval * 1000);
    },
    
    pauseSlideShow: function(event)
    {
        clearInterval(this.slideShowTimerId);
        this.slideShowTimerId = null;
        this.zoomPauseNavigationImage.hide();
        this.zoomPlayNavigationImage.show();
    },
    
    toggleSlideShow: function()
    {
        if(this.slideShowTimerId)
            this.pauseSlideShow();
        else
            this.startSlideShow();
    },   
    
    addBoxHtml: function()
    {
        var html = '<div id="zoomDiv" style="position: absolute; z-index: 999; display:none;">\
        <img border="0" src="" id="zoomImage" style="cursor: pointer;"/>\
        <div id="zoomClose" style="position: absolute; left: -15px; top: -15px;">\
        <img width="30" height="30" border="0" src="' + this.templatesPath + 'closebox.png" style="cursor: pointer;"/>\
        </div>\
        <div id="zoomNavigationPanel" style="z-index:1200; position: absolute; left:50%; bottom:0px; margin: -70px 0px 0px -66px; color:red">\
        <div style="margin-bottom: 10px"> \
        <ul style="height: 40px; list-style: none; margin: 0; padding: 0;">\
        <li style="float: left; padding: 5px 0;"><a href="#" onmouseover="this.style.backgroundPosition=\'0 -40px\'" onmouseout="this.style.backgroundPosition=\'0 0\'" style="background-position: 0 0; background-image: url(' + this.templatesPath + 'navigationPanel.png); display: block;float: left;height: 40px;width: 44px; outline: none;" title="Poprzednie - strzałka w lewo" id="zoomLeftNavigationArrowImage"></a></li>  \
        <li style="float: left; padding: 5px 0;"><a href="#" onmouseover="this.style.backgroundPosition=\'-44px -40px\'" onmouseout="this.style.backgroundPosition=\'-44px 0\'" style="background-position: -44px 0; background-image: url(' + this.templatesPath + 'navigationPanel.png); display: block;float: left;height: 40px;width: 44px; outline: none;" title="Wyświetl pokaz slajdów - spacja" id="zoomPlayNavigationImage"></a></li>  \
        <li style="float: left; padding: 5px 0;"><a href="#" onmouseover="this.style.backgroundPosition=\'-88px -40px\'" onmouseout="this.style.backgroundPosition=\'-88px 0\'" style="background-position: -88px 0; background-image: url(' + this.templatesPath + 'navigationPanel.png); display: none;float: left;height: 40px;width: 44px; outline: none;" title="Zatrzymaj pokaz slajdów" id="zoomPauseNavigationImage"></a></li>  \
        <li style="float: left; padding: 5px 0;"><a href="#" onmouseover="this.style.backgroundPosition=\'-132px -40px\'" onmouseout="this.style.backgroundPosition=\'-132px 0\'" style="background-position: -132px 0; background-image: url(' + this.templatesPath + 'navigationPanel.png); display: block;float: left;height: 40px;width: 44px; outline: none;" title="Nastepne - strzałka w prawo" id="zoomRightNavigationArrowImage"></a></li>  \
        </ul> \
        </div> \
        </div> \
        </div>\
        \
        <div style="position: absolute; display:none; z-index: 499" id="shadowBox">\
        <table style="border: 0px; width:100%; height: 100%;" cellpadding="0" cellspacing="0">\
        <tr><td><img src="' + this.templatesPath + 'shadowBox1.png"></td>\
            <td style="background-image: url(' + this.templatesPath + 'shadowBox2.png); height: 25px; padding:0px;"><img src="' + this.templatesPath + 'spacer.gif"></td>\
            <td><img src="' + this.templatesPath + 'shadowBox3.png"></td>\
        </tr>\
        <tr>\
            <td style="background-image: url(' + this.templatesPath + 'shadowBox4.png);width: 27px; padding:0px;"><img src="' + this.templatesPath + 'spacer.gif"></td>\
            <td style="background-color: #FFF;"></td>\
            <td style="background-image: url(' + this.templatesPath + 'shadowBox5.png); width: 27px; padding:0px;"><img src="' + this.templatesPath + 'spacer.gif"></td>\
        </tr>\
        <tr>\
            <td><img src="' + this.templatesPath + 'shadowBox6.png"></td>\
            <td style="background-image: url(' + this.templatesPath + 'shadowBox7.png); height: 26px; padding:0px;"><img src="' + this.templatesPath + 'spacer.gif"></td>\
            <td><img src="' + this.templatesPath + 'shadowBox8.png"></td>\
        </tr>\
        </table>\
        </div>\
        \
        <img src="' + this.templatesPath + 'progressCircle.gif" style="position:absolute; display: none; z-index:1100;" id="zoomProgressImage">\
        <img src="' + this.templatesPath + 'navigationPanel.png" style="position:absolute; z-index:1000; cursor:pointer; display:none;" > \
        <div style="background:black;position:absolute;left:0px;top:500px;opacity:0.5;filter:alpha(opacity=50);width:980px; height: 1000px; display: none;" id="bigShadow">f</div>';
                
        var dd = document.createElement("div");
        dd.innerHTML = html;
        var inBody = document.getElementsByTagName("body").item(0); 
        inBody.insertBefore(dd, inBody.firstChild);
    },
    
    nextImage: function(event)
    {
        if(event && event.preventDefault)event.preventDefault();
        if(this.preloadingInProgress || this.zoomingInProgress)return;
        
        this.currentPhotoIndex++;
        if(this.currentPhotoIndex == this.photos.length)this.currentPhotoIndex = 0;
        this.changeImage();
        //$("bigShadow").show();
    },
    
    previousImage: function(event)
    {
        if(event)event.preventDefault();
        if(this.preloadingInProgress || this.zoomingInProgress)return;
        
        this.currentPhotoIndex--;
        if(this.currentPhotoIndex == -1)this.currentPhotoIndex = this.photos.length - 1;
        this.changeImage();
    },
    
    changeImage: function()
    {
        var photo = this.photos[this.currentPhotoIndex];
        var addPath = this.fileNameToPath(photo.src);
        var src = "/uploads/photos/" + addPath + photo.src;
        this.preloadImage(src);
        
        if(this.preloadingInProgress)
        {
            this.onImagePreloaded = this.resize;
            this.startProgressAnimation();
        }
        else
        {
            this.resize();
        }
    },
    
    resize: function()
    {
        this.zoomStart = clone(this.zoomEnd);
        this.calculateZoomEnd();
        
        this.zoomCurrentStep = 0;
        this.zoomingInProgress = true;
        this.shadowBox.hide();
        this.zoomClose.hide();
        this.zoomTimerId = window.setInterval(this.resizeStep.handler(this), this.zoomTime);
    },
    
    resizeStep: function()
    {      
        var middle = parseInt(this.zoomTotalSteps / 2);
        
        if(this.zoomCurrentStep <= middle) 
            this.zoomImage.setOpacity(Interpolator.linear(100, 0, this.zoomCurrentStep, middle));
        else
            this.zoomImage.setOpacity(Interpolator.linear(0, 100, this.zoomCurrentStep - middle, this.zoomTotalSteps - middle));
        
        if(this.zoomCurrentStep == middle)
        {
            this.zoomImage.src = this.preloadedImage.src;
        }
        
        this.setZoomValues();
        
        if(this.zoomCurrentStep == this.zoomTotalSteps)
        {
            this.zoomingInProgress = false;
            this.setShadowValues();
            
            if(!BrowserProperties.isIE)
            {
                this.zoomClose.fadeIn();
                this.shadowBox.fadeIn();
            }
            else
            {
                this.zoomClose.show();
            }
            
            clearInterval(this.zoomTimerId);
            return;
        }
        
        this.zoomCurrentStep++;
    },
    
    fileNameToPath: function(fileName)
    {
        var path = "";
        
        for(var i = 0; i < 1; i++)
        {
            path += fileName.substring(i * 2, (i + 1) * 2) + "/";
        }
        
        return path;
    },
    
    onDocumentMouseMove: function(event)
    {
        if(this.zoomingInProgress || !this.isOpen)return;
        
        if(event.clientX < this.zoomDiv.getX()
        || event.clientY < this.zoomDiv.getY() - this.scroll.y
        || event.clientX > this.zoomDiv.getX() + this.zoomImage.getWidth()
        || event.clientY > this.zoomDiv.getY() + this.zoomImage.getHeight() - this.scroll.y)
            this.zoomNavigationPanel.hide();
        else
            this.zoomNavigationPanel.show();
    },
    
    onDocumentClick: function(event)
    {
        if(this.zoomingInProgress || !this.isOpen)return;
        
        if(event.clientX < this.zoomDiv.getX()
        || event.clientY < this.zoomDiv.getY() - this.scroll.y
        || event.clientX > this.zoomDiv.getX() + this.zoomImage.getWidth()
        || event.clientY > this.zoomDiv.getY() + this.zoomImage.getHeight() - this.scroll.y)
            this.zoomOut();
    },
    
    preloadImage: function(url)
    {
        
        var that = this;
        if(this.preloadingInProgress || this.lastUrl == url)return;
        //alert("Preload " + url); 
        this.lastUrl = url;

        this.preloadingInProgress = true;
        this.preloadedImage = new Image();

        this.preloadedImage.onload = function()
        {
            that.preloadingInProgress = false;
        }

        this.preloadedImage.src = url;    
    },
    
    onSmallImageMouseOver: function(event)
    {
        this.preloadImage(event.obj.getAttribute("href"));
    },
    
    startProgressAnimation: function()
    {
        if(!this.progressBarActive)
        {
            this.progressBarActive = true;
            var sizes = BrowserProperties.getSize();
            var x = sizes.page.width/2;
            var y = sizes.page.height/2 + sizes.scroll.y;
             
            this.zoomProgressImage.setPos(x,y);
            //this.zoomProgressImage.show();
            this.progressTimerId = setInterval(this.progressAnimationStep.handler(this), 50);
        }
    },
    
    progressAnimationStep: function()
    {
        if(!this.preloadingInProgress)
        {
            clearInterval(this.progressTimerId);
            this.progressBarActive = false;
            this.zoomProgressImage.hide();
            this.onImagePreloaded();
        }
    },
    
    onSmallImageClick: function(event)
    {
        event.preventDefault();
        this.link = event.obj;
        this.currentPhotoIndex = this.link.currentPhotoIndex || 0;
        
        if(this.preloadingInProgress || !this.preloadedImage)
        {
            this.onImagePreloaded = this.zoomIn;
            this.startProgressAnimation();
        }
        else
        {
            this.zoomIn();
        }
    },
    
    calculateZoomEnd: function()
    {
        this.zoomEnd.width = this.preloadedImage.width;
        this.zoomEnd.height = this.preloadedImage.height;
        
        var sizeRatio = this.zoomEnd.width / this.zoomEnd.height;
        
        if(this.zoomEnd.width > this.page.width - this.minBorder)
        {
            this.zoomEnd.width = this.page.width - this.minBorder;
            this.zoomEnd.height = this.zoomEnd.width / sizeRatio;
        }
        
        if(this.zoomEnd.height > this.page.height - this.minBorder)
        {
            this.zoomEnd.height = this.page.height - this.minBorder;
            this.zoomEnd.width = this.zoomEnd.height * sizeRatio;
        }
        
        this.zoomEnd.x = this.page.width / 2 - this.zoomEnd.width / 2;
        this.zoomEnd.y = this.page.height / 2 - this.zoomEnd.height / 2 + this.scroll.y;    
    },
    
    zoomIn: function()
    {
        var link = this.link;
        var size = BrowserProperties.getSize();
        this.page = size.page;
        this.scroll = size.scroll;
                
        if(link.childNodes[0].width)
        {
            this.zoomStart.width = link.childNodes[0].width;
            this.zoomStart.height = link.childNodes[0].height;
            startPos = $(link.childNodes[0]).findPos();
        }
        else
        {
            this.zoomStart.width = 10;
            this.zoomStart.height = 10;
            startPos = findElementPos(link);
        }

        this.zoomStart.x = startPos.x;
        this.zoomStart.y = startPos.y;

        if(this.zoomingInProgress)return;
        
        this.zoomLast = clone(this.zoomStart);
        this.calculateZoomEnd();
        this.zoomImage.src = this.preloadedImage.src; 

        this.zoomCurrentStep = 0;
        this.zoomingInProgress = true; 
        this.afterZoom = this.afterZoomIn;
        this.alphaStart = 0;
        this.alphaEnd = 100;
        
        this.setZoomValues();
        this.shadowBox.hide();
        this.zoomClose.hide();
        this.zoomNavigationPanel.hide();
        this.zoomDiv.show();
        
        this.zoomTimerId = window.setInterval(this.zoomStep.handler(this), this.zoomTime);
    },
    
    zoomOut: function()
    {
        if(this.zoomingInProgress)return;
        
        this.isOpen = false;
        this.shadowBox.hide();
        this.zoomClose.hide();
        this.zoomNavigationPanel.hide();
        
        var zoomTmp = clone(this.zoomEnd);
        this.zoomEnd = this.zoomLast;
        this.zoomStart = zoomTmp;

        this.zoomCurrentStep = 0;
        this.zoomingInProgess = true;
        this.afterZoom = this.afterZoomOut;
        this.alphaStart = 100;
        this.alphaEnd = 0;
        this.pauseSlideShow();
        this.zoomTimerId = window.setInterval(this.zoomStep.handler(this), this.zoomTime);
    },
    
    setShadowValues: function()
    {
        this.shadowBox.setX(this.zoomDiv.getX() - 13);
        this.shadowBox.setY(this.zoomDiv.getY() - 8);
        this.shadowBox.setWidth(this.zoomImage.getWidth() + 26);
        this.shadowBox.setHeight(this.zoomImage.getHeight() + 26);
    },
    
    afterZoomIn: function()
    {
        this.isOpen = true;
        this.setShadowValues();
        
        if(!BrowserProperties.isIE)
        {
            this.zoomClose.fadeIn();
            this.shadowBox.fadeIn();
        }
        else
        {
            this.zoomClose.show();
        }
    },
    
    onDocumentKeyDown: function(event)
    {
        if(!this.isOpen)return;
                   
        if(inArray(event.keyCode, new Array(Keyboard.VK_LEFT, Keyboard.VK_RIGHT, Keyboard.VK_ESC, Keyboard.VK_SPACE)))
        {
            switch(event.keyCode)
            {
                case Keyboard.VK_LEFT: this.previousImage(); break;
                case Keyboard.VK_RIGHT: this.nextImage(); break;
                case Keyboard.VK_ESC: this.zoomOut(); break;
                case Keyboard.VK_SPACE: this.toggleSlideShow(); break;
            }
            
            event.preventDefault();
            event.stopPropagation();
        }
    },
    
    onDocumentKeyPress: function(event)
    {
        if(!this.isOpen)return;
                   
        if(inArray(event.keyCode, new Array(Keyboard.VK_LEFT, Keyboard.VK_RIGHT, Keyboard.VK_ESC, Keyboard.VK_SPACE)))
        {
            event.preventDefault();
            event.stopPropagation();
        }
    },
    
    afterZoomOut: function()
    {
        this.zoomDiv.hide();
        this.zoomingInProgress = false;
    },
    
    setZoomValues: function()
    {
        this.zoomDiv.setX(this.getStepDimension("x"));
        this.zoomDiv.setY(this.getStepDimension("y"));
        this.zoomImage.setWidth(this.getStepDimension("width"));
        this.zoomImage.setHeight(this.getStepDimension("height"));
    },
    
    zoomStep: function()
    {
        this.setZoomValues();
        this.zoomImage.setOpacity(this.getStepAlpha());
        
        if(this.zoomCurrentStep == this.zoomTotalSteps)
        {
            this.zoomingInProgress = false;
            clearInterval(this.zoomTimerId);
            this.afterZoom();
            return;
        }
        
        this.zoomCurrentStep++;
    },
    
    getStepAlpha: function()
    {
        return Interpolator.linear(this.alphaStart, this.alphaEnd, this.zoomCurrentStep, this.zoomTotalSteps);  
    },

    getStepDimension: function(what)
    {
        return Interpolator.cubic(this.zoomStart[what], this.zoomEnd[what], this.zoomCurrentStep, this.zoomTotalSteps); 
    }
}


Fader = function(obj)
{
    this.obj = $(obj);
};

Fader.prototype =
{
    faderTimerId: null,
    faderCurrentStep: 0,
    faderTotalSteps: 10,
    faderIntervalTime: 15,
    faderAlphaStart: 0,
    faderAlphaEnd: 100, 
    
    fadeIn: function()
    {
        this.fade(0, 100);
    },
    
    fadeOut: function()
    {
        this.fade(100, 0);
    },
    
    fade: function(alphaStart, alphaEnd)
    {
        this.setOpacity(alphaStart);
        this.show();
        this.faderAlphaStart = alphaStart;
        this.faderAlphaEnd = alphaEnd;
        this.faderCurrentStep = 0;
        
        this.faderTimerId = setInterval(this.fadeStep.handler(this), this.faderIntervalTime);
    },
    
    fadeStep: function()
    {
        this.setOpacity(Interpolator.linear(this.faderAlphaStart, this.faderAlphaEnd, this.faderCurrentStep, this.faderTotalSteps))
        
        if(this.faderCurrentStep == this.faderTotalSteps)
        {
            clearInterval(this.faderTimerId);
            return;
        }
        
        this.faderCurrentStep++;
    },
    
    setOpacity: function(opacity)
    {
        this.style.filter = "alpha(opacity=" + opacity + ")";
        this.style.opacity = (opacity / 100);
    }
}

Object.extend(TunedHTMLElement.prototype, Fader.prototype);

Interpolator = 
{
    linear: function(start, end, step, totalStep)
    {
        return start + (end - start) * step / totalStep;  
    },
        
    cubic: function(start, end, step, totalStep)
    {      
        if((step /= totalStep / 2) < 1) return (end - start) / 2 * step * step * step + start;
        return (end - start) / 2 * ((step -= 2) * step * step + 2) + start;  
    }
}

Keyboard =
{
    VK_LEFT: 37,
    VK_RIGHT: 39,
    VK_ESC: 27,
    VK_SPACE: 32
}

BrowserProperties =
{
    isIE: (navigator.userAgent.indexOf("MSIE") != -1) ? true : false, 
    
    getSize: function()
    {
        // Window Size
        var page = new Array();
        var scroll = new Array();
        
        if (self.innerHeight){ // Everyone but IE
            page.width = window.innerWidth;
            page.height = window.innerHeight;
            scroll.y = window.pageYOffset;
        } else if (document.documentElement && document.documentElement.clientHeight) { // IE6 Strict
            page.width = document.documentElement.clientWidth;
            page.height = document.documentElement.clientHeight;
            scroll.y = document.documentElement.scrollTop;
        } else if (document.body) { // Other IE, such as IE7
            page.width = document.body.clientWidth;
            page.height = document.body.clientHeight;
            scroll.y = document.body.scrollTop;
        }

        // Page size w/offscreen areas
        if (window.innerHeight && window.scrollMaxY) {
            scroll.width = document.body.scrollWidth;
            scroll.height = window.innerHeight + window.scrollMaxY;
        } else if (document.body.scrollHeight > document.body.offsetHeight) { // All but Explorer Mac
            scroll.width = document.body.scrollWidth;
            scroll.height = document.body.scrollHeight;
        } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
            scroll.width = document.body.offsetWidth;
            scroll.height = document.body.offsetHeight;
        }
        
        return {"page" : page, "scroll" : scroll};
    }
}
 

