function AJAX(url,reqType,asynch){
	if(url == null){
		throw new Error("Le constructeur requiert un url");
	}
	if(reqType == null){
		throw new Error("Le deuxième argument (post ou get) est requis par le constructeur de la classe AJAX");
	}else if(reqType.toLowerCase() != "post" && reqType.toLowerCase() != "get"){
		throw new Error("Le type d'envoi (post ou get 2e argument string) est requis dans le constructeur");
	}
	if(asynch == null){
		throw new Error("Le troisième argument est requis par le constructeur de la classe AJAX");
	}else if(typeof asynch != "boolean"){
		throw new Error("Le troisième argument requis par le constructeur de la classe AJAX doit être booléen");
	}
	
	/*
	PRIVATE
	*/
	this.__request__ = null;
	if(window.XMLHttpRequest){
        this.__request__ = new XMLHttpRequest();
    } else if(window.ActiveXObject){
        this.__request__=new ActiveXObject("Msxml2.XMLHTTP");
        if (!this.__request__){
            this.__request__=new ActiveXObject("Microsoft.XMLHTTP");
				if (!this.__request__){
					if(this.debug)
						alert("Ce navigateur ne prend pas en charge les requêtes asynchrones");
					throw new Error("AJAX n'est pas pris en charge par ce navigateur");
				}
        }
	}
	this.__url__ = url;
	this.__asynch__ = asynch;//true par dfaut
	this.__reqType__ = reqType;//post par dfaut
	//this.__url__Vars sera pouss dans le tableau juste avant de faire le join("&")
	this.__url__Vars = arguments[3];//si GET cette valeur est nulle
	this.__urlVars__ = new Array();
	/*
	PUBLIC
	*/
	this.handleResponse = null;//on y affecte la fonction de recupration de document
	this.onreadystatechange = null;//on y affecte une fonction qui sera excute  chaque changement d'tat de la requte
	this.responseXML = null;//la rponse xml est affecte ici
	this.responseText = null;//la rponse Texte est affecte ici
	this.waitingForResponse = false;//permet de savoir si on attend aprs une rponse du serveur
	this.status = null;// = 200 ok ou 404 not found(int)
	this.statusText = null;//retourne "OK" ou "not found"(string)
	this.json = null;//pointeur sur l'objet json créé si le type mime du document est json
	this.charsetRequest = "iso-8859-1";
	this.debug = false;//va faire un alert de l'exception qui peut arriver dans le handleResponse
	/*
	0 = non initialisé, open() n'a pas encore ete call; 
	1 = en chargement, send( ) n'a pas encore ete call; 
	2 = load, send( ) a ete call, et headers/status sont disponibles; 
	3 = interactif, responseText contient des donnes partielles; 
	4 = complete.
	*/
	this.readyState = null;
	/*
	événements
	*/
	this.onInitRequest = null;//quand une demande au serveur est faite, cette fonction est dclenche
	this.onResponse = null;//quand la rponse du serveur est faite, cette fonction est dclenche
}
AJAX.prototype.addUrlKeyVal = function(cle,valeur){
	//si c'est une clé et une valeur
	if((typeof cle).toLowerCase() == "string"){
		this.__urlVars__.push(cle + "=" + encodeURIComponent(valeur));
	}else if(cle.type == "select-multiple"){//listbox multi select
		for(t=0;t<cle.options.length;t++){
			if(!cle.options[t].selected)
				continue;
			//bon pour php seulement
			this.__urlVars__.push(cle.name + "[]" + "=" + encodeURIComponent(cle.options[t].value));
		}
	}else if(cle.type == "select-one"){//listbox single select
		this.__urlVars__.push(cle.name + "=" + encodeURIComponent(cle.options[cle.selectedIndex].text));
	}else if(cle.type == "checkbox"){
		if(cle.checked){
			this.__urlVars__.push(cle.name + "=" + encodeURIComponent("on"));
			return;
		}
		this.__urlVars__.push(cle.name + "=" + encodeURIComponent("off"));
	}
}
AJAX.prototype.initRequest = function(){
    if(this.onInitRequest != null)
		this.onInitRequest();
	if(this.__request__ == null){
		alert("Votre fureteur ne permet pas d'utiliser toutes"+
              "\n les fonctionalités de cette application!\n Faites vos mises  jour");
		return false;
	}
	try{
		var me=this;
		this.__request__.onreadystatechange = function(){
			me.__onreadystatechange();
		}
        // Spécifie la fonction qui va etre appele lors de la reponse du serveur
        this.__open(this.__reqType__,this.__url__,this.__asynch__);
        this.waitingForResponse = true;
		if(this.__reqType__.toLowerCase() == "post") {
            this.__setRequestHeader("Content-Type",
                    "application/x-www-form-urlencoded; charset=" + this.charsetRequest);
            //des fois qu'un url serait passe par le constructeur
			if(this.__url__Vars != null)
				this.__urlVars__.push(this.__url__Vars);
			this.__send(this.__urlVars__.join("&"));
        }else{
            this.__send(null);
        }
		
    }catch(errv) {
		if(this.debug)
			alert(
			"L'application ne peut contacter "+
			"le serveur pour le moment.\n"+
			"Essayez de nouveau dans quelques secondes.\n"+
			"Detail de l'erreur: " + errv.message + "." + "\n\n(mode débogage)");
			return false;
    }
}
AJAX.prototype.__onreadystatechange = function(){
	if(!this.waitingForResponse)
		return false;
	this.readyState = this.__request__.readyState;
	if(this.readyState == 4){
		try{//le if plante dans mozilla quand une autre demande se fait avec le mme objet sans que celui-ci n'ait encore reu sa rponse
			this.status = this.__request__.status;
			this.statusText = this.__request__.statusText;
			if(this.status == 200 || this.status == 304/*opera*/){//si la page a ete trouve
				this.waitingForResponse = false;
				this.responseXML = this.__request__.responseXML;
				this.responseText = this.__request__.responseText;
				if(this.responseText==null)
					throw new Error("Vous devez exécuter la requête asynchrone avant d'appeler cette méthode");
				if(this.getResponseHeader("Content-Type").search(/json/gi) != -1){
					try{
						this.json = eval("(" + this.responseText + ")");
					}catch(e){
						if(this.debug)
							alert("Le document JSON récupéré n'est pas bien formé\nRetour du serveur:\n\n" + this.responseText + "\n\(mode déboguage)");
						throw new Error("Le document récupérée ne correspond pas à un format JSON");
					}
				}
				if(this.handleResponse != null){
					try{
						this.handleResponse();
					}catch(e){
						if(this.debug)
							alert(e.message + "\n\n(mode débogage)");	
					}
				}
				if(this.onResponse != null)
					this.onResponse();
			}else if(this.status == 404){
				if(this.debug)
					alert("La page n'a pu être trouvée sur le serveur" + "\n\n(mode débogage)");
				throw new Error("La page n'a pu être trouvée sur le serveur");
			}else{
				if(this.debug)
					alert("Une erreur a été rencontrée sur le serveur\nNo. de l'erreur : " + this.status + "\n\n(mode débogage)");
				throw new Error("Une erreur a été rencontrée sur le serveur\nNo. de l'erreur : " + this.status);
			}
		}catch(e){
		}
	}
	if(this.onreadystatechange != null)
		this.onreadystatechange();
}
AJAX.prototype.statusText = function(){
	return this.__request__.statusText;
}
AJAX.prototype.abort = function(){
	if(this.__request__.readyState != 0 && this.__request__.readyState != 4){
		this.__request__.abort();
		this.handleResponse = function(){};//mozilla est cave là-dessus, il se peut qu'il execute le handle pareil
	}
	this.waitingForResponse = false;
}
AJAX.prototype.getAllResponseHeaders = function(){
		return this.__request__.getAllResponseHeaders( ) 	
}
AJAX.prototype.getResponseHeader = function(header){
	return this.__request__.getResponseHeader(header);	
}
AJAX.prototype.__open = function(url,asynch){
	this.__request__.open(url,asynch);	
}
AJAX.prototype.__send = function(chaine) {
	this.__request__.send(chaine); 	
}
AJAX.prototype.__setRequestHeader = function(header,value){
	this.__request__.setRequestHeader(header,value);	
}
function WebAccessor(path,post,jsonParams){
	var me = this;
	this.responseListeners = new Array();
	this.ajax = new AJAX(path,post?"POST":"GET",true);
	for(x in jsonParams){
		this.ajax.addUrlKeyVal(x,jsonParams[x]);
	}
	this.ajax.debug = true;
	this.ajax.handleResponse = function(){
		alert(this.responseText);
		for(var i=0;i<me.responseListeners.length;i++)
			me.responseListeners[i](me,this.json);//passe le sender (WebAccessor) et l'objet json retourné du serveur
	}
	this.ajax.initRequest();
}
WebAccessor.prototype.addResponseListener=function(func){
	this.responseListeners.push(func)
}
