//	Declercq Carl, Robloche, Andrew Gregory & poof65

//Start ServerRequest Object
function ServerRequest() 
{
   //xmlHttpRequest object:
   this.xhr_object    = (typeof(XMLHttpRequest)!="undefined")?new XMLHttpRequest():null;
   
   //response value
	this.response      = null;

   //state of transaction
	this.ready         = true;

   //type of request connection
	this.asynchronous  = true;
   
   //Set some default variables
   this.postvars = new Array();
   
   //Set default execute params
   this.methode = "GET"
   this.server = 'phprequest.php';

   //reference to a methode that indicate the state of communication
	this.indicatorFunction = null;

   //reference to a methode that execute on result
   this.CallFunction = null;
  
   // Alias de this.getFileGet
   this.getFile = this.getFileGet;

   //Set the messages on?
   this.debugMode = false;
   
   //timer (to wait)
   this.timer=null;

   this._typeName = "ServerRequest";
   
}

//add some parameter to send
ServerRequest.prototype.add=function(name,value)
{
  //Add a new param object to the params
  if(this.replace(name,value)!=0)
     this.postvars.Add(new PostVariable(name,value));
}

ServerRequest.prototype.replace=function(name,value)
{
   var error=1;
   for(var i=0;i<this.postvars.length;i++)
   {
      if(this.postvars[i].name!=name)
         continue;
      this.postvars[i].value=value;
      error=0;
      break;
   }
   return error;
}

//convert the parameters array to a GET url string 
ServerRequest.prototype.stringOfparams=function()
{
    var txt = "";
    for(var i in this.postvars) 
    {
      if(this.postvars[i]._typeName == "PostVariable")
      {
         txt += '&'+this.postvars[i].toString();
      }
    }
    return txt; 
}

// Permet de définir la fonction qui servira d'indicateur de communication
ServerRequest.prototype.setIndicatorFunction = function(func,args) 
{
	if(typeof(func) != "function") 
      return;
   
   if(typeof(args)!='string')
   {
      this.indicatorFunction = new AddFunction("",func);
      this.indicatorFunction.AddParams(args);
   }
   else
      this.indicatorFunction = new AddFunction(args,func);      
}

ServerRequest.prototype.setCallFunction = function(func,args) 
{
	if(typeof(func) != "function") 
      return;
   
   if(typeof(args)!='string')
   {
      this.CallFunction = new AddFunction("",func);
      this.CallFunction.AddParams(args);
   }
   else
      this.CallFunction = new AddFunction(args,func);      
}

ServerRequest.prototype.setSynchronous = function() 
{
	this.asynchronous = false;
}

ServerRequest.prototype.setAsynchronous = function() 
{
	this.asynchronous = true;
}

// do A request with GET data
// Lance une requête sur un fichier du serveur en passant éventuellement des paramètres, avec la méthode GET
ServerRequest.prototype.getFileGet = function(url, data) 
{
	return this.doRequest(url, "GET", data);
}

// do A request with POST data
// Lance une requête sur un fichier du serveur en passant éventuellement des paramètres, avec la méthode POST
ServerRequest.prototype.getFilePost = function(url, data)
{
	return this.doRequest(url, "POST", data);
}

// Get all the headers to link to the url 
//(Récupère tous les header associés à l'URL passée en paramètre, ou juste le header passé en paramètre s'il est précisé)
ServerRequest.prototype.getFileHeader = function(url, header) 
{
	return this.doRequest(url, "HEAD", header);
}

// Excute the request 
//  - method : GET, POST or HEAD
//  - url    : path to the file.
//  - data   : data to send (ex : a=5&foo=bar)
ServerRequest.prototype.execute=function(fl_load)
{
   return this.doRequest(this.server,this.methode,this.stringOfparams());
}

ServerRequest.prototype.doRequest = function(url, method, data) 
{
	if(!this.ready || !this.xhr_object) return false;

	// Recherche header_name dans tous les headers et retourne la valeur correspondante
	// ou "Header inconnu..." si header_name n'a pas été trouvé
	function _getResponseHeader(headers, header_name) 
   {
		var tmp = headers.split("\n");
		for(var i=0, n=tmp.length, t=[]; i<n-1; ++i) {
			t = tmp[i].split(": ");
			if(t[0].toLowerCase() == header_name.toLowerCase()) return t[1];
		}
		return "Unknow Header...";
	}

	if(this.indicatorFunction)
      this.indicatorFunction.func(true,this.indicatorFunction.param);

   this.ready = false;

	// On copie la référence à l'objet courant car il ne sera plus "dans le contexte"
	// au moment où la fonction onreadystatechange sera exécutée
	var obj = this;
	function onreadystatechangeFunction() 
   {
		if(obj.xhr_object.readyState != 4) 
         return;
      
		if(obj.indicatorFunction) 
         obj.indicatorFunction.func(false,obj.indicatorFunction.param);
      /*
      if (!obj.xhr_object || !obj.xhr_object.status ||obj.xhr_object.status != 200)
      {
         if (obj.debugMode) 
         {
		      alert('Error HTTP\ncode = ' + obj.xhr_object.status + '\nMsg = ' + obj.xhr_object.statusText);
		   }
         obj.response="";
      }
      else
      {
         */
         var all_headers = obj.xhr_object.getAllResponseHeaders();
         if(method == "HEAD") 
         {
			   obj.response = data ? _getResponseHeader(all_headers, data) : all_headers;
		   }
		   else 
         {
			   var content_type = _getResponseHeader(all_headers, "Content-Type");
			   if (content_type != "Unknow Header..." && (new RegExp("^text/xml.*$", "gi")).test(content_type))
				   obj.response = obj.xhr_object.responseXML;
			   else
				   obj.response = obj.xhr_object.responseText;
            
            if(obj.CallFunction)
               obj.CallFunction.func(obj,obj.CallFunction.param);
         }
      //}
   }
	
   if(method == "GET" && typeof(data) != "undefined" && data != "") 
      url += "?"+data;
	
   //alert("method: "+method+" url: "+url+" asynchrone"+ this.asynchronous);
   try 
   {
      this.xhr_object.open(method, _AJAX_addDummyData(url), this.asynchronous);
   }
   catch (e)
   {
      //alert("Can't open XHR object Error:"+e.name+" message : "+e.message);
      this.ready = true;
      return false;
   } 
   
	if(this.asynchronous)
		this.xhr_object.onreadystatechange = onreadystatechangeFunction;
	
	if(data) 
      this.xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=iso-8859-1");
	else
   { 
      data = null;
   }
   
	this.xhr_object.send(data);

	if(!this.asynchronous)
		onreadystatechangeFunction();

	return true;
}

ServerRequest.prototype.IsBusy=function()
{
   return !this.ready;
}
// Return true if the result is returned else false
ServerRequest.prototype.hasResponse = function() 
{
	return this.response != null;
}

// Return the last result of the request
ServerRequest.prototype.getResponse = function() 
{
	return this.response;
}

// Init the request object (a new one can be done now)
ServerRequest.prototype.validateRequest = function() 
{
	this.ready    = true;
	this.response = null;
}
ServerRequest.prototype.cleanRequest = function()
{
   if(this.IsBusy())
   {
      this.cancelRequest();
   }

   this.response      = null;
	this.ready         = true;
	this.asynchronous  = true;
   this.postvars = new Array();
   this.methode = "GET"
   this.server = 'phprequest.php';
	this.indicatorFunction = null;
   this.CallFunction = null;
   this.getFile = this.getFileGet;
   this.debugMode = false;
   this.timer=null;
}
// Cancel the Request 
ServerRequest.prototype.cancelRequest = function() 
{
	this.xhr_object.abort();
	if(this.indicatorFunction)
      this.indicatorFunction.func(false,this.indicatorFunction.param);

	this.validateRequest();
}

//Utility Param class
function PostVariable(name,value)
{
  this.name = name;
  this.value = value;
  this._typeName = "PostVariable";
}

PostVariable.prototype.toString=function()
{
   if(typeof(this.value)=="string")
     return this.name+"="+this.value.replace(/\+/g,"%2B");
   else
     return this.name+'='+this.value;
}

function _AJAX_addDummyData(str) {
	var t = new Date();
   if (str.indexOf("?") == -1) str += "?ajax_dummy=";
   else                        str += "&ajax_dummy=";
	return str+t.getTime();
}

