/*
 * anet.ajax
 * Objet statique de gestion de la communication client/serveur.
 */
anet.ajax = new function() {
	this._connections = new Array();	// tableau de connexions et donnees afferentes

	// send()
	// Ouvre une communication, envoie du JSON et recupere du JSON.
	// Parametres :
	// url			URL de connexion.
	// callback		Fonction a appeler au retour. Peut etre null ou optionnel.
	// data			Objet Javascript a envoyer en POST apres serialisation JSON. Peut etre null ou optionnel.
	// timeout		Duree de timeout (en secondes) pour l'ensemble de la communication. Peut etre null ou optionnel.
	// callbackError	Fonction a apeller si le timeout se declenche. Peut etre null ou optionnel.
	// errorData		Parametre a donner a la fonction de timeout. Peut etre null ou optionnel.
	this.send = function(url, callback, data, timeout, callbackError, errorData) {
		var param = null, requestType = "POST";
		if (!data)
			requestType = "GET";
		else {
			param = encodeURIComponent(data.toJSONString());
			if (!param.length) {
				requestType = "GET";
				param = null;
			}
		}
		var index = this._createConnection();
		this._connections[index].handler = callback;
		this._connections[index].errorHandler = callbackError;
		this._connections[index].errorData = errorData;

		this._connections[index].http.open(requestType, url, true);
		if (requestType == "POST") {
			this._connections[index].http.setRequestHeader("Content-length", param.length);
			this._connections[index].http.setRequestHeader("Connection", "close");
			this._connections[index].http.setRequestHeader("Connection", "close");
		}
		if (timeout)
			this._connections[index].timer = setTimeout(function() {
				anet.ajax._abortConnection(index);
			}, timeout * 1000);
		this._connections[index].http.onreadystatechange = function() {
			var http = anet.ajax._connections[index].http;
			if (http.readyState != 4)
				return;
			if (anet.ajax._connections[index].timer)
				clearTimeout(anet.ajax._connections[index].timer);
			if (http.status != 200)
				return;

			// appelle le handler avec le bon parametre
			if (anet.ajax._connections[index].handler) {
				//var xml = http.responseXML;
				var json = http.responseText.parseJSON();
				anet.ajax._connections[index].handler(json);
			}
			anet.ajax._deleteConnection(index);
		};
		this._connections[index].http.send(param);
	}

	// *******************************************************
	// *                  Methodes privees                   *
	// *******************************************************

	// _createXMLHttpRequest()
	// Cree un objet de connexion XML/HTTP.
	this._createXMLHttpRequest = function() {
		try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) {}
		try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {}
		try { return new XMLHttpRequest(); } catch(e) {}
		alert("XMLHttpRequest not supported");
	};

	// _createConnection()
	// Cree une connexion HTTP et retourne son index.
	this._createConnection = function() {
		var http = this._createXMLHttpRequest();
		var connection = {
			http:		http,	// anet.ajax, anet.Rpc
			timer:		null,	// anet.ajax, anet.Rpc
			handler:	null,	// anet.ajax, anet.Rpc
			errorHandler:	null,	// anet.ajax
			errorData:	null,	// anet.ajax
			rpc:		null,	// anet.Rpc
			data:		null,	// anet.Rpc
			callbackData:	null	// anet.Rpc
		};
		var index = this._connections.push(connection);
		return (index - 1);
	};

	// _abortConnection()
	// Termine une connexion.
	this._abortConnection = function(index) {
		this._connections[index].http.abort();
		this._connections[index].timer = null;
		if (this._connections[index].errorHandler)
			this._connections[index].errorHandler(this._connections[index].errorData);
		this._deleteConnection(index);
	};

	// _deleteConnection()
	// Efface une connection.
	this._deleteConnection = function(index) {
		this._connections[index] = null;
	};
};

