/****************************************************************************
 * @file          queue.js
 *
 * @project       YAMI (Yet Another Mapping Interface)
 * @contributors  Rose Jackson, William Garrick, Eric Hanson, Morgan Harvey,
 *                Cristopher Holm, David Percy       
 * 
 * Copyright (c) 2006, Academic & Research Computing, Portland State 
 *                University, Portland Oregon.
 * 
 ***************************************************************************/

var http_request=null;

function Queue() {
  this.items=new Array();
  this.timeout=10000;   // 10 seconds (in milliseconds) allowed for a queued item to run
  this.isIE=false;
  this.busy=false;
  
  this.init=function() {
    if (window.ActiveXObject) this.isIE=true;
    window.setInterval("queue.CheckQueue()",400);
  }
  
  this.EnqueueItem=function(name,notifyFunction,url,useXML) {
    var queueItem=new QueueItem(name,notifyFunction,url,useXML);
    queue.items.push(queueItem);
  }
  
  this.CheckQueue=function() {
    if (queue.items.length>0) {
      var queueItem=queue.items[0];
      if (queueItem.state=="pending") {
        queue.ProcessItem();
      } else if (queueItem.state=="working") {
        // check the timestamp to see how long its been working
        var now=new Date();
        if (now - queueItem.processTimestamp > queue.timeout) {
          // it's been running for longer than the timeout, so kill it
          queueItem.http_request.abort();
          // remove the item from the queue and notify the user
          queueItem=queue.items.shift();
          if (queueItem.notifyFunction) {
            try {
              queueItem.notifyFunction('Timeout','');
            } catch (e) {
              alert("Error notifying '"+queueItem.name+"': "+e.message);
            }
          } else {
            alert("http request for '"+queueItem.name+"' timed out.");
          }
        }
      }
    }
  }
  
  this.ProcessItem=function() {
    var queueItem=queue.items[0];
    if (window.XMLHttpRequest) {
      try {
        queueItem.http_request=new XMLHttpRequest();
      } catch (e) {
        alert("Error creating XMLHttpRequest object: "+e.message);
      }
    } else if (window.ActiveXObject) {
      try {
        queueItem.http_request=new ActiveXObject("Msxml2.XMLHTTP");
      } catch (e) {
        try {
          queueItem.http_request=new ActiveXObject("Microsoft.XMLHTTP");
        } catch (e) {
          alert("Error creating ActiveX http request object: "+e.message);
        }
      }
    }

    if (queueItem.http_request!=null) {
      queueItem.http_request.onreadystatechange=queue.handleProcessing;
      queueItem.http_request.open("GET",queueItem.url,true);
      queueItem.state="working";
      queueItem.processTimestamp=new Date();
      try {
        if (queue.isIE)
          queueItem.http_request.send();
        else
          queueItem.http_request.send(null);
      } catch (e) {
        alert("Error sending http request for '"+queueItem.name+"': "+e.message);
      }
    }
  }
  
  this.handleProcessing=function() {
    var tryNotification=true;
    var queueItem=queue.items[0];
    if (queueItem.http_request.readyState == 4) {
      queueItem.state="notifying";
      if (queueItem.http_request.status == 200) {
        queueItem.status="OK";
      } else {
        //var status_text=http_request.statusText.replace(/'/g,"\\'");
        //status_text=status_text.replace(/[\n\r\t\v\f]/g," ");
        queueItem.status="Error. Status code: "+queueItem.http_request.status+"; message: "+queueItem.http_request.statusText;
      }
      if (queueItem.notifyFunction) {
        var response="";
        if (queueItem.useXML) {
          if (queueItem.http_request.responseXML) {
            response=queueItem.http_request.responseXML;
          } else {
            alert("Error notifying '"+queueItem.name+"': invalid responseXML");
            tryNotification=false;
          }
        } else {
          if (queueItem.http_request.responseText) {
            response=queueItem.http_request.responseText;
          } else {
            alert("Error notifying '"+queueItem.name+"': invalid responseText");
            tryNotification=false;
          }
        }
        if (tryNotification) {
          try {
            queueItem.notifyFunction(queueItem.status,response);
          } catch (e) {
            alert("Error notifying '"+queueItem.name+"': "+e.message);
          } 
        }
      }
      queueItem.http_request=null;
      queueItem=null;
      queue.items.shift();
    }
  }
}

function QueueItem(name,notifyFunction,url,useXML) {
  this.name=name;
  this.state="pending";
  this.notifyFunction=notifyFunction;
  this.url=url;
  this.status="OK";
  this.processTimestamp=null;
  this.useXML=useXML;
  this.http_request=null;
}