




AjaxRequest.METHOD_POST = 'POST';


AjaxRequest.METHOD_GET  = 'GET';


AjaxRequest.METHOD_PUT  = 'PUT';


AjaxRequest.READY_STATE_UNINITIALIZED = 0;


AjaxRequest.READY_STATE_LOADING       = 1;


AjaxRequest.READY_STATE_LOADED        = 2;


AjaxRequest.READY_STATE_INTERACTIVE   = 3;


AjaxRequest.READY_STATE_COMPLETE      = 4;


AjaxRequest.STATUS_OK        = 200;


AjaxRequest.STATUS_NOT_FOUND = 404;


AjaxRequest.CONTENT_TYPE = 'Content-Type';


AjaxRequest.CONTENT_TYPE_URL_ENCODED = 'application/x-www-form-urlencoded';


AjaxRequest.ACTIVEX_MSXML2_XMLHTTP = "Msxml2.XMLHTTP";


AjaxRequest.ACTIVEX_LEGACY_XMLHTTP = "Microsoft.XMLHTTP";


AjaxRequest.FORM_FIELD_BUTTON = 'button';


AjaxRequest.FORM_FIELD_SUBMIT = 'submit';


AjaxRequest.FORM_FIELD_TEXT = 'text';


AjaxRequest.FORM_FIELD_HIDDEN = 'hidden';


AjaxRequest.FORM_FIELD_TEXTAREA = 'textarea';


AjaxRequest.FORM_FIELD_RADIO = 'radio';


AjaxRequest.FORM_FIELD_CHECKBOX = 'checkbox';


AjaxRequest.FORM_FIELD_SELECT_ONE = 'select-one';


AjaxRequest.FORM_FIELD_SELECT_MULTIPLE = 'select-multiple';


AjaxRequest.DELIM_QS = '?';


AjaxRequest.DELIM_PARAM = '&';


AjaxRequest.DELIM_KEY_VALUE = '=';


AjaxRequest.ERROR_CREATE_REQUEST = 'Unable to create ActiveX XMLHttpRequest.'


AjaxRequest.ERROR_REQUEST_STATE = 'Error in XMLHttpRequest [$code/$text]';



function AjaxRequest(url, handlerFunction)
{
  // Object properties

  this.mUrl         = url;
  this.mHandler     = handlerFunction;
  //this.mMethod      = AjaxRequest.METHOD_GET;
  this.mMethod      = AjaxRequest.METHOD_POST;

  this.mContentType = null;
  this.mRequestBody = null;

  this.clearParameters();
}



AjaxRequest.prototype.setUrl = function(url)
{
  this.mUrl = url;
  return this;
}



AjaxRequest.prototype.setHandler = function(handlerFunction)
{
  this.mHandler = handlerFunction;
  return this;
}



AjaxRequest.prototype.setMethod = function(method)
{
  this.mMethod = method;
  return this;
}



AjaxRequest.prototype.setContentType = function(contentType)
{
  this.mContentType = contentType;
  return this;
}



AjaxRequest.prototype.setRequestBody = function(data)
{
  this.mRequestBody = data;
  return this;
}



AjaxRequest.prototype.clearParameters = function()
{
  this.mParams = new Array();
  return this;
}



AjaxRequest.prototype.setParameter = function(key, value)
{
  this.mParams[this.mParams.length] = encodeURIComponent(key)
      + AjaxRequest.DELIM_KEY_VALUE + encodeURIComponent(value);
  return this;
}



AjaxRequest.prototype.setParameters = function(form)
{
  var fields = form.elements;

  for (var i=0; i < fields.length; i++)
  {
    if (fields[i].disabled) continue;

    var name = fields[i].name;

    switch(fields[i].type)
    {
      case AjaxRequest.FORM_FIELD_TEXT:
      case AjaxRequest.FORM_FIELD_HIDDEN:
      case AjaxRequest.FORM_FIELD_TEXTAREA:
        this.setParameter(name, fields[i].value);
        break;
      
      case AjaxRequest.FORM_FIELD_RADIO:
      case AjaxRequest.FORM_FIELD_CHECKBOX:
        if (fields[i].checked)
        {
          this.setParameter(name, fields[i].value);
        }
        break;
      
      case AjaxRequest.FORM_FIELD_SELECT_ONE:
      case AjaxRequest.FORM_FIELD_SELECT_MULTIPLE:
        var options = fields[i].options;

        for (var j=0; j < options.length; j++)
        {
          if (options[j].selected)
          {
            this.setParameter(name, options[j].value);
          }
        }
        break;
    }
  }
  return this;
}



AjaxRequest.prototype.submit = function()
{

 
  var request = null;

  // INSTANTIATE THE XMLHttpRequest

  if (window.XMLHttpRequest)
  {
    request = new XMLHttpRequest();
  }
  else if (window.ActiveXObject) // MSIE 6 and older
  {
    try
    {
      request = new ActiveXObject(AjaxRequest.ACTIVEX_MSXML2_XMLHTTP);
    }
    catch (errorActiveX)
    {
      try
      {
        // older versions of MSIE
        request = new ActiveXObject(AjaxRequest.ACTIVEX_LEGACY_XMLHTTP);
      }
      catch (errorLegacyActiveX)
      {
        alert(AjaxRequest.ERROR_CREATE_REQUEST);
      }
    }
  }
  
  // SET THE READY STATE CHANGE HANDLER

  // cannot reference object member from the anonymous function
  var handlerFunction = this.mHandler;

  request.onreadystatechange = function() {
    
    if (AjaxRequest.READY_STATE_COMPLETE == request.readyState)
    {
      if (AjaxRequest.STATUS_OK == request.status)
      {
        if (handlerFunction) // only invoke if defined
        {
          handlerFunction(request.responseXML, request.responseText);
        }
      }
      else
      {
        alert(AjaxRequest.ERROR_REQUEST_STATE
          .replace(/\$code/, request.status)
          .replace(/\$text/, request.statusText));
      }
    }
  }

  // PREPARE THE REQUEST PROPERTIES AND ANY DEFAULTS

  var url    = this.mUrl;
  var body   = this.mRequestBody;
  var type   = this.mContentType;
  var params = this.mParams.join(AjaxRequest.DELIM_PARAM);

  // if no parameters are set, then there is no need to dispatch them

  if (params.length > 0)
  {
    var paramDelim = (0 > url.indexOf("?"))   // if a url already has a query
                   ? AjaxRequest.DELIM_QS     // string delimiter (?), use an
                   : AjaxRequest.DELIM_PARAM  // ampersand (&) instead

    if (body != null)      // User-set request body, all params go in
    {                      // the query string for both POST and GET.
      url += paramDelim + params;
    }
    else                   // no request body
    {
      if (this.mMethod == AjaxRequest.METHOD_POST)
      {
        url += paramDelim + params;
      }
      else
      {
        body = params;

        if (type == null)  // assign default if no type is set
        {
          type = AjaxRequest.CONTENT_TYPE_URL_ENCODED;
        }
      }
    }
  }

  // SUBMIT THE REQUEST

  request.open(this.mMethod, url, false);

  if (type != null)
  {
    request.setRequestHeader(AjaxRequest.CONTENT_TYPE, type);
  }

  type = AjaxRequest.CONTENT_TYPE_URL_ENCODED;
  request.setRequestHeader(AjaxRequest.CONTENT_TYPE, type);
  request.send(body);
  handlerFunction(request.responseXML, request.responseText);

}

