var GRAB_CURSOR = '-moz-grab';
var GRABBING_CURSOR = '-moz-grabbing';

if(Engine.isMSIE){
  GRAB_CURSOR = '/images/grab.cur';
  GRABBING_CURSOR = '/images/grabbing.cur';
}

if(Engine.isKHTML){
  GRAB_CURSOR = 'move';
  GRABBING_CURSOR = 'move';
}

Gucci.Zoomer = Class.create();
Object.extend(Gucci.Zoomer, {
  ZOOM_IN_SPEED: 0.8,
  ZOOM_OUT_SPEED: 0.4,
  FACTOR: 3.9682539,
  expand: true
});
Object.extend(Gucci.Zoomer.prototype, {
  _zoomed: false,
  _zooming: false,
  active: false,
  initialize: function(element, full, style, url){
    this.active = true;
    this.element = $(element);
    this.full = full;
    this.style = style;
    this.url = url;
    this.expand = Gucci.Zoomer.expand;

    new Insertion.Bottom(this.element,
      '<img class="zoomer-image" id="zoomer-'+style+'-image" style="position:absolute;display:none" />'+
      '<div class="zoomer-button zoomer-reset" id="zoomer-'+style+'-reset" style="display:none">' +
      '<div class="content">' + Gucci.getTerm('reset') + '</div><div class="end"> </div></div>' +
      '<img class="zoomer-cursor" id="zoomer-'+style+'-cursor" src="/images/zoom-cursor.png" style="position:absolute;display:none" />');

    $(this.full).setStyle({cursor:'url(/images/zoom-in.cur),-moz-zoom-in'});
    
    this.zoomInEvent = this.zoomIn.bindAsEventListener(this);
    this.zoomOutEvent = this.zoomOut.bindAsEventListener(this);
    Event.observe(this.element,'click',this.zoomInEvent);
    Event.observe('zoomer-'+style+'-reset','click',this.zoomOutEvent);

    if(Engine.isKHTML) {
      this.khtmlMouseMoveEvent = this.khtmlMouseMove.bindAsEventListener(this);
      this.khtmlMouseOutEvent  = this.khtmlMouseOut.bindAsEventListener(this);
      Event.observe(this.element,'mousemove',this.khtmlMouseMoveEvent);
      Event.observe(this.element,'mouseout',this.khtmlMouseOutEvent);
    }
  },
  setViews: function(images){
    if(images.back){
      new Insertion.Bottom(this.element,
        '<div class="zoomer-button zoomer-back" id="zoomer-'+this.style+'-back">' +
        '<div class="content">' + Gucci.getTerm('back') + '</div><div class="end"> </div></div>');
      this._views = images;
      this._currentView = 'front';
      this.switchViewsEvent = this.switchViews.bindAsEventListener(this);
      Event.observe('zoomer-'+this.style+'-back','click',this.switchViewsEvent);
    }
    if(images.front.is360){
      this._is360 = true;
      this._frames = images.front.is360;
      new Insertion.Bottom(this.element,
        '<div style="display:none;z-index:1000" class="zoomer-360" id="zoomer-'+this.style+'-container">'+
        '<div class="zoomer-button zoomer-left" id="zoomer-'+this.style+'-left"> </div>'+
        '<div class="zoomer-button zoomer-right" id="zoomer-'+this.style+'-right"> </div>'+
        '</div>'
      );
      this._views = images;
      this._currentView = '1';
      this.rotateLeftEvent = this.rotateLeft.bindAsEventListener(this);
      this.rotateRightEvent = this.rotateRight.bindAsEventListener(this);
      Event.observe('zoomer-'+this.style+'-left','click',this.rotateRightEvent);
      Event.observe('zoomer-'+this.style+'-right','click',this.rotateLeftEvent);
      this.setRotation();
      setTimeout(function(){
        $('zoomer-'+this.style+'-container').show().setStyle({left:(260-$('zoomer-'+this.style+'-container').offsetWidth)/2+'px'});
      }.bind(this),10);
    } else {
      if(Engine.isMSIE){
        this.full.setStyle({width:this.full.offsetWidth+'px',height:'504px'});
        this.full.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.full.src+"',sizingMethod='scale')";
        this.full.src = '/images/empty.gif';
      }
    }
  },
  stopRotating: function(){
    if(this._rotateTimeout) clearTimeout(this._rotateTimeout);
  },
  setRotation: function(){
    if(!this._zooming) $(this.full).style.left = -(this._currentView-1)*260 + 'px';
    $(this.full).deltax = -(this._currentView-1)*260;
  },
  rotate: function(speed){
    this.stopRotating();
    this._currentView++;
    if(this._currentView>this._frames) this._currentView = 1;
    this.setRotation();
    this._rotateTimeout = setTimeout( function(){ this.rotate(speed) }.bind(this), speed || 1000 );
  },
  rotateOnce: function(){
    this.stopRotating();
    (12).times(function(i){
      setTimeout( function(){
        this._currentView++;
        if(this._currentView>this._frames) this._currentView = 1;
        this.setRotation();
      }.bind(this), (Gucci.Zoomer.ZOOM_IN_SPEED*0.9)/12*1000*i)
    }.bind(this));
  },
  rotateLeft: function(event){
    this.stopRotating();
    this._currentView--;
    if(this._currentView<1) this._currentView = this._frames;
    this.setRotation();
    Event.stop(event);
  },
  rotateRight: function(event){
    this.stopRotating();
    this._currentView++;
    if(this._currentView>this._frames) this._currentView = 1;
    this.setRotation();
    Event.stop(event);
  },
  switchViews: function(event){
    if(this._currentView == 'front'){
      $('zoomer-'+this.style+'-back').down('div.content').update(Gucci.getTerm('front'));
      this.url = this._views.back.zoom;
      this.full.src = this._views.back.full;
      this._currentView = 'back'
    } else {
      $('zoomer-'+this.style+'-back').down('div.content').update(Gucci.getTerm('back'));
      this.url = this._views.front.zoom;
      this.full.src = this._views.front.full;
      this._currentView = 'front';
    }
    Event.stop(event);
  },
  khtmlMouseMove: function(event){
    if(this._zoomed || this._paused) return;
    var c = Event.localPointer(event,this.element);
    $('zoomer-'+this.style+'-cursor').show();
    $('zoomer-'+this.style+'-cursor').setStyle({left:c[0]+12+'px',top:c[1]+15+'px'});
  },
  khtmlMouseOut: function(){
    $('zoomer-'+this.style+'-cursor').hide();
  },
  destroy: function(){
    if(!this.active) return;
    Event.stopObserving(this.element,'click',this.zoomInEvent);
    Event.stopObserving('zoomer-'+this.style+'-reset','click',this.zoomOutEvent);
    if(Engine.isKHTML) {
      Event.stopObserving(this.element,'mousemove',this.khtmlMouseMoveEvent);
      Event.stopObserving(this.element,'mouseout',this.khtmlMouseOutEvent);
    }
    $('zoomer-'+this.style+'-image').remove();
    $('zoomer-'+this.style+'-reset').remove();
    $('zoomer-'+this.style+'-cursor').remove();
    if($(this.full)) $(this.full).setStyle({cursor:'default'});
    this._views = null;
    this._currentView = null;
    if($('zoomer-'+this.style+'-back')) $('zoomer-'+this.style+'-back').remove();
    this.active = false;
  },
  swap: function(style, fullUrl, zoomUrl) {
    if(this._zoomed){
      this.zoomOut();
      setTimeout(function(){
        this.destroy();
        $(this.full).src = fullUrl;
        this.initialize(this.element,this.full,style,zoomUrl);
      }.bind(this),450);
    } else {
      this.destroy();
      $(this.full).src = fullUrl;
      this.initialize(this.element,this.full,style,zoomUrl);
    }
  },
  setNA: function(naUrl){
    if(this._zoomed){
      this.zoomOut();
      setTimeout(function(){
        this.destroy();
        $(this.full).src = naUrl;
      }.bind(this),450);
    } else {
      this.destroy();
      $(this.full).src = naUrl;
    }
  },
  FACTOR: 3.9682539,
  zoomIn: function(event){
    if(this._is360) return this.zoomIn360(event);
    if(this._zoomed || this._paused || !$('zoomer-'+this.style+'-image')) return;
    this._zoomed = true;

    $('zoomer-'+this.style+'-image').src = this.url;

    var c = Event.localPointer(event,this.element);
    var m = [c[0],c[1]];
    if(m[1]<99) m[1] = 99;
    if(m[1]>382) m[1] = 382;
    
    m[0] = m[0]*(this.FACTOR)*(this.expand ? 0.5 : 0.75);
    
    m[1] = m[1]*(this.FACTOR)*0.75;
    var p = [m[0]+5, m[1]-297];
    $('zoomer-'+this.style+'-image').setStyle({left:'-'+p[0]+'px',top:'-'+p[1]+'px'});

    this.element.style.zIndex = 3;
    
    var effects = [
      new Effect.Scale(this.full,this.FACTOR*100,{sync:true,scaleContent:false}),
      new Effect.Move(this.full,{x:-m[0],y:-m[1],sync:true})
    ]
    if(this.expand) effects.push(new Effect.Scale(this.element,200,{scaleContent:false,scaleY:false,sync:true}));

    if(Engine.isKHTML) $('zoomer-'+this.style+'-cursor').hide();
    if(Engine.isGecko && this.expand) effects.push(new Effect.Move(this.element,{x:-260,sync:true}));
    
    new Effect.Parallel(effects,{duration:Gucci.Zoomer.ZOOM_IN_SPEED, transition:Gucci.cubic});

    setTimeout(function(){
      $('zoomer-'+this.style+'-image').setOpacity(0.0);
      $('zoomer-'+this.style+'-image').show();
      $('zoomer-'+this.style+'-image').style.cursor = GRAB_CURSOR;
      $('zoomer-'+this.style+'-image').setStyle({left:'-'+p[0]+'px',top:'-'+p[1]+'px'});
      /* if(Engine.isMSIE) $(this.full).setOpacity(0.999); // IE bug workaround */
      new Effect.Opacity('zoomer-'+this.style+'-image',{from:0.0,to:1.0,duration:0.7});
    }.bind(this), Gucci.Zoomer.ZOOM_IN_SPEED*1000 + 10);

    new Draggable('zoomer-'+this.style+'-image',{
      starteffect: function(){ $('zoomer-'+this.style+'-image').style.cursor = GRABBING_CURSOR}.bind(this),
      endeffect: function(){ $('zoomer-'+this.style+'-image').style.cursor = GRAB_CURSOR}.bind(this),
      snap: function(x,y,draggable) {
        function constrain(n, lower, upper) {
          if (n > upper) return upper;
          else if (n < lower) return lower;
          else return n;
        }
        var p = [
          constrain(x, -(1040-(this.expand ? 520 : 260)), 0),
          constrain(y, -(1343-504), 0)];
        this._fullStyle = { left:p[0]+5+'px',top:p[1]-297+'px' };
        return p;
     }.bind(this)});

    if($('zoomer-'+this.style+'-back')) $('zoomer-'+this.style+'-back').hide();
    Effect.Appear('zoomer-'+this.style+'-reset',{delay:0.6,to:1.0,duration:0.7});
  },
  zoomOut: function(event, resetZ){
    if(this._is360) return this.zoomOut360(event, resetZ);
    if(!this._zoomed) return;
    this._zoomed = false;
    
    if(this._fullStyle) {
      $(this.full).setStyle(this._fullStyle);
      this._fullStyle = null;
    }
    
    resetZ = resetZ || 2;

    $('zoomer-'+this.style+'-image').hide();
    $(this.full).show();
    $('zoomer-'+this.style+'-reset').hide();
    
    if($('zoomer-'+this.style+'-back')) $('zoomer-'+this.style+'-back').show();

    var effects = [
      new Effect.Scale(this.full,100/this.FACTOR,{sync:true}),
      new Effect.Move(this.full,{x:-$(this.full).offsetLeft,y:-$(this.full).offsetTop,sync:true})
    ];
    if(this.expand) effects.push(new Effect.Scale(this.element,50,{scaleContent:false,scaleY:false,sync:true}));
    if(Engine.isGecko && this.expand) effects.push(new Effect.Move(this.element,{x:260,sync:true}));

    new Effect.Parallel(effects,{duration:Gucci.Zoomer.ZOOM_OUT_SPEED,transition:Gucci.cubic,queue:Shop.queue,
      afterFinish:function(){
        this.element.style.zIndex = resetZ;
        this.full.style.left = null;
        this.element.style.left = null;
        Element.undoPositioned(this.element);
      }.bind(this)
    });

    if(event) Event.stop(event);
  },
  zoomIn360: function(event){
    if(this._zoomed || this._paused || !$('zoomer-'+this.style+'-image')) return;
    this._zoomed = true;
    this._zooming = true;
    
    //this.rotateOnce();

    // $('zoomer-'+this.style+'-image').src = this.url.gsub(/\*/, (this._currentView > 9 ? '0' : '00') + this._currentView);
	$('zoomer-'+this.style+'-image').src = this.url[this._currentView-1];

    var c = Event.localPointer(event,this.element);
    var m = [c[0],c[1]];
    if(m[1]<99) m[1] = 99;
    if(m[1]>382) m[1] = 382;
    
    m[0] = m[0]*(this.FACTOR)*(this.expand ? 0.5 : 0.75);   
    m[1] = m[1]*(this.FACTOR)*0.75;
    
    var p = [m[0]+5, m[1]-297];
    $('zoomer-'+this.style+'-image').setStyle({left:'-'+p[0]+'px',top:'-'+p[1]+'px'});

    this.element.style.zIndex = 3;
    
    var effects = [
      new Effect.ZoomIn360( this.full, { pointer: c, frames: this._frames, sync: true })
    ]
    if(this.expand) effects.push(new Effect.Scale(this.element,200,{scaleContent:false,scaleY:false,sync:true}));

    if(Engine.isKHTML) $('zoomer-'+this.style+'-cursor').hide();
    if(Engine.isGecko && this.expand) effects.push(new Effect.Move(this.element,{x:-260,sync:true}));
    
    new Effect.Parallel(effects,{ duration:Gucci.Zoomer.ZOOM_IN_SPEED, transition:Gucci.cubic });

    this.full.up().setStyle({width:'520px',overflow:'hidden'});

    setTimeout(function(){
      this._zooming = false;
      $('zoomer-'+this.style+'-image').setOpacity(0.0);
      $('zoomer-'+this.style+'-image').show();
      $('zoomer-'+this.style+'-image').style.cursor = GRAB_CURSOR;
      $('zoomer-'+this.style+'-image').setStyle({left:'-'+p[0]+'px',top:'-'+p[1]+'px'});
      /* if(Engine.isMSIE) $(this.full).setOpacity(0.999); // IE bug workaround */
      new Effect.Opacity('zoomer-'+this.style+'-image',{from:0.0,to:1.0,duration:0.7});      
    }.bind(this), Gucci.Zoomer.ZOOM_IN_SPEED*1000 + 10);

    new Draggable('zoomer-'+this.style+'-image',{
      starteffect: function(){ $('zoomer-'+this.style+'-image').style.cursor = GRABBING_CURSOR}.bind(this),
      endeffect: function(){ $('zoomer-'+this.style+'-image').style.cursor = GRAB_CURSOR}.bind(this),
      snap: function(x,y,draggable) {
        function constrain(n, lower, upper) {
          if (n > upper) return upper;
          else if (n < lower) return lower;
          else return n;
        }
        var p = [
          constrain(x, -(1040-(this.expand ? 520 : 260)), 0),
          constrain(y, -(1343-504), 0)];
          this._fullStyle = { left:p[0]+5+'px',top:p[1]-297+'px' };
        return p;
     }.bind(this)});

    if($('zoomer-'+this.style+'-back')) $('zoomer-'+this.style+'-back').hide();
    if($('zoomer-'+this.style+'-left')) $('zoomer-'+this.style+'-left').hide();
    if($('zoomer-'+this.style+'-right')) $('zoomer-'+this.style+'-right').hide();
    Effect.Appear('zoomer-'+this.style+'-reset',{delay:0.6,to:1.0,duration:0.7});
  },
  zoomOut360: function(event, resetZ){
    if(!this._zoomed) return;
    this._zoomed = false;
    
    if(this._fullStyle) {
      $(this.full).setStyle(this._fullStyle);
      this._fullStyle = null;
    }
    
    resetZ = resetZ || 2;
    $('zoomer-'+this.style+'-image').hide();
    $(this.full).show();
    $('zoomer-'+this.style+'-reset').hide();
    
    var effects = [
      new Effect.ZoomOut360( this.full, { frames: this._frames, sync: true })
    ];
    
    if(this.expand) effects.push(new Effect.Scale(this.element,50,{scaleContent:false,scaleY:false,sync:true}));
    if(Engine.isGecko && this.expand) effects.push(new Effect.Move(this.element,{x:260,sync:true}));

    new Effect.Parallel(effects,{duration:Gucci.Zoomer.ZOOM_OUT_SPEED,transition:Gucci.cubic,queue:Shop.queue,
      afterFinish:function(){
        this.element.style.zIndex = resetZ;
        this.element.style.left = null;
        Element.undoPositioned(this.element);
        
        if($('zoomer-'+this.style+'-left')) $('zoomer-'+this.style+'-left').show();
        if($('zoomer-'+this.style+'-right')) $('zoomer-'+this.style+'-right').show();
      }.bind(this)
    });

    if(event) Event.stop(event);
  },
  zoomOutAndPause: function(){
    if(this._zoomed){
      this.zoomOut(null, 3);
      setTimeout(function(){
        this.pause()
      }.bind(this),450);
    } else {
      this.pause();
    }
  },
  zoomOutAndDestroy: function(){
    if(this._zoomed){
      this.zoomOut();
      setTimeout(function(){
        this.destroy()
      }.bind(this),450);
    } else {
      this.destroy();
    }
  },
  pause: function(){
    this._paused = true;
  },
  unpause: function(){
    this._paused = false;
  }
});