/**************************************************************************************************
* Classe générale de gestion des requêtes XMLHttpRequest
**************************************************************************************************/
// Constructeur
function xhr()
{
	this._xhr=null;
	this._busy=false;
	this._url=null;
	this._data=null;
	this._fct='';
	this._fctwait='';
	this._msg=false;
	this._timer=null;
	this._timeout=60000;
	this._async=null;
	this._sendval=null;
	this._starttime=0;
	this._time=0;
	this._responsesize=0;
	this._response='';
	this._ok=(window.XMLHttpRequest || window.ActiveXObject) ? true : false;
}

// Effectue une requete XMLHttpRequest et traite son résultat en fonction des paramètres passés
//	_url : url du fichier à exécuter
//	_fct : fonction qui doit traiter le résultat de la requête.
//			- S'il n'y a pas d'argument autre que la réponse de la requête, on passe juste le nom de la fonction
//			- S'il y a d'autres arguments que la réponse de la requête, on la passe sous la forme fonction('arg1','arg2'), avec ou sans la parenthèse fermante
//	_fctwait : fonction à appeler entre l'appel de la requête et son résultat (pour afficher un message de chargement en cours ou autre)
//	_sync : 1 = synchrone, 0 = asynchrone
xhr.prototype.request=function(_method,_url,_data,_fct,_fctwait,_sync)
{
	// Si une requête est en cours, on l'annule avant de lancer la nouvelle
	if (!this._ok) return false;
	if (this._xhr)
	{
		this.setBusy(false);
		this._xhr.abort();
		this._xhr=null;
	}
	this._response='';
	this._responsesize=0;
	this._starttime=new Date().getTime();
	this._time=0;
		
	// Détection du support d'XMLHttpRequest et création d'un objet s'y rapportant
	// Firefox et tous navigateurs Gecko compatibles (mozilla 1.4+, Netscape 7.1+, Safari 1.2.1+)
	if (window.XMLHttpRequest) this._xhr=new XMLHttpRequest();
	// Internet Explorer
	else if (window.ActiveXObject) this._xhr=new ActiveXObject("Microsoft.XMLHTTP");

	this._async=(typeof _sync == 'undefined' || !_sync) ? true : false; // true si mode asynchrone
	if (typeof _fct == 'undefined') _fct='';
	if (this._xhr && (!this._async || _fct))
	{
		// Ajout d'un paramêtre aléatoire à la liste des paramêtres de l'url appelée pour éviter les poblèmes de cache d'IE et Safari
		_data+=((_data) ? '&' : '') + 'xhrrand=' + Math.random();
		if (_fct)
		{
			// S'il y a une parenthèse fermante à la fonction passée en paramêtre, on la retire
			if (_fct.substring(_fct.length-1) == ')') _fct=_fct.substring(0,_fct.length-1);
			// Si la fonction est passée sans arguments, on ajoute la parenthèse d'ouverture, sinon on ajoute une virgule après les arguments
			_fct+=(_fct.indexOf('(') == -1) ? '(' : ',';
		}

		this._url=_url;
		this._data=_data;
		this._fct=_fct;
		this._fctwait=_fctwait;
		this.setBusy(true);

		if (_method == 'POST')
		{
			this._xhr.open('POST',_url,this._async);
			this._xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
			this._sendval=_data;
		}
		else this._xhr.open('GET',_url + '?' + _data,this._async);

		var _xhrtmp=this;
		if (this._async) this._xhr.onreadystatechange=function() { _xhrtmp.response(); };

		// 1 : début du transfert des données, à placer ici car Opera ne l'interprète pas dans la fonction "response"
//		if (this._xhr.readyState == 1 && this._fctwait) eval(this._fctwait);

		this._xhr.send(this._sendval); // Envoi de la requête
		if (!this._async) this.response();

		return true;
	}
	else return false;
};

xhr.prototype.get=function(_url,_data,_fct,_fctwait,_sync)
{
	return this.request('GET',_url,_data,_fct,_fctwait,_sync);
};
	
xhr.prototype.post=function(_url,_data,_fct,_fctwait,_sync)
{
	return this.request('POST',_url,_data,_fct,_fctwait,_sync);
};
	
xhr.prototype.setBusy=function(_state)
{
	// On stocke l'état actuel
	this._busy=_state;

	// Fonction d'attente au début du transfert, se substitue à (this._xhr.readyState == 1)
	if (_state && this._fctwait) eval(this._fctwait);

	// Si un timer tourne, on le stoppe
//	if (this._timer) this._timer=clearTimeout(this._timer);
	if (this._timer) clearTimeout(this._timer);

	// Si la requête est en cours et si elle est asynchrone, on lance le timer de timeout
	var _xhrtmp=this;
	if (this._async && _state && this._timeout) this._timer=setTimeout(function() { _xhrtmp.timedOut(); },this._timeout);
};

xhr.prototype.timedOut=function()
{
	this._busy=false;
	this._xhr.abort();
	if (this._fct) eval(this._fct + '"")');
};
	
xhr.prototype.response=function()
{
	if (this._busy)
	{
		// 1 : début du transfert des données, Opéra ne l'interprète pas lorsque placé ici
//		if (this._xhr.readyState == 1 && this._fctwait) eval(this._fctwait);
		// 4 : requête terminée
		if (this._xhr.readyState == 4)
		{
			this.setBusy(false);

			// 200 : code HTTP pour OK
			if (this._xhr.status == 200)
			{
				if (this._xhr.responseText != null)
				{
					this._response=this._xhr.responseText;
					this._responsesize=this._xhr.responseText.length;
				}
 				this.setRequestTime(); // Peut être redéfini après le traitement de la fonction this._fct() au besoin
				if (this._fct) eval(this._fct + '"' + escape(this._xhr.responseText) + '")');
			}
			// Si échec, on appelle la fonction sans texte résultat, la fonction devant interpréter ca comme un échec
			else if (this._fct) eval(this._fct + '"")');
		}
	}
};

xhr.prototype.setRequestTime=function()
{
	this._time=new Date().getTime() - this._starttime;
};

xhr.prototype.test=function(_txt) { alert(_txt); };
