	function gatherPrices() {
	  
	  itemPrices = {};
    itemTotals = {};
    totalShipping = 0;
    totalUnits = 0;
    totalCost = 0;
    
    // loop through each product, and save to hash
	  jQuery("input[name*=quantity]").each(function(){	    
      name = getInt(this.name);
	    if (jQuery(this).nextAll("input[name*=type]").val() == "magnum") {
	      var parent = jQuery(this).nextAll("input[name*=parent]").val();
	      if (itemPrices[parent] == undefined) {
	        itemPrices[parent] = {};
	        itemTotals[parent] = {};
	      }
  	    itemPrices[parent][name] = {};
  	    itemTotals[parent][name] = {};
  	    
  	    itemPrices[parent][name]["bottle"] = parseFloat(jQuery(this).nextAll("input[name*=perbottle]").val());
  	    itemPrices[parent][name]["case"] = parseFloat(jQuery(this).nextAll("input[name*=percase]").val());
  	    itemPrices[parent][name]["casesize"] = parseFloat(jQuery(this).nextAll("input[name*=casesize]").val());
  	    itemPrices[parent][name]["target"] = jQuery(this).nextAll("input[name*=target]").val();
      } else {
  	    itemPrices[name] = {};
  	    itemTotals[name] = {};
  	    
  	    itemPrices[name]["bottle"] = parseFloat(jQuery(this).nextAll("input[name*=perbottle]").val());
  	    itemPrices[name]["case"] = parseFloat(jQuery(this).nextAll("input[name*=percase]").val());
  	    itemPrices[name]["casesize"] = parseFloat(jQuery(this).nextAll("input[name*=casesize]").val());
  	    itemPrices[name]["target"] = jQuery(this).nextAll("input[name*=target]").val();
	    }
	    update.apply(this);
	  });
	}
	
	function update(target) {
	  var item;
	  var parent = false;
	  // logic to see if this is direct or from key binding
	  if (this.id == undefined) {
	    item = target;
    } else {
      item = this;
    }
    
    var thisInt = getInt(item.name);
    
    var units;
    if (isNaN(parseInt(item.value)) && item.value != "") {
      jQuery(this).val(0);
      units = 0;
    } else if (item.value == "") {
      units = 0;
    } else {
      if (isNaN(item.value)) {
        jQuery(this).val(parseInt(item.value));
      }
      units = parseInt(item.value);
    }
    
    var thisPrices
    
    if (jQuery(item).nextAll("input[name*=type]").val() == "magnum") {
      parent = jQuery(item).nextAll("input[name*=parent]").val();
      thisPrices = itemPrices[parent][thisInt];
    } else {
      thisPrices = itemPrices[thisInt];
    }
    
    // calculations
    var cases = Math.floor(units / thisPrices["casesize"]);
    var bottles = units % thisPrices["casesize"];
    
    var result = (thisPrices["bottle"] * bottles) + (thisPrices["case"] * cases);
    var varietyTotal = 0;
    var itemTarget
    
    if (!parent) {
  	  itemTotals[thisInt]["cost"] = result;
  	  itemTotals[thisInt]["unit"] = units;
  	  varietyTotal = result;
  	  itemTarget = itemPrices[thisInt]["target"];
	  } else {
  	  itemTotals[parent][thisInt]["cost"] = result;
  	  itemTotals[parent][thisInt]["unit"] = units;
  	  for(var i in itemTotals[parent]) {
  	    varietyTotal += itemTotals[parent][i]["cost"];
  	  }
  	  itemTarget = itemPrices[parent][thisInt]["target"];
	  }
	  
	  jQuery("input#total_"+thisInt).val(formatCurrency(result));
	  jQuery("dd#"+itemTarget).text(formatCurrency(varietyTotal));
	  
	  total();
	}
	
	function total() {
	  totalCost = 0;
	  totalUnits = 0;
	  for(var i in itemTotals) {
	    if (itemTotals[i]["cost"] == undefined) {
	      for (var p in itemTotals[i]) {
  	      totalCost += itemTotals[i][p]["cost"];
  	      totalUnits += itemTotals[i][p]["unit"];
	      }
	    } else {
  	    totalCost += itemTotals[i]["cost"];
  	    totalUnits += itemTotals[i]["unit"];
	    }
    }
    
    // update shipping
    shipping();
    
    jQuery(".totals .bottles").text(totalUnits);
    jQuery("#total_products").val(totalUnits);
    jQuery(".totals .subtotal").text(formatCurrency(totalCost));
    jQuery("#total_subprice").val(formatCurrency(totalCost));
    
    totalCost += (totalShipping);
    jQuery(".totals dd.total").text(formatCurrency(totalCost));
    jQuery("#total_price").val(formatCurrency(totalCost));
	}
	
	function shipping() {
	  totalShipping = 0;
	  
	  if (totalUnits > 0) {
	    totalShipping = 15;
	  }
    jQuery(".totals .shipping").text(formatCurrency(totalShipping));
    jQuery("#total_shipping").val(formatCurrency(totalShipping));
	}
	
	function formatCurrency(amount) {
  	var i = parseFloat(amount);
  	if(isNaN(i)) { i = 0.00; }
  	var minus = '';
  	if(i < 0) { minus = '-'; }
  	i = Math.abs(i);
  	i = parseInt((i + .005) * 100);
  	i = i / 100;
  	s = new String(i);
  	if(s.indexOf('.') < 0) { s += '.00'; }
  	if(s.indexOf('.') == (s.length - 2)) { s += '0'; }
  	s = minus + "$" + s;
  	return s;
  }
  
  function getInt(string) {
	  return string.split('_',2)[1];
  }
  
  
  jQuery(document).ready( function () {
    if (jQuery("body#OrderPage").length > 0) {
      // bind the recalc function to the quantity fields
      jQuery("input[name*=quantity]").bind("keyup", update);
  		
  		// get all the prices and put them in a nice hash
  		gatherPrices();
  	}
  });
