Utilities.FormValidators = {};

Utilities.AddEvent(window, 'load', function(){
	
	for(var x in Utilities.FormValidators){
		var v = Utilities.FormValidators[x];
		if(!v.Form){
			v.Bind();
			}
		}
	});

Utilities.FormValidator = function(formid){
	
	this.Id = formid;
	this.Elements = {};
	this.Form = null;
	this.BeforeSubmit = null;
		
	Utilities.FormValidators[formid] = this;
	this.Bind();
	}

Utilities.FormValidator.prototype.AddElement = FormValidator_AddElement;
Utilities.FormValidator.prototype.Bind = FormValidator_Bind;
Utilities.FormValidator.prototype.Error = FormValidator_Error;
Utilities.FormValidator.prototype.Trim = FormValidator_Trim;
Utilities.FormValidator.prototype.Validate = FormValidator_Validate;
Utilities.FormValidator.prototype.Value = FormValidator_Value;

function FormValidator_AddElement(element, validation){
	
	this.Elements[element] = validation;
	}

function FormValidator_Bind(){
	
	this.Form = document.getElementById(this.Id);
	if(this.Form){
		Utilities.AddEvent(this.Form, 'submit', function(evt){
			
			var evt = new Utilities.Event(evt);
			var id = evt.target.id;
			Utilities.FormValidators[id].Validate(evt.Event);
			});
		}
	}

function FormValidator_Error(field, msg, evt){
	
	alert(msg);
	this.Form[field].focus();
	this.Form[field].select();
	evt.preventDefault();
	return false;
	}

function FormValidator_Trim(str){
	
	return str.replace(/(^\s+)|(\s+$)/g, '');
	}

function FormValidator_Validate(evt){
	
	var evt = new Utilities.Event(evt);
	
	for(var x in this.Elements){
		var el = this.Form[x];
		var v = this.Elements[x];
		if(el){
			val = this.Value(v, el);
			if(v.Required && val == ''){
				return this.Error(x, v.Friendly + ' is required.', evt);
				}
			if(val != '' && v.MinLength && v.MinLength > val.length){
				return this.Error(x, v.Friendly + ' must be at least ' + v.MinLength + ' characters.', evt);
				}
			if(val != '' && v.MaxLength && v.MaxLength < val.length){
				return this.Error(x, v.Friendly + ' must be no more than ' + v.MaxLength + ' characters.', evt);
				}
			if(val != '' && v.Numeric && !val.match(/^[0-9.,]*$/)){
				return this.Error(x, v.Friendly + ' must be numeric.', evt);
				}
			if(val != '' && v.Numeric && v.MinValue && val < v.MinValue){
				return this.Error(x, v.Friendly + ' must be greater than or equal to ' + v.MinValue, evt);
				}
			if(val != '' && v.Numeric && v.MaxValue && val > v.MaxValue){
				return this.Error(x, v.Friendly + ' must be less than or equal to ' + v.MaxValue, evt);
				}
			if(val != '' && v.RegExp && !new RegExp(v.RegExp).test(val)){
				return this.Error(x, v.Friendly + ' is invalid', evt);
				}
			if(val != '' && v.Email && !val.match(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i)){
				return this.Error(x, v.Friendly + ' is not a valid Email address', evt);
				}
			if(val != '' && v.PostCode && !val.match(/^[A-Z]{1,2}[0-9R][0-9A-Z]? ?[0-9][ABD-HJLNP-UW-Z]{2}$/i)){
				return this.Error(x, v.Friendly + ' is not a valid Post Code', evt);
				}
			if(val != '' && v.PhoneNumber && !val.replace(/( |-|(|))/gi, '').match(/^((\+44 ?)|0)[0-9]{9,10}$/i)){
				return this.Error(x, v.Friendly + ' is not a valid phone number', evt);
				}
			if(val != '' && v.Upload && !new RegExp('\.(' + v.Upload + ')$', 'i').test(val)){
				return this.Error(x, v.Friendly + ' is not a valid file.\nValid files: *.' + v.Upload.replace(/\|/g, ', *.'), evt);
				}
			if(val != '' && v.Match && this.Form[v.Match] && val != this.Value(this.Elements[v.Match], this.Form[v.Match])){
				return this.Error(x, v.Friendly + ' doesn\'t match ' + this.Elements[v.Match].Friendly, evt);
				}
			}
		}
		
	if(this.BeforeSubmit){
		if(!this.BeforeSubmit(evt.Event)){
			evt.preventDefault();
			}
		}
	}

function FormValidator_Value(item, el){
	
	var val;
	if(item.Split){
		val = this.Trim(el.value) + item.SplitSeparator + this.Trim(this.Form[item.Split].value);
		}
	else{
		if(el.getAttribute('type') == 'checkbox'){
			val = (el.checked) ? 'on' : '';
			}
		else{
			val = el.value
			}
		}
	return this.Trim(val);
	}
