// Some basic utility functions and object enhancements
    function $(id) {
        return document.getElementById(id);
    }
    String.prototype.trim = function () {
        return this.replace(/^\s*(.*?)\s*$/, '$1');
    };
    function select_all(id) {
        var obj = $('search-'+id);
        obj.focus();
    // Gecko
        if (obj.setSelectionRange) {
            obj.setSelectionRange(0,obj.value.length);
        }
    // IE
        else if (obj.createTextRange) {
            var r = obj.createTextRange();
            r.moveStart('character', 0);
            r.moveEnd('character', obj.value.length);
            r.select();
        }
    }

// Utility specific to this website
    function cleanup_search_fields() {
        if ($('search-where').value.length > 0)
            $('search-where').value = $('search-where').value.trim();
        if ($('search-name').value.length > 0)
            $('search-name').value = $('search-name').value.trim();
        if ($('search-category').value.length > 0)
            $('search-category').value = $('search-category').value.trim();
    }

// Search-field functions
    function validate_searchform() {
        cleanup_search_fields();
        var name     = $('search-name');
        var cat      = $('search-category');
        if (name.value.length < 1 && cat.value.length < 1) {
            alert("Please search for something.");
            cat.focus();
            return false;
        }
        else if ($('search-where').value.length < 1) {
            alert("Please provide a location to search.");
            $('search-where').focus();
            return false;
        }
        return true;
    }
    function update_search_tabindex(elem) {
        var cat   = $('search-category');
        var name  = $('search-name');
        var where = $('search-where');
        if (elem == cat) {
            if (cat.value.length > 0) {
                name.tabIndex  = 1;
                cat.tabIndex   = 2;
            }
            else {
                name.tabIndex  = 2;
                cat.tabIndex   = 1;
            }
            where.tabIndex = 3;
        }
        else if (elem == name) {
            if (name.value.length > 0) {
                name.tabIndex  = 2;
                cat.tabIndex   = 1;
            }
            else {
                name.tabIndex  = 1;
                cat.tabIndex   = 2;
            }
            where.tabIndex = 3;
        }
        else if (elem == where) {
            where.tabIndex = 2;
            if (name.value.length > 0) {
                cat.tabIndex   = 1;
                name.tabIndex  = 3;
            }
            else {
                cat.tabIndex   = 3;
                name.tabIndex  = 1;
            }
        }
    }
    function handle_search_keypress(elem, evt) {
        if (!evt || !elem)
            return;
        if (evt.type != 'keypress')
            return;
        // Get the key code
        var unicode = evt.keyCode? evt.keyCode : evt.charCode;
        var key = String.fromCharCode(unicode);
        // Get shorter references to the form fields we'll be working with
        var cat   = $('search-category');
        var name  = $('search-name');
        var where = $('search-where');
        // Tab character should switch between form fields.  This only triggers
        // in FF, and is present because sometimes the browser seems to just
        // ignore the tabIndex values.
        if (key == "\t") {
            cleanup_search_fields();
            // Which field triggered the event?
            if (elem == cat) {
                if (cat.value.length > 0)
                    setTimeout('select_all("where")', 50);
                else
                    setTimeout('select_all("name")', 50);
            }
            else if (elem == name) {
                if (name.value.length > 0)
                    setTimeout('select_all("where")', 50);
                else
                    setTimeout('select_all("category")', 50);
            }
            else if (elem == where) {
                if (name.value.length > 0)
                    setTimeout('select_all("name")', 50);
                else
                    setTimeout('select_all("category")', 50);
            }
        }
        // Some sort of visible character means we should clear out alternate
        // search fields, if necessary.  Due to browser weirdness, the
        // character that triggered this event is not always present in the
        // field's value yet, so we need to add a small delay.
        else if (key.match(/[^\n\t]/)) {
            setTimeout('keypress_postprocess($("'+elem.id+'"))', 50);
        }
    }
    function keypress_postprocess(elem) {
        // Get shorter references to the form fields we'll be working with
        var cat   = $('search-category');
        var name  = $('search-name');
        // Process
        if (elem == cat) {
            if (name.value.length > 0) {
                name.value = "";
            }
        }
        else if (elem == name) {
            if (cat.value.length > 0) {
                cat.value = "";
            }
        }
        update_search_tabindex(elem);
    }


