// A bunch of XML HTTP recipes used to do RPC from within javascript

/** Candidate Active X types.
  * @private
  */
var _XH_ACTIVE_X_IDENTS = [
  "MSXML2.XMLHTTP.5.0", "MSXML2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0",
  "MSXML2.XMLHTTP", "MICROSOFT.XMLHTTP.1.0", "MICROSOFT.XMLHTTP.1",
  "MICROSOFT.XMLHTTP" ];
/** The active x identifier used for ie.
 * @private
 */
var _xh_ieProgId = undefined;

// Domain for XmlHTTPRequest.readyState
var XML_READY_STATE_UNINITIALIZED  = 0;
var XML_READY_STATE_LOADING        = 1;
var XML_READY_STATE_LOADED         = 2;
var XML_READY_STATE_INTERACTIVE    = 3;
var XML_READY_STATE_COMPLETED      = 4;

/** initialize the private state used by other functions.
  * @private
  */
function _XH_XmlHttpInit() {
  // Nobody (on the web) is really sure which of the progid's listed is totally
  // necessary. It is known, for instance, that certain installations of IE will
  // not work with only Microsoft.XMLHTTP, as well as with MSXML2.XMLHTTP.
  // Safest course seems to be to do this -- include all known progids for
  // XmlHttp.
  if (typeof XMLHttpRequest == 'undefined' &&
      typeof ActiveXObject != 'undefined') {
    for (var i = 0; i < _XH_ACTIVE_X_IDENTS.length; i++) {
      var candidate = _XH_ACTIVE_X_IDENTS[i];

      try {
        new ActiveXObject(candidate);
        _xh_ieProgId = candidate;
        break;
      } catch (e) {
        // do nothing; try next choice
      }
    }
  }
}

_XH_XmlHttpInit();

/** create and return an xml http request object that can be passed to
  * {@link #XH_XmlHttpGET} or {@link #XH_XmlHttpPOST}.
  */
function XH_XmlHttpCreate() {
  if (_xh_ieProgId !== undefined) {
    return new ActiveXObject(_xh_ieProgId);
  } else if (window.XMLHttpRequest) {
    return new window.XMLHttpRequest();
  } else {
    return null;
  }
}

/** send a get request.
  * @param xmlhttp as from {@link XH_XmlHttpCreate}.
  * @param url the service to contact
  * @param handler function called when the response is received.
  */
function XH_XmlHttpGET(xmlhttp, url, handler) {
  xmlhttp.onreadystatechange = handler;
  xmlhttp.open("GET", url, true);
  _XH_XmlHttpSend(xmlhttp, null);
}

/** send a post request.
  * @param xmlhttp as from {@link XH_XmlHttpCreate}.
  * @param url the service to contact
  * @param data the request content.
  * @param handler function called when the response is received.
  */
function XH_XmlHttpPOST(xmlhttp, url, data, handler) {
  xmlhttp.onreadystatechange = handler;
  xmlhttp.open("POST", url, true);
  xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  xmlhttp.setRequestHeader("Content-Length", data.length);
  _XH_XmlHttpSend(xmlhttp, data);
}

/** @private */
function _XH_XmlHttpSend(xmlhttp, data) {
  try {
    xmlhttp.send(data);
  } catch (e) {
    // you may want to log/debug this error
    // one that you should be aware of is e.number == -2146697208,
    // which occurs when the 'Languages...' setting in IE is empty.
    log('XMLHttpSend failed ' + e.toString() + '<br>' + e.stack);
    throw e;
  }
}

/** execute async request function **/

function asyncExec(url, processFunc, method, adddata, addvars) {
  //method is GET or POST, GET is default value
	//can be extended with networkErrorFunc, serverErrorFunc
  if (!method) method = "GET";
  
  var req = XH_XmlHttpCreate();
  var handler = function() {
    if (req.readyState == XML_READY_STATE_COMPLETED) {
      var failed = false;
      // Connection failures (Safari returns null, IE returns 12029, and
      // Firefox throws exception.
      try {
        if (req.status == null || req.status == 12029) {
          failed = true;
        }
      } catch (e) {
        // Firefox calls onerror() when a network error occurs.  Inside the
        // onerror handler, accessing the status attribute results in an
        // exception, which we catch here.
        failed = true;
      }

      if (failed) {
        //process Network Error
        return;
      }      

      if (req.status == 500) {
        //process some other server error
        return;
      }

      if (req.status == 200) {
			  //addvars
				var addvarsData = "";
				if (addvars && addvars.length>0)
				 for (var i = 0; i < addvars.length; i++) {
				   addvarsData = addvarsData + ", " + addvars[i];
				 }
        // any edits will revive the autosave button
        //getRefToDiv("b").innerHTML=req.responseText;
				eval(processFunc + '(req.responseText' + addvarsData + ')'); 
      } else {
        // Display error message and make appropriate changes to save button
        // behavior if necessary.
        //obj.showError(resp);
      }
    }
  }

	//anticache
	var useurl = url;
	if (useurl.indexOf("?") == -1) useurl = useurl + "?";
	else useurl = useurl + "&";
	useurl = useurl + Math.random();
	
	if (method == "GET") {
  XH_XmlHttpGET(
      req,
      useurl,
      handler);
	} else {		
	XH_XmlHttpPOST(
      req,
      useurl,
      adddata,
      handler);
	}
};
