// Routines used to implement YellowHawk chat client
var HTTP = function() {
  this.count=0

  // Create an underlying HTTP object
  this.http = HTTP.makeNewRequest();  

  HTTP._allReqs.push(this);
};

HTTP._factories = [
  function() {return new XMLHttpRequest();},
  function() {return new ActiveXObject("Msxml2.XMLHTTP"); },
  function() {return new ActiveXObject("Microsoft.XMLHTTP"); }
];

HTTP._timer;
HTTP._factory;
HTTP._allReqs = [];

HTTP.makeNewRequest = function() {
  if (HTTP._factory!=null) 
    // Already know how to create the request
    return HTTP._factory();

  // Need to discover
  for (var i=0;i<HTTP._factories.length;i++) {
    try {
      var factory = HTTP._factories[i];
      var req = factory();
      if (req!=null) {
        HTTP._factory = factory;
        return req;
      }
    }
    catch (ev) {
      continue;
    }
  }
  // If we get here then XML requests are not supported
  HTTP._factory = function() {
    throw new Error("XMLHttpRequest not supported");
  }
  HTTP._factory();
}

/*********************************************
HTTP.newRequest
Create a new meta-request and return to the
caller.
*********************************************/
HTTP.newRequest = function() {
  // Any requests in the available list?
  for (var i=0;i<HTTP._allReqs.length;i++) {
    if (HTTP._allReqs[i].count==-1) {
      HTTP._allReqs[i].count = 0;
      return HTTP._allReqs[i];
    }
  }
  // No available requests so need to create a new one.
  // Make a new one
  return new HTTP;
}

HTTP.checkRequests = function() {
  HTTP._timer = null;
  delete HTTP._timer;

  var activeReqs=0;

  for (var i=0;i<HTTP._allReqs.length;i++) {
    // Check for status 4 and count>0
    var req=HTTP._allReqs[i];

    if (req.count>0) {
      // >0 means we're active. Check for completed response
      if (req.http.readyState==4) {
        req.count=0;
        req.complete();
      }
      else
        // Not complete - check for timeout
        req.tick();

      // The callback is allowed to re-use the request, but if it does then
      // the count will be reset for the new request. If the count is still zero then
      // this req is no longer required and can be returned to the pool.
      if (req.count==0) {
        // Client MUST finish with the request after the callback - reclaim to the pool
        req.count=-1;
      }
      if (req.count>0)
        activeReqs++;
    }
  }
  // If there are any active requests then start another timer
  if (activeReqs>0)
    HTTP._timer = setTimeout(HTTP.checkRequests, HTTP.poll_timerval);
}

HTTP.prototype.complete = function() {
  var req = this.http;

  // Request is complete
  if (req.status==200) {
    // Request successful
    this.callback(this, req.responseText);
  }
  else if (this.errorHandler!=null) {
    this.errorHandler(this, req.status, req.statusText);
  }
  else
    this.callback(this);
}

HTTP.prototype.finished = function() {
  this.count=0;
}

HTTP.prototype.tick = function() {
  var req = this.http;

  if (req.count>0) {
    req.count--;
    if (req.count==0) {
      if (this.timeoutHandler!=null)
        this.timeoutHandler(this,url);

      // Client MUST finish with the request after the callback - reclaim to the pool
      this.count=-1;
    }
  }
}

HTTP.encodeFormData = function(data) {
  var pairs=[];
  var regexp = /%20/g;

  for (var name in data) {
    var value = data[name].toString();

    var pair = encodeURIComponent(name).replace(regexp,"+")+"="+encodeURIComponent(value).replace(regexp,"+");
    pairs.push(pair);
  }
  return pairs.join('&');
}

HTTP.init_timerval       = 250;
HTTP.poll_timerval       = 500;
HTTP.startTickCount = 1;

HTTP.prototype.get = function(url,callback,options) {

  this.callback = callback;

  if (options.timeoutHandler)
    this.timeoutHandler = options.timeoutHandler;

  if (HTTP._timer==null)
    HTTP._timer = setTimeout(HTTP.checkRequests, HTTP.init_timerval);

  var target=url;
  if (options.parameters)
    target += '?'+HTTP.encodeFormData(options.parameters);

  this.count=HTTP.startTickCount;
  this.http.open("GET",target);
  this.http.send(null);
}


