
Array.prototype.intersect = function( setB ) {
   var setA = this;
   var setA_seen = {};
   var setB_seen = {};
   for (var i = 0; i < setB.length; i++)
       setB_seen[setB[i]] = true;
   var intersection = [];
   for (i = 0; i < setA.length; i++)
       if (!setA_seen[setA[i]]) {
           setA_seen[setA[i]] = true;
           if (setB_seen[setA[i]])
               intersection.push(setA[i]);
       }
   return intersection;
};

var dependors = {};

function get_dependor (is) {
    var d = dependors[is];
    if (!d)
      d = dependors[is] = { elems: [], hooks: [] };
    return d;
}

function register_dependor (id, is) {
    var p = get_dependor(is);
    p.elems.push($("#" + id));
    function on_change () {
        var v = jQuery.map(p.elems, function (x) { return $(x).val(); });
        jQuery.each(p.hooks, function () { this(v); });
    }
    $("#" + id).change(on_change).change();
}

function register_dependent (id, is, options) {
    var e = $("#" + id);
    function helper (v) {
        var opts = options[v[0]];
        if (opts) {
            for (var i = 1; i < v.length; ++i)
                if (options[v[i]])
                    opts = opts.intersect(options[v[i]]);
                else {
                    opts = undefined;
                    break;
                }
        }
        var oldsel = e.val();
        e.empty();
        if (!opts) {
            if (v.length > 1)
                e.append($("<option value = ''>").text("(Choose all " + is + "s to see options)"));
            else
                e.append($("<option value = ''>").text("(Choose a " + is + " to see options)"));
        } else {
            e.append("<option value=''>(Please Choose)</option>");
            jQuery.each(opts,
                        function () {
                            var txt = "" + this;
                            var e2 = $("<option>").text(txt);
                            e.append(e2);
                        });
        }
        e.append("<option>(Unsure)</option>");
        e.val(oldsel);
    }
    get_dependor(is).hooks.push(helper);
}

