

/*********/


/********************* IMAGE ZOOMER ***********************/

Zoom = Class.create();
/**
 * Image zoom control
 *
 * @author      Magento Core Team <core@magentocommerce.com>
 */

Zoom.prototype = {
    initialize: function(imageEl, trackEl, handleEl, zoomInEl, zoomOutEl, moveBtn, galleryEl, loadingElSrc, backgroundEl, closeBtn){
        this.containerEl = $(imageEl).up().up();
        this.backgroundEl = $(backgroundEl);
        this.handleEl = $(handleEl);
        this.trackEl = $(trackEl);
        
        this.containerDim = Element.getDimensions(this.containerEl);
        this.loadingElSrc = loadingElSrc;
        this.imageDim = new Object();

        this.selects = $$('select');

        Event.observe($(closeBtn), 'click', this.close.bind(this));
        //Event.observe(window, 'resize', this.resetPosition.bind(this)); 
        
        // Move In/Out

        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));

        this.selects = document.getElementsByTagName('select');
        
        // Move Image
        $$('.'+moveBtn).invoke('observe', 'mousedown', this.startMove.bind(this));
        $$('.'+moveBtn).invoke('observe', 'mouseup', this.stopMove.bind(this));
        $$('.'+moveBtn).invoke('observe', 'mouseout', this.stopMove.bind(this));

        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)
        });
        
        //this.resetPosition.bind(this);
        
        this.imageEl = $(imageEl);
        this.loadImage($(imageEl).src);
        
        // Load another Image
        $$('.'+galleryEl).invoke('observe', 'click', function(event){

            var e = Event.element(event);
            Event.stop(event);
            this.show();
            this.loadImage(e.up().href);

        }.bind(this));

    },
/*
    
    resetPosition: function()
    {
    
        var viewport = document.viewport.getDimensions();
        var body = $$('body')[0].getDimensions();

    },
    
*/
    show: function()
    {
        this.containerEl.show();
        this.backgroundEl.show();
        //TODO: hide selects for IE only

        for (i=0; i<this.selects.length; i++) {
            this.selects[i].style.visibility = 'hidden';
        }
        this.backgroundEl.observe('click',this.close.bind(this));
    },
    
    close: function(event)
    {
            //TODO: hide selects for IE only

        for (i=0; i<this.selects.length; i++) {
            this.selects[i].style.visibility = 'visible';
        }
        Event.stop(event);
        this.backgroundEl.hide();
        this.containerEl.hide();
    },
    
    loadImage: function(url)
    {
        this.imageEl.hide();
        this.imageEl.up().style.background = 'url('+this.loadingElSrc+') center center no-repeat';
        
        imageObj = new Image();
        imageObj.onload = function(){ 

            this.imageEl.up().style.background = 'transparent';
            this.imageEl.show();
            this.imageEl.width = imageObj.width;
            this.imageEl.height = imageObj.height;
            
            this.imageDim['height'] = imageObj.height;
            this.imageDim['width'] = imageObj.width;
            
            
            this.onImageload(imageObj.src);
            
        }.bind(this);
        imageObj.src = url;
    },
    
    onImageload: function(url)
    {                           
        this.imageEl = $('image');
        this.imageEl.src = url;
        
        this.imageDim.ratio = this.imageDim.width/this.imageDim.height;        
        
        if (this.imageDim.height > this.containerDim.height) {
            this.imageY = -(this.imageEl.getDimensions().height-this.containerDim.height )/2;
            this.imageEl.setStyle({top:(-(this.imageEl.getDimensions().height-this.containerDim.height )/2)+'px'})
            
        }
        
        this.floorZoom = 1;
        
        if (this.imageDim.width > this.imageDim.height) {
            this.ceilingZoom = this.imageDim.width / this.containerDim.width;
        } else {
            this.ceilingZoom = this.imageDim.height / this.containerDim.height;
        }
        
        this.imageX = 0;
        this.imageY = 0;
        this.imageZoom = 1;
    
        this.sliderSpeed = 0;
        this.sliderAccel = 0;
        this.zoomBtnPressed = false;
    
        // ??? 
        this.showFull = false;
    
        // initial zoom
        this.slider.value = 0.2;
        this.scale(0.2);
    },

    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));
        if (this.ceilingZoom < 1 ){
            
            //alert(this.imageZoom*this.containerDim.height)
            this.imageEl.height = (this.imageZoom*this.containerDim.height);
            this.imageEl.width = (this.imageZoom*this.containerDim.height);
            
            //this.imageEl.style.height = (this.imageDim.height)+'px';
        }
        else {
            //alert(this.imageZoom*this.containerDim.height)
            //this.imageEl.style.height = (this.imageZoom*this.containerDim.height)+'px';
            this.imageEl.height = (this.imageZoom*this.containerDim.height);
            this.imageEl.width = (this.imageZoom*this.containerDim.height);

        }
        
        if(this.containerDim.ratio){
          this.imageEl.style.width = (this.imageZoom*this.containerDim.height*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;
    },
    
    startMove: function(event)
    {
        var direction = Event.element(event).id;
        
        this.moveX = 0;
        this.moveY = 0;
        
        switch (direction){
            case 'move_top':
                this.moveY = 5;
                break;
            case 'move_right':
                this.moveX = -5;
                break;
            case 'move_bottom':
                this.moveY = -5;
                break;
            case 'move_left':
                this.moveX = 5;
                break;                 
        }
        
        this.mover = new PeriodicalExecuter(this.periodicalMove.bind(this), .001);
        return this;
    },
    
    stopMove: function(direction)
    {
        // do anything
        if (!this.mover)
            return;
        this.mover.stop();
        return this;
    },
    
    startZoomIn: function()
    {
        this.zoomBtnPressed = true;
        this.sliderAccel = .002;
        this.periodicalZoom();
        this.zoomer = new PeriodicalExecuter(this.periodicalZoom.bind(this), .001);
        return this;
    },

    startZoomOut: function()
    {
        this.zoomBtnPressed = true;
        this.sliderAccel = -.002;
        this.periodicalZoom();
        this.zoomer = new PeriodicalExecuter(this.periodicalZoom.bind(this), .001);
        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;
    },

    periodicalMove: function()
    {
        
        this.imageX += this.moveX;
        this.imageY += this.moveY;
        
        this.contain(this.imageX, this.imageY, this.draggable);
        return this;
    },

    contain: function (x,y,draggable) {
        
        var dim = Element.getDimensions(draggable.element);
        
        var xMin = 0, xMax = this.containerDim.width-dim.width;
        var yMin = 0, yMax = this.containerDim.height-dim.height;

        x = x>xMin ? xMin : x;
        x = x<xMax ? xMax : x;
        y = y>yMin ? yMin : y;
        y = y<yMax ? yMax : y;

        if (this.imageEl.getDimensions().height < this.containerDim.height)
            y = (this.containerDim.height-this.imageEl.getDimensions().height )/2;
            
        if (this.imageEl.getDimensions().width < this.containerDim.width)
            x = (this.containerDim.width-this.imageEl.getDimensions().width )/2;

        this.imageX = x;
        this.imageY = y;

        this.imageEl.style.left = this.imageX+'px';
        this.imageEl.style.top = this.imageY+'px';
        
        return [x,y];
    }
}



