/**
 * On mozilla, asynchronous web calls, which are the heart of AJAX paradigms, are handled through the XMLHttpRequest.
 * However on IE, there is an array of objects which are created through the ActiveXObject. To support cross browser
 * asynchronous methods, we create the "Asynchronous" class.
 *
 * Users attach handling to a particular Asynchronous instance by setting the 'loading', 'loaded', 'interactive', and
 * 'complete' methods which are called as the Asynchronous class enters each state. (The default behavior of each is to
 * do nothing.)
 *
 * Credit: this code based on (and currently pretty much a copy of the Asynchronous class described in Christian 
 * Gross's "AJAX Patterns and Best Practices"
 */
function FactoryXMLHttpRequest() {
  if(window.XMLHttpRequest) { return new XMLHttpRequest(); }
  else if (window.ActiveXObject) {
    var msxmls = new Array(
        'Msxml2.XMLHTTP.5.0',
        'Msxml2.XMLHTTP.4.0',
        'Msxml2.XMLHTTP.3.0',
        'Msxml2.XMLHTTP',
        'Microsoft.XMLHTTP.5.0');
    for (var i = 0; i < msxmls.length; i++) {
      try { return new ActiveXObject(msxmls[i]); }
      catch (e) {}
    }
  }
  throw new Error("Could not instantiate XMLHttpRequest");
}

function Asynchronous() {
  this._xmlhttp = new FactoryXMLHttpRequest();
}

Asynchronous.prototype._xmlhttp;

function Asynchronous_call(url, data) {
  var instance = this;
  this._xmlhttp.open('POST', url, true);
  this._xmlhttp.onreadystatechange = function() {
    switch(instance._xmlhttp.readyState) {
      case 1:
        instance.loading();
	break;
      case 2:
        instance.loaded();
	break;
      case 3:
        instance.interactive();
	break;
      case 4:
        instance.complete(instance._xmlhttp.status,
	                  instance._xmlhttp.statusText,
			  instance._xmlhttp.responseText,
			  instance._xmlhttp.responseXML);
        break;
    }
  }
  this._xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  this._xmlhttp.send(data);
}

//TODO: I'm pretty sure we can replace each of these with 'Asynchrounous_doNothing' and just set each of the prototype attribute to that single function
function Asynchronous_loading() {}

function Asynchronous_loaded() {}

function Asynchronous_interactive() {}

function Asynchronous_complete(status, statusText, responseText, responseXML) {}

Asynchronous.prototype.loading = Asynchronous_loading;
Asynchronous.prototype.loaded = Asynchronous_loaded;
Asynchronous.prototype.interactive = Asynchronous_interactive;
Asynchronous.prototype.complete = Asynchronous_complete;
Asynchronous.prototype.call = Asynchronous_call;