/*
// Must be defined elsewhere; contains trailing '/'.
var rootUrl;

// Must be defined elsewhere if 'i' flag is used.
function cityChooser_choiceCallback(idprefix) {}
*/

// Internal.
var cityChooser_requestIds = {};  // assoc.array (idprefix => cities requestId).

function cityChooser_enable(idprefix, en) {
	var cc = cityChooser_controls(idprefix);
	var stateid = cc.stateid.value * 1;
	var cityid = cc.cityid.value * 1;
	cc.stateid.disabled = !en;
	if (cc.statename) {
		cc.statename.disabled = !en || stateid != 1;
	}
	cc.cityid.disabled = !en || stateid <= 0;
	if (cc.cityname) {
		cc.cityname.disabled = !en || cityid != -1;
	}
}

function cityChooser_controls(idprefix) {
	return {stateid: dimGet(idprefix + 'stateid'),
			cityid: dimGet(idprefix + 'cityid'),
			statename: dimGet(idprefix + 'statename'),
			cityname: dimGet(idprefix + 'cityname')};
}

// Internal, <select name="stateid" onchange="..."/> handler.
function cityChooser_stateChange(idprefix, flags) {
	var cc = cityChooser_controls(idprefix);
	var stateid = cc.stateid.value * 1;
	if (stateid == 0 || stateid < -1) {  // "choose state" or any user-defined special value
		dimSetSelectValue(cc.cityid, 0);  // "choose city"
		cc.cityid.disabled = true;
		if (cc.statename) {
			cc.statename.disabled = true;
		}
		if (cc.cityname) {
			cc.cityname.disabled = true;
		}
		return;
	}
	if (stateid > 0) {  // real state
		// TODO This won't work I guess
		cc.cityid.options.length = 0;
		cc.cityid.options.add(new Option('Loading...', 0, true, false));
		cc.cityid.disabled = true;
		if (cc.statename) {
			cc.statename.disabled = true;
		}
		if (cc.cityname) {
			cc.cityname.disabled = true;
		}
		
		if (cityChooser_requestIds[idprefix]) {
			window.dimgel.ajax.remove(cityChooser_requestIds[idprefix]);
		}
		cityChooser_requestIds[idprefix] = window.dimgel.ajax.request(
				rootUrl + 'ajax/cities/cities?stateid=' + stateid + '&flags=' + flags,
				null, cityChooser_ajaxCallback, {idprefix:idprefix, stateid:stateid, flags:flags});  
		return;
	}
	if (stateid == -1) {  // "custom state"
		cc.statename.disabled = false;
		cc.statename.focus();
		cc.cityname.disabled = false;
		cc.cityid.disabled = true;
		dimSetSelectValue(cc.cityid, -1);  // "custom city"
		return;
	}
}

// Internal, called upon cities list load completion.
function cityChooser_ajaxCallback(id, tag, status, text, xml) {
	cityChooser_requestIds[tag.idprefix] = null;
	var cc = cityChooser_controls(tag.idprefix);
	if (status != 200) {
		alert('AJAX jequest error: status=' + status);
		return;
	}
	if (cc.stateid.value * 1 != tag.stateid) {
		return;
	}

	cc.cityid.options.length = 0;
	var xcities = null;
	var e;
	for (e = xml.documentElement.firstChild;  e;  e = e.nextSibling) {
		if (e.nodeType == 1 && e.nodeName == 'cities') {
			xcities = e;
			break;
		}
	}
	if (!xcities) {
		alert('AJAX jequest error: invalid response');
		return;
	}
	for (e = xcities.firstChild;  e;  e = e.nextSibling) {
		if (e.nodeType == 1) {
			cc.cityid.options.add(new Option(e.getAttribute('text'), e.getAttribute('id'), false, false));
		}
	}
	cc.cityid.disabled = false;
}

// Internal, <select name="cityid" onchange="..."/> handler.
function cityChooser_cityChange(idprefix, flags) {
	var cc = cityChooser_controls(idprefix);
	var cityid = cc.cityid.value * 1;
	if (cityid == -1) {  // "custom city"
		cc.cityname.disabled = false;
		cc.cityname.focus();
	} else {  // "choose city", or real city, or user-defined specific row
		if (cc.cityname) {
			cc.cityname.disabled = true;
		}
	}

	if (flags.indexOf('i') >= 0 && (cityid == -2 || cityid > 0)) {  // "all cities" or real city
		cityChooser_choiceCallback(idprefix);
	}
}
