AJAX = new function() {
	this.xmlBase = '/ajax';
	this.handlerURL = this.xmlBase+'/ajax_core.cfm';
	this.popupURL = this.xmlBase+'/ajax_popup.cfm';
	this.debugMode = true;
	this.queue = [ ];
	this.reportWindow = null;
	
	this.create = function(owner, handler) {
		return OO.create(AJAX.Request, owner, handler);
	}
	
	this.XMLHTTP = function() {
		return UTIL.Try(
			function() { return new ActiveXObject("Microsoft.XMLHTTP"); },
			function() { return new XMLHttpRequest(); }
		);
	}
	
	this.prepareSend = function(owner, action, params, timeout) {
		if (!this.busy) { this.busy = true; return true; }
		this.queue.push({ owner: owner, action: action, params: params, timeout: timeout });
		return false;
	}
	
	this.releaseSend = function() {
		var next = this.queue.shift();
		this.busy = false;
		if (next) next.owner.send(next.action, next.params, next.timeout);
	}
}

AJAX.Request = function() {
	this.inherit(OO.Broadcaster);
	this.inherit(OO.Timer);
}
AJAX.Request.prototype = { 
	initSelf: function(owner, handler) {
		this.addListener(owner);
		this.handler = handler;
	},
		
	setHandler: function(handler) {
		this.handler = handler;
	},
	
	send: function(action, params, timeout) {
		var oThis = this;
		var divider = '';
		var key;
		var paramsStr = '';
		
		if (!AJAX.prepareSend(this, action, params, timeout)) return;
		
		params = params || { };
		
		//params = { handler: this.handler, action: action, data: JSON.stringify(params) };
		
		for (key in params) {
			paramsStr += divider + key + '=' + escape(params[key]);
			divider = '&';
		}
		
		this.ajaxRequest = AJAX.XMLHTTP();
		this.ajaxRequest.onreadystatechange = function() { if (oThis.ajaxRequest.readyState == 4) { oThis.handleResponse();	} }
		this.ajaxRequest.open("POST", AJAX.handlerURL, true);
		this.ajaxRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		this.ajaxRequest.send(paramsStr);
		
		if (timeout) {
			this.setTimeout('AJAXTimeout', timeout, this.handleTimeout, action);
		}
		
		AJAX.currentRequest = { url: AJAX.handlerURL, handler: this.handler, action: action, data: params.data };
		
	},
	
	handleTimeout: function(action) {
		this.sendMessage('ajaxTimeout', action);
		AJAX.releaseSend();
	},
	
	setTextHandler: function(o, handler) {
		this.textHandler = { o: o, handler: handler };
	},
	
	handleResponse: function() {
		var ok = false;
		
		this.clearTimeout('AJAXTimeout');
		
		if (this.ajaxRequest.status == 200) {
			if (this.textHandler) {
				this.textHandler.handler.call(this.textHandler.o, this.ajaxRequest.responseText);
				AJAX.releaseSend();
				return;
			}
			try {
				eval('var data = '+this.ajaxRequest.responseText);
				ok = true;
			} catch(e) {
			}
			if (ok) { 
				if (data.data.messagequeue)
					data.data.messagequeue.forEach(function(item) { this.sendMessage('ajaxResponse', item.message, item.data); }, this);
				else
					this.sendMessage('ajaxResponse', data.message, data.data);
			}
		}
		if (!ok) { this.sendMessage('ajaxFail'); this.failureReport(); }
		
		AJAX.releaseSend();
	},
	
	defaultErrorHandler: function(error) {
		var errorText = error.getAttribute('errorText');
		alert('AJAX ERROR: \n' + errorText);
	},

	failureReport: function() {
		var d = new Date();
		var oThis = this;
		var newWindow = false;
		if (AJAX.debugMode) {
			var showWin = confirm('AJAX SERVER ERROR:\nDo you want to display the error report?');
			if (showWin) {								
				//if (!AJAX.reportWindow) {
					newWindow = true;
					AJAX.reportWindow = window.open(AJAX.popupURL+'?ajaxHandler='+escape(AJAX.currentRequest.url),'_blank');
				//}
				
				AJAX.reportWindow.displayErrorText = this.ajaxRequest.responseText;
				AJAX.reportWindow.ajaxURL = AJAX.currentRequest.url;
				AJAX.reportWindow.ajaxData = AJAX.currentRequest.data;
				AJAX.reportWindow.ajaxAction = AJAX.currentRequest.action;
				AJAX.reportWindow.ajaxHandler = AJAX.currentRequest.handler;
				AJAX.reportWindow.focus(); 
				
				if (!newWindow)
					AJAX.reportWindow.displayError();
			}
		}
	}
}

