/*

Call to requestRetrieveXML to receive an xml document from the server, 
asynchronously.  DO NOT call to requestHandleXML, it is a private function only.

url              = web page on server that will return an XML data stream
callBackStatus   = javascript function name to call as the status of the request 
                   gets updated.  This will go through several iterations until 
                   readyState reachs 4 (completed)
callBackFinished = javascript function name to call once the full stream has 
                   been retrieved from the server.

*IMPORTANT: both callback functions must have one parameter, 'xml', that 
will be a returned xml DOM tree.  Use functions getElementById and 
getElementsByTagName to search for information from this tree.

*/

var xmlFound = false;
var xmlFoundChild = null;

function xmlRequest(url, callbackStatus, callbackFinished){
	var req = null;
	
	// Append date to any request so that MSIE doesn't cache results.
	if (url.indexOf("?") == -1) {
		url += "?stamp=" + new Date().getTime();
	} else {
		url += "&stamp=" + new Date().getTime();
	}
	
	// Branch for native XMLHttpRequest object.
	if (window.XMLHttpRequest) {
		req = new XMLHttpRequest();
		req.onreadystatechange = function(event) { xmlRequestHandler(req, callbackStatus, callbackFinished); };
		req.open("GET", url, true);
		req.send(null);
	
	// Branch for IE/Windows ActiveX version.
	} else if (window.ActiveXObject) {
		req = new ActiveXObject("Microsoft.XMLHTTP");
		if (req) {
			req.onreadystatechange = function(event) { xmlRequestHandler(req, callbackStatus, callbackFinished); };
			req.open("GET", url, true);
			req.send();
		}
	}
}
function xmlRequestHandler(handle, callbackStatus, callbackFinished) {
	if (callbackStatus != null) callbackStatus(handle.readyState);
	if (handle.readyState == 4 && handle.status == 200) {
		if (callbackFinished) callbackFinished(handle.responseXML);
	}
}

// Recurse through the xml tree, searching one level at a time.
// Do not recurse straight to the bottom of the tree because
// it is slow and inefficient, and is not likely to find what
// we're looking for there.

function xmlFindChild(xml, name) {
	
	// Initialize variables.
	xmlFound = false;
	xmlFoundLevel = 0;
	xmlFoundChild = null;
	xmlFoundChildren = new Array();
	
	if (xml == null) return null;
	if (xml.childNodes.length == 0) return null;
	
	// Recurse the tree (max of 5 levels).
	for (var i = 0; i < 5; i++) {
		xmlDigLevels(xml, name, i);
		if (xmlFound) return xmlFoundChild;
	}
	return null;
}
function xmlDigLevels(xml, name, levels) {
	if (xml.childNodes.length == 0) return;
	
	var children = xml.childNodes;
	for (var i = 0; i < children.length; i++) {
		if (levels == 0) {
			// If reached the 'bottom' level to search at, 
			// actually check this level's children for a match.
			xmlDigOneLevel(xml, name);
		} else {
			// Otherwise, dig another level down.
			xmlDigLevels(children[i], name, levels - 1);
		}
		if (xmlFound) return;
	}
}

function xmlDigOneLevel(xml, name) {
	if (xml.childNodes.length == 0) return;
	
	// Search through all children of the current node.
	var children = xml.childNodes;
	var child = null;
	for (var i = 0; i < children.length; i++) {
		child = children[i];
		
		// If matching child found, mark it.
		if (child.nodeType == 1) {
			if (child.nodeName == name) {
				xmlFound = true;
				xmlFoundChild = child;
				return;
			}
		}
	}
}

function xmlDigOneValue(xml, name) {
	var element = xml.getElementsByTagName(name);
	if (!element || element.length == 0) return null;
	if (!element.childNodes || element.childNodes.length == 0) return null;
	return element.firstChild.nodeValue;
}
