// vim: set tabstop=4 shiftwidth=4 foldmethod=marker :
/**
 * XMLHTTP-based remote scripting layer (AJAX).
 */
// {{{ ajax_create_xmlhttp()
function ajax_create_xmlhttp()
{
	var ret = null;
    try {
        ret = new ActiveXObject('Msxml2.XMLHTTP');
    }
    catch (e) {
        try {
            ret = new ActiveXObject('Microsoft.XMLHTTP');
        }
        catch (ee) {
            ret = null;
        }
    }
    if (!ret && typeof XMLHttpRequest != 'undefined')
        ret = new XMLHttpRequest();

    return ret;
}
// }}}
// {{{ ajax_query(callbackFunction, url, postArray, asText)
function ajax_query(callbackFunction, url, postArray, asText, silentFail)
{
	// Use Javascript " inner functions" to have local variables retain values after outer
	// function has returned. This ensures thread safety.
	// {{{ ajax_bind_callback()
	
	function ajax_bind_callback() {
		// Must be "complete"
		if (req.readyState == 4) {
			// "HTTP OK"
			if (req.status == 200) {
				if (ajax_callback) {
					if (asText) {
						ajax_callback(req.responseText);
					} else {
						ajax_callback(req.responseXML);
					}
				} else {
					//alert('no callback defined');
				}
			} else {
			    // Change the message to "Unable to contact the server.  Please check your connection and try again."
			    alert("Unable to contact the server.  Please check your internet connection and try again.");
				//alert("There was a problem retrieving the xml data:\n" + req.status + ":\t" + req.statusText + "\n" + req.responseText);
			}
		}
	}
	// }}}
	// hold everything in local variables until inner function is called
	var ignore_errs = false;
	if ((silentFail != undefined) && silentFail) {
	    ignore_errs = true;
	}
	var req = ajax_create_xmlhttp();
	if (!req) { return false; }

   	var ajax_callback = callbackFunction;
	if (typeof callbackFunction == 'function') {
    	req.onreadystatechange = ajax_bind_callback;
	}
	
	if (postArray) {
	  //alert('posting data');
	  if (postArray.cleanUpProperties) {
	    //alert('cleaning');
	    postArray.cleanUpProperties();
	  }
		req.open('POST',url,true);
		req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		//alert(ajax_encode_array(postArray));
		req.send(ajax_encode_array(postArray));
	} else {
		req.open('GET',url,true);
		req.send(null);
	}
}
// }}}
// {{{ ajax_encode_array(dataToEncode)
function ajax_encode_array(dataToEncode)
{
	var post_data = '';
	for (var key in dataToEncode) {
		post_data += '&' + escape(key) + '=' + encodeURIComponent(dataToEncode[key]);
	}
	// handle the case where nothing is posted
	if (post_data.length==0) { return ''; }
	// trim off first &
	return post_data.substring(1);
}
// }}}
// {{{ ajax_inject_html(tagId,htmlToInject)
/**
 * @todo optimize by generating offline and using a replace node
 */
function ajax_inject_html(tagId, htmlToInject)
{
    //alert('ajax_inject_html:'+tagId);
	var tag_obj = document.getElementById(tagId);
	if (!tag_obj) {
		alert('No such element: '+tagId);
		return false;
	}
    var temp_obj = tag_obj.cloneNode(false);
    temp_obj.innerHTML = htmlToInject;
    tag_obj.parentNode.replaceChild(temp_obj,tag_obj);
    return true;
    //tag_obj.replaceNode(temp_obj);
    //tag_obj = temp_obj;
    //alert(tag_obj.innerHTML);
	//tag_obj.innerHTML = htmlToInject;
	//return true;
}
// }}}
