/******************************************
Copyright (c) 2007 Siborg2

Package Ajax : 
Class object Ajax
Contient toutes les fontions de relative à la communication de requête au serveur

/**********************/
/* Historique 

29 Nov. 2007 : création du fichier -> Sylvie Nault
29 Nov. 2007 : création class Ajax -> Sylvie Nault
29 Nov. 2007 : création méthode Ajax.makeRequest -> Sylvie Nault
29 Nov. 2007 : création méthode Ajax.prepareHTTPRequest -> Sylvie Nault
29 Nov. 2007 : création méthode Ajax.setSuccessCallback -> Sylvie Nault
29 Nov. 2007 : création méthode Ajax.setCallback -> Sylvie Nault
29 Nov. 2007 : création méthode Ajax.setFailureCallback -> Sylvie Nault
29 Nov. 2007 : création méthode Ajax.setOtherCallback -> Sylvie Nault
29 Nov. 2007 : création méthode Ajax.setProgressCallback -> Sylvie Nault

12 Dec. 2007 : création méthode Ajax.init -> Sylvie Nault
12 Dec. 2007 : création méthode Ajax.buildRequest -> Sylvie Nault
12 Dec. 2007 : création méthode Ajax.buildBody -> Sylvie Nault
12 Dec. 2007 : création méthode Ajax.send -> Sylvie Nault

12 Dec. 2007 : destruction méthode Ajax.makeRequest -> Sylvie Nault
12 Dec. 2007 : destruction méthode Ajax.prepareHTTPRequest -> Sylvie Nault


*******************************************/

/************************************/
// Contructeur Ajax
/************************************/	
function Ajax(){
	this.request = null;
	
	if (!this.init())
		throw "Ajax: Impossible d'initialiser la requête AJAX";
		
	this.method = Ajax.METHOD_GET;
	this.cacheControl = Ajax.CACHE_NONE;
	
	this.arg_list = null;
	
	this.requestArguments = { };
	this.bodyArguments = { };
	
	this.callbacks = { success: null, failure: null, other: null, progress: null };
}


Ajax.METHOD_GET = 				"GET";
Ajax.METHOD_POST = 				"POST";

Ajax.RESPONSE_PLAIN = 			1;
Ajax.RESPONSE_XML = 			2;
Ajax.RESPONSE_HTML = 			3;
Ajax.RESPONSE_SERIALIZED = 		4;
Ajax.RESPONSE_HTML_SERIALIZED = 5;
Ajax.RESPONSE_JSON = 			6;
Ajax.RESPONSE_HTML_JSON = 		7;

Ajax.STATE_UNINITIALIZED 		= 0;
Ajax.STATE_LOADING		 		= 1;
Ajax.STATE_LOADED		 		= 2;
Ajax.STATE_INTERACTIVE	 		= 3;
Ajax.STATE_COMPLETE	 			= 4;

Ajax.CACHE_NONE = 				"no-cache";

Ajax.EVT_ALL = 					100;
Ajax.EVT_REQUEST_STARTED = 		101;
Ajax.EVT_READY_STATE_CHANGE = 	102;

Ajax.XML_NODE_DOCUMENT =		0;
Ajax.XML_NODE_TAG = 			1;
Ajax.XML_NODE_TEXT =			2;

Ajax.escape = function ( str )
{
//	return (str==null) ? null : encodeURIComponent(str.toString().toAnsi("_"));
	return (str==null) ? null : escape(str.toString().toAnsi("_"));
}


/************************************/
// Methode init
// Cette methode permet d'initialisé une requête AJAX
/************************************/	
Ajax.prototype.init = function ()
{
	var request = null;
	if (window.XMLHttpRequest) { // Mozilla, Opera, Safari,...
		request = new XMLHttpRequest();
	}
	else if (window.ActiveXObject) { // IE
		try {
			request = new ActiveXObject("Microsoft.XMLHTTP");
		} catch (e) { }
	}

	if (!request) throw "Ajax : Impossible de créer une instance XMLHTTP";
	
	if(arguments.length>2){
		this.arg_list = new Array();
		for(var a=2; a<arguments.length; a++){
			this.arg_list.push(arguments[a]);
		}
	}

	var _this = this;
	request.onreadystatechange = function () {
		if (_this.callbacks.progress)
			_this.callbacks.progress(_this);
		
		if (_this.request.readyState == Ajax.STATE_COMPLETE) {
			var statusCode = _this.request.status;
			
			if (statusCode>=400 && statusCode<600) {
				throw "Ajax : Un problème est survenu avec la requête. Code : "+_this.request.status;
				alert('Un problème est survenu avec la requête. Code : '+_this.request.status );
				if (_this.callbacks.failure)
					_this.callbacks.failure(_this);
			} else if (statusCode>=200 && statusCode<300) {
				if (_this.callbacks.success){
					if(typeof(_this.arg_list) == "object")
						_this.callbacks.success(_this, _this.arg_list);
					else
						_this.callbacks.success(_this);
				}		
			} else {
				throw "Ajax : Un problème est survenu avec la requête. Code : "+_this.request.status;
				alert('Un problème est survenu avec la requête. Code : '+_this.request.status );
				if (_this.callbacks.other)
					_this.callbacks.other(_this);
			}
		}
	}

	this.request = request;
	return true;
}


/************************************/
// Setter function callback
//Liste des fonctions permettant de setter les différentes fonction de retour de la variable callbacks
/************************************/	
Ajax.prototype.setSuccessCallback = function ( func )
{
	if (func!=null && typeof(func)!="function")
		throw "Ajax.setSuccessCallback: Function manquante le retour de la requête";
	this.callbacks.success = func || null;
}

Ajax.prototype.setCallback = Ajax.prototype.setSuccessCallback; // alias

Ajax.prototype.setFailureCallback = function ( func )
{
	if (func!=null && typeof(func)!="function")
		throw "Ajax.setFailureCallback: Function manquante le retour de la requête";
	this.callbacks.failure = func || null;
}

Ajax.prototype.setOtherCallback = function ( func )
{
	if (func!=null && typeof(func)!="function")
		throw "Ajax.setOtherCallback: Function manquante le retour de la requête";
	this.callbacks.other = func || null;
}

Ajax.prototype.setProgressCallback = function ( func )
{
	if (func!=null && typeof(func)!="function")
		throw "Ajax.setProgressCallback: Function manquante le retour de la requête";
	this.callbacks.progress = func || null;
}


Ajax.prototype.setMethod = function ( method )
{
	if (!method)
		throw "Ajax.setMethod: Must provide a constant for Ajax request method (POST, GET)";

	this.method = method;
}

Ajax.prototype.setResponseType = function ( responseType )
{
	if (responseType)
		this.setArgument("response", intVal(responseType));
}

Ajax.prototype.clearArguments = function ()
{
	this.requestArguments = new Object();
}

Ajax.prototype.getArgument = function ( name )
{
	if (name==null) throw "Ajax.getArgument: Must provide a name for request argument";

	return this.requestArguments[name.toString()];
}

Ajax.prototype.setArgument = function ( name, value )
{
	if (name==null) throw "Ajax.setArgument: Must provide a name for request argument";

	if (arguments.length==1 && typeof(arguments[0])=="object")
		for (var k in arguments[0]) {
			this.requestArguments[k] = arguments[0][k];
		}
	else if (arguments.length==2)
		this.requestArguments[name.toString()] = value;
}

Ajax.prototype.clearBodyArguments = function ()
{
	this.bodyArguments = new Object();
}

Ajax.prototype.setBodyArgument = function ( name, value )
{
	if (!name) throw "Ajax.setArguments: must provide a name for body argument";

	if (arguments.length==1 && typeof(arguments[0])=="object")
		for (var k in arguments[0]) {
			this.bodyArguments[k] = arguments[0][k];
		}
	else if (arguments.length==2)
		this.bodyArguments[name.toString()] = value;
}

Ajax.prototype.buildRequest = function ( scriptUrl, randomize ){
	var str = "";
	for (var name in this.requestArguments) {
		if (str!="") str += "&";
		str += (Ajax.escape(name)+"="+Ajax.escape(this.requestArguments[name]));
	}
	if (randomize!==false)
		str += ((str=="") ? ("rnd="+Math.random()) : ("&rnd="+Math.random()));
	return (scriptUrl+"?"+str);
}


Ajax.prototype.buildBody = function (){
	var str = "";
	for (var param in this.bodyArguments) {
		if (str!="") str += "&";
		str += (Ajax.escape(param)+"="+Ajax.escape(this.bodyArguments[param]));
	}
	return str;
}


Ajax.prototype.send = function ( url, sync, method, allowCaching ){
	if (!this.init())
		throw "Ajax.send: Impossible d'initialiser la requête AJAX";

	if (!method) method = this.method;

	var fullUrl = this.buildRequest(url, (allowCaching!==true)); // debugging
	//prompt("tetst", fullUrl)
	this.request.open(method, fullUrl, (sync!==true));
	this.request.setRequestHeader("Cache-control", "no-cache");
	if (method==Ajax.METHOD_POST)
		this.request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	if (this.request.overrideMimeType) // bug mozilla
		this.request.setRequestHeader("Connection", "close");

	//prompt("",fullUrl)
	var body = this.buildBody();
	this.request.send(body);
	
}






