// This module expects to find two global variables:
//   Styles: An ordered array of product styles (e.g.: color, size...);
//   InStock: An n-dimensional associative array of skus, where n is the length
//            of the Styles array, above, the columns are represented by the categories
//            named in Styles, in that order, and the keys are attribute values
//            (e.g.: InStock['blue']['large'][...]

// This module expects to find a number of select elements equal to the number of
// elements in the Styles array. Each element will have names and ids of "tag"
// concatenated with one of the elements of the Styles array.

// The options array of each of the style elements will contain the allowable keys
// for the InStock associative array.

if (!(typeof(addEvent)=='function')) {
  function addEvent(name,obj,f) {
    if (window.attachEvent) {
      obj.attachEvent("on"+name,f);
    } else if (window.addEventListener) {
      obj.addEventListener(name,f,false);
    }
  }
}

addEvent('load',window,function() {
  var attrib=new Object();

  // INIT
  //   Build an "attrib" structure keyed by each element of Styles, containing an array of keys,
  //   and the element to which they all belong.
  for (var i=0;i<Styles.length;i++) {
    var el=document.getElementById('tag'+Styles[i]);
    attrib[Styles[i]]=new Object();
    attrib[Styles[i]].el=el;
    attrib[Styles[i]].keys=new Array();
    for (var j=0;j<el.options.length;j++) {
      attrib[Styles[i]].keys.push(el.options[j].value);
    }

    // doChange
    //   Fires on each select element whenever it changes. Enables/Disables elements in OTHER
    //   selects based on whether an item is available, given ALL the SELECTED attributes.
    var doChange = function(e) {
      // "el" is the element that changed.
      var el;
      if (!e) var e = window.event;
      if (e.target) el = e.target;
      else if (e.srcElement) el = e.srcElement;
      if (el.nodeType == 3) // defeat Safari bug
        el = el.parentNode;

      // "mycolumn" is the name of the Style of the element that changed, hidden in the id.
      // var mycolumn=el.id.substr(3);

      // Get the current value of all selectors. Set the "current" value to that value.
      for (var i=0;i<Styles.length;i++) {
        attrib[Styles[i]].current=attrib[Styles[i]].el.options[attrib[Styles[i]].el.selectedIndex].value;
      }

      // For each selector, loop through all values, holding constant the current values of all
      // other selectors, and test whether the combination is available.

      // If so, activate the value. If not, deactivate it.
      for (i=0;i<Styles.length;i++) {
        // if (Styles[i]==mycolumn) continue;
        for (var k=0;k<attrib[Styles[i]].keys.length;k++) {
          var s="";
          for (var j=0;j<i;j++) {
            s=s+"['"+attrib[Styles[j]].current+"']";
          }
          s=s+"['"+attrib[Styles[i]].keys[k]+"']";
          for (var j=i+1;j<Styles.length;j++) {
            s=s+"['"+attrib[Styles[j]].current+"']";
          }

          // At this point, s is a string that looks like a set of n subscripts. Try to evaluate
          // 'InStock'+s. If it evaluates to a string, this would be the sku, and therefore the
          // product is available. It will either throw an error or evaluate to 'undefined' otherwise.

          // Enable or disable the option in question, as appropriate.
          try {
            var isInStock=typeof(eval('InStock'+s));
            if (isInStock=='undefined') throw 'out of stock';
            attrib[Styles[i]].el.options[k].disabled=false;
          } catch(er) {
            attrib[Styles[i]].el.options[k].disabled=true;
          }
        }
      }
    };
    addEvent('change',el,doChange);
  }

  // Trigger a change event programmatically to get the ball rolling.
  if (attrib[Styles[0]]) {
    doChange({"target":attrib[Styles[0]].el});
  }
});