/************************************************************************************
/// Titre: Classe d'abstraction AJAX
/// Date: 21/11/2005
/// Auteur: mathieu ALLOUCHE
/// 
/// Description: 
/// Permet de faire des requettes HTTP, sur un serveur web ou un web service.
/// Compatibilité : IE5.x et sup, mozilla 5.x et sup. 
///
///	Constructor list
///		- XMLHTTP()
/// Properties list :
///		- Response
///		- IsReady
/// Methods list
///		- ActivSynchronousMethode()
///		- ActivASynchronousMethode()
///		- SendGETRequest(URL, Data)
///		- SendPOSTRequest(URL, Data)
///		- GetHeader(URL, HeaderName)
///		- CancelRequest()
///		- HasResponse()
///		- GetResponse()
///		- Clear();
/// Events list
///		- OnCommunication
///		- OnArrivalMessage
///
/// Version:
/// 1.0		21/10/2003 - version initiale											(MA)
/// 
///************************************************************************************/

function XMLHTTP() {
	// Initialised the class properties	
	this.Response					= null;
	this.IsReady					= true;
	this.WithAsynchronousMethode	= true;
	this.RSobject					= null;
	this.OnCommunicationFunction	= null;
	
	// Create the communication object
	if(window.XMLHttpRequest) // Mozilla
		this.RSobject = new XMLHttpRequest();
	else if(window.ActiveXObject) // Internet Explorer
		this.RSobject = new ActiveXObject("Microsoft.XMLHTTP");
	else // XMLHttpRequest non supporté par le navigateur
		alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");

	///////////////////////////////////////////////////////////////////////////////////
	//                               PUBLIC METHOD LIST                              //
	///////////////////////////////////////////////////////////////////////////////////
	
	/// PUBLIC METHOD : OnCommunication 
	/// PARAMS : none
	/// DESCRIPTION : Link event
	this.OnCommunication = function(func) {
		//alert(func);
		if(typeof(func) == "function") this.OnCommunicationFunction = func;
	}
	
	/// PUBLIC METHOD : OnArrivalMessage 
	/// PARAMS : none
	/// DESCRIPTION : Link event
	this.OnArrivalMessage = function(func) {
		if(typeof(func) == "function") this.OnArrivalMessageFunction = func;
	}
	
	/// PUBLIC METHOD : ActivSynchronousMethode 
	/// PARAMS : none
	/// DESCRIPTION : Active the synchronous methode
	this.ActivSynchronousMethode = function() {
		this.WithAsynchronousMethode = false;
	}

	/// PUBLIC METHOD : ActivSynchronousMethode 
	/// PARAMS : none
	/// DESCRIPTION : Active the Asynchronous methode
	this.ActivASynchronousMethode = function() {
		this.WithAsynchronousMethode = true;
	}

	/// PUBLIC METHOD : SendGETRequest 
	/// PARAMS :
	///		- URL : HTML page or Web Service reference
	///		- Data : parameters for the page. Ex : var1=1&var2=2
	/// DESCRIPTION : Send a request for an URL and parameters, with GET method
	this.SendGETRequest = function(URL, Data) {
		return this.doRequest(URL, "GET", Data);
	}

	/// PUBLIC METHOD : SendGETRequest 
	/// PARAMS :
	///		- URL : HTML page or Web Service reference
	///		- Data : parameters for the page. Ex : var1=1&var2=2
	/// DESCRIPTION : Send a request for an URL and parameters, with POST method
	this.SendPOSTRequest = function(URL, Data) {
		return this.doRequest(URL, "POST", Data);
	}

	/// PUBLIC METHOD : GetHeader 
	/// PARAMS :
	///		- URL : HTML page or Web Service reference
	///		- HeaderName <optional> : awaited headings. If not specified, retrun all headings.
	/// DESCRIPTION : Recover headings for and URL.
	this.GetHeader = function(URL, HeaderName) {
		return this.doRequest(URL, "HEAD", HeaderName);
	}

	/// PUBLIC METHOD : doRequest 
	/// PARAMS :
	///		- URL : HTML page or Web Service reference
	///		- Method : GET, POST or HEAD
	///		- Data : awaited headings. If not specified, retrun all headings.
	/// DESCRIPTION : Private method. Execute the request.
	this.doRequest = function(URL, Method, Data) {
		//alert(URL+" " + this.IsReady);
		if(!this.IsReady || !this.RSobject) return false;
		
		if(this.OnCommunicationFunction) this.OnCommunicationFunction(true);
		this.IsReady = false;
		
		var obj = this;
		function onreadystatechangeFunction() {
		//alert(obj.RSobject.readyState);
			if(obj.RSobject.readyState != 4) return;
			if(obj.OnCommunicationFunction) obj.OnCommunicationFunction(true);

			var all_headers = obj.RSobject.getAllResponseHeaders();
			
			if(Method == "HEAD") {
				obj.response = Data ? _getResponseHeader(all_headers, Data) : all_headers;
			}
			else {
				var content_type = _getResponseHeader(all_headers, "Content-Type");
				//alert(content_type);
				if (content_type != "unknown header" && (new RegExp("^text/xml.*$", "gi")).test(content_type))
					obj.response = obj.RSobject.responseXML;
				else
				{
					obj.response = obj.RSobject.responseText;
					//alert(obj.response);
				}
				
				if(obj.OnArrivalMessageFunction) 
				{
					
					obj.OnArrivalMessageFunction(obj.response);
				}
			}
			if(obj.OnCommunicationFunction) obj.OnCommunicationFunction(false);
		}

		if(Method == "GET" && typeof(Data) != "undefined" && Data != "") URL += "?"+Data;
		//alert(Method + " " + URL + " " +this.WithAsynchronousMethode);
		this.RSobject.open(Method, URL, this.WithAsynchronousMethode);

		if(this.WithAsynchronousMethode)
			this.RSobject.onreadystatechange = onreadystatechangeFunction;
		
		if(Data)
			this.RSobject.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		else
			Data = null;
		this.RSobject.send(Data);

		if(!this.WithAsynchronousMethode) onreadystatechangeFunction();

		return true;
	}

	/// PUBLIC METHOD : HasResponse 
	/// PARAMS : none
	/// DESCRIPTION : Return true if request has return a response.
	this.HasResponse = function() {
		return this.response != null;
	}

	/// PUBLIC METHOD : GetResponse 
	/// PARAMS : none
	/// DESCRIPTION : Get the last response.
	this.GetResponse = function() {
		return this.response;
	}

	/// PUBLIC METHOD : Clear 
	/// PARAMS : none
	/// DESCRIPTION : Clear the response. Object ready for the next request.
	this.Clear = function() {
		this.IsReady    = true;
		this.response = null;
	}

	/// PUBLIC METHOD : CancelRequest 
	/// PARAMS : none
	/// DESCRIPTION : Cancel the request.
	this.CancelRequest = function() {
		this.RSobject.abort();
		if(this.OnCommunicationFunction) this.OnCommunicationFunction(false);
		this.ValidateRequest();
	}
	
	///////////////////////////////////////////////////////////////////////////////////
	//                               PRIVATE METHOD LIST                             //
	///////////////////////////////////////////////////////////////////////////////////
	
	/// PRIVATE METHOD : _getResponseHeader 
	/// PARAMS :
	///		- URL : HTML page or Web Service reference
	///		- Method : GET, POST or HEAD
	///		- Data : awaited headings. If not specified, retrun all headings.
	/// DESCRIPTION : ExtractPrivate method. Execute the request.
	
	function _getResponseHeader(headers, HeaderName) {
			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() == HeaderName.toLowerCase()) return t[1];
			}
			return "unknown header";
		}

}

/****************************************EXEMPLE********************************************

	///////////////////////////////////////////////////////////////////////////////////
	//                               ASYNCHRONOUS EXEMPLE                            //
	///////////////////////////////////////////////////////////////////////////////////
	
	var Request = new XMLHTTP();;
	var check_delay = 1000;
	var State; var NbUser;
	
	function initXMLHTTPRequestAsynchronous() {
		NbUser = getObject("NBUSER");
		sendRequestAsynchronous();}
			
	function sendRequestAsynchronous(){
		if (!Request.SendGETRequest("Http://www.test.fr/NBuser.aspx", "")) return
		setTimeout("checkResponse()", check_delay);}
		
	function checkResponse() {
		if (Request && Request.HasResponse()){
			var rep = Request.GetResponse();
			
			NbUser.innerHTML = rep.substring(0,4);
			
			Request.Clear();
			sendRequestAsynchronous();
			return(true);}
		else
				setTimeout("checkResponse()", check_delay);}
	
		
	///////////////////////////////////////////////////////////////////////////////////
	//                          SYNCHRONOUS EXEMPLE WITH EVENT                       //
	///////////////////////////////////////////////////////////////////////////////////
	
	var Request = new XMLHTTP();;
	var check_delay = 1000;
	var State; var NbUser;
	
	function initXMLHTTPRequestSynchronous() {
		NbUser = getObject("NBUSER");
		State  = getObject("STATE");
		Request.ActivSynchronousMethode();
		Request.OnCommunication(OnEvent);
				
		sendRequestSynchronous();}
			
	function sendRequestSynchronous(){
		if (!Request.SendGETRequest("Http://www.test.fr/NBuser.aspx", "var=Count")) return
		var rep = Request.GetResponse();
		
		NbUser.innerHTML = rep.substring(0,4);
		
		Request.Clear();
		setTimeout("sendRequestSynchronous()", check_delay);}
			
	function OnEvent(bCommunicate) {
		if (bCommunicate) State.innerHTML="Waiting"; else innerHTML.innerHTML="Ready";}
			
	document.onload = initXMLHTTPRequestSynchronous;
	
*******************************************************************************************/

