// global flag
var isIE = false;

// global request and XML document objects
var req;
var URL;
// send an RPC message. Specify url and data. The url identifies a 'closure'
function rcall(url, data) {
    URL=url;
    //alert(url);
    // branch for native XMLHttpRequest object
    // do we need to set a content type to send data? If so I'll have it default to XML unless specified otherwise.
    if (window.XMLHttpRequest) {
        req = new XMLHttpRequest();
        req.onreadystatechange = processReqChange;
        if (data == undefined) {
            req.open("GET", url, true);
            req.send(null);
        } else {
	    // alert("going to post " + data);
            req.open("POST", url, true);
	    req.setRequestHeader("Content-type","image/gif");
            req.send(data);
        }
    // branch for IE/Windows ActiveX version
    } else if (window.ActiveXObject) {
        isIE = true;
        req = new ActiveXObject("Microsoft.XMLHTTP");
        if (req) {
            req.onreadystatechange = processReqChange;
            if (data == undefined) {
                req.open("GET", url, true);
                req.send('');
            } else {
                req.open("POST", url, true);
		req.setRequestHeader("Content-type","image/gif");
                req.send(data);
            }
        }
    }
}

// handle onreadystatechange event of req object
function processReqChange() {
    // only if req shows "loaded"
    if (req.readyState == 4) {
        // only if "OK"
        //alert(req.status);
	//alert(req.responseText);
	//alert(nodeInnerXML(req.responseXML));
        if (req.status == 200) {
            // now we have to deal with the reply...
            if (req.responseText.substring(0,1) == "<") {
                
		//alert(nodeXML(req.responseXML.firstChild));
                var de = req.responseXML.firstChild;
                while (de.nextSibling) {de=de.nextSibling};
                if (de.nodeName == 'l') {
		    //alert('process...');
                    var i;
                    for (i=0; i<de.childNodes.length; i++) {
			//alert('process item...' + de.childNodes[i]);
                        processItem(de.childNodes[i]);
                    }
                    //req.responseXML.
                } else {
                    processItem(de);
                }
            } else {
                // It must just be simple javascript commands. That's easy...
                eval(req.responseText);
            }
         } else {
            alert("There was a problem retrieving the XML data:\n" +
                req.statusText + ' -- ' + req.status + ": " + req.responseText + ' -- ' + URL);
         }
    }
}

// surely there must be a better way of doing this?
function nodeXML(node) {
    var i;
    //alert(node.nodeName);
    if (node.nodeName == '#text') {
        return escapeString(node.data);
    } 
    
    if (node.nodeName == '#comment') {
	return '<!-- '+node.data + '-->';
    }

    var r;
    r = "<" + node.nodeName;
    for (i=0; i<node.attributes.length; i++) {
	r += ' '+node.attributes[i].nodeName + '="' + escapeString(node.attributes[i].nodeValue) + '"';
    }
    r+='>';
    r+=nodeInnerXML(node);
    r+= "</" + node.nodeName + ">";
    return r;
}

function nodeInnerXML(node) {
    var r='';
    var i;
    for (i=0; i<node.childNodes.length; i++) {
	//alert(i);
        r += nodeXML(node.childNodes[i]);
    }
    return r;
}

function escapeString(str) {
    str=str.replace(/\&/g, "&amp;");
    str=str.replace(/\</g, "&lt;");
    str=str.replace(/\"/g, "&quot;");
    return str;
}

function nodeAttribute(node,n) {
    var i;
    for (i=0; i<node.attributes.length; i++) {
        if (node.attributes[i].name == n)
            return node.attributes[i].value;
    }
}

// process a response item
function processItem(node) {
    var theDoc = document;
    // This allows things in IFRAMES to do rcalls which effect the parent frame
    if (parent)
	theDoc=parent.document;
    if (node.nodeName == '#text')
        eval(node.data);

    if (node.nodeName == 'ap')
        document.getElementById(nodeAttribute(node,'id')).innerHTML += nodeInnerXML(node);

    if (node.nodeName == 'rp')
        document.getElementById(nodeAttribute(node,'id')).innerHTML = nodeInnerXML(node);

    if (node.nodeName == 'rm') {
        var elem = document.getElementById(nodeAttribute(node,'id'));
	elem.parentNode.removeChild(elem);
    }
}
