var async_request_timeout = 30000;
var aj_timers   = new Array();
var aj_timeouts = new Array();
function startAjaxTimer(id){
	var aj_timer  = new Date();
	aj_timers[id] = aj_timer.getTime();
}
function stopAjaxTimer(id){
	if(typeof(aj_timers) == "undefined" || typeof(aj_timers[id]) == "undefined" || aj_timers[id] == null) return 0;
	var aj_timer  = new Date();
	end_time = aj_timer.getTime();
	var e_time = (end_time - aj_timers[id])/1000;
	aj_timers[id] = null;
	return e_time;
}

//////////////////////////////////////////////////////////////////////
//  AjaxClient()
//////////////////////////////////////////////////////////////////////
function AjaxClient(){
	this.response = 'AJAX_NO_RESPONSE_YET';
	try {
		if (document.all){
			this.ajax_client = new ActiveXObject("Microsoft.XMLHTTP");
		}else{
			this.ajax_client = new XMLHttpRequest();
		}
		this.complete    = new AJAXCallbackManager2();  // status code 4
		this.interactive = new AJAXCallbackManager2();  // status code 3
		this.loaded      = new AJAXCallbackManager2();  // status code 2
		this.loading     = new AJAXCallbackManager2();  // status code 1
		this.init        = new AJAXCallbackManager2();  // status code 0
	}
	catch(error){
		AJAX_handle_exception2(error);
	}
}

var __counter__ = 0;
AjaxClient.prototype ={
	/**
	*  send a get query
	*/
	get:function(url, async) {
		var c = __counter__;
		str  = "__ac__"+__counter__++;
		if (async){
			startAjaxTimer(c);
			this.ajax_client.open('GET', url);
			eval(str+" = this;");
			eval(str+".ajax_client.onreadystatechange = function() {"+str+".handleResponse("+str+","+c+");"+"}");
			this.ajax_client.send(null);
			aj_timeouts[c] = window.setTimeout(str+".checkReadyState('"+url+"','')", async_request_timeout);
		} else {
			this.ajax_client.open('GET', url ,false);
			this.ajax_client.send(null);
			return this.ajax_client.responseText;
		}
	},
	handleResponse:function(ac_obj, c){
		var msg = ac_obj.ajax_client.readyState;
		msg += " ";
		try{
			msg += ac_obj.ajax_client.status
		}
		catch(e){msg += " no status";}
		if(ac_obj.ajax_client.readyState == 4){
			clearTimeout(aj_timeouts[c]);
			var e_time = stopAjaxTimer(c);
			ac_obj.complete.callback(ac_obj.ajax_client.responseText, ac_obj.ajax_client.status+"  "+ac_obj.ajax_client.statusText+"  ("+e_time+" sec)");
		}
		
		if(ac_obj.ajax_client.readyState == 3){
			ac_obj.internalResponseHandler ('interactive (3)');
			ac_obj.interactive.callback ();
		}
		
		if(ac_obj.ajax_client.readyState == 2){
			ac_obj.internalResponseHandler ('loaded (2).');
			ac_obj.loaded.callback ();
		}
		
		if(ac_obj.ajax_client.readyState == 1){
			ac_obj.internalResponseHandler ('loading.... (1)');
			ac_obj.loading.callback ();
		}
		
		if(ac_obj.ajax_client.readyState == 0){
			ac_obj.internalResponseHandler ('uninitialized (0)');
			ac_obj.init.callback ();
		}
	},
	internalResponseHandler:function(status){
		//document.title = 'js client status: ' + status;
	},
	/**
	 *   send a post query
	 */
	post:function (url, request, async) {
		var c = __counter__;
		str  = "__ac__"+__counter__++;
		try {
			if (async) {
				startAjaxTimer(c);
				this.ajax_client.open("POST",url,true);
				this.ajax_client.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
				this.ajax_client.send(request);
				eval(str+" = this;");
				eval(str+".ajax_client.onreadystatechange = function() {"+str+".handleResponse("+str+","+c+");"+"}");
				aj_timeouts[c] = window.setTimeout(str+".checkReadyState('"+url+"','"+request+"')", async_request_timeout);
			} else {
				this.ajax_client.open("POST",url,false);
				this.ajax_client.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
				this.ajax_client.send(request);
				return this.ajax_client.responseText;
			}
		} catch (error) {
			AJAX_handle_exception2 (error);
		}
	},
	checkReadyState:function(url, request){
		if(this.ajax_client.readyState != 4){
			this.ajax_client.abort();
		}
	}
}

/**
 *
 * This is a better callback manager which allows many callbacks
 *
 */
function AJAXCallbackManager2()
{
	this.callback_counter =0;
	this.callbacks = new Array ();
	/** this one iterates over registered callbacks */
	this.callback=function callback(response_text, status){
		for (var i=0;i<this.callbacks.length;i++){
			try{
				this.callbacks[i](response_text, status);
			} catch (error) {
				AJAX_handle_exception2 (error);
			}
		}
	};
	this.register=function(callbackFunction) {
		this.callbacks[this.callback_counter++]=callbackFunction;
	};
}

function AJAX_handle_exception2 (error)
{
	alert("[Exception|creating AJAX_ro()]: "+error.name+ "; "+error.message + "; "+error.description+"; "+error.number);  
}
