var pattern = {
	"numbers":		/^\d+$/,
	"all":			/.+/,
	"email":		/^([\w\-\.]+)@((\[([0-9]{1,3}\.){3}[0-9]{1,3}\])|(([\w\-]+\.)+)([a-zA-Z]{2,4}))$/,
	"phone":		/^\d{3}(-\d{3}-\d{4}| \d{3} \d{4}|\d{7})$/,
	"zip":			/^\d{5}(-\d{4})?$/	
}
var errors = {
	"numbers":		"must contain only numbers",
	"all":			"must be specified",
	"email":		"must contain a valid e-mail address",
	"phone":		"must be a valid phone number (123-123-1234, 123 123 1234 or 1231231234)",
	"zip":			"must contain a US zip code",
	"list":			"must be selected",
	"box": 			"must be checked",
	"similar":		"must be identical to"
}

function Field(f_name, f_type, f_lengthObj){
	if(this.form[f_name]){
		this.field = this.form[f_name];
		this.name = f_name;
	} else {
		alert("Field '"+f_name+"' does not exist in '"+this.form.name+"'");
		return false;
	}
	this.type = f_type;
	this.pattern = pattern[f_type] || pattern["varchar"];
	this.value = this.field.value;
	this.len = this.value.length;
	if(f_lengthObj){
		if(f_lengthObj.min>f_lengthObj.max){
			alert("The minimum setting can't be larger than maximum!");
			return false;
		} else {
			this.min = f_lengthObj.min || false;
			this.max = f_lengthObj.max || false;
		}
	}
	this.lengthValue = (this.min && !this.max && (this.len < this.min))? false : (this.max && !this.min && (this.len > this.max))? false : (this.max && this.min && ((this.len < this.min) || (this.len > this.max)))? false : true;
	this.validated = new Function("return(this.pattern.test(this.value)&&this.lengthValue);");
	this.error = errors[f_type] || errors["varchar"];
	this.error += (this.min && this.max)? " and contain a minimum of "+this.min+" and a maximum of "+this.max+" characters" : (this.min)?" and contain a minimum of "+this.min+" characters" : (this.max)? " and contain a maximum of "+this.max+" characters":"";
	return this;
}

function SimilarField(f_name,f_similar,f_similarname){
	if(this.form[f_name] && this.form[f_similar]){
		this.field = this.form[f_name];
		this.similar = this.form[f_similar];
		this.name = f_name;
	} else {
		alert("Field '"+f_name+"' or field '"+f_similar+"' does not exist in '"+this.form.name+"'");
		return false;
	}
	this.type = "similar";
	this.value = this.field.value;
	this.similarvalue = this.similar.value;
	this.error = errors.similar+" "+f_similarname;
	this.validated = new Function("return(this.value==this.similarvalue)");
	return this;
}

function List(f_name){
	if(this.form[f_name]){
		this.field = this.form[f_name];
		this.name = f_name;
	} else {
		alert("Field '"+f_name+"' does not exist in '"+this.form.name+"'");
		return false;
	}
	this.validated = new Function("return this.field.selectedIndex>0");
	this.error = errors.list;
	return this;
}

function Box(f_name){
	if(this.form[f_name]){
		this.field = this.form[f_name];
		this.name = f_name;
	} else {
		alert("Field '"+f_name+"' does not exist in '"+this.form.name+"'");
		return false;
	}
	this.returnValue = false;
	if(this.field.length){
		for(var i=0; i<this.field.length; i++){
			if(this.field[i].checked){
				this.returnValue = true;
				break;
			}
		}
	} else {
		this.returnValue = this.field.checked;
	}
	
	this.validated = new Function("return this.returnValue");
	this.error = errors.box;
	return this;
}

function validate(objForm){	
	var errors = new Array;
	var objects = new Array();
	var counter = 0;
	
	Field.prototype.form=objForm;
	SimilarField.prototype.form=objForm;
	List.prototype.form=objForm;
	Box.prototype.form=objForm;
	
	arrFieldsToValidate = defineFields();	
	for(var i in arrFieldsToValidate){
		if(!arrFieldsToValidate[i].validated()){
			errors[counter] = "'"+i+"' "+arrFieldsToValidate[i].error;
			objects[counter] = arrFieldsToValidate[i].field;
			counter++;
		}
	}
	
	if(errors.length>0){
		alert(errors.join("\n"));
		if(objects[0].type=="text") objects[0].focus();
		return false;
	} else {
		return true;
	}
}