var _cbc_registry = new Object();
var _cbc_all_keys = new Array();
var _cbc_master_elements = new Object();

function getCityElementToModify(form_name, element_id) {
    var cur_form = document.forms[form_name];
    if (typeof(cur_form)=="undefined") { alert("The form "+form_name+" could not be found in the document."); return;}
    var slave_field = cur_form[element_id];
    if (typeof(slave_field)=="undefined") { alert("Slave field "+element_id+" could not be found in the form "+form_name); return;}
    return slave_field;
}

function modifyCityField(responseText, cur_sel) {
    switch (cur_sel['action']) {
    case "search_vocabulary":
    case "vocabulary":
        modifyList(responseText, cur_sel);
        break;
    case "value":
        modifyCityValue(responseText, cur_sel);
        break;
    default:
        //should not get here
    }
}

function modifyCityValue(responseText, cur_sel) {
    var cur_elem = getCityElementToModify(cur_sel["form"], cur_sel["slave"]);
    cur_elem.value = responseText
    //Handle select boxes in all browsers
    if (cur_elem.options) {
        for (var i=0; i < cur_elem.options.length; i++) {
            if (cur_elem.options[i].value == responseText) {
                cur_elem.selectedIndex = i
            }
        }
    }
    //pass a bogus event and the real element
    changeCityOnSelect('',cur_elem);
    if (cur_elem.onchange) cur_elem.onchange();
}


function modifyList(list_text, cur_sel) {
    var cur_elem = getCityElementToModify(cur_sel["form"], cur_sel["slave"]);
    var options_array = list_text.split('|');
    var options_length = options_array.length;
    options_array[0] = options_array[0].replace("<div>","").replace(/^\s*<div>\s*/, "");
    options_array[options_length-1] = options_array[options_length-1].replace(/\s*<\/div>\s*$/, "");
    cur_elem.options.length = 0;
    for (var j=0; j < options_length; j++) {
        var desc_name = options_array[j].split('^');
        var newOpt = new Option(desc_name[0],desc_name[1],false,false);
        newOpt.selected = false;
        newOpt.defaultSelected = false;
        cur_elem.options[cur_elem.options.length] = newOpt;
    }
    //pass a bogus event and the real element
    changeCityOnSelect('',cur_elem);
    if (cur_elem.onchange) cur_elem.onchange();
}

function getNewCities(selectInput, cur_key) {
    var cur_sel = _cbc_registry[cur_key];
    var url = cur_sel["url"];
    if (cur_sel["last_val"] != selectInput.value) {
        cur_sel["last_val"] = selectInput.value;
        var result = cur_sel["_cache"][selectInput.value];
        if (typeof(result)!="undefined") {
            modifyCityField(result,cur_sel);
            return;
        }
        var change_func = new Function('selectProcessRequestChange("'+cur_key+'","'+selectInput.value+'");')
        var selectRequest = cur_sel["_request"]
        // abort any earlier requests on this same key
        if (selectRequest.readyState != 0) selectRequest.abort();
        selectRequest.onreadystatechange = change_func;
        selectRequest.open("GET", url + selectInput.value, true );
        selectRequest.send(null);
    }
}

function selectProcessRequestChange(cur_key, selectValue) {
    var cur_sel = _cbc_registry[cur_key];
    var selectRequest = cur_sel["_request"];
    if (selectRequest.readyState==4) {
        if (selectRequest.status==200) {
            if (typeof(cur_sel)!="undefined") {
                modifyCityField(selectRequest.responseText, cur_sel);
                cur_sel["_cache"][selectValue] = selectRequest.responseText;
            }
        } else {
            alert("Problem retrieving XML data from url "+cur_sel["url"]+selectValue)
        }
    }
}

function changeCityOnSelect(ev, master_element) {
    if (! master_element) {
        if (ev.target) var master_element = ev.target;
        else if (ev.srcElement) var master_element = ev.srcElement;
        else var master_element = this;
    }
    var selectInput = master_element;
    var form_name = master_element.form.name;
    var master_key = form_name+'|'+selectInput.id;
    var key_list = _cbc_master_elements[master_key];
    if (typeof(key_list)!="undefined") {
        for (var i=0; i < key_list.length; i++) {
            var cur_key = key_list[i];
            var cur_sel = _cbc_registry[cur_key];
            if (typeof(cur_sel)!="undefined") {
                var element_id = cur_sel["slave"];
                switch (cur_sel["action"]) {
                    case "search_vocabulary":
                    case "vocabulary":
                    case "value":
                        var cur_elem = getCityElementToModify(form_name, element_id);
                        //Change slave vocabulary
                        getNewCities(selectInput, cur_key);
                        break;
                    default:
                        break;
                }
            }
        }
    }
}

function inArray(list, value) {
    for (var i=0; i < list.length; i++) {
        if (list[i] == value) return true;
    }
    return false;
}

function registerCitySelect(form_name, master_id, slave_id, action, base_url, null_str) {
    var url;
    switch (action) {
    case "value":
        url = 'getXMLSlaveValue?value=';
        break;
    case "vocabulary":
    case "search_vocabulary":
        url = 'getXMLCitiesVocab?null_str='+null_str+'&value=';
        break;
    default:
        // should not happen
        alert("registerCitySelect: invalid action " + action);
    }
    if (base_url) 
        url = base_url + '/' + url;
    var select_desc = new Object();
    var key = form_name+'|'+master_id+'|'+slave_id+'|vocabulary'
    var master_key = form_name+'|'+master_id;
    select_desc["form"] = form_name;
    select_desc["master"] = master_id;
    select_desc["slave"] = slave_id;
    select_desc["action"] = action;
    select_desc["url"] = url;
    select_desc["last_val"] = "";
    select_desc["_cache"] = new Object();
    select_desc["_request"] = new XMLHttpRequest();
    _cbc_registry[key] = select_desc;
    var all_children = _cbc_master_elements[form_name+'|'+master_id];
    if (typeof(all_children)=="undefined") all_children = new Array();
    all_children.push(key);
    _cbc_master_elements[master_key] = all_children;
    _cbc_all_keys.push(master_key);
}

function citySelectInit() {
    for (var i=0; i < _cbc_all_keys.length; i++) {
        var key_list = _cbc_master_elements[_cbc_all_keys[i]];
        //just get the first one for a given master.
        var cur_sel = _cbc_registry[key_list[0]];
        var master = getCityElementToModify(cur_sel["form"],cur_sel["master"]);
        if (master.addEventListener) {
            master.addEventListener('change', changeCityOnSelect, false);
        } else if (master.attachEvent) {
            master.attachEvent('onchange', changeCityOnSelect);
        }
    }
}

if (window.addEventListener) window.addEventListener("load", citySelectInit,false);
else if (window.attachEvent) window.attachEvent("onload", citySelectInit);
