/**
 * @depends prototype.js
 * @depends effects.js
 * @depends g-ext.js
 * @depends minibag.js
 */
 
var Minibag = Class.create ({
  minibagTemplate: null, 
  itemCounter:     0,
  
  initialize: function (minibag, options) {
    this.options = Object.extend({ },options || {});
    this.minibag = minibag;
    this.minibagTemplate = new Template('<a href="#"><img src="#{miniThumb}" /> </a>'+
        '<a class="remove" title="Remove from minibag" href="#">&nbsp;&nbsp;</a>');      
    gucci.Minibag.initialize();
    gucci.Minibag.startSync({
      onSyncComplete: function() {
        this.minibag.fire('minibag:syncProduct');
      }.bind(this)
    });
    
    this.products = gucci.Minibag.getProducts();
    this.itemCounter = this.products.size();
    this.minibagProducts = $('minibag-products');
    this.waitlistProducts = $('waitlist-products');
    
    this.build();

    // Event delegation rules
    var minibag_clickevents = {
      'a.remove': function(event) {
        event.stop();
        this.minibag.fire('minibag:removeProduct',{item: event.element().up('li')});
      }.bind(this),
      '.product a:first-child': function(event){
        event.stop();
        this.minibag.fire('minibag:showProduct',{item: event.element().up('li')});
      }.bind(this)
    };
    
    var minibag_hoverevents = {
      '.product': function(event){
        if((Event.localPointer(event, this)[0] < 0 || Event.localPointer(event, this)[0] >= 39) || (Event.localPointer(event, this)[1] < 0 || Event.localPointer(event, this)[1] >= 50))
          this.removeClassName('hover');
        else
          this.addClassName('hover'); 
      }
    };
    
    this.minibag.delegate('click', minibag_clickevents);
    
    if (Prototype.Browser.IE6) {
      this.minibag.delegate('mouseover', minibag_hoverevents);
      this.minibag.delegate('mouseout', minibag_hoverevents);
    }
    
    this.registerEvents();
  }, 
  
  
  updateText: function(){
	  if (this.itemCounter==0) {
	    $('minibag').addClassName("empty");
	    $('minibag').down('.count').update('');
	  } else {
	    $('minibag').removeClassName("empty");
	    $('minibag').down('.count').update('('+this.itemCounter+') ');
	  }
  },
  
  registerEvents: function() {
     this.minibag.observe('minibag:syncProduct', this.onSyncProduct.bindAsEventListener(this));
     this.minibag.observe('minibag:removeProduct', this.onRemoveProduct.bindAsEventListener(this));
     this.minibag.observe('minibag:showProduct', this.onShowProduct.bindAsEventListener(this));
     this.minibag.observe('minibag:addProduct', this.onAddProduct.bindAsEventListener(this));
  },
  
  onAddProduct: function (event) {
    var product = event.memo.product;
    this.addProduct(product, event.memo);
  },
  
  onRemoveProduct: function (event) {
    var item = event.memo.item;
    var sku = item.readAttribute('rel');
    this.removeProduct(sku, item, event.memo);
  },

  onShowProduct: function (event) {
    var item = event.memo.item;
    var sku = item.readAttribute('rel');
    this.showProduct(sku, event.memo);
  }, 
  
  onSyncProduct: function (event) {
    this.syncProducts();
  },
  
  syncProducts: function() {
    this.products = gucci.Minibag.getProducts();
    this.itemCounter = this.products.size();
    this.build();
  },

  removeProduct: function(sku, item, args) {
    var ops = args || {};
    var product = this.products.find(function(product) { return product.sku==sku;});
  
    gucci.Minibag.removeProduct(product.sku, {
      onRemoved: function() {
        this.itemCounter--;
        this.removeAnimation(item, ops);
        document.fire('minibag:removeSuccess',ops);
        }.bind(this)
    });
  },

  showProduct: function(sku, args) {
    var ops = args || {};
    var product = this.products.find(function(product) { return product.sku==sku;});
    var url = product.href + '#' + (product.panel_id || 0) + '-' + product.displayGroupId + '-' + product.stylenumber + '-' + product.sku;
    
    
    var reference = url.split('#');
    if (reference[0].charAt(reference[0].length-1) != '/') {
      reference[0] += '/';
    }
    if (location.pathname.indexOf(reference[0]) != -1 || (location.pathname + '/').indexOf(reference[0]) != -1) {
      document.fire('shop:showProductFromDeepLink', {sku: reference[1]});
    //NOTE: there is maybe a weird encoded url-snipped in the location.pathname
    // so try to match it anyway.
    } else if(location.pathname.replace(/%2D/g, "-").indexOf(reference[0].replace(/%2D/g, "-")) != -1) {
      document.fire('shop:showProductFromDeepLink', {sku: reference[1]});
    } else {
      location.href = url;
    }    
  },

  addProduct: function(product, args) {
    var ops = args || {};
    gucci.Minibag.addProduct(product, {
      onSuccess: function () {
        this.itemCounter++;
        this.addAnimation(product);
        this.updateText();
        document.fire('minibag:addSuccess', ops);
      }.bind(this),
      onFailure: function () {
        document.fire('minibag:addFailure', ops);
      }.bind(this)
    });
  },

  addAnimation: function (product) {
    var item = this.buildItem(product);
    var container = product.status == 'backorder' ? this.waitlistProducts : this.minibagProducts;
    container.insert({'top': item});
    
    item.setStyle('top: 64px; width: 1px').show();

    new Effect.Morph(item, {
      style: 'width: 39px',
      duration: .5,
      afterFinish: function(fx) {
        fx.element.morph('top: 0px; opacity: 1')
          duration: 1.5
      }
    });
  },

  removeAnimation: function (item, option) {
    that = this;
    new Effect.Morph(item, {
      style: 'top: 64px; opacity: 0',
      duration: 1.5,
      afterFinish: function(fx) {
        fx.element.morph('width:1px', { 
          duration: .5,
          afterFinish: function() {
            item.remove();
            that.updateText();
          }
        });
      }
    });
  },

  buildItem: function(obj){
    return new Element('li', {
      className: 'product',
      rel: obj.sku,
      style: 'display: none'
    }).update(this.minibagTemplate.evaluate(obj));
  },
  
  build: function () {
    this.waitlistProducts.update();
    this.minibagProducts.update();
    
    this.updateText();
    this.products.each(function(product, idx) {
      var item = this.buildItem(product);
      
      // is it a waitlist item: 'wl'
      // or is it a minibag product 'mb' ?
      var shoppos=product.cookie.substring(0,2);
      var target = null;
      if (shoppos=='wl') {
        target = this.waitlistProducts.insert({top: item});
      } else {
        target = this.minibagProducts.insert({top: item});
      } 
    }.bind(this));
    $$('#minibag-products li').invoke('show');
    $$('#waitlist-products li').invoke('show');
  }
});

(function () {
  Event.observe(document, 'dom:loaded', function () {
    var mb=new Minibag($('minibag'));
  })
})();