// ----------------------------------------------------
//
// formChecker: oggetto per gestione controlli su form
//
// V 1.0.1
// ----------------------------------------------------

//GPP: aggiunte virgolette
//GPP: aggiunto controllo su esistenza metodo focus
//GPP: eliminato debug ripristina


// definizioni

/**
 * Funzione generica per trovare un oggetto in pagina HTML
 * @does Nothing
 * @return Un oggetto
 * @param n Nome dell'oggetto
 * @param d Nome del documento (opzionale)
 */
 
function MM_findObj(n,d) { //v4.01
  var p,i,x;  
  if(!d) {d=document;}
  if((p=n.indexOf("?"))>0&&parent.frames.length) {d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) {x=d.all[n];}
  for (i=0;!x&&i<d.forms.length;i++) {x=d.forms[i][n];}
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) {x=MM_findObj(n,d.layers[i].document);}
  if(!x && d.getElementById) {x=d.getElementById(n);} return x;
}

/**
 * Abbozzo di funzione di evidenziazione componente
 */
function componentHighlight(obj) {
	//alert(obj);
	
	if (document.all&&obj) {
		obj.style.borderStyle = this.fc.borderStyle;
		obj.style.borderColor = this.fc.borderColor;
	}
}
 
var fc_messages_it = new Array();
//GPP: aggiunte virgolette
fc_messages_it["isnull"] = "Il campo \"%1\" non può essere vuoto";
fc_messages_it["isdate"] = "Il campo \"%1\" non contiene una data valida (GG/MM/AAAA)";
fc_messages_it["isdateoryear"] = "Il campo \"%1\" non contiene una data valida (GG/MM/AAAA o AAAA)";
fc_messages_it["isemail"] = "Il campo \"%1\" non contiene una E-mail valida";
fc_messages_it["ischecked"] = "Si deve scegliere un valore per il campo \"%1\"";
fc_messages_it["isnumeric"] = "Il campo \"%1\" può contenere solo cifre";
fc_messages_it["isofsize"] = "Il campo \"%1\" deve essere almeno \"%2\" caratteri";
fc_messages_it["isequal"] = "I campi \"%1\" devono essere uguali";
fc_messages_it["isequalnotnull"] = "I campi \"%1\" devono essere uguali e non vuoti";
fc_messages_it["matchregexp"] = "Il valore del campo \"%1\" non è esatto"; 
fc_messages_it["privacy"] = "E' necessario dare il proprio assenso al trattamento dei dati";
fc_messages_it["custom"] = "a"; 

var fc_messages_uk = new Array();
fc_messages_uk["isnull"] = "Field \"%1\" can't be empty";
fc_messages_uk["isdate"] = "Field \"%1\" is not a valid date (DD/MM/YYYY)";
fc_messages_uk["isdateoryear"] = "Field \"%1\" is not a valid date (DD/MM/YYYY or YYYY)";
fc_messages_uk["isemail"] = "Field \"%1\" is not a valid E-mail";
fc_messages_uk["ischecked"] = "You must choose a value for field \"%1\"";
fc_messages_uk["isnumeric"] = "Field \"%1\" must be a number";
fc_messages_uk["isofsize"] = "Field \"%1\" must be at least %2 char";
fc_messages_uk["isequal"] = "Fields \"%1\" must be equal";
fc_messages_uk["isequalnotnull"] = "Fields \"%1\" must be equal and not empty";
fc_messages_uk["matchregexp"] = "Il valore del campo \"%1\" non è esatto";
fc_messages_uk["privacy"] = "It's mandatory to agree with the privacy statement";
fc_messages_uk["custom"] = "a"; 

/**
 * Classe formChecker  -
 * <A href="../formChecker.txt">Release notes</A> 
 * @constructor
 * @param formname	Nome della form
 * @param lang		lingua (it,uk per ora i soli valori disponibili)
 * @param setfocus	indica se va fatto il posizionamento sul primo errore (true/false)
 */
function formChecker (formname,lang,setfocus) {
	var c;
	// inizializzazione array interni all'oggetto
	this.checks = new Array();
	this.errors = new Array();
	this.formname = formname;
	this.highlight = true; // highligh disabilitato
	// impostazione array dei messaggi in base alla lingua	
	if (lang =="it") {
		this.messages = fc_messages_it;
	} else {
		this.messages = fc_messages_uk;
	}
	
	// indica se si deve fare il posizionamento dopo visualizzazione
	// errori
	this.borderColor = "#FF0000";
	this.borderStyle = "dashed";
	this.setfocus = setfocus;
}

/**
 * Array di messaggi in Italiano
 */
formChecker.prototype.fc_messages_it = fc_messages_it;
/**
 * Array di messaggi in Inglese
 */
formChecker.prototype.fc_messages_uk = fc_messages_uk;

/**
 * Funzione che imposta il focus
 * @param c Nome (nomi) del componente su cui puntare il focus, se sono più di uno
 * 			usa il primo (fa anche un check di esistenza componente)
 */

function formChecker_setFocus(c) {
	//alert(c.name);
//GPP: aggiunto controllo su esistenza metodo focus
	if (c.name.indexOf(',') > 0) {
		var oa = c.name.split(',');
		obj = MM_findObj(oa[0]);
		if (obj && obj.focus) {
			obj.focus();
		}
	} else {
		obj = MM_findObj(c.name);
		if (obj && obj.focus) { 
				obj.focus();
				//componentHighlight(obj);
		}
	}
}
	
/**
 * Funzione che imposta flag di highlight
 * @param flag flag che abilita/disabilita highlight (true/false)
 */
function formChecker_setHighlight(flag) {
	this.highlight = flag;
}

/**
 * Funzione che imposta il tipo di bordo evidenziato per un errore
 * @param s stringa che definisce lo stile (solid,double, etc...)
 */
function formChecker_setHighlightBorderStyle(s) {
	this.borderStyle = s;
}

/**
 * Funzione che imposta il colore del bordo evidenziato per un errore
 * @param s stringa che definisce il colore (#FFFFFF)
 */
function formChecker_setHighlightBorderColor(s) {
	this.borderColor = s;
}
/**
 * Funzione base di aggiunta controllo
 * @param name	Nome (nomi) del componente su cui fare il controllo
 * @param label	Label da usare come riferimento nel messaggio di errore
 * @param type	parametro base che stabilisce il tipo di controllo
 * @param args	argomenti aggiuntivi (possono essere di vario tipo a seconda del
 * 				parametro type
 * @param required	indica se il controllo è facoltativo o obbligatorio (true/false)
 */
function formChecker_add(name,label,type,args,required) {
	var sfc = new formCheck(this,name,label,type,args,required);
	this.checks.push(sfc);
	return(sfc);
	}

/**
 * Funzione base di aggiunta messaggio di errore per errori custom
 * @param checkname	mnemonico del controllo da effettuare
 * @param msg		messaggio di errore
 */
function formChecker_addErrorMessage(checkname,msg) {
	this.messages[checkname] = msg;
	return;
	}
	
/**
 * Esegue il check effettivo della form
  */
function formChecker_validate() {
	var i;
	this.errors = new Array();
	for (i = 0; i < this.checks.length; i ++) {
		this.checks[i].validate(this);
	}
	if (this.errors.length > 0) {
		this.displayErrors(this.errors);
		if (this.setfocus) {
			this.setFocus(this.errors[0]);
		}
		i = false;
	} else {
		i = true;
	}
	return(i);
}

/**
 * Crea il singolo messaggio di errore
 * @param e	oggetto formError
 */
function formChecker_createMessage(e) {
	var c,m,t,re;
	c = e.component;
	m = e.message;
	//t = sprintf(message,);
	re = /%1/;
	m = m.replace(re, c.label);
	return(m);
}


/**
 * Mostra il messaggio di errore (per ora in un alert)
 */
function formChecker_displayErrors() {
	var i,msg = "";
	for (i = 0; i < this.errors.length; i++) {
		msg = msg + this.createMessage(this.errors[i]) + "\n";
	}
	alert(msg);
	return(false);
}

//----------------------------------------------------------------------------
// assegnazione metodi oggetto formChecker
//----------------------------------------------------------------------------

formChecker.prototype.setFocus = formChecker_setFocus;
formChecker.prototype.add = formChecker_add;
formChecker.prototype.addErrorMessage = formChecker_addErrorMessage;
formChecker.prototype.validate = formChecker_validate;
formChecker.prototype.setHighlight = formChecker_setHighlight;
formChecker.prototype.setHighlightBorderStyle = formChecker_setHighlightBorderStyle;
formChecker.prototype.setHighlightBorderColor = formChecker_setHighlightBorderColor;
formChecker.prototype.createMessage = formChecker_createMessage;
formChecker.prototype.displayErrors = formChecker_displayErrors;


//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------


/**
 * Classe formCheck - rappresenta il singolo controllo da effettuare sulla 
 * form  
 * <pre>
 * </pre>
 * @constructor
 * @param args	argomenti aggiuntivi che possono essere di varia natura
 * @param f 	nome del form su cui va effettuato il check
 * @param name	nome dell'elemento o elementi separati da "," coinvolti nel controllo
 * @param label	etichetta che viene mostrata nel messaggio di errore come riferimento al campo
 * @param type	il tipo fondamentale di controllo
 * @with What is that
 */
function formCheck (f,name,label,type,args,required) {
	this.name = name;
	this.label = label;
	this.type = type;
	this.args = args;
	this.fc = f;
	this.required = required;
	this.originalBorderStyle = "solid";
	this.originalBorderColor = "#444444";
	//alert(parent.formname);
	}

/**
 * Metodo base dell'oggetto, chiede di effettuare il controllo
 * @return true/false
 * @param f indica l'istanza di classe formChecker da utilizzare
 */
function formCheck_validate (f) {
	//alert(this.type);
	var obj;
	var n = f.errors.length;
	//alert(n);
	switch (this.type) {
		case "isnull": 
			if (this.isNull()) 	{f.errors.push(new formError(this,f.messages["isnull"],null));}
			break;
		case "isdate": 
			if (!this.isDate()) 	{f.errors.push(new formError(this,f.messages["isdate"],null));}
			break;
		case "isdateoryear":
			if (this.required) {
				if(this.isYear() || this.isDate()) {}
				else {
					f.errors.push(new formError(this,f.messages["isdateoryear"],null));
				} 
			} else {
				if(!this.isNull()) {
					if ((this.isYear() || this.isDate())) { }
					else {f.errors.push(new formError(this,f.messages["isdateoryear"],null));} 
				}
			}
			break;
		case "isemail":
			if (this.required) {
				if(this.isEmail()) 	{f.errors.push(new formError(this,f.messages["isemail"],null));}
			} else {
				if(!this.isNull() && (this.isEmail())) 	{f.errors.push(new formError(this,f.messages["isemail"],null));}
			}
			break;
		case "ischecked": 
			if(!this.isChecked()) 	{f.errors.push(new formError(this,f.messages["ischecked"],null));}
			break;
		case "isnumeric": 
			if (this.required) {
				if(!this.isNumeric()) 	{f.errors.push(new formError(this,f.messages["isnumeric"],null));}
			} else {
				if(!this.isNull() && !this.isNumeric()) 	{f.errors.push(new formError(this,f.messages["isnumeric"],null));}
			}
			break;
		case "isequal": 
			if(!this.isEqual(false)) 	{f.errors.push(new formError(this,f.messages["isequal"],null));}
			break;
		case "isequalnotnull": 
			if(!this.isEqual(true)) 	{f.errors.push(new formError(this,f.messages["isequalnotnull"],null));}
			break;
		case "isboxchecked": 
			if(!this.isBoxChecked()) 	{f.errors.push(new formError(this,f.messages["ischecked"],null));}
			break;
		case "matchregexp": 
			if(!this.matchRegExp()) 	{f.errors.push(new formError(this,f.messages["matchregexp"],null));}
			break;
		case "privacy": 
			if(!this.checkPrivacy()) 	{f.errors.push(new formError(this,f.messages["privacy"],null));}
			break;
		case "custom": 
			if(!this.customCheck()) 	{f.errors.push(new formError(this,f.messages[this.name],null));}
			break;
		default:
			break;
	}
	if (f.errors.length == n && f.highlight) {
			obj = MM_findObj(this.name);
			if (document.all && obj !== null && (obj.type == "text" || obj.type == "password")) {
				//GPP: eliminato debug ripristina
				//alert("ripristina: " + this.originalBorderStyle + "  " + this.name);
				obj.style.borderStyle = this.originalBorderStyle;
				obj.style.borderColor = this.originalBorderColor;
			}
	}
	return(true);	
}

function formCheck_isNull() {
	var obj = MM_findObj(this.name);
	if (obj.value === "" || obj.value === undefined) {
		return(true);
	} else {
		return(false);
	}
}

function formCheck_isString() {
	return;
}

/**
 * Funzione di test per vedere se un campo di accettazione privacy è stato selezionato 
 * @return true/false
 */
function formCheck_checkPrivacy() {
	var ct,obj,retval;
	//alert(this.name);
	obj = MM_findObj(this.name);
	//alert(obj.length);
	retval = false;
	for (ct = 0; ct < obj.length; ct++) {
			//alert(obj[ct].checked);
			if (obj[ct].checked === true) {
				//alert(obj[ct].value);
				if (obj[ct].value == this.args) {
					retval = true;
				} 
			}
			
	}
	return(retval);
}

/**
 * Funzione di test custom (v1.0) 
 * @return true/false
 */
function formCheck_customCheck() {
	var ct,obj,retval;
	//alert(this.args);
	return(this.args(this.fc,this));
}

function formCheck_isDate() {
	var obj = MM_findObj(this.name);
	if (obj) {
		if (isValidDate(obj.value)) {
			return(true);
		} else {
			return(false);
		}
	}
	return(false);
}

function formCheck_isYear() {
	var obj = MM_findObj(this.name);
	
	if (isValidYear(obj.value)) {
		return(true);
	} else {
		return(false);
	}
}

function formCheck_isEmail() {
	var obj = MM_findObj(this.name);
	if (isValidEmail(obj.value)) {
		return(false);
	} else {
		return(true);
	}
}

function formCheck_isChecked() {
	var obj = MM_findObj(this.name);
	var ct = 0;
	var retval = false;
	while (obj[ct]) { 		// cicla tra tutti i sottocomponenti
		if (obj[ct].checked) {
			retval = true;
		}
		//alert(obj[ct].checked);
		ct++;
	}
	return(retval);
}

function formCheck_isBoxChecked() {
	//alert(this.fc.formname + " " +this.name);
	var obj = MM_findObj(this.fc.formname);
	
	var ct = 0;
	var retval = false;
	while (obj.elements[ct]) { 		// cicla tra tutti i sottocomponenti
			if (obj.elements[ct].type == "checkbox") {
				//alert(obj.elements[ct].name);
				if (obj.elements[ct].name.toString().indexOf(this.name) === 0) {
					//alert("checked starts");
					if (obj.elements[ct].checked) {
						retval = true;
					}
				}
			}
		
		//alert(obj[ct].checked);
		ct++;
	}
	return(retval);
}

/**
 * Funzione di test per vedere se un campo è numerico
 * @return true/false
 */
function formCheck_isNumeric() {
	var obj = MM_findObj(this.name);
	if (isNumeric(obj.value)) {
		return(true);
	} else {
		return(false);
	}
}


/**
 * Funzione di test per vedere se un campo è uguale ad un valore
 * o se due campi sono uguali
  * @return true/false
 * @param flag indica se l'uguaglianza tra due valori comprende anche valore nullo
 */
function formCheck_isEqual(flag) {
	if (this.name.indexOf(',') > 0) {
		var oa = this.name.split(",");
		if (oa.length == 2) {
			var obj1 = MM_findObj(oa[0]);
			var obj2 = MM_findObj(oa[1]);
			//alert(obj1.name.value + " " + obj2.name.value);
			if (flag) {
				condition =  (obj1.value) && (obj2.value);
			} else {
				condition = true;
			}
			return(obj1.value == obj2.value && condition);
		} else {
			alert("non implementato");
			return(true);
		}
	} else {
		var obj = MM_findObj(this.name);
		return(obj.value == this.args);
		}
}

/**
 * Funzione di test per vedere se un campo soddisfa una Regular Expression
  * @return true/false
 * @has Not a single thing
 */
function formCheck_matchRegExp() {
	var obj = MM_findObj(this.name);
	if (this.args.test(obj.value)) {
		return(true);
	} else {
		return(false);
	}
}
	
/**
 * Funzione di test per vedere se un campo se un campo è un Codice Fiscale
 * <B>DA IMPLEMENTARE</B>
 * @return true/false
 */
function formCheck_isCF() {	// da implementare
	return(true);
	}

/**
 * Funzione di test per vedere se un campo è in un intervallo di date
 * <B>DA IMPLEMENTARE</B>
 * @return true/false
 */
function formCheck_isDateInRange() {
	var dates = new Array();
	dates = this.args.split("|");		
	return;
	}

//----------------------------------------------------------------------------
// assegnazione dei metodi di formCheck
//----------------------------------------------------------------------------

formCheck.prototype.isNull = formCheck_isNull;
formCheck.prototype.isDate = formCheck_isDate;
formCheck.prototype.isYear = formCheck_isYear;
formCheck.prototype.isDateInRange = formCheck_isDateInRange;
formCheck.prototype.isString = formCheck_isString;
formCheck.prototype.isEmail = formCheck_isEmail;
formCheck.prototype.isChecked = formCheck_isChecked;
formCheck.prototype.isBoxChecked = formCheck_isBoxChecked;
formCheck.prototype.isNumeric = formCheck_isNumeric;
formCheck.prototype.isEqual = formCheck_isEqual;
formCheck.prototype.matchRegExp = formCheck_matchRegExp;
formCheck.prototype.validate = formCheck_validate;
formCheck.prototype.isCF = formCheck_isCF;
formCheck.prototype.checkPrivacy = formCheck_checkPrivacy;
formCheck.prototype.customCheck = formCheck_customCheck;


/**
 * Classe formError  
 * classe di descrizione di singolo errore - tiene un riferimento al controllo
 * che lo ha generato
 * @constructor
 * @with What is that
 */
function formError(c,message,formatMethod) {
	this.component = c;
	this.name = c.name;
	this.message = message;
	this.formatMethod = formatMethod;
	//alert(c.name);
	obj = MM_findObj(c.name);
	//alert(c.fc.highlight);
	if (obj && (obj.type == "text" || obj.type == "password") && c.fc.highlight) {
		componentHighlight(obj,c);
	}
}

function formError_setMessage(m) {
	this.message = message;
}

formError.prototype.setMessage = formError_setMessage;

//----------------------------------------------------------------------------
// funzioni varie di supporto 
//----------------------------------------------------------------------------

function isValidEmail(email) {
	//alert(email);
	var str = email;
	if(email === "") {return (false);}
	if (window.RegExp) {
		var reg1str = "(@.*@)|(\\.\\.)|(@\\.)|(\\.@)|(^\\.)";
		var reg2str = "^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$";
		var reg1 = new RegExp(reg1str);
		var reg2 = new RegExp(reg2str);
		if (!reg1.test(str) && reg2.test(str))  {return(true);}
		return false;
	} else {
		//alert("no RegExp");
		if(str.indexOf("@") >= 0) {return(true);}
		else {return(false);}
	}
}

function isValidYear(year) {
	//alert(email);
	//alert(year);
	var str = year;
	if(str === "") {return (false);}
	if (window.RegExp) {
		var reg1str = /^\d{4,4}$/;
		//alert(reg1str);
		//var reg1 = new RegExp(reg1str);
		if (reg1str.test(str)) {return(true);}
		else {return false;}
	} else {
		alert("no RegExp");
		if(str.length() == 4) {return (true);}
			else {return (false);}
	}
}

function isValidDate( strValue ) {
	var objRegExp = /^\d{1,2}(\-|\/|\.)\d{1,2}\1(\d{4}|\d{2})$/;
	
	if(!objRegExp.test(strValue)) {
		return false;
	} else {
		var t = strValue;
		var tre = /\d/g;
		t = strValue.replace(tre,"");
		
		var strSeparator = t.substring(1,2);
		var arrayDate = strValue.split(strSeparator);
		var arrayLookup = { '01' : 31,'1' : 31,'03' : 31,'3' : 31, '4' : 30,'04' : 30,'05' : 31,'5' : 31,'06' : 30,'6' : 30,'07' : 31,'7' : 31, '08' : 31,'8' : 31,'09' : 30,'9' : 30,'10' : 31,'11' : 30,'12' : 31};
		var intDay = parseInt(arrayDate[0]);
		
		if(arrayDate[1] < 12 && arrayLookup[arrayDate[1]] !== null) {
			if(intDay <= arrayLookup[arrayDate[1]] && intDay !== 0) {
				return (true);
			}
		}
		
		var intYear = parseInt(arrayDate[2]);
		var intMonth = parseInt(arrayDate[1]);
		if( ((intYear % 4 === 0 && intDay <= 29) || (intYear % 4 !== 0 && intDay <=28)) && intDay !== 0) {
			return (true);
		}
	}
	return false;
}

function isNumeric( strValue ) { // USA
	
	if (strValue === undefined) {
			return (false);
	}
	var objRegExp  =  /(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/;
	return objRegExp.test(strValue);
}


