var open_toggler = null;

function toggle (toggler)
{
	var inputs, i, type, text_input;

	deactivate_all ();

	inputs = toggler.parentNode.getElementsByTagName ("input");
	for (i = 0; i < inputs.length; i++) {
		type = inputs[i].getAttribute ("type");
		if (!type || type == "text") {
			text_input = inputs[i];
			break;
		}
	}

	if (toggler.parentNode.className == "showhide") {
		toggler.parentNode.className = "showhide-shown";
		/* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
		toggler.firstChild.data = "\u00AB";
		if (text_input)
			window.setTimeout(function() { text_input.focus(); }, 1);
		open_toggler = toggler;
	} else {
		toggler.parentNode.className = "showhide";
		/* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
		toggler.firstChild.data = "\u00BB";
		if (text_input)
			text_input.blur ();
		open_toggler = null;
	}
}

var row_key = null;
var active_row = null;
var active_item = null;
var active_heading = null;
var headings_active = false;

function activate_selectors (node, active) {
	var child;

	if (node.tagName == "SPAN") {
		if (active && node.className == "selector")
			node.className = "active_selector";
		else if (!active && node.className == "active_selector")
			node.className = "selector";
	}
	for (child = node.firstChild; child; child = child.nextSibling)
		activate_selectors (child, active);
}

function activate_label (node, active) {
	var child;

	if (node.tagName == "SPAN") {
		if (active && node.className == "label")
			node.className = "active_label";
		else if (!active && node.className == "active_label")
			node.className = "label";
	}
	for (child = node.firstChild; child; child = child.nextSibling)
		activate_label (child, active);
}

function activate_headings (active) {
	var headings, i;

	if (active_row)
		activate_selectors (active_row, false);
	if (active_heading) {
		activate_label (active_heading, false);
		activate_selectors (active_heading, false);
	}
	if (active_item)
		activate_label (active_item, false);

	headings_active = active;
	headings = document.getElementsByTagName ("th");
	for (i = 0; i < headings.length; i++)
		activate_selectors (headings[i], headings_active);
}

function activate_row (key) {
	row_key = key;
	active_heading = document.getElementById ("key_" + row_key);
	if (!active_heading)
		return false;
	activate_label (active_heading, true);

	if (active_heading.parentNode.nextSibling &&
	    active_heading.parentNode.nextSibling.tagName == "TD")
		active_row = active_heading.parentNode.nextSibling;
	else if (active_heading.parentNode.previousSibling &&
		 active_heading.parentNode.previousSibling.tagName == "TD")
		active_row = active_heading.parentNode.previousSibling;
	else
		return false;

	activate_selectors (active_row, true);
	return true;
}

function activate_item (key) {
	active_item = document.getElementById ("key_" + row_key + key);
	if (!active_item)
		return false;
	activate_label (active_item, true);
	return true;
}

function deactivate_all () {
	activate_headings (false);
	active_item = active_row = active_heading = null;
}

function do_key (event, kcode) {
	var key, node;

	key = String.fromCharCode(kcode).toLowerCase();

	if (open_toggler) {
		if (kcode == 27) {
			toggle (open_toggler);
			return false;
		}
		return true;
	}

	if (key == "/" || key == "\\") {
		activate_headings (!headings_active);
		if (event)
			event.stopPropagation ();
		return false;
	}
	activate_headings (false);

	if (key == "\n" || key == "\r") {
		if (active_item && active_item.parentNode.href) {
			window.location = active_item.parentNode.href;
			return false;
		}
	} else if (key == ">" || key == ".") {
		if (active_item && active_item.parentNode.nextSibling &&
		    active_item.parentNode.nextSibling.tagName == "DIV") {
			var div = active_item.parentNode.nextSibling;
			if (div.className == "sub")
				div = div.firstChild;
			toggle (div.firstChild.nextSibling);
			return false;
		}
	} else if (key == "?") {
		toggle (document.getElementById ("google"));
		return false;
	} else {
		if (!active_row) {
			if (activate_row (key))
				return false;
		} else if (activate_item (key))
			return false;
	}

	deactivate_all ();
	return true;
}

if (document.addEventListener) {
	document.addEventListener ("keypress", function (e) {
		if (e.altKey || e.ctrlKey)
			return true;
		return do_key (e, e.which || e.keyCode);
	}, true);
	window.addEventListener ("load", function (e) {
		load_stocks ();
	}, false);
} else if (document.attachEvent) {
	document.attachEvent ("onkeypress", function () {
		return do_key (null, event.keyCode);
	});
	window.attachEvent ("onload", function () {
		load_stocks ();
	});
}

function createXMLHttpRequest () {
	try { return new XMLHttpRequest (); } catch (e) {}
	try { return new ActiveXObject ("Msxml2.XMLHTTP"); } catch (e) {}
	try { return new ActiveXObject ("Microsoft.XMLHTTP"); } catch (e) {}
	return null;
}

function load_stocks () {
	var xh = createXMLHttpRequest ();
	if (xh) {
		var spans = document.getElementsByTagName ("span");
		var stocks = {};
		var query = null;
		for (var i = 0; i < spans.length; i++) {
			if (spans[i].className == "dynamic") {
				stocks[spans[i].id] = spans[i];
				if (query)
					query += "+" + spans[i].id;
				else
					query = "dynamic.php?quote=" + spans[i].id;
			}
		}

		xh.open ("GET",  query, true);
		xh.onreadystatechange = function () {
			if (xh.readyState == 4 && xh.status == 200) {
				for (stock in stocks) {
					var div = xh.responseXML.getElementById (stock);
					if (div)
						stocks[stock].appendChild (document.importNode (div, true));
				}
			}
		};
		xh.send (null);
	}
}
