/**
 *  BaseAction: functions for doing advanced ajax request
 *
 *  Home: http://www.anticore.org/
 *  @version 0.1
 *  @author Asnaghi Lucio
 *  @license GPL
 *
 */

var BaseAction = Class.create();
Object.extend(BaseAction.prototype,{

	url: null, // must be set
	action: "default",

	method: "POST",
	async: true,
	charset: "utf-8",

	parameters: null, // optional values
	formName: null,
	updateElement: null,
	mapObject: null,
	
	initialize: function(){
		this.parameters = {};
	},

	execute: function()
	{
		if (!this.onConfirm()) return;

		this.onBeforeRequest();

		this.postBody = "action=" + this.action;
		if (this.formName)
			this.postBody += "&" + Form.serialize(this.formName);
        for (var nomeParametro in this.parameters)
            this.postBody += "&" + nomeParametro + "=" + encodeURIComponent(this.parameters[nomeParametro]);
		if (this.mapObject) {
			this.postBody += "&w=" + this.mapObject.width;
			this.postBody += "&h=" + this.mapObject.height;
		}

		if (this.method == 'GET' && this.postBody.length > 0)
			this.url += (this.url.match(/\?/) ? '&' : '?') + this.postBody;
		
		this.transport = this.getTransport();
		this.transport.open (this.method, this.url, this.async);
		if (this.method == 'POST')
		{
			this.transport.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset='+this.charset);
   			this.transport.setRequestHeader('Content-Length', this.postBody.length);
//			if (this.transport.overrideMimeType)
//				this.transport.setRequestHeader('Connection', 'close');
		}

		this.transport.onreadystatechange = this.onStateChange.bind (this);
		this.transport.send (this.method == 'POST' ? this.postBody : null);
	},

	onStateChange: function()
	{
		if (this.transport.readyState == 4)
		{
			var isSuccessResponse =	this.responseIsSuccess(); 
			if (isSuccessResponse)
			{
				try
				{
					this.onInternalComplete();
				}
				catch(e)
				{
					alert ("BaseAction.onInternalComplete(): " + e.message+"\nIn: "+e.fileName+"\nLinea: "+e.lineNumber);
				}
			}
			else
			{
				try
				{
					var status = this.transport.status;
					var message = this.transport.responseText;

					this.onError (status, String(message).stripTags().replaceAll ("&quot;","'"));
				}
				catch(e)
				{
					alert ("BaseAction.onError(): " + e.message+"\nIn: "+e.fileName+"\nLinea: "+e.lineNumber);
				}
			}

			this.onAfterRequest();

			this.transport.onreadystatechange = function(){};
			this.transport = null;
		}
	},

	evaluateResult: function ()
	{
		var response = null;	
        if (this.transport.responseText == "")
		{
			response=new Object();
			//response.status="alert";
			//response.message="XmlHttp.responseText vuoto!"
		}
		else
			eval("response=(" + this.transport.responseText + ");");
		return response;
	},

	onInternalComplete: function()
	{
		this.response = this.evaluateResult ();

		if (this.response.debugMessage!==undefined)
			this.onDebug(this.response.debugMessage);

		if (this.response.popupURL)
			Global.openPopup (this.response.popupURL, {resize: 1});

		if (this.updateElement)
			this.update.innerHTML = this.transport.responseText;

		switch(this.response.status)
		{
		case "sessiontimeout":
			if (this.response.redirectURL) {
				top.location.href=this.response.redirectURL;
				if(window.opener) window.close();
			}else{
				this.onError(500,"Sessione scaduta!");
			}
			break;

		case "error":
		case "internalerror":
			this.onError (500, this.response.message);
			break;

		case "validationerror":
			this.onValidationError (this.response.rules);
			break;
			
		case "alert":
			if (this.response.message) alert (this.response.message);
			break;
			
		default:
			this.onComplete ();
			break;
		}
	},

	responseIsSuccess: function()
	{
		if (this.transport)
			return this.transport.status == undefined
				|| this.transport.status == 0
				|| (this.transport.status >= 200 && this.transport.status < 300);
		else
			return false;
	},

	responseIsFailure: function()
	{
		return !this.responseIsSuccess();
	},

	getTransport: function()
	{
	    return Try.these(
	      function() {return new XMLHttpRequest()},
	      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
	      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
	    ) || false;
	},
	
	// callback methods
	onConfirm: function() {return true;},
	onCreate: function() {},
	onBeforeRequest: function() {},
	onAfterRequest: function() {},
	onComplete: function()
	{
	    // if exists execute status handler
	    var method=this["on_"+this.response.status];
		if (typeof(method)=="function") method.call(this,this.response);
		else alert("Il codice di risposta '"+this.response.status+"' non è gestito!");
	},
	onValidationError: function(rulesArray)
	{
		var returnAlertString = "";
		for (var i=0; i<rulesArray.length; i++)
			returnAlertString += "- " + rulesArray[i].message + "\n";
		alert( "Errore Validazione:\n" + returnAlertString );
	},
	onError: function(number,desc) { alert( "Errore: " + number + " - " + desc ); },
	onDebug: function(text) { alert( "Debug: " + text); }
});


/**
 *  UploadAction: functions for doing advanced iframe request
 *	especially useful if you are going to upload a form somewhere
 *
 *  Home: http://www.anticore.org/
 *  @version 0.1
 *  @author Asnaghi Lucio
 *  @license GPL
 */

var UploadAction = Class.create();
Object.extend(UploadAction.prototype,BaseAction.prototype);
Object.extend(UploadAction.prototype,{

	url: null,			// must be set
	action: "default",

	method: "post",
	charset: "utf-8",

	parameters: null,	// optional value
	formName: null,		// must be set
	iframeName: "",
	updateElement: null,
	mapObject: null,
	
	iframe: null,
	
	initialize: function(){
		this.parameters = {};
	},

	execute: function()
	{
		if (this.iframeName == "")
			alert ("You have not set variable 'iframeName' in UploadAction.");
			
		var form = document.forms[this.formName];
	
		if (!this.onConfirm()) return;

       	var element = form["upload_action"];
       	if (! element)
       	{
        	element = document.createElement("input");
        	element.type = "hidden";
        	element.name = "upload_action";
			element.value = this.action;
        	element = form.appendChild (element);
        }
		element.value = this.action;

        for (var nomeParametro in this.parameters)
        {
        	var element = form.elements[nomeParametro];
        	if (! element)
        	{
	        	element = document.createElement("input");
	        	element.type = "hidden";
	        	element.name = nomeParametro;
				element.value = this.parameters[nomeParametro];
	        	element = form.appendChild (element);
	        }
			element.value = this.parameters[nomeParametro];
        }
//		if (this.mapObject) {
//			this.postBody += "&w=" + this.mapObject.width;
//			this.postBody += "&h=" + this.mapObject.height;
//		}

		this.onBeforeRequest();

		this.form = form;
		setTimeout(function(){this.form.submit();}.bind(this), 20);	
	},

	evaluateResult: function () {
		return this.response;
	},

	responseIsSuccess: function() {
		return typeof this.response == "Object";
	},

	getTransport: function() {
		return null;
	}
	
});


/**
 *  ActionManager: global class to execute custom client actions
 *
 *  Home: http://www.anticore.org/
 *  @version 0.1
 *  @author Asnaghi Lucio
 *  @license GPL
 */
var ActionManager = {

	register: function (actionName, actionObject)
	{
		if (this.actionsArray[actionName] !== undefined)
		{
			alert("Attenzione: L'azione '"+actionName+"' è già stata registrata!");
			return;
		}
		
		this.actionsArray[actionName] = actionObject;
		this.actionsArray[actionName].action = actionName;
		this.actionsArray[actionName].onCreate();
	},

	execute: function (actionName)
	{
		if (this.actionsArray[actionName] !== undefined)
		{
			this.actionsArray[actionName].execute();
		}
		else
		{
			alert("Attenzione: azione '"+actionName+"' non presente!");
		}
	},

	executeDirect: function (actionObject)
	{
		if (actionObject !== undefined)
		{
			actionObject.execute();
		}
		else
		{
			alert("Attenzione: oggetto azione non specificato!");
		}
	},

	handleCompleteAction: function (actionName, resultObject)
	{
		if (this.actionsArray[actionName] !== undefined)
		{
			this.actionsArray[actionName].response = resultObject;
			this.actionsArray[actionName].onInternalComplete();
			this.actionsArray[actionName].onAfterRequest();
		}
		else
		{
			alert("Attenzione: azione '"+actionName+"' non presente!");
		}
	},

	action: function (actionName)
	{
		if (this.actionsArray[actionName] !== undefined) return this.actionsArray[actionName];
		else return null;
	},

	actionsArray: new Array()
};
