Array.prototype.unique = function () {
    // Extend Array with a unique() method that returns just the distinct elements of the array
    var r = new Array();
    o:for(var i = 0, n = this.length; i < n; i++)
	{
	    for(var x = 0, y = r.length; x < y; x++)
		{
		    if(r[x]==this[i])
			{
			    continue o;
			}
		}
	    r[r.length] = this[i];
	}
    return r;
};

function ucfirst (str) {
    // http://kevin.vanzonneveld.net
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   bugfixed by: Onno Marsman
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // *     example 1: ucfirst('kevin van zonneveld');
    // *     returns 1: 'Kevin van zonneveld'
 
    str += '';
    var f = str.charAt(0).toUpperCase();
    return f + str.substr(1);
}

var PT = {
  valid_products: function(criteria,db) {
    // This function returns the range (min - max) of prices that may apply given the criteria
    var results = new Array()
    db.each(function(item){
      var good=1;
      for (var attr in criteria) {
          if (item[attr] != criteria[attr]) { good=0; }
      }
      if (good) {
          results.push(item);
      }
    });
    return results;
  },

  pricerange: function(criteria,db){
    var min=1000000;
    var max=0;
    var products = PT.valid_products(criteria,db);
    products.each(function(p){
      var pr = p['price']*1.0
      if (pr < min) min = pr;
      if (pr > max) max = pr;
    });
    if (min == 1000000 || max == 0) { return ''; }
    return (min<max) ? PT.price(min)+' - '+PT.price(max) : PT.price(min)
  },

  price: function(p) {
    // Format price with dollar sign, showing cents only when they are nonzero
    p = p.toString();
    if (p.indexOf('.') == p.length - 2)
      p += '0';
    return '$'+p;
  },

  alternatives: function(db,attr) {
    return $A(db).pluck(attr).unique();
  },

  vers: new Array(),

  pricetable: function() {
    PT.order = ['size','version','color'];
    PT.unique = new Array(); // Tells whether the row should be clickable
    var t = '';
    // <form id="pricetable_form" onSubmit="return PT.add_to_cart()">
    t += '<table class="pricetable"><tr><th width=281 align=left>Product</th><th width=30>Qty</th><th width=45>Price (each)</th><th width=120>&nbsp;</th></tr></table>';
    var sizes = PT.alternatives(db,PT.order[0]);
    var i=0;
    var nonzero_qty = 0;
    sizes.each(function(ver) {
      PT.vers[i] = ver;
      PT.unique[i] = 1;  // later reset to 0 if we render a pulldown
      var par = {};
      par[PT.order[0]] = ver;
      var products = PT.valid_products(par,db);
      t += '<form id="pricetable_form_'+i+'" onSubmit="return false;">';
      t += '<table class="pricetable">';
      t += '<tr>';
      // t += '<td onclick="PT.clicked_row('+i+');">'+products[0].sku+'</td>';
      t += '<td width=300>';
      t += ver+'<div class="choices">';
      var p1s = PT.alternatives(products,PT.order[1]);
      var p2s = PT.alternatives(products,PT.order[2]);
      var par = {};
      var sku = '';
      //if (p1s.length == 1 && p2s.length == 1) {
	  sku = products[0].sku;
      //}
      t += '<input type="hidden" name="sku_'+i+'" id="sku_'+i+'" value="'+sku+'">';  // Set this only when we have a real sku.
      if (p1s.length > 1) {
        t += '<select onchange="PT.used_pulldown(this)" name="p1_'+i+'" id="p1_'+i+'">';
	//	var prefix = (p2s.length > 1 ? 'First, choose' : 'Choose');
	//        t += '<option value="">'+prefix+' a '+PT.order[1]+'</option>';
        p1s.each(function(c){
          var d = c.gsub('"','&quot;').gsub('\'','\\\'');
	  t += '<option value="'+d+'">'+c;
        });
        t += '</select><br>';
	PT.unique[i] = 0;
      } else {
	  t += '<input type=hidden id="p1_'+i+'" name="p1_'+i+'" value="'+p1s[0]+'">';
	  // ucfirst(PT.order[1])+': '+
	  if (p1s[0]) { t += p1s[0]+'<br>'; }
      }
      t += '<div id="p2set_'+i+'">';
      if (p2s.length > 1) {
        t += '<select onchange="PT.used_pulldown(this)" name="p2_'+i+'" id="p2_'+i+'">';
	//	var prefix = (p1s.length > 1 ? 'Next, choose' : 'Choose');
	//        t += '<option value="">'+prefix+' a '+PT.order[2]+'</option>';
        p2s.each(function(s){
           var par = {};
	   par[PT.order[2]]=s;
           var pr = PT.pricerange(par,products);
	   // FIX: this won't work if s contains any single quotes.  Need to escape them somehow
           var d = s.gsub('"','&quot;').gsub('\'','\\\'');
           t += '<option value=\''+d+'\'>'+s+' - '+ pr;
        });
        t += '</select>';
	PT.unique[i] = 0;
      } else {
	  t += '<input type="hidden" id="p2_'+i+'" name="p2_'+i+'" value="'+p2s[0]+'">';
	  // ucfirst(PT.order[2])+': '+
	  if (p2s[0]) { t += p2s[0]; }
      }
      t += '</div>';
      v = (sizes.length > 1 ? 0 : 1);
      v = 1;
      if (v>0 && products.length<=1) { nonzero_qty = 1; }
      t += '</div></td><td class=qty width=30>';
      t += '<input type="text" onchange="PT.used_pulldown(this)" name="qty_'+i+'" id="qty_'+i+'" size="2" value="'+v+'">';

      var price_display = PT.pricerange({},products);
    var par = {};
    par[PT.order[0]] = PT.vers[i];
    par[PT.order[1]] = p1s[0];
    par[PT.order[2]] = p2s[0];
    price_display = PT.pricerange(par,products);

      t += '</td><td id="price_'+i+'" align="center" width=45>'+price_display+'</td>';
      t += '<td width=120><input id="add_to_cart_btn_'+i+'" type="image" title="Click here to add this product into your shopping cart" src="/images/add-to-cart.png" onclick="PT.add_to_cart('+i+')"></td>';
      t += '</tr>';
      t += '</table>';
      t += '</form>';
      i += 1;
    });
    t += '</table>';
    return t;
  },

  clicked_row: function(i) {
     // TODO: Only run this if the qty is currently one, or if there are no multi-choice pulldowns for this row
     if (parseInt($('qty_'+i).value) > 0 || PT.unique[i]) {
       $('qty_'+i).value = parseInt($('qty_'+i).value) + 1;
       PT.used_pulldown($('qty_'+i));
     }
  },

  add_to_cart: function(i) {
	//console.log('add_to_cart, i='+i);
    var params = $('pricetable_form_'+i).serialize(true);
    //console.log(params);
    new Ajax.Request('/ajax/add_to_cart',{
      method: 'GET',
      parameters: params,
      onSuccess: function(t) {
	if ($('cart_btn')) {
	  if (t.responseText != $('cart_btn').innerHTML) {
	     $('cart_btn').update(t.responseText);
	  }
	  // TODO: after add to cart, reset all qtys to 0 in case they want to buy something else
	}
      }
    });
    animate($('add_to_cart_btn_'+i),$('cart_btn'),{ style: "background: url(/images/add-to-cart.png)", fly: { afterFinish: function() { GH.show_cart() } }});
    return false;
  },

  update_p2_pulldown: function(i) {
    var par = {};
    par[PT.order[0]] = PT.vers[i];
    par[PT.order[1]] = $F('p1_'+i);
    var products;
    if (PT.vers[i]) {
      products = PT.valid_products(par,db);
    }  else {
      products = db;
    }
    var p1s = PT.alternatives(products,PT.order[1]);
    var p2s = PT.alternatives(products,PT.order[2]);
    var t = '';
    // Remember current state of pulldown, and re-select prior choice if it's available
    var oldstate = $F('p2_'+i);
    if (p2s.length > 1) {
	var prefix = (p1s.length > 1 ? 'Next, choose' : 'Choose');
        t += '<select onchange="PT.used_pulldown(this)" name="p2_'+i+'" id="p2_'+i+'"><option value="">'+prefix+' a '+PT.order[2]+'</option>';
        p2s.each(function(s){
	   var par = {};
	   par[PT.order[2]] = s;
           var pr = PT.pricerange(par,products);
           t += '<option value="'+s+'" '+(s==oldstate?'selected="1"':'')+'>'+s+' - '+pr;
        });
        t += '</select>';
    } else if (p2s[0]) {
        t += '<input type="hidden" id="p2_'+i+'" name="p2_'+i+'" value="'+p2s[0]+'">'+ucfirst(PT.order[2])+': '+p2s[0];
    } else {
	t += '<input type="hidden" id="p2_'+i+'" name="p2_'+i+'" value="">';
    }
    $('p2set_'+i).update(t);
  },

  hover_image: function(url,node,txt) {
     PT.stash_img = $('pimg').src;
     PT.stash_txt = $('pimg_txt').innerHTML;
     $('pimg').src = url;
     if ($(node)) { $(node).style.border = '1px solid green'; }
     if (txt) { $('pimg_txt').update(txt); }
  },

  revert_image: function(node) {
     if (PT.stash_img) {
       $('pimg').src = PT.stash_img;
     }
     if ($(node)) { $(node).style.border = ''; }
     $('pimg_txt').update(PT.stash_txt);
  },

  used_pulldown: function(s) {
    // user set s.name to $F(s)
    var i = 0;
    var name = '';
    var result = /^(.*)_(\d+)/.exec(s.name);
    if (result.length >= 2) { name = result[1]; i = result[2]; }
    if (!name) { return; }

    // Set quantity to 1 if user touches that pulldown
    if (name != 'qty' && $F('qty_'+i) == 0) {
        $('qty_'+i).setValue(1);
    }
    // Set available choices for p2 when user touches p1
    if (name == 'p1' && $('p2_'+i)) {
        PT.update_p2_pulldown(i);
    }
    // TODO: Set available choices for p1 if user touches p2.
    // TODO: Confirm that this all works even when there's no variety in p1 and/or p2

    // Update displayed price range shown on right
    var par = {};
    par[PT.order[0]] = PT.vers[i];
    par[PT.order[1]] = $F('p1_'+i);
    par[PT.order[2]] = $F('p2_'+i);
    $('price_'+i).update(PT.pricerange(par,db));
    // Update sku for product in hidden field, based on choices in pulldowns
    var products = PT.valid_products(par,db);
    if (products.length == 1 && $F('qty_'+i) && $F('qty_'+i) >= 1) {
        $('sku_'+i).setValue(products[0].sku);
    } else {
        $('sku_'+i).setValue('');
    }
    // If any product has a confirmed sku choice, and qty >= 1, then enable add to cart button
    // else disable
    var enabled = 0;
    for (var i=0;i<PT.vers.length;i++) {
        if ($F('sku_'+i)) enabled=1;
    }
    //    if (enabled) {
    //	$('add_to_cart_btn').enable();
    //	$('add_to_cart_btn').src = '/images/add-to-cart.png';
    //    } else {
    //	$('add_to_cart_btn').disable();
    //	$('add_to_cart_btn').src = '/images/add-to-cart-disabled.png';
    //    }
    // If the user reset both pulldowns for any product to their default choice, then reset quantity to 0
    for (var i=0; i<PT.vers.length; i++) {
        if ($F('p1_'+i)=='' && $F('p2_'+i)=='' && $F('qty_'+i) >= 1) {
            $('qty_'+i).setValue(0);
        }
    }

    // Update prod img if it's different
    var type = (name == 'p1' ? PT.order[1] : PT.order[2]);
    if (type == 'color') {
	var new_img = '';
	db.each(function(item){
		if (item['color'] == $F(s)) {
		    new_img = item['hi_img'];
		}
	});
	if ($('pimg').src != new_img && new_img) {
	    $('pimg').src = new_img;
	}
    }
  }
};
