function preparePostData(form, options, submitButton) {
    var result = 'isAjaxCall=true';
	options.componentsId.each(
		function(component) {
			result += '&ajaxComponents=' + encodeURIComponent(component);
		}
	);
	if(form) {
	    for (var i = 0; i < form.elements.length; i++) {
	        var el = form.elements[i];
	        if (el.tagName.toLowerCase() == "select") {
	            for (var j = 0; j < el.options.length; j++) {
	                var op = el.options[j];
	                if (op.selected)
	                    result += "&" + encodeURIComponent(el.name) + "=" + encodeURIComponent(op.value);
	            }
	        } else if (el.tagName.toLowerCase() == "textarea") {
	            result += "&" + encodeURIComponent(el.name) + "=" + encodeURIComponent(el.value);
	        } else if (el.tagName.toLowerCase() == "input") {
	            if (el.type.toLowerCase() == "checkbox" || el.type.toLowerCase() == "radio") {
	                if (el.checked)
	                    result += "&" + encodeURIComponent(el.name) + "=" + encodeURIComponent(el.value);
	            } else if (el.type.toLowerCase() == "submit") {
	                if (el == submitButton) // is "el" the submit button that fired the form submit?
	                    result += "&" + encodeURIComponent(el.name) + "=" + encodeURIComponent(el.value);
	            } else if (el.type.toLowerCase() != "button") {
	                result += "&" + encodeURIComponent(el.name) + "=" + encodeURIComponent(el.value);
	            }
	        }
	    }
	    if (typeof submitButton != 'undefined' && submitButton != null && submitButton.type.toLowerCase() == "image") {
	        if (submitButton.name == null || submitButton.name == "" || typeof submitButton.name == "undefined")
	            result += "&x=1&y=1"; // .x and .y coordinates calculation is not supported.
	        else
	            result += "&" + encodeURIComponent(submitButton.name) + ".x=1&" +
	                      encodeURIComponent(submitButton.name) + ".y=1";
	    }
    }
    debug('Post parameters: ' + result);
    return result;
}

function retrieveAction(form) {
	action = form.action;
	if(action == null) {
		action = window.location.href;
	}
	debug('Form action: ' + action);
	return action;
}

function updateDocument(elementsToUpdate, originalRequest) {
	debug('Response: ' + originalRequest.responseText);
	html = originalRequest.responseText.split('<!-- ajax-separator -->');

	for(index = 0; index < elementsToUpdate.length; index++) {	
		clientId = elementsToUpdate[index];
		span = $(clientId + '_span');
		component = $(clientId);
		if(span == null) {
			span = document.createElement('span');
			span.id = clientId + '_span';
			component.parentNode.insertBefore(span, component);
			Element.remove(component);
		}
		Element.update(span, html[index]);
	}
}

AjaxCallBase = function() {};
AjaxCallBase.prototype = {
	setOptions: function(options) {
		this.options = {
			componentsId : null, 
			elementsToUpdate : null,
			showLigthBox : true,
			showOverlay : true,
			jsMethodToEval: null,
			timeout: 20
		}
    	Object.extend(this.options, options || {});
	},
	activecallcount:0
}

// Ultima chiamata Ajax in attesa del timeout per essere eseguita
var timeOutId = null;

AjaxCall = Class.create();
AjaxCall.prototype = Object.extend(new AjaxCallBase(), {
	initialize: function(element, options) 
	{			
		this.setOptions(options);
		this.element=$(element);

		// Elimino la chiamata precedente
		if(timeOutId!=null)
		{
			clearTimeout(timeOutId);
			timeOutId = null;
		}
				
		if(this.options.timeout > 0)
			timeOutId = setTimeout(this.doAjaxCall.bindAsEventListener(this), this.options.timeout);
		else
			this.doAjaxCall();
	},

	doAjaxCall: function() {
		element = this.element;
		
		if(element == null)
			return true;
		
		form = null;
		button = null;
		if(element.tagName == 'FORM')
			form = element;
		else if(element.tagName == 'INPUT') {
			if(element.type == 'submit' || element.type == 'image') {
				button = element;
				var parent = element.parentNode;
				while(parent != null) {
					if(parent.tagName == 'FORM') {
						break;
					}
					parent = parent.parentNode;
				}
				if(parent != null)
					form = parent;
				else
					return true;
			}
		}

		if(this.options.showLigthBox != null || this.options.showOverlay != null)
		{
			doubleSubmit = new LightboxAjax(form, this.options.showLigthBox, this.options.showOverlay);
			doubleSubmit.activate();
			if(form!=null)
				formId = form.id;
		}
		else
			doubleSubmit= null;
				
		if(this.options.componentsId == null) {
			this.options.componentsId = []
			this.options.componentsId.push(form.id);
		}
		
		params = preparePostData(form, this.options, button);
		if(this.options.elementsToUpdate == null)
			this.options.elementsToUpdate = this.options.componentsId;
		this.activecallacount++;
		elementsToUpdate = this.options.elementsToUpdate;

        azione = retrieveAction(form);
        meth2Eval = this.options.jsMethodToEval;
		var myAjax = new Ajax.Request(
			azione, 
			{
				method: 'post',
				contentType:  'application/x-www-form-urlencoded',
				parameters: params,
				asynchronous: true, 
				onSuccess:
					function(originalRequest)
					{
					    var loginString = originalRequest.responseText.substring(0, 24);
					    if( loginString == '<!-- ajax-login-info -->') 
					    {
					    	document.write(originalRequest.responseText);
							document.close();
					    }
					    else
					    {
							updateDocument(elementsToUpdate, originalRequest);
							this.activecallacount--;
							if(doubleSubmit!=null)
							{
								doubleSubmit.deactivate();
								doubleSubmit.uninstall(form);
								if(formId!=null)
								{	
									// riaggancio al nuovo form il prevent double submit
							   	 	//doubleSubmit = new PreventDoubleSubmit();
									formino = $(formId);
									new LightboxForm(formino);
								}
							}
				 
							if(meth2Eval != null) 
							   eval(meth2Eval);
						}												
					},
				onFailure:
					function(originalRequest)
					{
						this.activecallacount--;
						if(doubleSubmit!=null)
							doubleSubmit.deactivate();
						document.write(originalRequest.responseText);
						document.close();
					}
			}
		);
		return false;
	}
});