/* 
  visit yourstore.com/shopify/api.html for demo and examples 
*/
if ((typeof Shopify) == 'undefined') {
  var Shopify = {};
}

/* 

override so that Shopify.formatMoney returns pretty 
money values instead of cents  

*/

Shopify.money_format = "$ {{amount}}";

/* 

Events (override!) 

Example override:
  ... add to your theme.liquid's script tag....

  Shopify.onItemAdded = function(line_item) {	    
    $('message').update('Added '+line_item.title + '...');	    
  }	  
*/	

Shopify.onError = function(data) {   
  if (data.message) {
    if (console) conosle.log(data.message + '(' + data.status  + '): ' + data.description);
  } else {
    if (console) conosle.log('Error: ' + Shopify.fullMessagesFromErrors(data).join('; ') + '.');
  }
},

Shopify.fullMessagesFromErrors = function(errors) {
  var fullMessages = [];
  if (console) console.log(errors);
  $H(errors).each(function(attribute_and_messages) {
    attribute_and_messages[1].each(function(message, index) {
      fullMessages.push(attribute_and_messages[0] + ' ' + message);
    });
  });
  return fullMessages;
}

Shopify.onCartUpdate = function(cart) {
  if (console) conosle.log("There are now "+ cart.item_count + " items in the cart.");    
},  

Shopify.onCartShippingRatesUpdate = function(rates, shipping_address) {
  var readable_address = '';
  if (shipping_address.zip) readable_address += shipping_address.zip + ', ';
  if (shipping_address.province) readable_address += shipping_address.province + ', ';
  readable_address += shipping_address.country
  if (console) conosle.log('There are '+ rates.length +' shipping rates available for '+ readable_address +', starting at '+ Shopify.formatMoney(rates[0].price) +'.');
},  

Shopify.onItemAdded = function(line_item) { 
  if (console) conosle.log(line_item.title + ' Was added to your shopping cart');
},

Shopify.onProduct = function(product) {
  if (console) conosle.log('Received everything we ever wanted to know about '+ product.title);
},

/* Tools */

Shopify.formatMoney = function(cents, format) {
  if (typeof cents == 'string') cents = cents.replace('.','');
  var value = '';
  var patt = /\{\{\s*(\w+)\s*\}\}/;
  var formatString = (format || this.money_format);

  function addCommas(moneyString) {
    return moneyString.replace(/(\d+)(\d{3}[\.,]?)/,'$1,$2');
  }

  switch(formatString.match(patt)[1]) {
  case 'amount':
    value = addCommas(floatToString(cents/100.0, 2));
    break;
  case 'amount_no_decimals':
    value = addCommas(floatToString(cents/100.0, 0));
    break;
  case 'amount_with_comma_separator':
    value = floatToString(cents/100.0, 2).replace(/\./, ',');
    break;
  case 'amount_no_decimals_with_comma_separator':
    value = addCommas(floatToString(cents/100.0, 0)).replace(/\./, ',');
    break;
  }
  return formatString.replace(patt, value);
},

Shopify.resizeImage = function(image, size) {
  try {
    if(size == 'original') { return image; }
    else {      
      var matches = image.match(/(.*\/[\w\-\_\.]+)\.(\w{2,4})/);
      return matches[1] + '_' + size + '.' + matches[2];
    }    
  } catch (e) { return image; }
},
/* API */
  
Shopify.addItem = function(variant_id, quantity, callback) {            
  var quantity = quantity || 1;
  new Ajax.Request("/cart/add.js", this.params('post', 'quantity='+quantity+'&id='+variant_id, callback || this.onItemAdded.bind(this)));
}, 

Shopify.addItemFromForm = function(form_id, callback) {        
  new Ajax.Request("/cart/add.js", this.params('post', Form.serialize(form_id), callback || this.onItemAdded.bind(this)));
},

Shopify.getCart = function(callback) {
  new Ajax.Request("/cart.js", this.params('get', null, (callback || this.onCartUpdate.bind(this))));
},  

Shopify.getCartShippingRatesForDestination = function(shipping_address, callback) {
  callback = (callback || this.onCartShippingRatesUpdate.bind(this));
  var shipping_address_params = {};
  $H(shipping_address).each(function(pair) {
    shipping_address_params['shipping_address['+pair[0]+']'] = pair[1]
  });
  var params = this.params('get', shipping_address_params, callback);
  params.onSuccess = function(t) {      
    var response = $(eval('(' +t.responseText+')'))
    try {  callback(response.shipping_rates, shipping_address);  }
    catch(e) { if (console) conosle.log("API Error: " + e + "\n\n"+t.responseText); };      
  }.bind(this);
  new Ajax.Request("/cart/shipping_rates.json", params);
},  

Shopify.getProduct = function(handle, callback) {
  new Ajax.Request("/products/"+handle+'.js', this.params('get', null, (callback || this.onProduct.bind(this))));
},  

Shopify.changeItem = function(variant_id, quantity) {            
  new Ajax.Request("/cart/change.js", this.params('post', 'quantity='+quantity+'&id='+variant_id, this.onCartUpdate.bind(this)));
},  

Shopify.removeItem = function(variant_id) {            
  new Ajax.Request("/cart/change.js", this.params('post', 'quantity=0&id='+variant_id, this.onCartUpdate.bind(this)));
},              


Shopify.clear = function() {            
  new Ajax.Request("/cart/clear.js", this.params('post', '', this.onCartUpdate.bind(this)));
},

Shopify.updateCart = function(updates, callback) {
  var query = '';

  if(updates.type == Array) {    
    $A(array).flatten().each(function(qty) { 
      query += ('updates[]=' + qty.toString()) + "&" ;
    }); 
  }
  else if (updates.type == Object) {
    $H(array).flatten().each(function(id, qty) { 
      query += ('updates['+id.toString()+']=' + qty.toString()) + "&" ;
    });       
  }
  else {
    throw "updates parameter must be array of quantities or a hash of {item_ids: quantities}"
  }

  new Ajax.Request("/cart/update.js", this.params('post', query, (callback || this.onCartUpdate.bind(this))));
},

Shopify.updateCartFromForm = function(form_id, callback) {
  new Ajax.Request("/cart/update.js", this.params('post', Form.serialize(form_id) , (callback || this.onCartUpdate.bind(this))));
}

/* private */

Shopify.params = function(method, parameters, callback) {       

  var hash = {
    method:       (method || 'post'),
    parameters:   (parameters || ''),
    evalScripts:  false,
    asynchronous: true,
    requestHeaders: { 
      'If-Modified-Since': "Sat, 1 Jan 2000 00:00:00 GMT"
    }
  };           


  if(callback == null){
    callback = this.onDebug.bind(this);
  }

  hash.onSuccess = function(t) {      
    try {  callback($(eval('(' +t.responseText+')')));  }
    catch(e) { if (console) conosle.log("API Error: " + e + "\n\n"+t.responseText); };      
  }.bind(this);

  hash.onFailure = function(t) {
    try {  this.onError($(eval('(' +t.responseText+')'))); }
    catch(e) { if (console) conosle.log("API Error: " + e + "\n\n"+t.responseText); };             
  }.bind(this);

  return hash;
}
  
function floatToString(numeric, decimals) {  
  var amount = numeric.toFixed(decimals).toString();  
  if(amount.match(/^\.\d+/)) {return "0"+amount; }
  else { return amount; }
}
  

