
/** our global object **/
var ajaxRequest=new AjaxRequestQueue;

/** class initialization / construction **/
AjaxRequestQueue.prototype.requestQueueArray=new Array();
AjaxRequestQueue.prototype.requestLock=false;
AjaxRequestQueue.prototype.currentRequestObject=null;
AjaxRequestQueue.prototype.currentCallbackInterface=null;
AjaxRequestQueue.prototype.bUseXML=false;


/** the actual class definition... **/
function AjaxRequestQueue() {
  var requestQueueArray;
  var currentRequestObject;
  var currentCallbackInterface;
  var requestLock;
  var bUseXML;
};

/** 
 * creates and returns a request object (if available)
 * @return XMLHTTP request object (or null if failure)
 */
AjaxRequestQueue.prototype.getRequestObject=function() {
  try {
    this.currentRequestObject=new XMLHttpRequest();
    return true;
  } catch (ex) {
    // probably an IE browser... check the 
    // various possible ActiveX Objects
    // to try and use the most new version
    var axObjects = ["Msxml2.XMLHTTP.7.0", 
                     "Msxml2.XMLHTTP.6.0", 
                     "Msxml2.XMLHTTP.5.0", 
                     "Msxml2.XMLHTTP.4.0", 
                     "MSXML2.XMLHTTP.3.0", 
                     "MSXML2.XMLHTTP", 
                     "Microsoft.XMLHTTP"
                    ];
    for (var i=0; i < axObjects.length; i++) {
      try {
        this.currentRequestObject=new ActiveXObject(axObjects[i]);
        return true;
      } catch (ex) {
        // do nothing - try the next one...
      }
    }
  }

  this.currentRequestObject=null;
  return false;
};

/**
 * adds a new request to the queue
 * @param requestURL the URL to request
 * @param callbackFunction the function called upon completion
 */
AjaxRequestQueue.prototype.sendRequest=function(requestURL, callbackFunction) {
  // push the request into the array
  this.requestQueueArray[this.requestQueueArray.length]=new Array(requestURL, callbackFunction, false);

  // now call to check and see where we're at with processing...
  this.checkQueue();
};

AjaxRequestQueue.prototype.sendRequestXML=function(requestURL, callbackFunction) {
  // push the request into the array
  this.requestQueueArray[this.requestQueueArray.length]=new Array(requestURL, callbackFunction, true);

  // now call to check and see where we're at with processing...
  this.checkQueue();
};

/**
 * Checks the queue to see if we're ready for a 
 * request to be sent out
 */
AjaxRequestQueue.prototype.checkQueue=function() {
  // check to see if we have something in the queue
  // and if we're not processing a request at the moment
  if ((this.requestQueueArray.length > 0) && (this.currentRequestObject==null) && (this.requestLock==false)) {

    // lock it
    this.requestLock=true;
    
    // display the loading div (if applicable)
    var loadingElement=document.getElementById('loadingDiv');
    if (loadingElement) {
      loadingElement.style.display = 'block';
    }

    // create a new request object
    if (this.getRequestObject()==false) {
      alert("Failed to create XMLHttp Request Object!");
    }

    // pop the next item from the top of the queue
    var thisRequest=this.requestQueueArray.shift();

    // ensure we have a valid request object
    if (this.currentRequestObject!=null) {
      // set our state chance callback
      this.currentRequestObject.onreadystatechange=ajaxProcessStateChange;
      
      // set our final callback
      this.currentCallbackInterface=thisRequest[1];
      
      // set to use XML return or not
      this.bUseXML=thisRequest[2];
      
      // open the request
      this.currentRequestObject.open("GET", thisRequest[0], true);
      
      // send it
      this.currentRequestObject.send(null);
    }
  }
};

AjaxRequestQueue.prototype.resetRequestData=function() {
  // kill any current request object
  this.currentRequestObject=null;
  this.currentCallbackInterface=null;
  this.bUseXML=false;
  
  // finally, unlock it
  this.requestLock=false;
};

/**
 * our callback for the onReadyStateChange property
 * for now, we're only interested in complete requests
 */
function ajaxProcessStateChange() {
  if (ajaxRequest.currentRequestObject!=null) {
    switch(ajaxRequest.currentRequestObject.readyState) {
    case 0: /** uninitialized **/
            break;
    case 1: /** loading **/
            break;
    case 2: /** loaded **/
            break;
    case 3: /** interactive **/
            break;
    case 4: /** complete **/
            // we're done - call our current callback

            // clear the loading div (if applicable)
            var loadingElement=document.getElementById('loadingDiv');
            if (loadingElement) {
              loadingElement.style.display = 'none';
            }

            // callback prototype:
            // fxnName(statusCode, responseText, bUseXML);
            if (ajaxRequest.currentCallbackInterface!=null) {
              // the only thing to really watch for here is 
              // an infinite loop in the callback...
              if (ajaxRequest.bUseXML==true) {
                ajaxRequest.currentCallbackInterface(ajaxRequest.currentRequestObject.status, ajaxRequest.currentRequestObject.responseXML);
              } else {
                ajaxRequest.currentCallbackInterface(ajaxRequest.currentRequestObject.status, ajaxRequest.currentRequestObject.responseText);
              }
            }

            // reset our data for the next request
            ajaxRequest.resetRequestData();

            // send the next one
            ajaxRequest.checkQueue();

            break;
    default: /** should never get here... **/
            break;

    } // end switch(this.currentRequestObject.readyState)
  }
};

