/**
 * @depends prototype.js
 * @depends cookie.js
 */
 
if (!gucci) var gucci = {};

/*
Class: Minibag
  
Note:
  static class
*/
gucci.Minibag = {
  /*
  Property: initialize
    initializes minibag from cookies
    
  Arguments:
    options - optional, should be an object which can contain an <onInitialized> callback function
  */
  initialize: function(options) {
    options = Object.extend({
      onInitialized: Prototype.emptyFunction
    }, options || {});
    
    this.idle = false;
    this.cookies = {};
    
    //Shopping bag/Minibag
    var id = 1;
    var cookieData = null;    
    while ( cookieData = Cookie.get('mb'+id) ) {
      this.cookies['mb'+id] = cookieData;
      id++;
    }
    //Waitlist
    id = 1;
    while ( cookieData = Cookie.get('wl'+id) ) {
      this.cookies['wl'+id] = cookieData;
      id++;
    }
    
    var productData = Object.keys(this.cookies).map(function(key) {
      var product = decodeURIComponent(this.cookies[key]).split('|');
      var data = {
        stylenumber:    product[0],
        href:           product[1],
        miniThumb:      product[2],
        sku:            product[3],
        price:          product[4],
        displayGroupId: product[5],
        panel_id:       product[6], 
        cookie:         key
      };
      return data;
    }.bind(this));
    
    this.products = productData;
    options.onInitialized();
    this.idle = true;
  },
  
  /*
  Property: addProduct
    Sends a request containing all necessary product information to add a product to the bag.
    The response sets a cookie containing the product information which is needed for the minibag.
  */
  addProduct: function(sku, callbacks) {
    this.idle = false;

    var product = sku._parent;
    var displayGroup = product._parent;
    var panel = displayGroup._parent;
    var requestParams = {

      //HACK blabla || "" is to force the ajax request to make post requests like
      //this: ...&sale=&status=backorder&size=12... instead of
      //that: ...&sale&status=backorder&size=12... (that makes troubles on server side asp)

      //NOTE new params
      panel_id: panel.panel_id || "",
      displayGroup_id: displayGroup.displayGroup_id || "",
      style_number: product.style_number || "",
      
      //NOTE old params
      path: displayGroup.path || "",
      productLink: displayGroup.link_id || "",
      
      imageLink: product.images.thumb || "",
      miniThumbLink: product.images.miniThumb || "",
      shown: product.images.miniThumb ? 1 : 0,
      fullImageLink: product.images.full || "",
      description: product.text.grpdesc || "",
      variationDescription: product.text.vardesc || "",
      price: product.priceNum || "",
      style: product.formatStyleNumber(' ') || "",
      collection: product.collection || "",
      department: product.department || "",
      
      sale: product.priceSale || "",
      status: sku.status || "",
      sku: sku.sku || "",
      size: sku.sizename || ""
    };

    //NOTE URL
    new Ajax.Request('/' + Cookie.get('site') + '/mini_bag.asp', {
      parameters: requestParams,
      onComplete: function(res) {
        gucci.Minibag.idle = true;
        if (Object.isFunction(callbacks.onSuccess) && res.responseText.indexOf('true') == 0) {
          callbacks.onSuccess(callbacks.args, sku);
        } else if (Object.isFunction(callbacks.onFailure)) {
          callbacks.onFailure(callbacks.args, sku);
        }
      }
    });
  },
  
  /*
  Property: removeProduct
    sends a request containing a sku to the server, if the request successes the cookie
    corresponding to the product with the specific sku gets removed
    
  Arguments:
    sku - a number which describes the product to remove
    options - optional, should be an object containing an <onRemoved> function
  */
  removeProduct: function(sku, options) {
    this.idle = false;
    
    options = Object.extend({
      onRemoved: Prototype.emptyFunction
    }, options || {});
    
    //URL
    new Ajax.Request('/' + Cookie.get('site') + '/checkout/remove_item.asp', {
      parameters: { sku: sku },
      onSuccess: function() {
        options.onRemoved();
        gucci.Minibag.idle = true;
      }
    });
  },
  
  /*
  Property: startSync
    calls a <sync> function periodically, default interval is set to 600sec
    
  Arguments:
    options - optional, should be an object which can contain an <onSyncComplete> callback and an <interval> in sec
  */
  startSync: function(options) {
    options = Object.extend({
      onSyncComplete: Prototype.emptyFunction,
      interval: 30
    }, options || {});
    
    if (this.pe) {
      this.pe.stop();
      this.pe = null;
    }
    this.pe = new PeriodicalExecuter(this.checkSync.curry(options.onSyncComplete), options.interval);
  },
  
  checkSync: function(onSyncComplete) {
    var timestamp = Cookie.get('shoppingbag_sync_timestamp');
    var now = new Date();
    now = now.getTime();
    //NOTE: don't know why but sometimes the cookie value is 'undefined' (as string)
    if (!timestamp || timestamp == 'undefined') {
      Cookie.set('shoppingbag_sync_timestamp', now);
      return;
    }
    var updateInterval = 20 * 60 * 1000; //20 minutes
    if ((now - timestamp) > updateInterval) { //if 20 minutes are over
      gucci.Minibag.sync(function() {
        onSyncComplete();
        Cookie.set('shoppingbag_sync_timestamp', now);
      });
    }
  },
  
  /*
  Property: sync
    requests the serverside content of the shopping bag periodically,
    unsets all minibag specific cookies, the response sets the cookies corresponding to the
    content of the shopping bag, calls <Minibag.initialize> to reinitialize the minibag with the new cookies
    
  Arguments:
    onSyncComplete - a callback function
  */
  sync: function(onSyncComplete) {
    if (gucci.Minibag.idle) {
      new Ajax.Request('/' + Cookie.get('site') + '/mini_bag_sync.asp', {
        onSuccess: function() {
          gucci.Minibag.initialize();
          onSyncComplete();
        }
      });
    }
  },
  
  /*
  Property: unsetAllProductCookies
    tosses all minibag specific cookies which were first set by <Minibag.initialize>
  */
  unsetAllProductCookies: function() {
    //FIXME deleteme soon! "bad" method (no cookie manipulation on client side!, servers data!)
    Object.keys(this.cookies).each(function(key) {
      Cookie.unset(key);
    });
  },
  
  /*
  Property: getProducts
    returns all Products which are currently in the minibag
    
  Returns:
    products - an array of all products currently in the minibag
  */
  getProducts: function() {
    return this.products;
  },
  
  /*
  Property: setProducts
    sets/overrides all products currently in the minibag
    
  Arguments:
    products - an array of products
  */
  setProducts: function(products) {
    this.products = products;
  }
  
};



// startup code ...

(function () {
   Event.observe(document, 'dom:loaded', function() {
    if ($('minibag-container') && (!$('waitlist-products')))
      new Insertion.Bottom($('minibag-container'), new Element('div', { id: 'waitlist-products' }));
  
   if (typeof(Shop)!='undefined')
     Shop.initializeMinibag();
  
    //TODO drop this before launch
    //sync minibag every time the site refreshs.
    if ($('ann1')) 
      $('waitlist-products').hide();
    });
})();
