
/**
 * oggetti e metodi di utilita'
 */
function Entry(key, value) {
	this.name = key;
	this.value = value;
}

function findEnvelope(jQueryWrapper, forSubmit) {
	if (typeof forSubmit == "undefined") {
		forSubmit = true;
	}
	var jsonData = {};
	var jsonDataTag = jQueryWrapper.find("input[name=jFormSignature]"+(forSubmit?"":"[value='']"));
	if (jsonDataTag.size()==1) {
		eval("jsonData = "+jsonDataTag.attr("title"));
	}
	return getJsonEnvelope(jsonData);
}

function getJsonEnvelope(jsonData) {
	if (typeof jsonData == 'object' && typeof jsonData.envelope == 'object') {
		return jsonData.envelope;
	} else return null;
}

$.extend({
	getMapEntry: function(obj, index) {
		var key, entry;
		for (key in obj) {
			if(index-- == 0) {
				entry = new Entry(key, obj[key]);
				break;
			}
		};
		return entry;
	}
});


/**
 * jForm � un plugin di jQuery per la gestione delle form HTML
 */

$.fn.extend({
	jFormSubmit: function(action) {
		var actionElement = $("<input type=\"hidden\" name=\"jFormAction."+action+"\" value=\"\"/>");
		this.append(actionElement);
		this.submit();
		actionElement.remove();
	},
	jForm: function(config) {
		var me = this;
		
		//configurazioni di default di jForm
		config = $.extend({
			//target: {'#', jQuery_selector, null}
			target: null,
			//funzione chiamata prima del submit
			beforeSubmit: function (formData, jqForm, options) { 
			    // formData is an array; here we use $.param to convert it to a string to display it 
			    // but the form plugin does this for you automatically when it submits the data 
			 	//formData[formData.length] = {name: 'jFormResponseType', value: options.dataType=='json'?'json':'html' };

			    // jqForm is a jQuery object encapsulating the form element.  To access the 
			    // DOM element for the form do this: 
			    // var formElement = jqForm[0]; 
			 			 
			    // here we could return false to prevent the form from being submitted; 
			    // returning anything other than false will allow the form submit to continue 
			    return true; 
			},
			//funzione chiamata all'arrivo della risposta del server
			processResponse: function (responseText, statusText, xhr, $form) {
			},
			//funzione chiamata per processare i messaggi JSON inviati dal server
			processJson: function (envelope) { 
				//'envelope' contiene l'oggetto JSON
			    for (var error in envelope.errors) {
					alert(envelope.errors[error]);
					break;
				}
			    for (var message in envelope.messages) {
					alert(envelope.messages[message]);
					break;
				}
			    for (var action in envelope.actions) {
			    	var fAction = envelope.actions[action];
			    	try {
						if (typeof fAction == 'string') eval('fAction='+fAction);
					} catch (e) {
					}
					if (typeof fAction == 'function') fAction(envelope);
			    }
			    //me.populate(envelope.body); 
			},
            
            afterPopulate: function () {}
			
		}, config);
		
		//configurazioni per il plugin ajaxForm
		var ajaxFormConfig = { 
	        cache: false,
	        type: 'POST'
	    };
		
		if (config.target!=null) {
			if (config.target=='#') {
				ajaxFormConfig.dataType = 'json';
				ajaxFormConfig.target = null;
			} else {
				ajaxFormConfig.dataType = null;
				ajaxFormConfig.target = config.target;
			}
			ajaxFormConfig.beforeSubmit = config.beforeSubmit;
			ajaxFormConfig.success = function (responseText, statusText, xhr, $form) {
				config.processResponse(responseText, statusText, xhr, $form);
				var envelope = null;
				if (ajaxFormConfig.dataType == 'json') {
					envelope = getJsonEnvelope(responseText);
				} else if (ajaxFormConfig.target != null) {
					envelope = findEnvelope($(ajaxFormConfig.target), false);
				}
				if (envelope != null) config.processJson(envelope);
			};
			
			this.ajaxForm(ajaxFormConfig); 
		}
		
		var envelope = findEnvelope(this);
		if (envelope != null) {
			//valorizza i campi della form
		    this.populate(envelope.body);            
            config.afterPopulate;
		    //processa i messaggi JSON
			config.processJson(envelope);
		}
		
		/*
		this.find("input[name^='jFormAction.'],a[name^='jFormAction.']").click(function(){
			me.find("input[type=hidden][name=jFormAction]").val(this.attr("name").substring(12));
			me.submit();
		});
		*/
	},

	/**
	 * This function sets the values of form element variables from an array
	 * This is the reverse process of Mark Constable's serialize function
	 * It is expected to be used as a call back for an ajax call that retrieves the form data
	 * @param data : array or hash containing name,value pairs for elements in the form
	 *
	 * Examples
	 *
	 * 1. Deserialize from an array
	 *    populate([{'name':'firstname','value':'John'},{'name':'lastname','value':'Resig'}]);
	 *
	 * 2. Deserialize from a hash(object)
	 *    populate({'firstname':'John','lastname':'Resig'});
	 *
	 * 3. Deserialize multiple config for select/radio/checkbox
	 *    populate({'toppings':['capsicum','mushroom','extra_cheese'],'size':'medium'})
	 * which will set the corresponding select/radio/checkbox config for toppings
	 *
	 * 3. Deserialize multiple config for select/radio/checkbox and with isPHPnaming = true
	 *    populate({'toppings':['capsicum','mushroom','extra_cheese'],'size':'medium'},{isPHPnaming:true})
	 * which will set the corresponding select/radio/checkbox config for toppings, but will ignore select names ending with []
	 *
	 * @return         the jQuery Object
	 * @author         Ashutosh Bijoor (bijoor@reach1to1.com)
	 * @version        0.35
	 */	
	populate: function(d,config) {
		var data= d;
		me  = this;
	
		if (d === undefined) {
			return me;
		}
	
		config = $.extend({ isPHPnaming	: false,
							overwrite	: false},config);
		
		// check if data is an array, and convert to hash, converting multiple entries of 
		// same name to an array
		if (d.constructor == Array)	{
			data={};
			for(var i=0; i<d.length; i++) {
				if (typeof data[d[i].name] != 'undefined') {
					if (data[d[i].name].constructor!= Array) {
						data[d[i].name]=[data[d[i].name],d[i].value];
					} else {
						data[d[i].name].push(''+d[i].value);
					}
				} else {
					data[d[i].name]=d[i].value;
				}
			}
		}
	
		// now data is a hash. insert each parameter into the form
		$('input,select,textarea',me)
		.each(function() {
				  var p=this.name;
				  var v = [];
				  
				  // handle wierd PHP names if required
				  if (config.isPHPnaming) {
					  p=p.replace(/\[\]$/,'');
				  };
				  //eval("var data_p = data."+p); //era data[p]
				  var value_p;
				  value_p = data[p];
				  /*
				  for (var k in data[p]) {
					  value_p = data[p][k];
					  break;
				  }
				  */
				                 
				  if(p && value_p != undefined) {
					  v = value_p.constructor == Array ? value_p : [value_p]; 
				  }
				  // Additional parameter overwrite
				  if (config.overwrite === true || value_p) {
					  switch(this.type || this.tagName.toLowerCase()) {
					  case "radio":
					  case "checkbox":
						  this.checked=false;
						  for(var i=0;i<v.length;i++) {
							  this.checked|=(this.value!='' && v[i]==this.value);
						  }
						  break;
					  case "select-multiple" || "select":
						  for( i=0;i<this.options.length;i++) {
							  this.options[i].selected=false;
							  for(var j=0;j<v.length;j++) {
								  this.options[i].selected|=(this.options[i].value!='' && this.options[i].value==v[j]);
							  }
						  }
						  break;
					  case "button":
					  case "submit":
						  this.value=v.length>0?v.join(','):this.value;
							  break;
					  default:
						  this.value=v.join(',');
					  }
				  }
			  });
		return me;
	}
});

