
var NAME_SORT     = 0;
var TYPE_SORT     = 1;
var TYPE_SELECT   = "";
var EXOTIC_SELECT = "";
var LOC_SELECT    = "";
var HAB_SELECT    = "";

var FAMILY_WIDTH = 125;
var GENUS_WIDTH  = 225;
var COMMON_WIDTH = 225;
var CODES_WIDTH  = 50;
var NOTES_WIDTH  = 250;

var TYPES = [ "T", "S", "V", "H", "G", "F", "M", "L", "U", "B", "A", "N", "P", "I", "W" ];
// >>>>>>>>>>>> Do search on CAN_SELECT_T as well!!! <<<<<<<<<<<<

// Did URL tell us to mark a line?
var MARK_LATIN = null;

// Is this the supermarket list?
var DO_USDA = 0;

// ----------------------------
//  Cookie stuff.
// ----------------------------

function get_cookie() {
    var cookie = find_cookie(FILENAME);
    if (cookie != null) {
        NAME_SORT     = parseInt(parse_cookie(cookie, "NAME_SORT"));
        TYPE_SORT     = parseInt(parse_cookie(cookie, "TYPE_SORT"));
        TYPE_SELECT   =          parse_cookie(cookie, "TYPE_SELECT");
        EXOTIC_SELECT =          parse_cookie(cookie, "EXOTIC_SELECT");
        LOC_SELECT    =          parse_cookie(cookie, "LOC_SELECT");
        HAB_SELECT    =          parse_cookie(cookie, "HAB_SELECT");
        if (TYPE_SELECT   == null) TYPE_SELECT   = "";
        if (EXOTIC_SELECT == null) EXOTIC_SELECT = "";
        if (LOC_SELECT    == null) LOC_SELECT    = "";
        if (HAB_SELECT    == null) HAB_SELECT    = "";
    }
}

function set_cookie() {
    var data =
        "NAME_SORT:"     + NAME_SORT   + "|" +
        "TYPE_SORT:"     + TYPE_SORT   + "|" +
        "TYPE_SELECT:"   + TYPE_SELECT + "|" +
        "LOC_SELECT:"    + LOC_SELECT  + "|" +
        "HAB_SELECT:"    + HAB_SELECT  + "|" +
        "EXOTIC_SELECT:" + EXOTIC_SELECT;
    document.cookie = FILENAME + "=" + escape(data);
}

// ----------------------------
//  URL stuff.
// ----------------------------

function parse_url() {
    // Tell it to do a particular select.  Any criteria not
    // explicitly given gets cleared -- ie. ignores cookie.
    var type   = get_parameter("type");
    var exotic = get_parameter("exotic");
    var loc    = get_parameter("loc");
    var hab    = get_parameter("hab");
    if (type   != null ||
        exotic != null ||
        loc    != null ||
        hab    != null) {
        TYPE_SELECT   = type   == null ? "" : type;
        EXOTIC_SELECT = exotic == null ? "" : exotic;
        LOC_SELECT    = loc    == null ? "" : loc;
        HAB_SELECT    = hab    == null ? "" : hab;
    }

    // Tell it to highlight a given entry in blood-red.
    MARK_LATIN = get_parameter("latin");
}

// ----------------------------
//  Write table.
// ----------------------------

var inited_wait = 0;
function write_table() {

    // Create the "please wait" popup.
    if (!inited_wait++) {
        write_popup("wait",
            '<table bgcolor="#808080" cellspacing=1 cellpadding=0><tr><td>' +
            '  <table bgcolor="#101010" cellspacing=0 cellpadding=5><tr><td>' +
            '    Please wait a moment.  This can take a really long time<br>' +
            '    on some browsers (like Internet Explorer).  I developed<br>' +
            '    it for Netscape / Mozilla.  Other browsers beware.<br>' +
            '  </table>' +
            '</table>'
        );
    }

    // Display "please wait" popup in the center of the window.
    var win = get_window_size();
    var pos = get_position("wait");
    var xoff = get_window_x_offset();
    var yoff = get_window_y_offset();
    show_popup("wait", Math.floor(xoff + win.w/2 - pos.w/2),
                       Math.floor(yoff + win.h/2 - pos.h/2));

    // Give browser time to display it.
    window.setTimeout(write_table_2, 100);
}
function write_table_2() {
    var found_mark = 0;
    var html = "";

    function fmt(label, callback, active) {
        return "<a onclick=\"" + callback + "\"><b class=" +
            (active ? "active" : "button") + "><u>" + label + "</u></b></a>";
    }

    function join(list, num) {
        var html = "";
        for (var i=0; i<num; i++) {
            if (i > 0)
                html += ", ";
            if (i == num-1 && i != 0)
                html += " or ";
            html += list[i];
        }
        return html;
    }

    var buttons = new Array(100);

    html += "<p><a name=div id=div>\n";
    html += "<table width=100% cols=3><tr>\n";
    html += "  <td align=left valign=top>\n";

    if (1) {
        html += "Sort by:</a>\n";
        var num = 0;
        buttons[num++] = fmt("family",      "set_name_sort(0)", NAME_SORT == 0);
        buttons[num++] = fmt("genus",       "set_name_sort(1)", NAME_SORT == 1);
        buttons[num++] = fmt("common name", "set_name_sort(2)", NAME_SORT == 2);
        if (CAN_DO_TYPES)
            buttons[num++] = fmt("type", "set_type_sort()", TYPE_SORT);
        html += join(buttons, num) + ".<br>\n";
    }

    if (CAN_DO_TYPES) {
        html += "Select:\n";
        var num = 0;
                          buttons[num++] = fmt("all",        "set_type_select('')",  TYPE_SELECT == "");
        if (CAN_SELECT_T) buttons[num++] = fmt("trees",      "set_type_select('T')", TYPE_SELECT == "T");
        if (CAN_SELECT_S) buttons[num++] = fmt("shrubs",     "set_type_select('S')", TYPE_SELECT == "S");
        if (CAN_SELECT_V) buttons[num++] = fmt("vines",      "set_type_select('V')", TYPE_SELECT == "V");
        if (CAN_SELECT_H) buttons[num++] = fmt("herbs",      "set_type_select('H')", TYPE_SELECT == "H");
        if (CAN_SELECT_G) buttons[num++] = fmt("grasses",    "set_type_select('G')", TYPE_SELECT == "G");
        if (CAN_SELECT_F) buttons[num++] = fmt("ferns",      "set_type_select('F')", TYPE_SELECT == "F");
        if (CAN_SELECT_M) buttons[num++] = fmt("mosses",     "set_type_select('M')", TYPE_SELECT == "M");
        if (CAN_SELECT_L) buttons[num++] = fmt("lichen",     "set_type_select('L')", TYPE_SELECT == "L");
        if (CAN_SELECT_U) buttons[num++] = fmt("fungi",      "set_type_select('U')", TYPE_SELECT == "U");
        if (CAN_SELECT_B) buttons[num++] = fmt("birds",      "set_type_select('B')", TYPE_SELECT == "B");
        if (CAN_SELECT_A) buttons[num++] = fmt("mammals",    "set_type_select('A')", TYPE_SELECT == "A");
        if (CAN_SELECT_N) buttons[num++] = fmt("amphibians", "set_type_select('N')", TYPE_SELECT == "N");
        if (CAN_SELECT_P) buttons[num++] = fmt("reptiles",   "set_type_select('P')", TYPE_SELECT == "P");
        if (CAN_SELECT_I) buttons[num++] = fmt("insects",    "set_type_select('I')", TYPE_SELECT == "I");
        if (CAN_SELECT_W) buttons[num++] = fmt("fish",       "set_type_select('W')", TYPE_SELECT == "W");
        html += join(buttons, num) + ".<br>\n";
    }

    if (CAN_DO_LOCS || CAN_DO_HABS) {
        html += "Select:\n";
        var num = 0;
        if (CAN_DO_LOCS)
            buttons[num++] =
                fmt( "locations", "do_loc_popup()\" name=\"loc\" id=\"loc", 1) +
                (LOC_SELECT == "" ? " (all)" : " (<i>"+LOC_SELECT+"</i>)");
        if (CAN_DO_HABS)
            buttons[num++] =
                fmt( "habitats", "do_hab_popup()\" name=\"hab\" id=\"hab", 1) +
                (HAB_SELECT == "" ? " (all)" : " (<i>"+HAB_SELECT+"</i>)");
        html += join(buttons, num) + ".<br>\n";
    }

    if (CAN_DO_EXOTICS) {
        html += "Select:\n";
        var num = 0;
                          buttons[num++] = fmt("all",      "clear_exotic_select()",  EXOTIC_SELECT == "");
        if (CAN_SELECT_e) buttons[num++] = fmt("endemics", "set_exotic_select('e')", EXOTIC_SELECT == "e");
        if (CAN_SELECT_l) buttons[num++] = fmt("locals",   "set_exotic_select('l')", EXOTIC_SELECT == "l");
        if (CAN_SELECT_x) buttons[num++] = fmt("exotics",  "set_exotic_select('x')", EXOTIC_SELECT == "x");
        html += join(buttons, num) + ".<br>\n";
    }

    // Print out location if a single location is selected.
    if (CAN_DO_LOCS && LOC_SELECT.match(/^[A-Z][a-z0-9]?$/)) {
        var name = location_name(LOC_SELECT);
        if (name == null) {
            alert("Location query ("+LOC_SELECT+") is unrecognized.\n");
        } else {
            html += "  <td width=50>\n";
            html += "  <td align=center>\n";
            html += "<big><u>Selected Location:</u></big><br>\n";
            html += "<font size=+3 color=\"#FF8040\"><b>" + name +
                    "</b></font>\n";
        }
    }
    html += "</table>\n";

    var width = FAMILY_WIDTH + GENUS_WIDTH + COMMON_WIDTH + CODES_WIDTH +
        NOTES_WIDTH;

    var ncols = 0;
    if (FAMILY_WIDTH > 0) ncols++;
    if (GENUS_WIDTH > 0)  ncols++;
    if (COMMON_WIDTH > 0) ncols++;
    if (CODES_WIDTH > 0)  ncols++;
    if (NOTES_WIDTH > 0)  ncols++;

    html += '<p><table align=center width=' + width + ' cols=' + ncols +
        ' border=0 cellspacing=1 cellpadding=1>';
    html += '  <tr bgcolor="#804020" align=center valign=top>';
    if (FAMILY_WIDTH > 0)
        html += '<th width=' + FAMILY_WIDTH + ' align=left><font color="#FFEEC0">Family</font>';
    if (GENUS_WIDTH > 0)
        html += '<th width=' + GENUS_WIDTH  + ' align=left><font color="#FFEEC0">Latin Name</font>';
    if (COMMON_WIDTH > 0)
        html += '<th width=' + COMMON_WIDTH + ' align=left><font color="#FFEEC0">Common Name</font>';
    if (CODES_WIDTH > 0)
        html += '<th width=' + CODES_WIDTH  + ' align=left><font color="#FFEEC0">Codes</font>';
    if (NOTES_WIDTH > 0)
        html += '<th width=' + NOTES_WIDTH  + ' align=left><font color="#FFEEC0">Notes</font>';

    var last_type = "";
    var j = 0;
    for (var i=0; i<TABLE_LEN; i++) {
        var row = TABLE_DATA[i];
        if (row[0]) {

            // Add break between types if sorting by type.
            var type = row[6].substr(0, 1);
            if (TYPE_SORT && type != last_type) {
                if (last_type != "")
                    html += "<tr height=5 bgcolor=black>";
                last_type = type;
            }

            // Only mark first matching line!
            var mark = !found_mark && MARK_LATIN != null &&
                MARK_LATIN == row[4] ? 1 : 0;
            if (mark) found_mark = 1;

            // Now draw table row.
            if (mark) {
                html += "<tr bgcolor=\"#600000\">";
            } else if ((j++ & 1) == 0) {
                html += "<tr bgcolor=\"#403000\">";
            } else {
                html += "<tr bgcolor=\"#504000\">";
            }
            html += "<td width=" + FAMILY_WIDTH + ">";
            if (row[1] < 0) {
                html += debar(row[3]);
            } else {
                var first_popup_col = POPUP_DATA[row[1]][3][0];
                html += "<a onMouseOver=\"enter(" + i + "," + row[1] +
                    ")\" name=x" + i + " id=x" + i + " href=\"../systematics/" +
                    FILE_STRINGS[ first_popup_col[1] ] + ".html?node=" +
                    LATIN_STRINGS[ first_popup_col[ first_popup_col[2] + 2 ] ] +
                    "\" class=treelink>" + debar(row[3]) + "</a>";
            }
            if (GENUS_WIDTH > 0)
                html += "<td width=" + GENUS_WIDTH  + ">" + row[4] +
                    (mark ? "<a name=mark id=mark>&nbsp;</a>" : "");
            if (COMMON_WIDTH > 0)
                html += "<td width=" + COMMON_WIDTH + ">" +
                    (DO_USDA && in_usda(row[4]) ?
    "<nobr><a href=\"../../nutrition/table.html?latin="+row[4]+"\">" +
    "<img src=\"../../graphics/emptybox.gif\" " +
    "onmouseover=do_box('nutbox"+i+"',1) " +
    "onmouseout=do_box('nutbox"+i+"',0) " +
    "name=nutbox"+i+" id=nutbox"+i+" " +
    "width=15 height=15 align=right hspace=5 border=0></a>" +
    row[5] + "</nobr>"
                        : row[5]);
            if (CODES_WIDTH > 0)
                html += "<td width=" + CODES_WIDTH  + ">" + row[6];
            if (NOTES_WIDTH > 0)
                html += "<td width=" + NOTES_WIDTH  + ">" +
                    (row[8] ?
    row[7] + " <nobr>(<a href=\"../notes/" +
    notes_file(row[3], row[4], row[8]) + ".html\">notes</a>)</nobr>"
                        : row[7]);
        }
    }

    html += "</table>";

    write_popup("table", html);
    warp_scrollbars();
    set_cookie();
    hide_popup("wait");
}

function notes_file(fam, name, flag) {
    if (flag == 1)
        return fam + "_" + name.replace(/ .*/, "");
    if (flag == 2)
        return fam + "_" + name.replace(/ /, "_").replace(/ .*/, "");
    if (flag == 3)
        return fam + "_" + name.replace(/ /, "_").replace(/ /, "_");
    return name;
}

// ----------------------------
//  Perform sorts.
// ----------------------------

function do_sort() {
    if (TYPE_SORT) {
        if (NAME_SORT == 0)
            TABLE_DATA.sort(sort1);
        if (NAME_SORT == 1)
            TABLE_DATA.sort(sort2);
        if (NAME_SORT == 2)
            TABLE_DATA.sort(sort3);
    } else {
        if (NAME_SORT == 0)
            TABLE_DATA.sort(sort4);
        if (NAME_SORT == 1)
            TABLE_DATA.sort(sort5);
        if (NAME_SORT == 2)
            TABLE_DATA.sort(sort6);
    }
}

// ----------------------------
//  Sorting routines.
// ----------------------------

function my_cmp(a, b) {
    return (a < b) ? 1 : (a > b) ? -1 : 0;
}

function sort1(a, b) {
    return (
        (a[2] < b[2]) ? -1 : (a[2] > b[2]) ? 1 :
        (a[3] < b[3]) ? -1 : (a[3] > b[3]) ? 1 :
        (a[4] < b[4]) ? -1 : (a[4] > b[4]) ? 1 :
        (a[5] < b[5]) ? -1 : (a[5] > b[5]) ? 1 : 0
    );
}

function sort2(a, b) {
    return (
        (a[2] < b[2]) ? -1 : (a[2] > b[2]) ? 1 :
        (a[4] < b[4]) ? -1 : (a[4] > b[4]) ? 1 :
        (a[5] < b[5]) ? -1 : (a[5] > b[5]) ? 1 : 0
    );
}

function sort3(a, b) {
    return (
        (a[2] < b[2]) ? -1 : (a[2] > b[2]) ? 1 :
        (a[5] < b[5]) ? -1 : (a[5] > b[5]) ? 1 : 0
    );
}

function sort4(a, b) {
    return (
        (a[3] < b[3]) ? -1 : (a[3] > b[3]) ? 1 :
        (a[4] < b[4]) ? -1 : (a[4] > b[4]) ? 1 :
        (a[5] < b[5]) ? -1 : (a[5] > b[5]) ? 1 : 0
    );
}

function sort5(a, b) {
    return (
        (a[4] < b[4]) ? -1 : (a[4] > b[4]) ? 1 :
        (a[5] < b[5]) ? -1 : (a[5] > b[5]) ? 1 : 0
    );
}

function sort6(a, b) {
    return (
        (a[5] < b[5]) ? -1 : (a[5] > b[5]) ? 1 : 0
    );
}

// ----------------------------
//  Perform selections.
// ----------------------------

function do_select() {
    for (var i=0; i<TABLE_LEN; i++) {
        if (TYPE_SELECT   != "" && TYPES[TABLE_DATA[i][2]] != TYPE_SELECT ||
            EXOTIC_SELECT == "e" && !(TABLE_DATA[i][6].match("e")) ||
            EXOTIC_SELECT == "x" && !(TABLE_DATA[i][6].match("x")) ||
            EXOTIC_SELECT == "l" && (TABLE_DATA[i][6].match("x")) ||
            LOC_SELECT != "" && !loc_select(TABLE_DATA[i][6]) ||
            HAB_SELECT != "" && !hab_select(TABLE_DATA[i][6]))
             TABLE_DATA[i][0] = 0;
        else TABLE_DATA[i][0] = 1;
    }
}

function loc_select(codes) {
    var locs = codes.replace(/^[^ ]* /, "");  // Remove plant type and exotic.
    locs = locs.replace(/ .*/, "");           // Remove any trailing codes.
    if (locs == "*") return 1;

    var pat = LOC_SELECT;
    while (pat != "") {
        var major = pat.charAt(0);
        var pat_minors = pat.replace(/^./, "").replace(/[A-Z].*/, "");
        pat = pat.replace(/^[A-Z][a-z0-9]*/, "");
        major = locs.indexOf(major);
        if (major >= 0) {
            if (pat_minors == "") return 1;
            var locs = locs.substr(major + 1, locs.length - major - 1).replace(/[A-Z].*/, "");
            if (locs == "*") return 1;
            while (pat_minors != "") {
                if (locs.indexOf(pat_minors.charAt(0)) >= 0) return 1;
                pat_minors = pat_minors.replace(/^./, "");
            }
        }
    }
    return 0;
}

function hab_select(codes) {
    var habs = codes.replace(/^[^ ]* /, "");  // Remove plant type and exotic.
    if (CAN_DO_LOCS) habs = habs.replace(/^[^ ]* /, "");  // ...and locations.
    habs = habs.replace(/ .*/, "");           // Remove and trailing codes (?)
    if (habs == "*") return 1;

    var uppers = habs.match(/^\*/) ? "*" :
        habs.replace(/[^A-Z]*/, "");
    var lowers = habs.match(/^[A-Z]*[A-Z\*\.]\*/) ? "*" :
        habs.replace(/^[A-Z]*[A-Z\*\.]/, "").replace(/[^a-z]*/, "");
    var digits = habs.match(/\*$/) ? "*" :
        habs.replace(/^[^0-9]*/, "");

    for (var i=0; i<HAB_SELECT.length; i++) {
        var c = HAB_SELECT.charAt(i);
        if (c.match(/[A-Z]/)) {
            if (uppers == "*" || uppers.indexOf(c) >= 0) return 1;
        } else if (c.match(/[a-z]/)) {
            if (lowers == "*" || lowers.indexOf(c) >= 0) return 1;
        } else if (c.match(/[0-9]/)) {
            if (digits == "*" || digits.indexOf(c) >= 0) return 1;
        }
    }
    return 0;
}

// -----------------------------------
//  Change sort / select selections.
// -----------------------------------

function set_name_sort(val) {
    NAME_SORT = val;
    do_sort();
    write_table();
}

function set_type_sort() {
    TYPE_SORT = TYPE_SORT ? 0 : 1;
    do_sort();
    write_table();
}

function set_type_select(val) {
    TYPE_SELECT = val;
    do_select();
    write_table();
}

function clear_exotic_select(val) {
    EXOTIC_SELECT = "";
    do_select();
    write_table();
}

function set_exotic_select(val) {
    EXOTIC_SELECT = val;
    do_select();
    write_table();
}

// --------------------------------------
//  Warp scrollbars to show marked row.
// --------------------------------------

function warp_scrollbars() {
    if (MARK_LATIN == null) return;

    // Only mark line once.
    MARK_LATIN = null;

    // Get size of window and current state of scrollbars.
    var win  = get_window_size();
    var xoff = get_window_x_offset();
    var yoff = get_window_y_offset();
    var warp = yoff;

    // Get position of highlighted line.
    var div  = get_position("div");
    var mark = get_position("mark");
    div.y = 0; // (I can never tell what positions are relative to.)

    // Get position of last backref -- bottom of page.
    var bot = get_position("bottom");

    // Window showing beyond end of document?
    if (yoff + win.h > bot.y + 25)
        warp = bot.y + 25 - win.h;

    // Is blood-red highlighted line off screen?
    if (yoff > div.y + mark.y  ||
        yoff + win.h < div.y + mark.y)
        warp = div.y + mark.y - Math.floor(win.h/2);

    //alert("win.h="+win.h+", yoff="+yoff+" div.y="+div.y+
    //  ", mark.y="+mark.y+", bot.y="+bot.y+", warp="+warp);

    // Warp window if necessary.
    if (warp < 0) warp = 0;
    if (warp != yoff)
        window.scrollTo(xoff, warp)
}

// ------------------------------------
//  Do "go" boxes (supermarket only).
// ------------------------------------

var BOX_ON;
var BOX_OFF;

function init_boxes() {
    BOX_ON  = new Image();
    BOX_OFF = new Image();
    BOX_ON.src  = "../../graphics/fullbox.gif";
    BOX_OFF.src = "../../graphics/emptybox.gif";
}

function do_box(t, s) {
    document[t].src = s ? BOX_ON.src : BOX_OFF.src;
}

// ----------------------------
//  Do "loc" popup menu.
// ----------------------------

var any_loc_changed = 0;

function do_loc_popup() {
    var html = "<center><nobr><a onclick=\"clear_loc_select()\">" +
        "<b>(Clear Selections)</b></a></nobr></center>\n" +
        "<hr width=75% size=1 color=\"#808080\">\n";
    for (var i=0; i<NUM_LOCS; i++) {
        var major = LOC_CODES[i][0];
        var major_pos = LOC_SELECT.indexOf(major);
        html += "<nobr><img src=\"../../graphics/" +
            (major_pos >= 0 ? "full" : "empty") + "box.gif\" " +
            "onclick=\"do_loc_major('"+major+"')\" " +
            "name=menubox"+i+" id=menubox"+i+" " +
            "align=left width=15 height=15 hspace=2 border=0>" +
            "<a onclick=\"do_loc_major('"+major+"')\">" +
            "&nbsp;&nbsp;<b><i>" + major + "</i></b> &nbsp; " +
            LOC_CODES[i][1] + "&nbsp;</a></nobr><br>\n";
        if (major_pos < 0 || LOC_CODES[i][2] == 0)
            continue;
        var minors =
            LOC_SELECT.substr(major_pos+1, LOC_SELECT.length-major_pos-1).
            replace(/[A-Z].*/, "");
        for (j=0; j<LOC_CODES[i][2]; j++) {
            var minor = LOC_CODES[i][3][j*2];
            var minor_pos = minors.indexOf(minor);
            html += "<nobr><img src=\"../../graphics/" +
                (minor_pos >= 0 ? "full" : "empty") + "box.gif\" " +
                "onclick=\"do_loc_minor('"+major+"','"+minor+"')\" " +
                "name=menubox"+i+"_"+j+" id=menubox"+i+"_"+j+" " +
                "align=left width=15 height=15 hspace=10 + border=0>" +
                "<a onclick=\"do_loc_minor('"+major+"','"+minor+"')\">" +
                "<b><i>" + minor + "</i></b> &nbsp; " +
                LOC_CODES[i][3][j*2+1] + "&nbsp;</a></nobr><br>\n";
        }
    }
    do_codes_popup("loc", html);
}

function do_loc_major(major) {
    var major_pos = LOC_SELECT.indexOf(major);
    if (major_pos < 0) {
        LOC_SELECT += major;
    } else {
        LOC_SELECT =
            LOC_SELECT.substr(0, major_pos) +
            LOC_SELECT.substr(major_pos+1, LOC_SELECT.length-major_pos-1).
                replace(/[0-9a-z]*/, "");
    }
    any_loc_changed++;
    do_loc_popup();
}

function do_loc_minor(major, minor) {
    var major_pos = LOC_SELECT.indexOf(major);
    if (major_pos < 0) {
        LOC_SELECT += major + minor;
    } else {
        var minors =
            LOC_SELECT.substr(major_pos+1, LOC_SELECT.length-major_pos-1).
                replace(/[A-Z].*/, "");
        var minor_pos = minors.indexOf(minor);
        if (minor_pos < 0) {
            minors += minor;
        } else {
            minors =
                minors.substr(0, minor_pos) +
                minors.substr(minor_pos+1, minors.length-minor_pos-1);
        }
        LOC_SELECT =
            LOC_SELECT.substr(0, major_pos) +
            major + minors +
            LOC_SELECT.substr(major_pos+1, LOC_SELECT.length-major_pos-1).
                replace(/[0-9a-z]*/, "");
    }
    any_loc_changed++;
    do_loc_popup();
}

function clear_loc_select() {
    if (LOC_SELECT != "") {
        LOC_SELECT = "";
        any_loc_changed++;
        do_loc_popup();
    }
}

function location_name(code) {
    var major = code.charAt(0);
    var list = null;
    var location = "";
    for (var i=0; i<NUM_LOCS; i++)
        if (LOC_CODES[i][0] == major)
            list = LOC_CODES[i];
    if (list == null)
        return null;
    if (code.length > 1) {
        var minor = code.charAt(1);
        for (var j=0; j<list[2]; j++)
            if (list[3][j*2] == minor)
                return list[3][j*2+1];
        return null;
    } else {
        return list[1];
    }
}

// ----------------------------
//  Do "hab" popup menu.
// ----------------------------

var any_hab_changed = 0;

function do_hab_popup() {
    var html = "<center><nobr><a onclick=\"clear_hab_select()\">" +
        "<b>(Clear Selections)</b></a></nobr></center>\n";

    var any_upper = 0;
    var any_lower = 0;
    var any_digit = 0;

    for (var i=0; i<NUM_HABS; i++) {
        var code = HAB_CODES[i][0];
        var box_on = HAB_SELECT.indexOf(code) < 0 ? 0 : 1;

        if (code.match(/[A-Z]/) && !any_upper++ ||
            code.match(/[a-z]/) && !any_lower++ ||
            code.match(/[0-9]/) && !any_digit++)
                html += "<hr width=75% size=1 color=\"#808080\">\n";

        html += "<nobr><img src=\"../../graphics/" +
            (box_on ? "full" : "empty") + "box.gif\" " +
            "onclick=\"do_hab_box('"+code+"')\" " +
            "name=menubox"+i+" id=menubox"+i+" " +
            "align=left width=15 height=15 hspace=2 border=0>" +
            "<a onclick=\"do_hab_box('"+code+"')\">" +
            "&nbsp;&nbsp;<b><i>" + code + "</i></b> &nbsp; " +
            HAB_CODES[i][1] + "&nbsp;</a></nobr><br>\n";
    }
    do_codes_popup("hab", html);
}

function do_hab_box(code) {
    var code_pos = HAB_SELECT.indexOf(code);
    if (code_pos < 0) {
        HAB_SELECT += code;
    } else {
        HAB_SELECT =
            HAB_SELECT.substr(0, code_pos) +
            HAB_SELECT.substr(code_pos+1, HAB_SELECT.length-code_pos-1);
    }
    any_hab_changed++;
    do_hab_popup();
}

function clear_hab_select() {
    if (HAB_SELECT != "") {
        HAB_SELECT = "";
        any_hab_changed++;
        do_hab_popup();
    }
}

// ----------------------------
//  Do popup menus.
// ----------------------------

var installed_codes_popup = 0;
var codes_popup_up;
var codes_popup_pos;

function do_codes_popup(kind, html) {
    if (!installed_codes_popup++) {
        install_onmousemove(leave_codes_popup);
        hide_popup("popup");
        codes_popup_up = 0;
    }

    html =
      "<table bgcolor=\"#808080\" cellspacing=1 cellpadding=0><tr><td>\n" +
      "  <table bgcolor=\"#101010\" cellspacing=0 cellpadding=5><tr><td>\n" +
           html +
      "  </table>\n" +
      "</table>\n";

    write_popup("popup", html);
    codes_popup_pos = get_position(kind);

    // Don't ask why, but gets Y coord wrong in IE.
    var top1 = get_position("table");
    var top2 = get_position("div");
    codes_popup_pos.y += top1.y - top2.y;

    var x = codes_popup_pos.x;
    var y = codes_popup_pos.y + codes_popup_pos.h;
    fit_popup("popup", x, y);
    codes_popup_up = 1;
    watch_mouse(leave_codes_popup, 1);
}

function leave_codes_popup(event, x, y) {
    if (codes_popup_up &&
        !is_near_box(
            codes_popup_pos.x,
            codes_popup_pos.y,
            codes_popup_pos.w,
            codes_popup_pos.h, 25
        ) && !is_near_popup("popup", 25)) {

        hide_popup("popup");
        codes_popup_up = 0;
        watch_mouse(leave_codes_popup, 0);

        if (any_loc_changed) {
            any_loc_changed = 0;
            do_select();
            write_table();
        }

        if (any_hab_changed) {
            any_hab_changed = 0;
            do_select();
            write_table();
        }
    }
}


