/**
 * Ajax constructor
 */
function Ajax() { }

/* public const variables */
Ajax.prototype.ERROR_FAIL = 1;

/* private variables */
Ajax.prototype.success_codes = new Array(200, 201, 202, 203, 204, 205, 206);
Ajax.prototype.request_object = false;

/* public static XMLHttpRequest */ Ajax.prototype.getRequestObject = function() {
  if (this.request_object) { return this.request_object; }

  if (window.XMLHttpRequest) {
    this.request_object = new XMLHttpRequest();
    if (this.request_object.overrideMimeType)
      this.request_object.overrideMimeType('text/plain');
  } else {
    this.request_object = new ActiveXObject("Microsoft.XMLHTTP");
  }

  return this.request_object;
}

/* public static XMLHttpRequest */ Ajax.prototype.newRequestObject = function() {
  if (window.XMLHttpRequest) {
    this.request_object = new XMLHttpRequest();
    if (this.request_object.overrideMimeType)
      this.request_object.overrideMimeType('text/plain');
  } else {
    this.request_object = new ActiveXObject("Microsoft.XMLHTTP");
  }

  return this.request_object;
}

/* private void */ Ajax.prototype.defaultErrorFunction = function(code) { alert('ajax error: ' + code); }
/* private void */ Ajax.prototype.nullFunction = function(code) { }

/* private function() */ Ajax.prototype.dispatchResult = function(request_object, success, failure) {
  var start_time = new Date();
  return function() { 
    if (request_object.readyState < 4) return;
    var status = request_object.status;
    if (request_object.readyState == 4 && status >= 200 && status <= 206) { success(request_object.responseText, start_time); return; }
    failure(status); return;
  }
}

/* public string */ Ajax.prototype.getSyncHttpRequest = function(url, params) {
  if (arguments.length < 2) 
    params = {};

  var query = new Array();
  for (var k in params) 
    query.push(escape(k) + "=" + escape(params[k]));
  query = query.join("&");
  if (params) {
    url += "?" + query;
  }

  request_object = this.getRequestObject();
  request_object.open("GET", url, false);
  request_object.send(null);

  return request_object.responseText;
}

/* public string */ Ajax.prototype.postSyncHttpRequest = function(url, params) {
  if (arguments.length < 2) 
    params = {};

  var query = new Array();
  for (var k in params) 
    query.push(escape(k) + "=" + escape(params[k]));
  query = query.join("&");

  request_object = this.getRequestObject();
  request_object.open("POST", url, false);
  request_object.setRequestHeader("Content-length", query.length);
  request_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  request_object.send(query);
      
  return request_object.responseText;
}

/* public void */ Ajax.prototype.getAsyncHttpRequest = function(url, params, success_callback, error_callback) {
  if (arguments.length < 4)
    error_callback = this.defaultErrorFunction;
  if (arguments.length < 3) 
    success_callback = this.nullFunction;
  if (arguments.length < 2) 
    params = {};

  var query = new Array();
  for (var k in params) 
    query.push(escape(k) + "=" + escape(params[k]));
  query = query.join("&");
  if (params) {
    url += "?" + query;
  }

  request_object = this.newRequestObject();
  if (arguments.length < 3)
    error_callback = this.defaultErrorFunction;
  if (arguments.length < 2) {
    alert("Ajax.getAsyncHttpRequest() expected at least 2 arguments");
    return;
  }

  request_object.onreadystatechange = this.dispatchResult(request_object, success_callback, error_callback);
  request_object.open("GET", url, true);
  request_object.send(null);
}

/* public void */ Ajax.prototype.postAsyncHttpRequest = function(url, params, success_callback, error_callback) {
  request_object = this.newRequestObject();
  if (arguments.length < 4)
    error_callback = this.defaultErrorFunction;
  if (arguments.length < 3) 
    success_callback = this.nullFunction;
  if (arguments.length < 2) 
    params = {};

  var query = new Array();
  for (var k in params) 
    query.push(escape(k) + "=" + escape(params[k]));
  query = query.join("&");

  request_object = this.getRequestObject();
  request_object.onReadyStateChange = this.dispatchResult(request_object, success_callback, error_callback);
  request_object.open("POST", url, true);
  request_object.setRequestHeader("Content-length", query.length);
  request_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  request_object.send(query);
}
