/*****************************
 * extjscsienricher v. 1.4.1 *
 *****************************/


// Funzione javascript per gestire relazione tra due select //

// // ***** in ajaxifyTag
// var old_value_combobox=""; //--> variabile che contiene il valore dell'ultimo
// combobox su cui è andato il focus
// var old_name_combobox=""; //--> variabile che contiene il nome dell'ultimo
// combobox su cui è andato il focus
// var is_onclick_combobox=false; //--> variabile che indica se si è premuto col
// mouse sulla combobox su cui si ha il focus

function inFocus(oggetto) {
	old_value_combobox = oggetto.value;
	old_name_combobox = oggetto.name;
}

// --> funzione che viene eseguita alla perdita del focus da parte del combobox
// e simula il comportamento del click
// sul pulsante submit del form
function lostFocus(oggetto, Submit_name, Submit_value, url) {
	// se l'oggetto che perde il focus è lo stesso di quello per cui ho
	// memorizzato il suo vecchio valore e
	// quest'ultimo è diverso da quello corrente eseguo il submit del form
	if (old_value_combobox != oggetto.value
			&& old_name_combobox == oggetto.name) {
		document.forms[0].action = url + "?" + Submit_name + "=" + Submit_value;
		document.forms[0].submit();
	}
}

// --> funzione che viene eseguita al click sul combobox
function onCBClick(oggetto, Submit_name, Submit_value, url) {
	// controllo se è già stato premuto il tasto del mouse
	if (is_onclick_combobox == true) {
		// mi comporto come se la combobox perda il fuoco
		is_onclick_combobox = false;
		lostFocus(oggetto, Submit_name, Submit_value, url)
		old_value_combobox = oggetto.value;
		old_name_combobox = oggetto.name;
	} else
		// se non è stato premuto imposto la variabile a true per segnalare la
		// prima pressione
		is_onclick_combobox = true;
}


////////////////////////////////////////////////////////////////////////////////
//*********** RADIOBUTTONS ****************************************************
// Funzione javascript per gestire l'evento di change su un radiobutton
////////////////////////////////////////////////////////////////////////////////

function onRBClick(url) {
    document.forms[0].action = url;
    document.forms[0].submit();
}


// ////////////////////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////////////////////

Ext.ns('ExtCsi.enricher');
Ext.ns('ExtCsi.enrichments');
Ext.ns('ExtCsi.ui.windows');
Ext.ns('ExtCsi.util');

/**
 * @class ExtCsi.enricher.UIEnricher
 * @extends Object Gestore degli arricchimenti. Una pagina può contenere vari
 *          arricchimenti. Ciascun arricchimento è relativo ad un widget, ad un
 *          pannello, alla pagina nel complesso. Gli arricchimenti devono essere
 *          applicati: 1) al caricamento iniziale della pagina: tutti 2) ogni
 *          qual volta viene ricaricata la porzione di pagina a cui fa
 *          riferimento l'arricchimento Ogni arricchimento deve essere applicato
 *          una sola volta e non deve essere riapplicato se la porzione di
 *          pagina a cui fa riferimento non è stata rinfrescata. Poichè allo
 *          stato attuale il meccanismo di refresh ajax ha come elementi di
 *          refresh selettivo i pannelli e non i singoli widget, deve essere
 *          possibile comandare il "redo" selettivo degli arricchimenti in modo
 *          da riapplicare gli arricchimenti relativi a un insieme di pannelli.
 *          All'interno di un pannello, essendo possibile inserire vari widget,
 *          è ipotizzabile la necessità di realizzare vari arricchimenti atomici
 *          (magari ciascuno relativo ad un particolare widget). Non c'è però
 *          l'esigenza di applicare solo alcuni degli arricchimenti relativi ai
 *          vari widget, e dunque gli arricchimenti possono essere registrati a
 *          livello di pannello. Poichè i pannelli possono essere annidati e
 *          l'azione di refresh può essere associata a tutti i livelli di
 *          pannello è compito di chi registra e successivamnete richiama gli
 *          arricchimenti, registrare e richiamare gli arricchimenti corretti.
 * 
 * Registrazione: se P1 contiene P1_1 e P1_2 devono essere registrati
 * potenzialmente fino a 3 arricchimenti, se necessario: uno relativo
 * esclusivamente a P1_1, uno a P1_2, e uno a P1, con il criterio che gli
 * arricchimenti siano additivi e non sovrapposti.
 * 
 * Richiamo: se P1 contiene P1_1 e P1_2 e viene effettuato il refresh di P1
 * devono essere riapplicati gli arricchimenti relativi ai due sottopannelli e
 * al pannello contenitore, se viene effettuato il refresh di uno solo dei due
 * sottopannelli deve essere riapplicato solo l'arricchimento corrispondente.
 */
ExtCsi.enricher.UIEnricher = Ext.extend(Object, {
	enrichments : {},
	structure : {},
	ready : false,
	/**
	 * @method setReady Imposta come pronto l'enricher
	 */
	setReady : function() {
		this.ready = true;
	},
	/**
	 * @method
	 * @param {Object}
	 *            structure la struttura del pannello imposta al struttura di
	 *            pannelli di un ContentPanel. La struttura &egrave; del tipo:
	 * 
	 * <pre></code>
	 * 		 
	 * 	  { name : &lt;nome&gt;
	 * 	  	 panels : 
	 * 	    [
	 * 	      {
	 * 	      	 &lt;stessa struttura&gt;
	 * 	      }
	 * 	    ]
	 * 	  }		
	 * 		
	 * </code></pre>
	 */
	setStructure : function(structure) {
		this.structure = structure;
	},
	/**
	 * @method
	 * @param {String}
	 *            panelId
	 * @param {String}
	 *            currStruct
	 * @return {Object} il sottoalbero di struttura che ha come root panelId
	 */
	locateInStructure : function(panelId, currStruct) {
		// alert("locate in structure:"+panelId+","+currStruct);
		if (currStruct != null && currStruct != []) {
			if (currStruct instanceof Array) {
				// alert("currStruct is array of "+currStruct.length+"
				// elements");
				var i = 0;
				var currSubp = null;
				var locatedInChild = null;
				for (i = 0; i < currStruct.length; i++) {
					currSubp = currStruct[i];
					locatedInChild = this.locateInStructure(panelId, currSubp);
					// alert(locatedInChild);
					if (locatedInChild != null)
						return locatedInChild;
				}
				return null;
			} else if (currStruct.name != undefined) {
				// alert("currStruct is a panel named "+currStruct.name);
				if (currStruct.name == panelId) {
					return currStruct;
				} else {
					// alert("go down...");
					return this.locateInStructure(panelId, currStruct.panels);
				}
			}
		} else {
			return null;
		}
	},
	/**
	 * @method
	 * @param {String}
	 *            panelID
	 * @param {String}
	 *            enrichment registra un arricchimento relativo al pannello
	 *            "panelID". gli arricchimenti sono additivi.
	 */
	registerEnrichment : function(panelID, enrichment) {
		if (!this.ready) {
			// alert('UIEnricher.register:'+name);
			var enrichmentsForPanel = this.enrichments[panelID];
			// se è il primo istanzio l'array
			if (enrichmentsForPanel == null) {
				this.enrichments[panelID] = {
					value : new Array()
				};
				enrichmentsForPanel = this.enrichments[panelID];
			}
			var enrichmentsDtls = enrichmentsForPanel.value;
			enrichmentsDtls.push(enrichment);
		} else
			throw "UIEnricher cannot register in ready state";
	},
	/**
	 * @method
	 * @param {Array}
	 *            targets Applica tutt gli arricchimenti per i target
	 *            specificati, compresi quelli globali 'di skin'
	 */
	applyEnrichments : function(/* string[] */targets) {
		if (this.ready) {
			var i = 0;
			var currTarget;
			var targetStruct = null;
			for (i = 0; i < targets.length; i++) {
				currTarget = targets[i];
				targetStruct = this.locateInStructure(currTarget,
						this.structure);
				if (targetStruct != null) {
					this.applyEnrichmentsInternal(currTarget, targetStruct);
				} else
					throw "cannot locate " + currTarget + " in ui structure";
			}
			// globali
			try {
				styleEnrichments();
			} catch (err) {
				// ignore...
			}
		} else
			throw "UIEnricher cannot apply in non-ready state";
	},
	/**
	 * @param {String}
	 *            target il nome del pannello target su cui applicare
	 *            l'enrichment
	 * @param {Object}
	 *            targetStructure il sottoalbero di struttura pannelli con root
	 *            il nodo corrisp. al pannello target applica gli arricchimenti
	 *            per il singolo target tenendo presente la struttura dei
	 *            pannelli
	 */
	applyEnrichmentsInternal : function(/* string[] */target, targetStructure) {
		// alert("applyEnrichmentsInternal("+target+")");
		var currEnrStruct = this.enrichments[target];
		if (currEnrStruct != null) {
			var currEnrArray = currEnrStruct.value;
			for (var i = 0; i < currEnrArray.length; i++) {
				var currEnr = currEnrArray[i];
				currEnr();
			}
		} else {
			// scendo nella struttura
			var childs = targetStructure.panels;
			if (childs != null) {
				for (var i = 0; i < childs.length; i++) {
					var currChild = childs[i];
					this.applyEnrichmentsInternal(currChild.name, currChild);
				}
			}
		}
	},
	/**
	 * Applica tutti gli arricchimenti registrati nell'enricher, compresi quelli
	 * globali 'di skin'
	 */
	applyAll : function() {
		if (this.ready) {
			// alert('UIEnricher.applyAll:'+this.enrichments);
			for (var currTarget in this.enrichments) {
				// alert('UIEnricher.currTarget:'+currTarget);
				if (currTarget != null) {
					var currEnrArray = this.enrichments[currTarget].value;
					for (var i = 0; i < currEnrArray.length; i++) {
						var currEnr = currEnrArray[i];
						currEnr();
					}
				}
			}
			// globali
			try {
				styleEnrichments();
			} catch (err) {
				// ignore...
			}
		} else
			throw "UIEnricher cannot apply in non-ready state";
	}
});

// //////////////////////////////
// //////////////////////////////
// //////////////////////////////

/**
 * @class ExtCsi.enrichments.NRichment
 * @extends Object Classe base degli arricchimenti registrabili nell' UIEnricher
 */
ExtCsi.enrichments.NRichment = Ext.extend(Object, {
			/**
			 * @method
			 */
			applyNRich : function() {
			}// override

		});

/**
 * @class ExtCsi.enrichments.AddDatePicker
 * @extends ExtCsi.enrichments.NRichment Arricchimento per trasformare un input
 *          in calendar.
 */
ExtCsi.enrichments.AddDatePicker = Ext.extend(ExtCsi.enrichments.NRichment, {
			/**
			 * @cfg {String} widgId (obbligatorio) il nome del widget da
			 *      arricchire
			 */
			widgId : null,
			/**
			 * @cfg {Boolean} required (obbligatorio) true se il campo è
			 *      obbligatorio
			 */
			required : false,
			constructor : function(config) {
				this.widgId = config.widgId;
				this.required = config.required;
			},
			applyNRich : function() {
				var dh = Ext.DomHelper;
				var el = Ext.get(this.widgId);
				if (el != undefined && el != null) {
					var mustDisable = el.getAttribute("disabled") == "disabled"
							|| el.getAttribute("disabled") == true;
					var d = new Ext.form.DateField({
								applyTo : el,
								format : "d/m/Y",
								disabled : mustDisable,
								allowBlank : true
							});
				}
			}
		});

/**
 * @class ExtCsi.enrichments.ErrorPopupEnabler
 * @extends ExtCsi.enrichments.NRichment Abilita la visualizzazione dei popup di
 *          errore, se presenti. questo arricchimento e' globale e va richiamato
 *          ad ogni refresh.
 */
ExtCsi.enrichments.ErrorPopupEnabler = Ext.extend(ExtCsi.enrichments.NRichment,
		{
			applyNRich : function() {
				var spanError = Ext.query(".txtError");
				Ext.each(spanError, function(elemento, index) {
					var tip = '';
					Ext.each(elemento.childNodes, function(el) {
								if (el.tagName == 'SPAN') {
									Ext
											.fly(el)
											.addClass('elenco_errori_invisibile');
									tip = el.innerHTML;
								}
							});
					Ext.each(elemento.childNodes, function(el) {
								if (el.tagName == 'IMG') {
									el.removeAttribute('ALT')
											|| el.removeAttribute('alt');
									el.removeAttribute('TITLE')
											|| el.removeAttribute('title');
									new Ext.ToolTip({
												target : el,
												border : false,
												baseCls : 'elenco_errori_visibile',
												html : tip
											});
								}
							});
				});
			}
		});

/**
 * Libreria di arricchimenti standard
 */
function UIEnrichments() {
}

var uiNRichLib = new UIEnrichments();

/**
 * REMOVE IT!!
 */
UIEnrichments.prototype.addDatePickerNRich = function(widg_id, /* boolean */
		required) {
	nr = new ExtCsi.enrichments.AddDatePicker({
				widgId : widg_id,
				required : required
			});
	nr.applyNRich();
}

/**
 * @class ExtCsi.enrichments.AddTextSuggestion
 * @extends ExtCsi.enrichments.NRichment Arricchimento per aggiungere la
 *          suggestion remota ad un TextField.
 */
ExtCsi.enrichments.AddTextSuggestion = Ext.extend(ExtCsi.enrichments.NRichment,
		{
			/**
			 * @cfg (String) suggestionUrl (obbligatorio) l'url che restituisce
			 *      l'elenco di suggestion. L'url riceve il testo immesso nel
			 *      parametro http specificato in 'queryParamOgnl' e deve
			 *      restituire un array di stringhe serializzato in formato JSON
			 *      (es. ["uno", "due", "tre", ...])
			 */
			suggestionUrl : null,
			/**
			 * @cfg (String) widgetId (obbligatorio) l'id html del TextField a
			 *      cui si deve applicare l'arricchimento
			 */
			widgetId : null,
			/**
			 * @cfg (String) queryParamOgnl (obbligatorio) il nome in cui viene
			 *      passato al server il testo parziale digitato da utente
			 */
			queryParamOgnl : null,
			/**
			 * @cfg (Boolean) required (obbligatorio) true se il campo è
			 *      obbligatorio
			 */
			required : false,
			/**
			 * @cfg (Number) minChars (opzionale) specifica il numero di caratteri minimo
			 *      necessario per far partire la query. Il default è 4
			 */
			minChars : 4,
			constructor : function(config) {
				this.suggestionUrl = config.suggestionUrl;
				this.widgetId = config.widgetId;
				this.queryParamOgnl = config.queryParamOgnl;
				this.required = config.required;
				if (config.minChars != undefined && config.minChars != null)
					this.minChars = config.minChars;
			},
			applyNRich : function() {
				/**
				 * store dei suggerimenti
				 */
				var store = new Ext.data.JsonStore({
							// url:
							// 'cpSuggestion!handleTfSuggestedText_KEY_PRESSED.do',
							url : this.suggestionUrl,
							fields : [{
										name : "descrizione",
										convert : function(v, rec) {
											return rec;
										},
										type : "string"
									}],
							listeners : {
								exception : Ext.util.Format.messaggiErrore
								// ***gestisco
								// le eccezioni
								// server side
							}
						});

				/**
				 * Impostazione suggestion sul textfield preesistente
				 */
				var el = Ext.get(this.widgetId);

				if (el != undefined && el != null) {
					var mustDisable = el.getAttribute("disabled") == "disabled"
							|| el.getAttribute("disabled") == true;

					var suggest = new Ext.form.ComboBox({
								store : store,
								displayField : 'descrizione',
								queryParam : this.queryParamOgnl,
								typeAhead : true,
								forceSelection : false,
								loadMask : true,
								mode : 'remote',
								triggerAction : 'all',
								hideTrigger : true,
								selectOnFocus : true,
								applyTo : this.widgetId,
								loadingText : 'Attendere...',
								disabled : mustDisable,
								allowBlank : true,
								width : el.getWidth(),
								minChars : this.minChars
							});
				}
			}
		});

/**
 * REMOVE IT!!
 */
UIEnrichments.prototype.addTextSuggestionNRich = function(suggestionUrl,
		widgetId, queryParamOgnl, required, minChars) {
	nr = new ExtCsi.enrichments.AddTextSuggestion({
				suggestionUrl : suggestionUrl,
				widgetId : widgetId,
				queryParamOgnl : queryParamOgnl,
				required : required,
				minChars : minChars
			});
	nr.applyNRich();
};

ExtCsi.enrichments.AddComboSuggestion = Ext.extend(
		ExtCsi.enrichments.NRichment, {
			/**
			 * @cfg (String) suggestionUrl (obbligatorio) l'url che restituisce
			 *      l'elenco di suggestion.
			 */
			suggestionUrl : null,
			/**
			 * @cfg (String) widgetId (obbligatorio) l'id html del TextField a
			 *      cui si deve applicare l'arricchimento
			 */
			widgetId : null,
			/**
			 * @cfg (String) appDataName (obbligatorio) il nome dell'application
			 *      data
			 */
			appDataName : null,
			/**
			 * 
			 * @cfg {String} keyField nome della chiave della combo
			 */
			keyField : null,
			/**
			 * 
			 * @cfg {String} valueField nome del valore della combo
			 */
			valueField : null,
			/**
			 * 
			 * @cfg {String} refreshIds stringa che contiene gli id degli
			 *      oggetti da rileggere se è presente un evento di valuechanged
			 */
			refreshIds : null,
			/**
			 * 
			 * @cfg {String} valueChangedUrl url della action da richiamare sul
			 *      valuechange
			 */
			valueChangedUrl : null,
			/**
			 * 
			 * @cfg {String} pageId id della pagina
			 */
			var_pageId : null,
			/**
			 * 
			 * @cfg {String} nome della form
			 */
			formName : null,
			/**
			 * @cfg (Boolean) required (obbligatorio) true se il campo è
			 *      obbligatorio
			 */
			required : false,
			/**
			 * valueChangedCallback
			 */
			valueChangedCallback : null,
			/**
			 * @cfg (Number) minChars (opzionale) specifica il numero di caratteri minimo
			 *      necessario per far partire la query. Il default è 4
			 */
			minChars : 4,
			constructor : function(config) {
				this.suggestionUrl = config.suggestionUrl;
				this.widgetId = config.widgetId;
				this.appDataName = config.appDataName;
				this.keyField = config.keyField;
				this.valueField = config.valueField;
				this.required = config.required;
				this.refreshIds = config.refreshIds;
				this.valueChangedUrl = config.valueChangedUrl;
				this.var_pageId = config.pageId;
				this.formName = config.formName;
				if (config.minChars != undefined && config.minChars != null)
					this.minChars = config.minChars;
				this.valueChangedCallback = function() {
					Ext.Ajax.request({
						url : config.valueChangedUrl,
						form : config.formName,
						method : 'POST',
						beforerequest : showLoadBox(),
						// requestcomplete: maskStore.hide(),
						requestexception : Ext.util.Format.messaggiErroreConnection,
						success : function(response, opts) {
							runSuccessAction(response, opts, config.refreshIds, config.pageId);
						},
						failure : function(response, opts) {
							runFailureAction(response, opts);
						}
					});
				}
			},
			applyNRich : function() {
				
				var queryParamOgnl = this.appDataName + '.' + this.valueField;
				/**
				 * Impostazione suggestion sul textfield preesistente
				 */
				var el = Ext.get(this.widgetId);
				/**
				 * store dei suggerimenti
				 */		
				var store = new Ext.data.JsonStore({
							url : this.suggestionUrl,
							fields : [this.keyField, this.valueField],
							listeners : {
								exception : Ext.util.Format.messaggiErrore
								// ***gestisco
								// le eccezioni
								// server side
							}
						});
				
				if (!Ext.isEmpty(el)) {
					var mustDisable = el.getAttribute("disabled") == "disabled"
							|| el.getAttribute("disabled") == true;

					var suggest = new Ext.form.ComboBox({
								id : this.widgetId,
								hiddenId : 'hidden_'+this.widgetId,
								store : store,
								displayField : this.valueField,
								hiddenName : this.appDataName + '.' + this.keyField,
								valueField : this.keyField,
								submitValue : true,
								queryParam : queryParamOgnl,
								typeAhead : true,
								forceSelection : false,
								loadMask : true,
								mode : 'remote',
								triggerAction : 'all',
								hideTrigger : false,
								selectOnFocus : true,
								applyTo : this.widgetId,
								loadingText : 'Attendere...',
								disabled : mustDisable,
								allowBlank : true,
								width : el.getWidth(),
								minChars : this.minChars,
								listeners : {
									render : function(combo){
										if(!Ext.isEmpty(combo.getRawValue())){
											//combo.queryParam = combo.getRawValue();
											//***rileggo il valore selezionato per poter settare l'hidden alla
											//***lettura della pagina se il campo non è vuoto											
											combo.store.reload();
											(function(){
												for (var i = 0; i < combo.store.getCount(); i++) {
												    var rec = combo.store.getAt(i);
													if(!Ext.isEmpty(rec)){
														var value = rec.get(combo.displayField);
														var idd = rec.get(combo.valueField);
														if(value == combo.getRawValue()){
															document.getElementById(combo.hiddenId).value = idd;
															break;
														}
													}
												}
											}).defer(500);
										}
									}
								}
							});

					if (!Ext.isEmpty(this.valueChangedUrl)) {
						suggest.on('select', this.valueChangedCallback);
					}
					/*
					var gg = Ext.get(appDataName + '.' + keyField);
					if(!Ext.isEmpty(gg)){
						alert(gg.getValue());
					}*/
				}
			}
		});

UIEnrichments.prototype.addComboSuggestionNRich = function(suggestionUrl,
		widgetId, appDataName, keyField, valueField, refreshIds,
		valueChangedUrl, pageId, formName, required, minChars) {
	nr = new ExtCsi.enrichments.AddComboSuggestion({
				suggestionUrl : suggestionUrl,
				widgetId : widgetId,
				appDataName : appDataName,
				keyField : keyField,
				valueField : valueField,
				refreshIds : refreshIds,
				valueChangedUrl : valueChangedUrl,
				pageId : pageId,
				formName : formName,
				required : required, 
				minChars : minChars
			});
	nr.applyNRich();
};

/**
 * @class ExtCsi.enrichments.AddComboNarrowing
 * @extends ExtCsi.enrichments.NRichment Aggiunge ad una comboBox la funzione di
 *          autonarrowing, preservando un eventuale evento di VALUE_CHANGED
 */
ExtCsi.enrichments.AddComboNarrowing = Ext.extend(ExtCsi.enrichments.NRichment,
		{
			/**
			 * @cfg {String} widgetId (obbligatorio) l'id html della Table a cui
			 *      si deve applicare l'arricchimento
			 */
			widgetId : null,
			/**
			 * @cfg {Boolean} required (obbligatorio) true se il campo è
			 *      obbligatorio
			 */
			required : false,
			constructor : function(config) {
				this.widgetId = config.widgetId;
				this.required = config.required;
			},
			applyNRich : function() {
				var el = Ext.get(this.widgetId);
				if (el != undefined && el != null) {
					var mustDisable = el.getAttribute("disabled") == "disabled"
							|| el.getAttribute("disabled") == true;
					var originalOnBlur = el.getAttribute("onblur");
					var valueChangedFunc = null; // NOP
					if (originalOnBlur != null && originalOnBlur != undefined) {
						if (typeof originalOnBlur == 'string') {
							if (originalOnBlur != "") {
								var xmlHttpPostIdx = originalOnBlur
										.indexOf('xmlHttpPost');
								var returnIdx = originalOnBlur
										.indexOf('return');
								if (returnIdx > -1) {
									// rimuovo il "return;" finale
									originalOnBlur = originalOnBlur.substring(
											xmlHttpPostIdx, returnIdx - 1);
								}
								// trasformo in function
								valueChangedFunc = function() {
									eval(originalOnBlur);
								};
							}
						} else if (typeof originalOnBlur == 'function')
							valueChangedFunc = originalOnBlur;
						else
							throw "errore nell'impostazione della callback di on-select: tipo dell'attributo onblur ("
									+ (typeof originalOnBlur) + ") non valido";
					}
					var convertedCombo = new Ext.form.ComboBox({
								typeAhead : false,
								triggerAction : 'all',
								transform : this.widgetId,
								forceSelection : true,
								disabled : mustDisable,
								allowBlank : true,
								width : el.getWidth() + 17
							});
					if (valueChangedFunc != null){
						convertedCombo.on('select', valueChangedFunc);
					    /* STDMDD-770 */ convertedCombo.on('change', 
					    		function(convertedCombo, newVal, oldVal){convertedCombo.reset();});
					}
				}
			}
		});

/**
 * REMOVE IT!!
 */
UIEnrichments.prototype.addComboNarrowingNRich = function(widgetId, required) {
	nr = new ExtCsi.enrichments.AddComboNarrowing({
				widgetId : widgetId,
				required : required
			});
	nr.applyNRich();
}

/**
 * @class ExtCsi.enrichments.AddTableHeadTooltip
 * @extends ExtCsi.enrichments.NRichment Aggiunge i tooltip a popup alle
 *          intestazioni della tabella
 */
ExtCsi.enrichments.AddTableHeadTooltip = Ext.extend(
		ExtCsi.enrichments.NRichment, {
			/**
			 * @cfg {String} widgetId (obbligatorio) l'id html della Table a cui
			 *      si deve applicare l'arricchimento
			 */
			widgetId : null,
			/**
			 * @cfg {Array} tips array di stringhe contenente i testi dei tips
			 *      da applicare. Se una colonna non deve avere tip, il
			 *      corrispondente elemento deve essere valorizzato con "". La
			 *      cardinalità dell'array deve essere identico al numero di
			 *      colonne della tabella.
			 */
			tips : null,
			constructor : function(config) {
				this.widgetId = config.widgetId;
				this.tips = config.tips;
			},
			applyNRich : function() {
				var els = Ext.getDom(this.widgetId);
				if (els != null) {
					Ext.each(els.childNodes, function(el) {
						if (el.tagName == 'THEAD') {

							Ext.each(el.childNodes, function(trEl) {
								if (trEl.tagName == 'TR') {
									var iChilds = 0;
									var iTips = 0;
									for (; iChilds < trEl.childNodes.length; iChilds++) {
										var currChild = trEl.childNodes[iChilds];
										if (currChild.tagName == 'TH') {
											if (this.tips[iTips] != "") {
												new Ext.ToolTip({
															target : currChild,
															html : this.tips[iTips]
														});
											}
											iTips++;
										}
									}
								}
							});
						}
					});
				}
			}

		})

/**
 * REMOVE IT!!
 */
UIEnrichments.prototype.addTableHeadTooltipNRich = function(widgetId, /* string[] */
		tips) {
	nr = new ExtCsi.enrichments.AddTableHeadTooltip({
				widgetId : widgetId,
				tips : tips
			});
	nr.applyNRich();
}

/**
 * @class ExtCsi.enrichments.AddTooltipsByID
 * @extends ExtCsi.enrichments.NRichment Associa un tooltip a popup agli
 *          elementi html identificati tramite id. L'arricchimento e' effettuato
 *          in bundle. Se il tip vale null o "" non viene aggiunto
 */
ExtCsi.enrichments.AddTooltipsByID = Ext.extend(ExtCsi.enrichments.NRichment, {
			/**
			 * @cfg tipsMap: mappa <id, tip>
			 */
			tipsMap : null,
			constructor : function(config) {
				this.tipsMap = config.tipsMap;
			},
			applyNRich : function() {
				var i = 0;
				for (i = 0; i < this.tipsMap.length; i++) {
					var currEntry = this.tipsMap[i];
					var currId = currEntry.id;
					var currTip = currEntry.tip;
					var currEl = Ext.get(currId);
					if (currEl != null && currTip != null && currTip != "") {
						new Ext.ToolTip({
									target : currEl,
									html : currTip
								});
					}
				}
			}
		});

/**
 * REMOVE IT!!!
 */
UIEnrichments.prototype.addTooltipsByIDNRich = function(tipsMap) {
	nr = new ExtCsi.enrichments.AddTooltipsByID({
				tipsMap : tipsMap
			});
	nr.applyNRich();
}

/**
 * @class ExtCsi.enrichments.BasicTextFieldNRichment
 * @extends ExtCsi.enrichments.NRichment Arricchisce i TextField attribuendo il
 *          L&F ExtJs, con: - evidenziazione constraint di required -
 *          evidenziazione constraint di validazione/conversione (?)
 */
ExtCsi.enrichments.BasicTextFieldNRichment = Ext.extend(
		ExtCsi.enrichments.NRichment, {
			/**
			 * @cfg {String} widgetId
			 */
			widgetId : null,
			/**
			 * @cfg {Boolean} required
			 */
			required : false,
			/**
			 * @cfg {String} dataType
			 */
			dataType : null,
			/**
			 * @cfg {String} dataTypeModifier
			 */
			dataTypeModifier : null,
			constructor : function(config) {
				this.widgetId = config.widgetId;
				this.required = config.required;
				this.dataType = config.dataType;
				this.dataTypeModifier = config.dataTypeModifier;
			},
			applyNRich : function() {
				var el = Ext.get(this.widgetId);
				if (el != undefined && el != null) {
					var mustDisable = el.getAttribute("disabled") == "disabled"
							|| el.getAttribute("disabled") == true;
					if (this.dataType != null
							&& (this.dataType == "int" || this.dataType == "float"
									|| this.dataType == "long"
									|| this.dataType == "double"
									|| this.dataType == "java.lang.Integer"
									|| this.dataType == "java.lang.Float"
									|| this.dataType == "java.lang.Double" 
									|| this.dataType == "java.lang.Long")) {
						var integerNumber = this.dataType == "int"
								|| this.dataType == "long"
								|| this.dataType == "java.lang.Integer"
								|| this.dataType == "java.lang.Long";

						new Ext.form.NumberField({
							xtype : 'numberfield',
							applyTo : this.widgetId,
							allowBlank : true,
							decimalSeparator : ',',
							allowDecimals : !integerNumber,
							decimalPrecision : !integerNumber ? 2 : 0,
							preventMark : true,
							setValue : function(v) {
								return v;
							}
								// manca gestione D.T.Mod.
							});
					} else {
						new Ext.form.TextField({
							applyTo : this.widgetId,
							allowBlank : true
								// manca gestione D.T.Mod.
							});
					}
				}
			}
		});

/**
 * REMOVE IT !!!
 */
UIEnrichments.prototype.basicTextFieldNRich = function(widgetId, required,
		dataType, dataTypeModifier) {
	nr = new ExtCsi.enrichments.BasicTextFieldNRichment({
				widgetId : widgetId,
				required : required,
				dataType : dataType,
				dataTypeModifier : dataTypeModifier
			});
	nr.applyNRich();
}

/**
 * @class ExtCsi.enrichments.DynaDisplayTableNRichment
 * @extends ExtCsi.enrichments.NRichment Arricchisce una displayTable
 *          aggiungendo: - la possibilita' di ridimensionare le colonne - la
 *          possibilita' di nascondere selettivamente le colonne - la
 *          possibilita' di modificare l'ordine delle colonne - i tooltip sugli
 *          header di colonna
 */
ExtCsi.enrichments.DynaDisplayTableNRichment = Ext.extend(
		ExtCsi.enrichments.NRichment, {
			/**
			 * @cfg {String} widgId l'id della tabella originale
			 */
			widgId : null,
			/**
			 * @cfg {Array} tips : array di stringhe (non HTML) d autilizzare
			 *      per i tooltip sugli header di colonna (devopno esser ein
			 *      numero identico al numero totale di colonne, compresa
			 *      l'eventuale colonna del check, e se il valore e' stringa
			 *      vuota il tooltip non viene aggiunto
			 */
			tips : null,
			/**
			 * @cfg {String} pageId: (opzionale) se presente contribuisce a
			 *      formare lo stateId
			 */
			pageId : null,
			constructor : function(config) {
				this.widgId = config.widgId;
				this.tips = config.tips;
				this.pageId = config.pageId;
			},
			applyNRich : function() {
				var el = Ext.get(this.widgId);
				var widgetStateId = (this.pageId != undefined && this.pageId != null
						? this.pageId + '_' + this.widgId
						: this.widgId);

				if (el != null) {

					var grid = new Ext.ux.grid.TableGrid(this.widgId, this.tips, {
						stateId : widgetStateId,
						stripeRows : true,
						listeners : {
							render : function() {
								var menu = this.view.hmenu;
								for (var i = 0; i < menu.items["items"].length; i++) {
									menu.items["items"][i].hide();
								}
								var cm = this.colModel, colCount = cm
										.getColumnCount();
								for (var i = 0; i < colCount; i++) {
									var testo = cm.getColumnHeader(i);
									// ***non IE
									if (testo.indexOf('</a>') > -1) {
										testo = testo.substring(testo
														.indexOf('">')
														+ 2, testo
														.indexOf('</a>'));
									}
									// ***IE
									if (testo.indexOf('</A>') > -1) {
										testo = testo.substring(testo
														.indexOf('">')
														+ 2, testo
														.indexOf('</A>'));
									}
									if (cm.config[i].hideable != false
											&& testo.length > 1) {
										this.view.hmenu
												.add(new Ext.menu.CheckItem({
													itemId : 'col-'
															+ cm.getColumnId(i),
													text : testo,
													checked : !cm.isHidden(i),
													hideOnClick : false,
													disabled : cm.config[i].hideable == false
												}));
									}
								}
							}
						}
					});
					grid.render();
				}
			}
		});

/**
 * REMOVE IT!!!
 */
UIEnrichments.prototype.dynaDisplayTableNRich = function(widgId, tips, pageId) {
	nr = new ExtCsi.enrichments.DynaDisplayTableNRichment({
				widgId : widgId,
				tips : tips,
				pageId : pageId
			});
	nr.applyNRich();
};

// /////////////////////////////////////////////
// // DIALOG E POPUP
// /////////////////////////////////////////////

/**
 * @class ExtCsi.ui.windows.HtmlDialog
 * @extends Object Dialog a popup utilizzabile per mostrare il contenuto di una
 *          pagina reperibile ad un determinato URL.
 */
ExtCsi.ui.windows.HtmlDialog = Ext.extend(Object, {
			/**
			 * @cfg {String} url la url della pagina da visualizzare
			 */
			url : null,
			/**
			 * @cfg {Integer} height dimensione verticale del dialog
			 *      (300=default)
			 */
			height : 300,
			/**
			 * @cfg {Integer} width dimensione orizzontale del dialog
			 *      (300=default)
			 */
			width : 300,
			/**
			 * @cfg {Boolean} resizable true=finestra ridimensionabile
			 */
			resizable : true,
			constructor : function(config) {
				this.url = config.url;
				this.height = config.height;
				this.width = config.width;
				this.resizable = config.resizable;
			},
			show : function() {
				var ulDialog = new Ext.Window({

							height : this.height,
							width : this.width,
							minHeight : 50,
							minWidth : 100,
							modal : true,
							shadow : true,
							collapsible : true,
							closable : true,
							autoScroll : true,
							body : new Ext.ux.ManagedIFrame({
										autoCreate : {
											id : 'dynamicIframe1',
											cls : 'x-window-body',
											width : '100%',
											height : '100%',
											src : ExtCsi.util.URLUtils
													.normalizzaUrl(this.url)
										}
									}),
							animate : true,
							title : "Dialog",
							resizable : true,
							bodyBorder : true,
							buttons : [{
										text : "Chiudi",
										handler : function() {
											ulDialog.hide();
											ulDialog.destroy();
										}
									}],
							keys : [{
										key : 27,
										fn : function() {
											ulDialog.hide();
											ulDialog.destroy();
										},
										scope : this
									}]
						});
				ulDialog.show();
			}
		});

/**
 * @class ExtCsi.ui.windows.HtmlPopup
 * @extends Object Dialog a popup utilizzabile per mostrare il contenuto di una
 *          pagina reperibile ad un determinato URL.
 */
ExtCsi.ui.windows.HtmlPopup = Ext.extend(Object, {
			/**
			 * @cfg {String} url la url della pagina da visualizzare
			 */
			url : null,
			/**
			 * @cfg {Integer} height dimensione verticale del dialog
			 *      (300=default)
			 */
			height : 300,
			/**
			 * @cfg {Integer} width dimensione orizzontale del dialog
			 *      (300=default)
			 */
			width : 300,
			/**
			 * @cfg {Boolean} resizable true=finestra ridimensionabile
			 */
			resizable : true,
			/**
			 * @cfg {Boolean} scrollable true=finestra scrollabile
			 */
			scrollable : true,
			/**
			 * @cfg {Boolean} toolbar true=toolbar presente
			 */
			toolbar : true,
			constructor : function(config) {
				this.url = config.url;
				this.height = config.height;
				this.width = config.width;
				this.resizable = config.resizable;
				this.scrollable = config.scrollable;
				this.toolbar = config.toolbar;
			},
			show : function() {
				var parametri = '';
				if (this.toolbar) {
					parametri += 'toolbar=yes, ';
				} else {
					parametri += 'toolbar=no, ';
				}
				if (this.resizable) {
					parametri += 'resizable=yes, ';
				} else {
					parametri += 'resizable=no, ';
				}
				if (this.scrollable) {
					parametri += 'scrollbars=yes, ';
				} else {
					parametri += 'scrollbars=no, ';
				}
				parametri += 'top=70, ';
				parametri += 'left=70, ';
				parametri += 'width=' + this.width + ', ';
				parametri += 'height=' + this.height;
				window.open(ExtCsi.util.URLUtils.normalizzaUrl(this.url), 'Window',
						parametri);
			}
		});

/**
 * @class ExtCsi.util.URLUtil
 * @extends Object Funzioni di utilita' per la manipolazione di URL.
 */
ExtCsi.util.URLUtils = function() {
	return {
		/**
		 * @method
		 * @param {String}
		 *            url l'url da normalizzare
		 * @return {String} l'url normalizzato [TODO:spiegare meglio]
		 */
		normalizzaUrl : function(url) {
			if (url.indexOf('http:') != -1) {
				return url;
			}

			var tmpPath = location.href.toString();

			if (ExtCsi.util.URLUtils.startsWith(url, '/')) {
				return tmpPath.substring(0, tmpPath
								.indexOf(ExtCsi.util.URLUtils.rightBack(
										tmpPath, "/"))
								- 1)
						+ url;
			} else {
				return tmpPath.substring(0, tmpPath
								.indexOf(ExtCsi.util.URLUtils.rightBack(
										tmpPath, "/")))
						+ url;
			}
		},
		/**
		 * @method
		 * @param {String}
		 *            strSource [TODO:??]
		 * @param {String}
		 *            strSearch [TODO:??] usata per ricostruire l'url [TODO:
		 *            spiegare meglio]
		 */
		rightBack : function(strSource, strSearch) {
			sourceStringBack = "";
			searchStringBack = "";
			result = "";
			turn = "";
			pos = -1;
			for (i = strSource.length; i > -1; i--) {
				sourceStringBack = sourceStringBack + strSource.charAt(i)
			} // end for
			for (i = strSearch.length; i > -1; i--) {
				searchStringBack = searchStringBack + strSearch.charAt(i)
			} // end for
			pos = sourceStringBack.indexOf(searchStringBack);
			result = sourceStringBack.substring(0, pos)
			for (i = result.length; i > -1; i--) {
				turn = turn + result.charAt(i)
			}
			return turn;
		},
		/**
		 * @method
		 * @param {String}
		 *            str la stringa in cui cercare il prefisso
		 * @param {String}
		 *            prefix il prefisso da cercare nella stringa verifica se
		 *            una stringa inizia con un prefisso specificato.
		 */
		startsWith : function(str, prefix) {
			return (str.match("^" + prefix) == prefix);
		}
	}

}();

// /////////////////////////////////////////////
// / gestione dello stato client side dei widget
// /////////////////////////////////////////////

/**
 * Inizializza il gestore dello stato client side basato sui cookie. Ciascun
 * widget interessato avra' uno 'stateId' univoco composto da <id content
 * panel>_<id widget>.
 */
UIEnrichments.prototype.initStateManager = function() {
	var cp = new Ext.state.CookieProvider({
				path : "/",
				expires : new Date(new Date().getTime() + (1000 * 60 * 60 * 8))
			});
	Ext.state.Manager.setProvider(cp);
}

// /////////////////////
// /////////////////////
// /////////////////////

/**
 * Mantiene gli arricchitori dell'intera applicazione
 */
// function UIEnricherMgr() {
// this.enrichers = {};
// this.ready = false;
// }
ExtCsi.enricher.UIEnricherMgr = Ext.extend(Object, {
			enrichers : {},
			ready : false,
			setReady : function() {
				// alert('nrm.setReady');
				this.ready = true;
				for (var currEnricher in this.enrichers) {
					this.enrichers[currEnricher].value.setReady();
				}
			},
			setEnricherForPage : function(pageId, /* UIEnricher */enricher) {
				if (!this.ready) {
					// alert('UIEnricherMgr.setEnricherForPage:'+pageId )
					this.enrichers[pageId] = {
						value : enricher
					};
				} else
					throw "UIEnricherMgr: cannot set enricher in ready state";
			},
			getEnricherForPage : /* UIEnricher */function(pageId) {
				// alert('UIEnricherMgr.getEnricherForPage:'+pageId );
				var temp = this.enrichers[pageId];
				if (temp != null)
					return temp.value;
				else
					return null;
			},
			registerEnrichment : function(pageId, name, enrichment) {
				// alert('UIEnricherMgr.register:'+pageId+','+name);
				var enricher = this.getEnricherForPage(pageId);
				if (enricher == null) {
					enricher = new ExtCsi.enricher.UIEnricher();
					this.setEnricherForPage(pageId, enricher);
				}
				enricher.registerEnrichment(name, enrichment);
			},
			setPageStructure : function(pageId, structure) {
				var enricher = this.getEnricherForPage(pageId);
				if (enricher == null) {
					enricher = new ExtCsi.enricher.UIEnricher();
					this.setEnricherForPage(pageId, enricher);
				}
				enricher.setStructure(structure);
			},
			applyAll : function(pageId) {
				if (this.ready) {
					// alert('UIEnricher.applyAllRich:'+pageId);
					var enricher = this.getEnricherForPage(pageId);
					if (enricher != null)
						enricher.applyAll();
				} else
					throw "UIEnricherMgr cannot apply in non-ready state";
			},
			apply : function(pageId, /* string [] */targets) {
				if (this.ready) {
					// alert('UIEnricher.applyRich:'+pageId+','+targets);
					var enricher = this.getEnricherForPage(pageId);
					if (enricher != null)
						enricher.applyEnrichments(targets);
				} else
					throw "UIEnricherMgr cannot apply in non-ready state";
			}

		});

/**
 * "singleton" di Enricher manager per tutta l'applicazione
 */
// var uiEnricherMgr = new UIEnricherMgr();
var uiEnricherMgr = new ExtCsi.enricher.UIEnricherMgr();
