
arpt.FormValidator = function() {
}

arpt.FormValidator.prototype = {

	form: null,
	required: false,
	
	attach: function(id, async, json) {
	
		this.form = $id(id);
		
		if (!this.form) {
			throw "Form not found with id " + id;
		}
		
		id = this.form.getAttribute("id");

		var flds = arpt.form.getFields(this.form);
		for (var i=0; i!=flds.length; i++) {
			this.attachField(flds[i]);
		}
		
		YAHOO.Event.addListener(this.form, "submit", this.onSubmit, this); 
	},
			
	attachField: function(fld) {
		// Setup a paragraph element for the error message.
		//
		var p = $new('p');
		
		// Set it's id and class name.
		//
		p.id = fld.name + '-msg';
		p.className = 'field-msg';

		// Insert the error message before the label.
		//		
		while ((fld = fld.previousSibling)!=null) {
			if (fld.tagName=='LABEL') {
				fld.parentNode.insertBefore( p, fld );
				break;
			}
		}
	},
		
	// Reset all states.
	//
	resetStates: function() {
	
		var inputs = arpt.form.getFields(this.form);
		
		for(var i = 0; i < inputs.length; i++) {
			// Get the input field.
			var fld = inputs[i];
			YAHOO.Dom.removeClass(fld, 'fldInvalid');
			
			var n = $id(fld.name+'-msg');
    		if (n) {
                n.style.display = "none";
            }
		}
	},
			
	checkConstraint: function(value,args) {
		// Call the method actual validation function.
		//
		var fn = args.shift();
		
		return eval( fn+'(value,args)');
	},
	
	onSubmit: function(ev) {
		if (!this.validateForm()) {
			YAHOO.Event.stopEvent(ev);
		}
	},
	
	validateForm: function() {
	
		// Reset all states.
		//
		this.resetStates();
		var flds = arpt.form.getFields(this.form);
		var profile = { required:[], constraints:new Object() };

		// Build up the dojo validation profile.
		//
		for (var i_fld in flds) {
			var fld = flds[i_fld];

			var rule = fld.getAttribute('required');
			if (rule) {
				if (rule=="true" || rule=="1")
					profile.required.push(fld.name);
			} else if (this.required) {
				profile.required.push(fld.name);
			}
						
			// validation="EmailAddress,false,true"
			// validation="ValidDate,YYYY.MM.DD"
			// validation="arpt.validation.name,args"
			//
			var rule = fld.getAttribute('validation');
			if (rule) {
				var args = rule.split(',');
				if (args[0].indexOf('.')==-1)
					args[0] = 'dojo.validate.' + args[0];
				
				// Setup the constraint rule in the profile.
				//	
				profile.constraints[fld.name] = [ this.checkConstraint, args ];
			}
		}
		
		var results=dojox.validate.check(this.form, profile);
				
		if (!this.processResults(this.form, results)) {
			this.summarizeErrors(this.form, results);
			return false;
		}
		
		return true;
	},

	summarizeErrors: function(form, results) {
	
	},
	
	processResults:function(form, results) {
		if (results.isSuccessful()) { 
			return true; 
		} 
		
		var valid=true;
		if (results.hasMissing()) {
			var missing=results.getMissing();
			for (var i=0; i < missing.length; i++) {
				this.handleInvalidField(missing[i]);
				this.showInvalidMessage(missing[i]);
			}
			
			valid=false;
		}
		
		if (results.hasInvalid()) {
			var invalid=results.getInvalid();
			for (var i=0; i < invalid.length; i++) {
				this.handleInvalidField(invalid[i]);
				this.showInvalidMessage(invalid[i]);
			}
			valid=false;
		}
		
		if (valid==false) {
			this.showFormMessage();
		}
		
		return valid; // if got past successful everything is invalid
	},
	
	/**
	 * Default field decorator for missing/invalid fields.
	 * 
	 * @param field The field element that had invalid data.
	 * @param profile The form validation profile.
	 */
	handleInvalidField: function(fldName) {
		field = this.form[fldName];
		YAHOO.Dom.addClass(field, 'fldInvalid');
    },
    
   	showInvalidMessage: function(field) {
		field = this.form[field];
		
		var msg = field.getAttribute('invalidMessage');
		if (msg) {
    		var n = $id(field.name+'-msg');
    		if (n) {
    			arpt.setTextContent(n,msg);
                n.style.display = "block";
            }
	    }
	},
	
   	showFormMessage: function() {
		var msg = this.form.getAttribute('invalidMessage');
		if (msg) {
	    	var n = $id(this.form.id+'-msgs');
	    	if (n) {
    			arpt.setTextContent(n,msg);
	            n.style.display = "block";
	        }
		}
	}
};	


var form_validation_methods = {
	'email': 	 form_validate_email,
	'compare': 	 form_validate_compare,
	'integer' :  /^[\+\-]?\d*$/,
	'string':  	 form_validate_true,
	'numeric':	 /^[0-9]+$/,
	'telephone': /^[\+]?[0-9]{7,15}$/
};


function form_validate_true(rule,form,value) {
	return null;
}
	
function form_validate_compare(rule,form,value) {
	
	var fld = form[rule['with']];
					
	if (value != fld.value)
		return "The field must match the previous field.";
}


function form_validate_email(rule,form,value) {

    var emailFilter=/^.+@.+\..{2,3}$/;
   	if (!(emailFilter.test(value))) { 
   		return "The email address is not a valid email";
 	}
   	else {
		//test email for illegal characters
   		var illegalChars= /[\(\)\<\>\,\;\:\\\"\[\]]/
      	if (value.match(illegalChars)) {
       		return "The email address contains illegal characters.";
   		}
  	}
  	
	return null;
}
