/* Package contents:

  StoreHover
  StoreHoverManager

*/

/**
 * @author timharwood
 */


var trace = function(str){

    try {
        opera.postError(str);
    } 
    catch (e) {
        try {
            console.log(str);
        } 
        catch (f) {
            //alert(str);
        }
    }

}
 
var StoreHover = new Class({
  
  // couple of magic numbers
  options: {
    xMargin: 5
   ,yMargin: 5
   ,propagateLinks: true
  }
  
 ,initialize: function(_hoverLiElement, options) {
  
    this.setOptions(options);
    this.hoverLiElement = _hoverLiElement;
    
    this.itemIndex=-1;
    this.isOver=false;
    
    this.bodyElem=null;
    
    this.productHoverElem=null;
    this.productHoverImg=null;
    this.productHoverImgLoaded=false;
    
    this.rollTimerId=null;
    
    this.hoverFade=null;
    
    this.aElem = this.hoverLiElement.getElement('a');
    
    if ($chk(this.aElem)) {
	    if (!this.options.propagateLinks) { this.aElem.setProperty('href','#'); }
	  
      this.aElem.removeEvent('mouseover', this.elemMouseOver );
      this.aElem.removeEvent('mouseout', this.elemMouseOut );
      this.aElem.removeEvent('click', this.elemMouseClick );
      
      this.aElem.addEvent('mouseover', this.elemMouseOver.bind(this) );
      this.aElem.addEvent('mouseout', this.elemMouseOut.bind(this) );
      this.aElem.addEvent('click', this.elemMouseClick.bind(this) );
    }
    
  },
  
  toString: function() {
    return "[StoreHover]";
  },
  
  setItemIndex: function(_indexNum) {
    this.itemIndex=_indexNum;
  },
  
  setBodyElem: function(_bodyElem) {
    this.bodyElem=_bodyElem;
  },
  
  elemMouseOver: function(el) {
    if (!this.isOver) {
      this.isOver = true;
      clearTimeout(this.rollTimerId);
      this.showProductHover();
      //this.rollTimerId=setTimeout(this.showProductHover.bind(this),100);
    }
  },
  
  elemMouseOut: function(el) {
    if (this.isOver) {
      this.isOver=false;
      clearTimeout(this.rollTimerId);
      this.rollTimerId=setTimeout(this.hideProductHover.bind(this),200);
    }
  },
  
  elemMouseClick: function (event) {
    if (window.debugging) { trace('StoreHover.elemMouseClick() click event ' + event.target); }
    if (!this.options.propagateLinks) {
      event = new Event(event);
      event.stop();
    }
  },
  
  showProductHover: function() {
    this.fireEvent('onShowProductHover',{target:this, type:'onShowProductHover'});
    if (!$chk(this.productHoverElem)) { this.addProductHover(); }
    if (!this.productHoverImgLoaded) { this.loadImage(); } 
    this.resizeProductHover();
    this.positionProductHover();
    this.displayProductHover();

  },
  
  hideProductHover: function() {
    if (!this.isOver) {
      this.fireEvent('onHideProductHover',{target:this, type:'onHideProductHover'});
      if ($chk(this.productHoverElem)) { this.unDisplayProductHover(); }
    }
  },
  
  resizeProductHover: function() {
    var nSize = this.productHoverImg.getSize();
    this.productHoverElem.setStyles({
      'width'  : nSize.size.x+'px',
      'height': nSize.size.y+'px'
    });
  },
  
  
  positionProductHover: function() {

    var liSize = this.hoverLiElement.getCoordinates();
    var hSize = this.productHoverElem.getCoordinates();
    var wSize = window.getSize();
    
    var idealLeft = liSize.left + (liSize.width/2) - (hSize.width/2);
    var idealTop = liSize.top + (liSize.height/4) - (hSize.height);
    
    var yDiff = wSize.scroll.y - (idealTop);
    idealTop += (yDiff>0) ? (yDiff + this.options.yMargin) : 0;
    
    var xDiff = (idealLeft+hSize.width)-wSize.size.x;
    idealLeft -= (xDiff>0)? (xDiff + this.options.xMargin) : 0;
    
    this.productHoverElem.setStyles({'top':idealTop+'px', 'left': idealLeft+'px'});

    
  },
  
  displayProductHover: function() {
    //this.productHoverElem.setStyle('visibility','visible');
    this.productHoverElem.setStyle('display','block');
    this.fireEvent('onShowProductHoverComplete',{target:this, type:'onShowProductHoverComplete'});
  },
  
  unDisplayProductHover: function() {
    //this.productHoverElem.setStyle('visibility','hidden');
    this.productHoverElem.setStyle('display','none');
    this.fireEvent('onHideProductHoverComplete',{target:this, type:'onHideProductHoverComplete'});
  },

  addProductHover: function () {

    this.productHoverImg=new Element('img', {
      'id'   : 'prodHoverImg_'+this.itemIndex,
      'class' : 'prodHoverImg'
    });
    
    this.productHoverImg.addEvent('load', this.imageLoaded.bind(this) );
    
    this.productHoverElem=new Element('a', {
      'id'   : 'prodHover_'+this.itemIndex,
      'class' : 'prodHover',
      'style'  : 'display : none;',
      'href'  : (!this.options.propagateLinks ? '#' : this.hoverLiElement.getElement('a').href)
    });
    
    this.productHoverElem.addEvent('mouseover', this.elemMouseOver.bind(this) );
    this.productHoverElem.addEvent('mouseout', this.elemMouseOut.bind(this) );
    this.productHoverElem.addEvent('click', this.elemMouseClick.bind(this));
    
    this.hoverFade   = new Fx.Styles(this.productHoverElem,   {duration: 250, transition: Fx.Transitions.Quad.easeInOut});
    
    
    this.productHoverElem.adopt(this.productHoverImg);
    //this.hoverLiElement.adopt(this.productHoverElem);
    if (this.bodyElem) this.bodyElem.adopt(this.productHoverElem);
    
  },
  
  loadImage: function() {
    this.productHoverImg.src = this.getHoverImagePath(this.hoverLiElement.getElement('img').src);
  },
  
  imageLoaded: function() {
    this.productHoverImgLoaded = true;
    this.resizeProductHover();
    this.positionProductHover();
  },

  getHoverImagePath: function(_img) {
    return _img.replace('thumb/','mid/');
  }
  
});

StoreHover.implement(new Events, new Options);


/**
 * @author timharwood
 */

 
 var StoreHoverManager = new Class({
   
  initialize: function(propagateLink) {
    if (window.debugging) { trace("new StoreHoverManager"); }
    this.storeHovers = [];
    this.currentHover=null;
    this.propagateLink = $chk(propagateLink) ? propagateLink : true;
  },
  
  toString: function() {
    return "[StoreHoverManager]";
  },
  
  addStoreHover: function(_storeHoverItem) {
    if (this.inStoreHovers(_storeHoverItem)<0) {
      _storeHoverItem.addEvent('onShowProductHover',this.hideHovers.bind(this));
      this.storeHovers.push(_storeHoverItem);
    }
  }, 
  
  inStoreHovers: function(_storeHoverItem) {
    return this.storeHovers.indexOf(_storeHoverItem);
  },
  
  hideHovers: function(_event) {
    this.storeHovers.each(function (el){
      if (el!=_event.target) el.hideProductHover();
    });
  }
 
 
 });
 
 StoreHoverManager.implement(new Events, new Options);