var AjaxCallbacks = {
    showLoading: function(){},
    hideLoading: function(){},
    bodyOnScroll: function(){},
    scroll: function(){AjaxCallbacks.bodyOnScroll();},
    showError: function(message){
    	StatusMessages.showError(message);
    },
    showStatus: function(message){
    	if (message == '') return;
    	clearTimeout(statusMsgTimeoutID_s);
    	$('status').innerHTML = message;
    	Element.show('status');
    	statusMsgTimeoutID_s = setTimeout('hideStatus();', 10000);
    },
    hideMessages: function(){StatusMessages.hide();}
}
function $Fs(object) {
    try{ 
        return $F(object); 
    }catch(e){
        return null;
    }
}
var AjaxDispatcher = {
	busy: false,
	queue: new Array(0),
	addWaitingEvent: function (request){
		this.queue.push(request);
	},
	executeWaitingEvent: function(){
		if (this.queue.length == 0) {
			this.busy = false;
			return;
		}
		this.busy = true;
		this.executedRequest = this.queue.shift();
		
		var options = {method:'post', onComplete: AjaxDispatcher.onComplete, onSuccess: AjaxDispatcher.onSuccess, onFailure: AjaxDispatcher.onFailure, postBody:this.executedRequest.options.postBody};
		
		if (this.executedRequest.options.onStart != undefined) this.executedRequest.options.onStart();
		if (this.executedRequest.options.silent != true)
			AjaxCallbacks.showLoading();
		AjaxCallbacks.hideMessages();
		new Ajax.Request(this.executedRequest.method + '?ajax=1', options);
	},
	executedRequest:null,
	request: function(method, options){
	    if (options == undefined) options = {};
		AjaxDispatcher.addWaitingEvent({method: method, options: options});
		if (!AjaxDispatcher.busy)
			AjaxDispatcher.executeWaitingEvent();
	},
	onComplete: function(){
		AjaxCallbacks.hideLoading();
		AjaxDispatcher.executeWaitingEvent();
	},
	onFailure: function(t){
    	alert('Error ' + t.status + ' -- ' + t.statusText);
		AjaxCallbacks.hideLoading();
	},
	onSuccess: function(transport){
		var response = transport.responseJSON;
		if (response == null){
		    AjaxDispatcher.executedRequest.onError();
		    AjaxDispatcher.onFailure({status:"handling", statusText:"invalid response" + transport.responseText});
			return;
	    }
		var callSuccess = true;
		var callParam = null;
	// ONCOMPLETE
		try{AjaxDispatcher.executedRequest.options.onComplete();}catch(e){}
	// REDIRECT	
		if (response.redirect != undefined){
			callSuccess = false;
			var loc =  response.redirect;
			if (loc.substr(0,8) == '::reload') window.location.reload();
			else window.location = loc;
	    }
	// ERROR
		if (response.error != undefined){
			callSuccess = false;
			AjaxCallbacks.showError(unescape(response.error));
			AjaxDispatcher.executedRequest.onError(unescape(response.error));
	    }
	// RESPONSE	
		if (response.response != undefined){
		    if (typeof(response.response) == 'string'){
		        try{
	    		    callParam = unescape(response.response);
	        		if (AjaxDispatcher.executedRequest.updateElement != undefined){
	        			$(AjaxDispatcher.executedRequest.updateElement).update(callParam);
	                }
	                callParam.evalScripts();
	        	}catch(e){
	                alert(e.message);
	        	}
			}else{
			    callParam = response.response;
		    }
		}
	// STATUS
		if (response.status != undefined){
			AjaxCallbacks.showStatus(unescape(response.status));
		}
		if (callSuccess) AjaxDispatcher.executedRequest.options.onSuccess(callParam, AjaxDispatcher.executedRequest.extraParam);
	}
}
function ajaxUpdate (element, method, options){
    if (options == undefined) options = {};
	options.updateElement = element;
	return ajaxRequest(method, options);
}
function ajaxFormSubmit(formId, onSuccess, options){
	if (options == undefined) options = {};
	options.postBody = Form.serialize(formId);
	options.onSuccess = onSuccess;
	var method = null;
	if (Object.isString($(formId).action)){
		method = $(formId).action;
	}
	ajaxRequest(method, options);	
	return false;
}
function ajaxRequest(method, options){return AjaxDispatcher.request(method,options);}


var statusMsgTimeoutID_e;
var statusMsgTimeoutID_s;
var StatusMessages = {
    showError: function(message){
    	if (message == '') return;
    	clearTimeout(statusMsgTimeoutID_e);
    	$('error').innerHTML = message;
    	Element.show('error');
    	statusMsgTimeoutID_e = setTimeout('hideError();', 10000);
    },
    hide: function(message){
        hideError();
        hideStatus();
    }
    
}
hideError = function(){
	$('error').innerHTML = '';
	Element.hide('error');	
}
hideStatus = function(){
	$('status').innerHTML = '';
	Element.hide('status');	
} 
