
// AJAX PROTOTYPE ________________________________________________________


Ajax = function ()
{
	this.isIE = false;
	this.http = null;
}



Ajax.prototype.makeRequest = function (url, param)
{
  this.init();
  
  // options parameters
	//
	var param = (param) ? param : {};
	
	
  /*
   * the paramaters can define
   * the request method (GET | POST)
   * if the request is asynchrounous (true | false)
   * and the handlers for 
   * onclomplete, onloading, onerror events (they are function with the xmlhttpreqest, target 
   * object and element target object as parameters).
   * 
   */
   
  // defaults values
	var def = {
    method:'POST',
    target:null,
    asynch:true,
    timeout:180000,// 3 min (!)
    onTimeOut:function(target){ alert('The application is taking a bit too long...\nPlease try again'); },
    onComplete:function(o,target){ if(target) target.innerHTML = o.responseText; else throw "Error: no target specified"; },
    onLoading:function(o,target){},
    onError:function(o,target){ alert("ERROR: "+o.statusText); }
  };
  
  // fill in the missing user param with default values
  for (k in def)
	if ((typeof(param[k]) != typeof(def[k])) && typeof(def[k]) != null) 	param[k] = def[k];
  
  this.target = param.target;
  this.onComplete = param.onComplete;
  this.onError = param.onError;
  this.onLoad = param.onLoading;
  this.onTimeOut = param.onTimeOut;
  this.aborted = false;
  this.reqComplete = false;
  
  var pointer = this;
  this.http.onreadystatechange = function () { pointer.processReqChange() };
  
  var onTimeoutInternal = function() { 
    if ( pointer.http !=null && !pointer.reqComplete) { 
      
      pointer.aborted = true;
      pointer.http.abort();
      pointer.onTimeOut(pointer.target);
      
      // Opera won't fire onreadystatechange after abort, but other browsers do. 
      // So we can't rely on the onreadystate function getting called. Clean up here! 
      delete pointer.http['onreadystatechange']; 
      pointer.http = null; 
    }
  }
  
  this.http.open(param.method, url, param.asynch);
	  
  if(param.method.toUpperCase() == 'POST'){

    if(param.data == null) param.data = '';  

    this.http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    this.http.setRequestHeader("Content-length", param.data.length);
    this.http.setRequestHeader("Connection", "close");
    
    // send http data to the server
    var postdata = param.data;
  }
  else 
  {
	  var postdata = null;
  }
  if (param.timeout > 0) {
    setTimeout(onTimeoutInternal,param.timeout);
  }  
  this.http.send(postdata);
}


Ajax.prototype.init = function ()
{
  if(this.http != null)
     return this.http;

  try
  {
    // Firefox, Opera, Safari, IE7
    this.http = new XMLHttpRequest();
    //alert(' XMLHttpReques object created');
  }
  catch(e)
  {
    // Internet Explorer Microsoft :-(
    this.isIE = true;
    var success = false;
    //alert('XMLHttpReques NOT supported, trying ActiveX');
    
    var XMLHTTPD_IDS = new Array('MSXML2.XMLHTTP.5.0',
        							 'MSXML2.XMLHTTP.4.0',
        							 'MSXML2.XMLHTTP.3.0',
        							 'MSXML2.XMLHTTP',
        							 'Microsoft.XMLHTTP');
        
    for (var i = 0; i < XMLHTTPD_IDS.length && !success; i++){
      try
      {
         //alert("trying with "+XMLHTTPD_IDS[i]);
         this.http = new ActiveXObject(XMLHTTPD_IDS[i]);
      	 success = true;
      }
      catch(e) {  }
      }
      if (! this.http)
      {
        throw "No XMLHTTPRequest support found";
      }
    }
}


Ajax.prototype.processReqChange = function()
{
  switch(this.http.readyState)
  {   
    case 1: {
     try { 
       this.onLoad(this.http, this.target); 
     }
     catch(e){ alert(e);}
    }
    break;
    case 4: {
      
      if(this.aborted)
        return;
      try{
        // only if "OK"
        if (this.http.status == 200)
        {
          this.onComplete( this.http, this.target );
        } 
        else
        {
          this.onError( this.http, this.target);
          alert("STATUS = "+this.http.status);
          
        }
        this.reqComplete = true;
      }
      catch(e){ alert("e = "+e.toString()); this.onError(this.http, this.target); }
      
      // Clean up so IE doesn't leak memory
      delete this.http['onreadystatechange']; 
      this.http = null;
    }
  }
}



// STATIC AJAX SERIALIZE__________________________________________________________________________________________

Ajax.serialize = function(formName)
{
  var form = document.forms[formName];
  var urlQuery = "";
  
  for(var i = 0; i < form.length; i++)
  {
    if(!form[i].disabled && (form[i].type == 'checkbox'? form[i].checked: true)){
      urlQuery += (i > 0) ? "&" : "";
      urlQuery += encodeURI(form[i].name) + "=" + encodeURI(form[i].value);
    }
  }
 
  // returns serialized URI encoded elements of the specified form
  return urlQuery;
}

//var ajax = new Ajax();
