AJAX = {


	/** Framework entry point location */
	location: null,

	/** XMLHttpRequest object */
	http: null,

	/** Call in progress flag */
	callInProgress: false,

	/** Max time to live for AJAX request */
	ttl: 15,

	/** AJAX request timer */
	timer: 0,

	/** Incomplete requests sweeper process */
	job: null,

	/** AJAX requests queue */
	queue: new Array(),


	getHttp: function() {
		if (window.XMLHttpRequest) {
			if (window.XMLHttpRequest) {
	            this.http = new XMLHttpRequest();
	        } else if(window.ActiveXObject) {
	            this.http = new ActiveXObject('Microsoft.XMLHTTP');
	        } else {
	            alert('Your browser does not support XMLHttpRequest object. May we suggest you using Firefox or Opera browser.');
	            document.location = 'http://www.getfirefox.com';
	        }
			if (typeof this.http.overrideMimeType != 'undefined') {
				this.http.overrideMimeType('text/xml');
			}
		} else if (window.ActiveXObject) {
			this.http = new ActiveXObject('Microsoft.XMLHTTP');
		}
		this.http.open('POST', this.location, true);
		this.http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
		this.http.onreadystatechange = this.httpHandler;
		return this.http;
	},


	httpHandler: function() {
		try {
			if (AJAX.http.readyState != 4 || AJAX.http.status != 200) {
				AJAX.timer = 0;
				return;
			}
		} catch (e) {
			alert('AJAX handler has a problem:\n' + e.message);
		}
		clearInterval(AJAX.job);
		AJAX.callInProgress = false;
		AJAX.receive(AJAX.http.responseText);
		AJAX.execute();
	},


	enqueue: function(msg) {
		this.queue.push(msg);
	},


	execute: function() {
		if (this.callInProgress) {
			return;
		}
		if (this.queue.length == 0) {
			this.hideThrobber();
			this.callInProgress = false;
			return;
		}
		this.callInProgress = true;
		this.timer = 0;
		this.job = setInterval(this.checkTimeout, 1000);
		var http = this.getHttp(true);
		http.send(this.queue.shift());
	},


	receive: function(response) {
		response = response.replace(/^\s+|\s+$/g, '');
		if (response.length > 0 && response.charAt(0) != '[') {
			debug(response);
			return;
		}
		var json = eval(response);
		for (var i in json) {
			var cmd = eval(json[i]);
			var handler = cmd.shift();
 			var args = (cmd.length > 0)
				? json[i].substring(handler.length + 4, json[i].length - 1)
				: '';
			try {
				eval(handler + '(' + args + ')');
			} catch (e) {
				debug(e.message);
			}
		}
	},


	checkTimeout: function() {
		if (++AJAX.timer < AJAX.ttl) {
			return;
		}
		clearInterval(AJAX.job);
		AJAX.callInProgress = false;
		AJAX.execute();
	},



	showThrobber: function() {
		var throbber = document.getElementById('throbber');
		if (throbber != null)
			throbber.style.visibility = 'visible';
	},


	hideThrobber: function() {
		var throbber = document.getElementById('throbber');
		if (throbber != null)
			throbber.style.visibility = 'hidden';
	}


};


call = function(action, args) {
	var msg = 'ajax=' + new Date().getTime() + '&action=' + action;
	if (args != null) {
		for (i=0; i<args.length; i++) {
			msg += '&args[]=' + ((args[i] == null || args[i] == undefined) ? '' : Base64.encode(args[i] + ''));
		}
	}
	var throbber = document.getElementById('throbber');
	if (throbber != null) {
		throbber.style.visibility = 'visible';
	}
	AJAX.enqueue(msg);
	AJAX.execute();
};


debug = function(message) {
	message = message.replace(/\n/g, '<br/>');
	var w = window.open("","_blank","toolbar=no, location=no, directories=no, status=yes, menubar=yes, scrollbars=yes, resizable=yes, copyhistory=no, width=800, height=400");
	w.document.body.innerHTML = '<p style="font-family: Verdana; font-size: 8pt"><strong>guru meditation</strong><br/>' + message + '</p>';
};
