if(typeof Image=='undefined') {
    var Image = {};
}

Image.Zoom = Class.create();
Image.Zoom.prototype = {
    initialize: function(imageEl, trackEl, handleEl, zoomInEl, zoomOutEl){
        this.containerEl = $(imageEl).parentNode;
        this.imageEl = $(imageEl);
        this.handleEl = $(handleEl);
        this.trackEl = $(trackEl);
        
        this.containerDim = Element.getDimensions(this.containerEl);
        this.imageDim = Element.getDimensions(this.imageEl);

        if (this.imageDim.width < this.containerDim.width)
            this.containerDim.width = this.imageDim.width;

        if (this.imageDim.height < this.containerDim.height)
            this.containerDim.height = this.imageDim.height;


        if (this.imageDim.width > this.imageDim.height){
            this.imageDim.ratio = this.imageDim.width/this.imageDim.height;
        } else {
            this.imageDim.ratio = this.imageDim.height/this.imageDim.width;        
        }
        this.floorZoom = 1;        
        this.imageX = 0;
        this.imageY = 0;
        this.imageZoom = 1;
        
        this.sliderSpeed = 0;
        this.sliderAccel = 0;
        this.zoomBtnPressed = false;
        
        this.showFull = false;
        
        this.selects = document.getElementsByTagName('select');
        
        this.draggable = new Draggable(imageEl, {
            starteffect:false, 
            reverteffect:false, 
            endeffect:false, 
            snap:this.contain.bind(this)
        });
        
        this.slider = new Control.Slider(handleEl, trackEl, {
            axis:'horizontal', 
            minimum:0, 
            maximum:Element.getDimensions(this.trackEl).width,
            alignX:0, 
            increment:1, 
            sliderValue:0, 
            onSlide:this.scale.bind(this), 
            onChange:this.scale.bind(this)
        });

        if (this.imageDim.width > this.containerDim.width){
            this.ceilingZoom =  this.imageDim.width/this.containerDim.width;
        } else {
            this.ceilingZoom =  this.containerDim.width/this.imageDim.width;
            $(trackEl).hide();
            $(zoomInEl).setAttribute('style','-moz-opacity: 0.2;');
            $(zoomOutEl).setAttribute('style','-moz-opacity: 0.2;');
        }
        this.scale(0);

        
        Event.observe(this.imageEl, 'dblclick', this.toggleFull.bind(this));
        
        Event.observe($(zoomInEl), 'mousedown', this.startZoomIn.bind(this));
        Event.observe($(zoomInEl), 'mouseup', this.stopZooming.bind(this));
        Event.observe($(zoomInEl), 'mouseout', this.stopZooming.bind(this));
        
        Event.observe($(zoomOutEl), 'mousedown', this.startZoomOut.bind(this));
        Event.observe($(zoomOutEl), 'mouseup', this.stopZooming.bind(this));    
        Event.observe($(zoomOutEl), 'mouseout', this.stopZooming.bind(this));   

    },
        
    toggleFull: function () {
        this.showFull = !this.showFull;
        //TODO: tylko dla IE
        for (i=0; i<this.selects.length; i++) {
            this.selects[i].style.visibility = this.showFull ? 'hidden' : 'visible';
        }
        this.trackEl.style.visibility = this.showFull ? 'hidden' : 'visible';
        this.containerEl.style.overflow = this.showFull ? 'visible' : 'hidden';
        this.containerEl.style.zIndex = this.showFull ? '100' : '1';
        
        return this;
    },
       
    scale: function (v) {
        
        var centerX = (this.containerDim.width*(1-this.imageZoom)/2-this.imageX)/this.imageZoom;
        var centerY = (this.containerDim.height*(1-this.imageZoom)/2-this.imageY)/this.imageZoom;
        
        this.imageZoom = this.floorZoom+(v*(this.ceilingZoom-this.floorZoom));               
        this.imageEl.style.width = (this.imageZoom*this.containerDim.width)+'px';
        if(this.containerDim.ratio){
          this.imageEl.style.height = (this.imageZoom*this.containerDim.width*this.containerDim.ratio)+'px'; // for safari
        }        
        this.imageX = this.containerDim.width*(1-this.imageZoom)/2-centerX*this.imageZoom;
        this.imageY = this.containerDim.height*(1-this.imageZoom)/2-centerY*this.imageZoom;
        this.contain(this.imageX, this.imageY, this.draggable);
                
        return true;
    },
    
    startZoomIn: function()
    {
        this.zoomBtnPressed = true;
        this.sliderAccel = .004;
        this.periodicalZoom();
        this.zoomer = new PeriodicalExecuter(this.periodicalZoom.bind(this), .05);
        return this;
    },
    
    startZoomOut: function()
    {
        this.zoomBtnPressed = true;
        this.sliderAccel = -.004;
        this.periodicalZoom();
        this.zoomer = new PeriodicalExecuter(this.periodicalZoom.bind(this), .05);
        return this;
    },
    
    stopZooming: function()
    {
        if (!this.zoomer || this.sliderSpeed==0) {
            return;
        }
        this.zoomBtnPressed = false;
        this.sliderAccel = 0;
    },
    
    periodicalZoom: function()
    {
        if (!this.zoomer) {
            return this;
        }
        
        if (this.zoomBtnPressed) {
            this.sliderSpeed += this.sliderAccel;
        } else {
            this.sliderSpeed /= 1.5;
            if (Math.abs(this.sliderSpeed)<.001) {
                this.sliderSpeed = 0;
                this.zoomer.stop();
                this.zoomer = null;
            }
        }
        this.slider.value += this.sliderSpeed;
        
        this.slider.setValue(this.slider.value);
        this.scale(this.slider.value);
        
        return this;
    },
    
    contain: function (x,y,draggable) {

        var dim = Element.getDimensions(draggable.element);
        var imgDim = Element.getDimensions(this.imageEl);
        
        /*
        var xMin = 0, xMax = this.containerDim.width-dim.width;
        var yMin = 0, yMax = this.containerDim.height-dim.height;
        */
        var xMin = 0, xMax = this.containerDim.width-dim.width-imgDim.width;
        var yMin = 0, yMax = this.containerDim.height-dim.height-imgDim.height;
        
        x = x>xMin ? xMin : x;
        x = x<xMax ? xMax : x;
        y = y>yMin ? yMin : y;
        y = y<yMax ? yMax : y;
        
        this.imageX = x;
        this.imageY = y;
        
        this.imageEl.style.left = this.imageX+'px';
        this.imageEl.style.top = this.imageY+'px';
        
        return [x,y];
    }
}

