var ZoomImageBox = Class.create();
ZoomImageBox.prototype = {
    KeepInRightBound: true,
    x: 0,
    y: 0,
    timer: null,
    activeZoomImage: null,
    initialize: function(boxElementId, width, height, scale, images)
    {
        this.boxElement = $(boxElementId);
        this.zoomImages = images;
        this.elemWidth = width;
        this.elemHeight = height;
        this.scaleFactor = scale;
        Event.observe(window, 'load', this.onLoad.bindAsEventListener(this));
    },
    onLoad: function()
    {
        for(var i = 0; i < this.zoomImages.length; ++i)
        {
            var elem = this.zoomImages[i].render(this);
            Event.observe(elem.zoomImage.img, 'mouseover', this.onMouseOver.bindAsEventListener(this));
            Event.observe(elem.zoomImage.label, 'mouseover', this.onMouseOver.bindAsEventListener(this));
            Event.observe(elem.zoomImage.img, 'click', this.onClick.bindAsEventListener(this));
            Event.observe(document.body, 'mousemove', this.omMouseMove.bindAsEventListener(this));
            this.boxElement.appendChild(elem);
        }
    },
    omMouseMove: function(e)
    {
        this.x = Event.pointerX(e);
        this.y = Event.pointerY(e);
    },
    onMouseOver: function(e)
    {
        var zoomImage = Event.findElement(e, 'div').zoomImage;
        if(this.activeZoomImage == zoomImage)
        {
            return;
        }
            
        if(this.timer !== null)
        {
            clearTimeout(this.timer);
            this.timer = null;
        }
        
        if(this.activeZoomImage !== null)
        {
            if(this.activeZoomImage.maximizeComplete())
            {
                this.activeZoomImage.reset(this);
            }
            this.activeZoomImage = null;
        }
        
        this.activeZoomImage = zoomImage;
        this.timer = setTimeout(this.onMaximize.bind(this), 500);
    },
    onMaximize: function()
    {
        if(this.activeZoomImage === null)
        {
            return;
        }
            
        if(!Position.within(this.activeZoomImage.div, this.x, this.y))
        {
            this.activeZoomImage = null;
            return;
        }
        
        this.activeZoomImage.bringToFront();
        
        var eff = new Effect.Scale(this.activeZoomImage.div, 100 * this.scaleFactor, {
                duration: 0.2, 
                scaleFromCenter: true,
                scaleContent: false,
                scaleMode: { originalWidth: this.elemWidth, originalHeight: this.elemHeight },
                queue: 'maximize',
                afterFinish: this.onMaximizeComplete.bind(this, this.activeZoomImage)
            });
    },
    onMaximizeComplete: function(maximizedZoomImage)
    {
        if (maximizedZoomImage != this.activeZoomImage)
        {
            maximizedZoomImage.reset(this);
            return;
        }
        
        if(this.KeepInRightBound)
        {
            var parentOffsetX = (Position.cumulativeOffset(this.boxElement)[0] + this.boxElement.offsetWidth) - (Position.cumulativeOffset(this.activeZoomImage.div)[0] + this.activeZoomImage.div.offsetWidth);
            if( parentOffsetX < 0 )
            {
                var eff = new Effect.Move(this.activeZoomImage.div, {
                        duration: 0.05,
                        x: /*parentOffsetX*/ -60,
                        mode: 'relative'
                    });
            }
        }
       
        maximizedZoomImage.toLarge();
        
        if(Prototype.Browser.Opera)
        {
            maximizedZoomImage.controlPanel.show();
        }
        else
        {
            var ef2 = new Effect.SlideDown(maximizedZoomImage.controlPanel, { 
                    duration:0.2,
                    afterFinish: this.onShowPanelComplete.bind(this, maximizedZoomImage)
                }); 
        }
    },
    onShowPanelComplete: function(maximizedZoomImage)
    {
        if (maximizedZoomImage != this.activeZoomImage)
        {
            maximizedZoomImage.reset(this);
            return;
        }
        this.timer = setTimeout(this.onMouseCheck.bind(this, maximizedZoomImage), 500);
    },
    onMouseCheck: function(maximizedZoomImage)
    {
        if(this.activeZoomImage != maximizedZoomImage)
        {
            return;
        }
        
        if(Position.within(maximizedZoomImage.div, this.x, this.y))
        {
            this.timer = setTimeout(this.onMouseCheck.bind(this, maximizedZoomImage), 500);
        }
        else
        {
            this.activeZoomImage = null;
            maximizedZoomImage.reset(this);
        }
    },
    onClick: function(e)
    {
        var zoomImage = Event.findElement(e, 'div').zoomImage;
        window.location.href = zoomImage.navigateUrl;
    }
};

var ZoomImage = Class.create();
ZoomImage.prototype = {
    initialize: function(name, x, y, smallUrl, largeUrl, navigateUrl, chartUrl) 
    {
        this.title = name;
        this.navigateUrl = navigateUrl;
        this.posX = x;
        this.posY = y;
        this.smallUrl = smallUrl;
        this.largeUrl = largeUrl;
        this.chartUrl = chartUrl;
    },
    render: function(imageBox)
    {
        this.smallImage = new Image();
        this.smallImage.src = this.smallUrl;
        
        this.div = document.createElement('div');
        this.div.style.position = 'absolute';
        this.div.zoomImage = this;
        
        this.img = document.createElement('img');
        this.img.src = this.smallImage.src;
        this.img.style.width = '100%';
        this.img.style.height = '100%';
        this.img.setAttribute('alt', '');
        this.div.appendChild(this.img);
        
        this.label = document.createElement('span');
        this.label.innerHTML = this.title;
        this.label.className = 'chartLabel';
        this.label.display = 'block';
        this.label.style.position = 'absolute';
        this.label.style.top = '1px';
        this.label.style.left = '1px';
        this.div.appendChild(this.label);
        
        this.controlPanel = document.createElement('div');
        this.controlPanel.innerHTML = '<a href="#" onclick="' + this.chartUrl + ';return false;"><img src="/img/btnchart.gif" alt="" title="" onmouseenter="this.src=\'/img/btncharthot.gif\'" onmouseout="this.src=\'/img/btnchart.gif\'" /></a>';
        this.controlPanel.className = 'chartControlPanel';
        this.controlPanel.style.position = 'absolute';
        this.div.appendChild(this.controlPanel);
        
        this.forcedReset(imageBox);
        
        return this.div;
    },
    toSmall: function()
    {
        this.img.src = this.smallImage.src;
        this.div.style.border = '0';
    },
    toLarge: function()
    {
        if(!this.largeImage)
        {
            this.largeImage = new Image();
            this.largeImage.src = this.largeUrl;
        }
        this.div.style.zIndex = 3;
        this.img.src = this.largeImage.src;
        this.div.style.border = 'solid 1px black';
    },
    bringToFront: function()
    {
        this.div.style.zIndex = 2;
    },
    maximizeComplete: function()
    {
        return (this.div.style.zIndex == 3);
    },
    reset: function(imageBox)
    {
        if(this.maximizeComplete())
        {
            this.controlPanel.style.display = 'none';
            this.div.style.zIndex = 0;
            var eff = new Effect.Scale(this.div, 100 / imageBox.scaleFactor, {
                    duration: 0.2, 
                    scaleFromCenter: true,
                    scaleContent: false,
                    scaleMode: { originalWidth: imageBox.elemWidth * imageBox.scaleFactor, originalHeight: imageBox.elemHeight * imageBox.scaleFactor },
                    queue: 'maximize',
                    afterFinish: this.forcedReset.bind(this, imageBox)
                });
        }
        else
        {
            this.forcedReset(imageBox);
        }
    },
    forcedReset: function(imageBox)
    {
        this.controlPanel.style.top = '2px';
        this.controlPanel.style.right = '2px';
        this.controlPanel.style.display = 'none';
        this.div.style.zIndex = 0;
        this.div.style.width = '' + imageBox.elemWidth + 'px';
        this.div.style.height = '' + imageBox.elemHeight + 'px';
        this.div.style.left = '' + this.posX + 'px';
        this.div.style.top = '' + this.posY + 'px';
        this.toSmall();
    }
};