/*
 * Inline Form Validation Engine, Prototype plugin
 * 
 * Copyright(c) 2009, Cedric Dugas
 * http://www.a-tono.com
 *	
 * Form validation engine witch allow custom regex rules to be added.
 */
Element.addMethods({
	validationEngine: function(element,settings)
		{
	        var element = $(element);
	        // allRules = { 	};
            var validateEngine = new ValidationEngine(element, settings);
    		
    		// ON FORM SUBMIT, CONTROL AJAX FUNCTION IF SPECIFIED ON DOCUMENT READY
        	_inlinSubmitEvent = function(event)
    		{
        		// caller e' il form che fa il submit
        		var caller = event.element();
        		this.onSubmitValid = true;
    			if(validateEngine.submitValidation(caller, validateEngine.settings) == false)
    			{
    				if(validateEngine.submitForm(caller) == true ) { return false; }
    			}
    			else
    			{
    				validateEngine.settings.failure && validateEngine.settings.failure(); 
    				return false;
    			}
    		};
    		_inlinEvent = function(caller) 
    		{
    			// calller e' il singolo elemento da validare (all'onblur on all'onclick se e' checkbox)
    			
	    		// STOP INLINE VALIDATION THIS TIME ONLY
	    		if(this.intercept == false || !this.intercept)
	    		{
	    			this.onSubmitValid=false;
	    			validateEngine.loadValidation(caller.element()); 
	    		}
	    		else
	    		{
	    			this.intercept = false;
	    		}
	    	};
	    	// associo _inlinSubmitEvent all'onsubmit
        	element.observe("submit", this._inlinSubmitEvent.bind(this));
    			    	
    		if(validateEngine.settings.inlineValidation == true) // Validating Inline ?
    		{
    			// associo _inlinEvent all'onblur di tutti i campi del form eccetto i checkbox
    			$$("#"+settings["idForm"]+" [class^=validate]").each(function(elem) 
    			{
    					$$("#"+elem.id+":not([type=checkbox])").each(function(elem) {
					    												elem.observe("blur", _inlinEvent.bind(this));
					    											});
    					$$("#"+elem.id+"[type=checkbox]").each( function(elem) { 
    																elem.observe("click", _inlinEvent.bind(this) ); 
    															});
    			});	   			
    		} // end Validating Inline
    	}
	}
);

ValidationEngine = Class.create(ValidationEngineLanguage, {
	allRules: {
		required:{    			  // Add your regex rules here, you can take telephone as an example
			regex:"none",
			alertText:"* Campo obbligatorio",
			alertTextCheckboxMultiple:"* Per favore seleziona una voce",
			alertTextCheckboxe:"* La casellina e' obbligatoria"},
		length:{
			regex:"none",
			alertText:"*compreso ",
			alertText2:" e ",
			alertText3: " caratteri ammessi"},
		minlength:{
			regex:"none",
			alertText:"* La stringa deve essere lunga almeno ",
			alertText2:" characters"},
		maxCheckbox:{
	    	regex:"none",
	    	alertText:"* Scelte sono permesse"},	
	    minCheckbox:{
	    	regex:"none",
	    	alertText:"* Per favore seleziona",	
			alertText2:" options"},
	    confirm:{
	    	regex:"none",
	    	alertText:"* I campi non coincidono"},	
	    depend:{
	    	regex:"none",
	    	alertText:"* Ci sono altri campi da compilare"},	
	    telephone:{
	    	regex: /^[0-9\-\(\)\ ]+$/,
	    	alertText:"* Numero di telefono non valido"},	
	    mobilephone:{
	    	regex: /^[0-9]{9,}$/,
	    	alertText:"* Numero di cellulare non valido"},
	    email:{
	    	regex: /^[a-zA-Z0-9_\.\-]+\@([a-zA-Z0-9\-]+\.)+[a-zA-Z0-9]{2,4}$/,
	    	alertText:"* Indirizzo email non valido"},	
	    date:{
	    	regex: /^(0[1-9]|[12]\d|3[01])\/(0[1-9]|1[0-2])\/([1-9])\d{3}$/,
	    	alertText:"* Data non valida, il formato deve essere gg/mm/aaaa"},
	    time:{
	    	regex: /^(0[0-9]|1[0-9]|2[0-4]):(0[0-9]|[1-5][0-9])(:0[0-9]|[1-5][0-9])?$/,
	    	alertText:"* Orario non valido, il formato deve essere hh:mm (o hh:mm:ss). 24 ore"},
	    datetime:{
	        regex: /^(0[1-9]|[12]\d|3[01])\/(0[1-9]|1[0-2])\/([1-9])\d{3} (0[0-9]|1[0-9]|2[0-4]):(0[0-9]|[1-5][0-9]):(0[0-9]|[1-5][0-9])?$/,
	        alertText:"* Data non valida, il formato deve essere gg/mm/aaaa hh:mm oppure gg/mm/aaaa hh:mm:ss"},
	    onlyNumber:{
	    	regex: /^[0-9\ ]+$/,
	    	alertText:"* Solo numeri"},
            noStartNumber:{
                regex: /^[a-zA-Z]+[0-9a-zA-Z]+$/,
                alertText:"* Non può iniziare con un numero"},	
	    positiveNumber:{
	    	regex: /^\d+([\.,]\d+)?$/,
	    	alertText:"* Solo numeri positivi"},
	    noSpecialCharacters:{
	    	regex: /^[0-9a-zA-Z]+$/,
	    	alertText:"* Non sono ammessi caratteri speciali"},	
	    onlyLetter:{
	    	regex: /^[a-zA-Z\ \']+$/,
	    	alertText:"* Solo caratteri"},
	    zip:{
	    	regex: /^\d{5}$/,
	    	alertText:"Codice postale non valido"},
	    ajaxUser:{
	    	file:"validateUser.php",
	    	alertTextOk:"* This user is available",	
	    	alertTextLoad:"* Loading, please wait",
	    	alertText: "* This user is already taken"}
	},
	
	initialize: function(element, settings) {   
		if( ValidationEngineLanguage.newLang ) 
		{
			ValidationEngineLanguage.newLang(this.allRules);
		}
		//this.settings = Object.extend({}, settings || {});
	  	this.settings = Object.extend({
			allrules: ValidationEngineLanguage.allRules,
			inlineValidation: true,
			idForm: "form",
			ajaxSubmit: false,
			promptPosition: "topRight",	// OPENNING BOX POSITION, IMPLEMENTED: topLeft, topRight, bottomLeft, centerRight, bottomRight
			success : false,
			failure : function() { return false; }
		}, settings || {});
		
		//Object.extend(this.allRules, ValidationEngineLanguage.allRules || {});
	    this.element = $(element);
	    this.ajaxValidArray = new Array()	// ARRAY FOR AJAX: VALIDATION MEMORY
	},
	
	//caller deve essere il form
	submitForm : function(caller) {
		if(this.settings.ajaxSubmit)
		{		
			var theform = $(caller); 
			new Ajax.Request(this.settings.ajaxSubmitFile, {
					method: "post",
					parameters: theform.serialize(),
					onComplete: function(response) 
					{
						if( response.status == 200 )// EVERYTING IS FINE, SHOW SUCCESS MESSAGE	
						{
							$(caller).setOpacity(1);
							$(caller).blindUp();
							$(caller).setStyle({display:none});
							$(caller).insert({before: "<div class='ajaxSubmit'>"+this.settings.ajaxSubmitMessage+"</div>"});
							this.closePrompt(".formError",true);
							$(".ajaxSubmit").blindDown();
							if (this.settings.success){	// AJAX SUCCESS, STOP THE LOCATION UPDATE
								this.settings.success && this.settings.success(); 
							return false;
							}
						}
						else // HOUSTON WE GOT A PROBLEM (SOMETING IS NOT VALIDATING)
						{
							var JSONobj = ( response.responseJSON || response.responseText.evalJSON());
							if( JSONobj != null )
							{
								for( var keyvalue in JSONobj)
								{
									fieldId = keyvalue[0];
									promptError = keyvalue[1];
									type = keyvalue[2];
									this.buildPrompt(fieldId,promptError,type);
								}
							}
						}
   				}// end function onComplete
			})	
			return true;
		}
		
		if (this.settings.success){	// AJAX SUCCESS, STOP THE LOCATION UPDATE
			this.settings.success && this.settings.success(); 
			return true;
		}
		return false;
	},
	
	// ERROR PROMPT CREATION AND DISPLAY WHEN AN ERROR OCCUR
	buildPrompt : function(caller,promptText,type,ajaxed) {			
		var divFormError = document.createElement('div');
		var formErrorContent = document.createElement('div');
		$(divFormError).id=this.prompt;	
		
		$(divFormError).addClassName("formError");
		$(divFormError).addClassName(this.settings.idForm+"formError");
		
		if(type == "pass"){ $(divFormError).addClassName("greenPopup"); }
		if(type == "load"){ $(divFormError).addClassName("blackPopup"); }
		if(ajaxed){ $(divFormError).addClassName("ajaxed"); }
		
		$(formErrorContent).addClassName("formErrorContent");
		$(formErrorContent).update("<a href=\"javascript:void(0)\" class=\"closeValidation\" onclick=\"new ValidationEngine().closePrompt('#"+this.prompt+"',true);\">x</a>");
		
		//$(this.settings.idForm).insert(divFormError);
		($$("body"))[0].insert(divFormError);
		
		$(divFormError).insert(formErrorContent);
			
		// NO TRIANGLE ON MAX CHECKBOX AND RADIO
		if(this.showTriangle != false) 
		{		
			var arrow = document.createElement('div');
			$(arrow).addClassName("formErrorArrow");
			$(divFormError).insert(arrow);
			if(this.settings.promptPosition == "bottomLeft" || this.settings.promptPosition == "bottomRight")
			{
				$(arrow).addClassName("formErrorArrowBottom");
				$(arrow).update('<div class="line1"><!-- --></div><div class="line2"><!-- --></div><div class="line3"><!-- --></div><div class="line4"><!-- --></div><div class="line5"><!-- --></div><div class="line6"><!-- --></div><div class="line7"><!-- --></div><div class="line8"><!-- --></div><div class="line9"><!-- --></div><div class="line10"><!-- --></div>');
			}
			if(this.settings.promptPosition == "topLeft" || this.settings.promptPosition == "topRight")
			{
				$(divFormError).insert(arrow);
				$(arrow).update('<div class="line10"><!-- --></div><div class="line9"><!-- --></div><div class="line8"><!-- --></div><div class="line7"><!-- --></div><div class="line6"><!-- --></div><div class="line5"><!-- --></div><div class="line4"><!-- --></div><div class="line3"><!-- --></div><div class="line2"><!-- --></div><div class="line1"><!-- --></div>');;
			}
		}
		$(formErrorContent).insert(promptText);
	
		callerTopPosition = $(caller).cumulativeOffset().top;
		callerleftPosition = $(caller).cumulativeOffset().left;
		callerWidth =  $(caller).getWidth();
		inputHeight = $(divFormError).getHeight();
	
		/* POSITIONNING */
		if(this.settings.promptPosition == "topRight")
		{
			callerleftPosition +=  callerWidth -30; 
			callerTopPosition += -inputHeight -10; 
		}
		if(this.settings.promptPosition == "topLeft"){ callerTopPosition += -inputHeight -10; }
		
		if(this.settings.promptPosition == "centerRight"){ callerleftPosition +=  callerWidth +13; }
		
		if(this.settings.promptPosition == "bottomLeft")
		{
			callerHeight =  $(caller).getHeight();
			callerleftPosition = callerleftPosition;
			callerTopPosition = callerTopPosition + callerHeight + 15;
		}
		if(this.settings.promptPosition == "bottomRight")
		{
			callerHeight =  $(caller).getHeight();
			callerleftPosition +=  callerWidth -30;
			callerTopPosition +=  callerHeight + 15;
		}
		
		$(divFormError).setStyle({
			opacity: 0,
			top: callerTopPosition+"px",
			left: callerleftPosition+"px"
		});

		$(divFormError).appear({to:   0.87});
		
		return true;
	},
	
	// UPDATE TEXT ERROR IF AN ERROR IS ALREADY DISPLAYED
	updatePromptText: function(caller,promptText,type,ajaxed) {	
		updateThisPrompt = this.prompt;

		(type == "pass") ? $(updateThisPrompt).addClassName("greenPopup") : $(updateThisPrompt).removeClassName("greenPopup");
		(type == "load") ? $(updateThisPrompt).addClassName("blackPopup") : $(updateThisPrompt).removeClassName("blackPopup");
		(ajaxed) ? $(updateThisPrompt).addClassName("ajaxed") : $(updateThisPrompt).removeClassName("ajaxed");
	
		$$("#"+updateThisPrompt+" > .formErrorContent").each(function(elem){ elem.update(promptText); });
		
		callerTopPosition = $(caller).cumulativeOffset().top;
		callerleftPosition = $(updateThisPrompt).cumulativeOffset().left;	
		callerWidth =  $(caller).getWidth();
		inputHeight = $(updateThisPrompt).getHeight();
		
		if(this.settings.promptPosition == "bottomLeft" || this.settings.promptPosition == "bottomRight")
		{
			callerHeight =  $(caller).getHeight();
			callerTopPosition =  callerTopPosition + callerHeight + 15;
		}
		if(this.settings.promptPosition == "centerRight"){ callerleftPosition +=  callerWidth +13; }
		if(this.settings.promptPosition == "topLeft" || this.settings.promptPosition == "topRight")
		{
			callerTopPosition = callerTopPosition  -inputHeight -10;
		}
		
		new Effect.Move($(updateThisPrompt), { mode: 'absolute', x: callerleftPosition, y: callerTopPosition, duration: 0.5});
	},
	
	// GET VALIDATIONS TO BE EXECUTED
	loadValidation: function(caller) {		
		rulesParsing = $(caller).readAttribute('class');
		rulesRegExp = /\[(.*)\]/;
		getRules = rulesRegExp.exec(rulesParsing);
		str = getRules[1];
		pattern = /\W+/;
		result= str.split(pattern);	
					
		var validateCalll = this.validateCall(caller,result);
		return validateCalll;			
	},
	
	// EXECUTE VALIDATION REQUIRED BY THE USER FOR THIS FILED 
	validateCall: function(caller, rules) 	
	{
			var resObj = null;
			this.promptText ="";
			this.prompt = ($(caller).readAttribute("id")) + "formError";
			var caller = caller;
			ajaxValidate = false;
			this.isError = false;
			this.showTriangle = true;
			callerType = $(caller).readAttribute("type"); //|| $(caller).type;
		    if(callerType == null || callerType == "" || callerType =="undefined") {
                try {
                    callerType = $(caller).type;
                }
                catch (e) {
                    callerType="text";
                }
            }
			for (i=0; i<rules.length;i++)
			{
				switch ( rules[i] )
				{
					case "optional": 	
						if( !$F(caller) )
						{
							this.closePrompt(caller);
							return this.isError;
						}
						break;
					case "required": 
						this._required(caller,rules[i]);
						break;
					case "custom": 
						this._customRegex(caller,rules,i);
						i++;
						break;
					case "ajax": 
						if(!this.onSubmitValid)
						{
							this._ajax(caller,rules,i);	
							i++;
						}
						break;
					case "length": 
						this._length(caller,rules,i);
						i=i+2;
						break;
					case "minlength": 
						this._minlength(caller,rules,i);
						i++;
						break;
					case "maxCheckbox": 
						this._maxCheckbox(caller,rules,i);
						i++;
					 	break;
					case "minCheckbox": 
						this._minCheckbox(caller,rules,i);
						i++;
					 	break;
					case "confirm": 
						this._confirm(caller,rules,i);
						i++;
						break;
					case "depend": 
						rules=this._depend(caller,rules,i);
						i++;
						break;
					default :;
				}
			} // end for rules
						
			if (this.isError == true)
			{
				this.radioHackOpen(caller);
				// show only one
				if (this.isError == true)
				{
					( $$("div#"+this.prompt).size() == 0 ) ? this.buildPrompt(caller,this.promptText,"error") : this.updatePromptText(caller,this.promptText);
				}
			}
			else 
			{
				this.radioHackClose(caller);
				this.closePrompt(caller); 
			}
			
			
			return ( ( this.isError ) ? this.isError : false );
			
	}, // end function validateCall
	
	/* UNFORTUNATE RADIO AND CHECKBOX GROUP HACKS */
	/* As my validation is looping input with id's we need a hack for my validation to understand to group these inputs */
	radioHackOpen: function(caller)
	{
		var callerName  = $(caller).readAttribute("name");
		
		// Hack for radio/checkbox group button, the validation go the first radio/checkbox
		if($$("input[name="+callerName+"]").size() > 1 && ( callerType == "radio" || callerType == "checkbox"))
		{
			caller = $$("input[name="+callerName+"]:first").first();
			this.showTriangle = false;
			var callerId = ( callerType == "radio" ? "" : "div" )+"."+ $(caller).readAttribute("id");
			if($$(callerId).size()==0){ this.isError = true; }
			else{ this.isError = false;}
			
			this.prompt = ($(caller).readAttribute("id")) + "formError";
		}
	}, // end function radioHackOpen
	
	radioHackClose: function (caller)
	{
		var callerName  = $(caller).readAttribute("name");
		
		// Hack for radio group && checkbox group button, the validation go the first radio/checkbox
		if($$("input[name="+callerName+"]").size() > 1 && ( callerType == "radio" || callerType == "checkbox"))
		{
			caller = $$("input[name="+callerName+"]:first").first();
			
			this.prompt = ($(caller).readAttribute("id")) + "formError";
		}
	}, // end function radioHackClose
	
	/* VALIDATION FUNCTIONS */
	_required: function(caller, rule)  // VALIDATE BLANK FIELD 
	{
		var hash = $H(this.settings.allrules);
		rule = hash.get(rule);
		callerType = $(caller).readAttribute("type");// || $(caller).type;
        if(callerType == null || callerType == "" || callerType =="undefined") {
            try {
                callerType = $(caller).type;
            }
            catch (e) {
                callerType="text";
            }
        }
	
		if (callerType == "text" || callerType == "password" || callerType == "textarea")
		{
			if( !$F(caller) )
			{
				this.isError = true;
				this.promptText += rule.alertText+"<br />";
			}	
		}
		if (callerType == "radio" || callerType == "checkbox" )
		{
			callerName = $(caller).readAttribute("name");

			if( $$("input[name="+callerName+"]:checked").size() == 0 )
			{
				this.isError = true;
				if( $$("input[name="+callerName+"]").size() == 1 ) 
				{
					this.promptText += rule.alertTextCheckboxe+"<br />"; 
				}
				else
				{
					this.promptText += rule.alertTextCheckboxMultiple+"<br />";
				}	
			}
		}	
		if (callerType == "select-one")  // added by paul@kinetek.net for select boxes, Thank you 
		{
			callerName = $(caller).readAttribute("name");

			//if(!$$("select[name="+callerName+"]").getValue()) 
            
			if(!($(caller).getValue())) 
			{
				this.isError = true;
				this.promptText += rule.alertTextCheckboxMultiple+"<br />";
				//this.promptText += this.settings.allrules.get(rules[i]).alertText+"<br />";
			}
		}
		if (callerType == "select-multiple")// added by paul@kinetek.net for select boxes, Thank you 
		{ 
			if( !$F(caller) ) 
			{
				this.isError = true;
				this.promptText += this.settings.allrules.get(rules[i]).alertText+"<br />";
			}
		}
	}, // end function _required

	_customRegex: function (caller,rules,position) // VALIDATE REGEX RULES
	{
		customRule = rules[position+1];
		hash = $H(this.settings.allrules);
		pattern = eval(hash.get(customRule).regex);
		
		if( !pattern.test($F(caller)) )
		{
			this.isError = true;
			this.promptText += hash.get(customRule).alertText+"<br />";
		}
	}, // end funtion _customRegex

	_checkInArray: function (validate) 
	{
		for(x=0;x<ajaxErrorLength;x++)
		{
			if(this.ajaxValidArray[x][0] == fieldId)
			{
				this.ajaxValidArray[x][1] = validate;
				existInarray = true;
			}
		}
	},
	
	_ajax: function (caller,rules,position) // VALIDATE AJAX RULES
	{		
		var customAjaxRule = rules[position+1];
		hash = $H(this.settings.allrules);
		postfile = hash.get(customAjaxRule).file;
		fieldValue = $F(caller);
		ajaxCaller = $(caller);
		fieldId = $(caller).identify();
		ajaxValidate = true;
		ajaxisError = this.isError;
		
		/* AJAX VALIDATION HAS ITS OWN UPDATE AND BUILD UNLIKE OTHER RULES */	
		if(!ajaxisError)
		{
			var params = new Hash();
			params.set("validateValue", fieldValue);
			params.set("validateId", fieldId);
			params.set("validateError", customAjaxRule);
			// BUILD A LOADING PROMPT IF LOAD TEXT EXIST	
			if(hash.get(customAjaxRule).alertTextLoad)
			{
				Ajax.Responders.register({
						onCreate: function() {
								var tmp = $$("div."+fieldId);
								if(!tmp[0]) return this.buildPrompt(ajaxCaller,hash.get(customAjaxRule).alertTextLoad, "load");
								else this.updatePromptText(ajaxCaller, hash.get(customAjaxRule).alertTextLoad, "load");
							}
				});
			}
			
			new Ajax.Request(postfile, {
					method: "post",
					parameters: params,
					onSuccess: function(response){					// GET SUCCESS DATA RETURN JSON
						var JSONobj = ( response.responseJSON || response.responseText.evalJSON());
						if( JSONobj != null )
						{
							ajaxisError = JSONobj[2];
							customAjaxRule =  JSONobj[1];
							fieldId = JSONobj[0];
							ajaxCaller = $(JSONobj[0]);
							ajaxErrorLength = this.ajaxValidArray.length;
							existInarray = false;
							// DATA FALSE UPDATE PROMPT WITH ERROR;
							if(ajaxisError == "false")
							{
								// Check if ajax validation alreay used on this field
								this._checkInArray(false);
					 			// Add ajax error to stop submit
								if(!existInarray)
								{		 		
					 			 	this.ajaxValidArray[ajaxErrorLength] =  new Array(2);
					 			 	this.ajaxValidArray[ajaxErrorLength][0] = fieldId;
					 			 	this.ajaxValidArray[ajaxErrorLength][1] = false;
					 			 	existInarray = false;
				 			 	}
								
								this.ajaxValid = false;
								this.promptText += hash.get(customAjaxRule).alertText+"<br />";
								this.updatePromptText(ajaxCaller,this.promptText,"",true);	
							}
							else
							{
								this._checkInArray(true);
								
							 	this.ajaxValid = true; 						   
		 			 			if(hash.get(customAjaxRule).alertTextOk) // NO OK TEXT MEAN CLOSE PROMPT
		 			 			{		 	
		 			 				this.updatePromptText(ajaxCaller,hash.get(customAjaxRule).alertTextOk,"pass",true);
					 			}
		 			 			else
		 			 			{
					 			 	ajaxValidate = false;		 	
					 			 	this.closePrompt(ajaxCaller);
					 			}	
							}
							
						}
			 		}				
			});
		}
	},
	
	_confirm: function (caller,rules,position) // VALIDATE FIELD MATCH
	{		
		confirmField = rules[position+1];

		if( $F(caller) != $F($(confirmField)) )
		{
			this.isError = true;
			this.promptText += this.settings.allrules.confirm.alertText+"<br />";
		}
	}, // end function _confirm
	
	_depend: function (caller,rules,position) // VALIDATE FIELD MATCH
	 {  
	  confirmField = rules[position+1];

	  if(!$F($(confirmField)) )
	  {
	   rules = new Array();
	  }
	  return rules;
	}, // end function _depend
	
	_length: function (caller,rules,position) // VALIDATE LENGTH
	{    
		startLength = eval(rules[position+1]);
		endLength = eval(rules[position+2]);
		feildLength = $F(caller).length;
		
		if( feildLength<startLength || feildLength>endLength )
		{
			this.isError = true;
			this.promptText += this.settings.allrules.length.alertText+startLength+this.settings.allrules.length.alertText2+endLength+this.settings.allrules.length.alertText3+"<br />";
		}
	}, // end function _length

	_minlength: function (caller,rules,position) // VALIDATE MINLENGTH
	{    
		Length = eval(rules[position+1]);
		feildLength = $(caller).readAttribute('value').length;

		if( feildLength<Length )
		{
			this.isError = true;
			this.promptText += this.settings.allrules.minlength.alertText+Length+this.settings.allrules.minlength.alertText2+"<br />";
		}
	}, //end function _minlength

	_maxCheckbox: function (caller,rules,position)// VALIDATE CHECKBOX NUMBER
	{  	  
		nbCheck = eval(rules[position+1]);
		groupname = $(caller).readAttribute("name");
		groupSize = $$("input[name='"+groupname+"']:checked").size();
		if(groupSize > nbCheck){	
			this.showTriangle = false
			this.isError = true;
			this.promptText += this.settings.allrules.maxCheckbox.alertText+"<br />";
		}
	}, // end function _maxCheckbox

	_minCheckbox: function (caller,rules,position) // VALIDATE CHECKBOX NUMBER
	{
		nbCheck = eval(rules[position+1]);
		groupname = $(caller).readAttribute("name");
		groupSize = $$("input[name="+groupname+"]:checked").size();

		if( groupSize < nbCheck )
		{	
			this.showTriangle = false
			this.isError = true;
			this.promptText += this.settings.allrules.minCheckbox.alertText+" "+nbCheck+" "+this.settings.allrules.minCheckbox.alertText2+"<br />";
		}
	}, // end function _minCheckbox
		
	closePrompt: function(caller, outside)	// CLOSE PROMPT WHEN ERROR CORRECTED
	{
		if(outside)
		{
			$$(caller).each(function(elem) {
				$(elem).fade({ afterFinish: function(effect){ $(elem).remove(); } });
			});
			return false;
		}
		
		if(!this.ajaxValidate)
		{
			closingPrompt = this.prompt;
			if( $(closingPrompt) )
			{
				$(closingPrompt).fade({ afterFinish: function(effect) { $(closingPrompt).remove(); } });
			}
		}
	}, // end function closePrompt
	
	submitValidation: function(caller, settings)	// FORM SUBMIT VALIDATION LOOPING INLINE VALIDATION
	{
		var stopForm = false;
		this.settings = settings
		this.ajaxValid = true
		callerId = "#"+$(caller).identify();
		
		var toValidateSize = $$(callerId+" [class^=validate]").size();

		var elems = $$(callerId+" [class^=validate]");
		var size = 0;
		try { size = elems.size(); }
		catch(e) { size = 0; }		
		for( var i=0; i< size; i++)
		{
			// DO NOT UPDATE ALREADY AJAXED FIELDS (only happen if no normal errors, don't worry)
			if(!$(elems[i]).hasClassName("ajaxed"))
			{
				var validationPass = this.loadValidation($(elems[i]), this.settings);
				if (validationPass)  stopForm = true;
			}
		}
		
		ajaxErrorLength = this.ajaxValidArray.length;		// LOOK IF SOME AJAX IS NOT VALIDATE
		for(x=0;x<ajaxErrorLength;x++)
		{
	 		if(this.ajaxValidArray[x][1] == false){
	 			this.ajaxValid = false
	 		}
	 	}
		
		// GET IF THERE IS AN ERROR OR NOT FROM THIS VALIDATION FUNCTIONS
		if(stopForm || !this.ajaxValid)
		{
			var formId = this.settings.idForm;
			$$("body").each(function(elem) {
				new Effect.ScrollTo($$("."+formId+"formError:not(.greenPopup):first").first());
			});
			
			return true;
		}
		else
		{
			return false;
		}
	}
});
