// AJAX classes

/***** 
* function AJAX.insertHTML(DOMObject)	<- the DOM object where to put the HTML and it does the rest.
* function AJAX.SetCallback(callback, cas) <- 
* EXAMPLE:
* <script>
* // declaring the object with the url where to get the HTML
* ajax = new AJAX('./test.html');
* < / script >
* <!-- when clicking on the div, the url is called and replace the current HTML by the new one -->
* <div id="where_to_put" onClick="javascript:ajax.insertHTML( this );">
*   This should be replaced if you click here</div>
* <script language="javascript" type="text/javascript">
* // we could display a loading message in the div. Here we do a simple alert
* function loading() {
* 	alert('loading');
* }
* // and we link the function with the loading state
* ajax.SetCallback( loading , 0);
*
* // for managing errors, we link the following function ...
* function errorLoading() {
* 	alert('404 error');
* }
* // ... with the error state
* ajax.SetCallback( errorLoading, 2);
* < / script >
*****/
function kk_AJAX(Url) {
	// public	: how does the server expect the request ? (GET|POST|HEAD)
	this.requestMethod = 'GET';
	// public	: response of the server (when fully loaded, see method AJAX.SetCallback() )
	this.response = '';

	/**
	* public	: retrieving an XML response
	* for documentation on this object, see http://www.devguru.com/Technologies/xmldom/quickref/obj_httpRequest.html
	* callbackWhenOK	: the callback that will receive the responseXML object
	*/
	this.getXML = function(callbackWhenOK) {
		if(callbackWhenOK) {
			this.callbackXML = callbackWhenOK;
		}
		this.SetCallback(this.getXMLCallback, 1);
		this.Get(this.source);
	}

	/**
	* public	: retrieving teh text contained in a url
	* callbackWhenOK	: the callback that will receive the responseText object
	*/
	this.getText = function(callbackWhenOK) {
		if(callbackWhenOK) {
			this.callbackText = callbackWhenOK;
		}
		this.SetCallback(this.getTextCallback, 1);
		this.Get(this.source);
	}
	
	/**
	* public	: registers a callback, depending on the state of the connection
	* case 0	=> initializing and loading (happens many times)
	* case 1	=> the source is fully loaded
	* case 2	=> failure (404 ...)
	*/
	this.SetCallback = function(callback, cas) {
		if(cas > 2 || cas < 0) {
			return;
		}
		this.callbacks[cas].push(callback);
	}

	/**
	* public	: gets and inserts the text from the source at a given DOM object
	*/
	this.insertHTML = function(DOMObject) {
		this.DOMObject = DOMObject;
		//this.SetCallback(this.insertHTMLCallback, 1);
		this.getText(this.insertHTMLCallback);
	}

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

	// private	: location of the ressource
	this.source = Url;
	// private	: XMLHTTPRequest Object
	this.request = new Object;
	// private	: list of the callback
	this.callbacks = new Array(new Array(), new Array(), new Array());
	// private	: if needed, the pointer to the DOM object where the HTML will be written is stocked here
	this.DOMObject = new Object;
	// private	: if needed, stocks the callback waiting for an XML feed. Used by getXML()
	this.callbackXML = new Function;
	// private	: if needed, stocks the callback waiting for the responseText to be complete
	this.callbackText = new Function;

// trick for the callbacks function to access to this object
	var me = this;

	/**
	* private	: called when source is available. it puts the requested HTML at the given DOM object
	*/
	this.insertHTMLCallback = function(responseText) {
		me.DOMObject.innerHTML = responseText;
	}
	
	/**
	* private	: called when source is available. it calls back the registered callbackXML function
	*/
	this.getXMLCallback = function() {
		me.callbackXML(me.request.responseXML);
	}
	
	/**
	* private	: called when source is available.
	*/
	this.getTextCallback = function() {
		me.callbackText(me.request.responseText);
	}
	
	/**
	* private	: called when the readystate of the connection changes, then calls the registered callbacks (see method AJAX.SetCallback() )
	*/
	this.GetCallback = function() {
		// case OK (1)
		if (me.request.readyState == 4 && me.request.status == 200) {
			cas = 1;
			//alert('received headers :'+me.request.getAllResponseHeaders() );
		}
		// case failure (2)
		if (me.request.readyState == 4 && me.request.status != 200)
			cas = 2;
		// case loading (0)
		if (me.request.readyState < 4)
			cas = 0;
		//alert(me.callbacks[cas]);
		for(var i = 0; i < me.callbacks[cas].length; i++) {
			me.callbacks[cas][i](me.request);
		}
	}

	/**
	* private	: runs the XMLHttpRequest request, assigning private method GetCallback as callback
	*/
	this.Get = function( Url) {
		// code for Mozilla, etc.
		if (window.XMLHttpRequest) {
			this.request = new XMLHttpRequest();
			this.request.onreadystatechange = this.GetCallback;
			this.request.open(this.requestMethod, Url, true);
			this.request.send(null);
		} // code for IE
		else if (window.ActiveXObject) {
			this.request = new ActiveXObject("Microsoft.XMLHTTP")
			if (this.request) {
				this.request.onreadystatechange = this.GetCallback;
				this.request.open(this.requestMethod, Url, true);
				this.request.send();
			}
		}
	}
}
