/*
	Generic Form Validation by Jacob Hage, hagedesign.dk
*/

// Object of regex patterns
var pattern = {
	"email":		/^([\w\-\.]+)@((\[([0-9]{1,3}\.){3}[0-9]{1,3}\])|(([\w\-]+\.)+)([a-zA-Z]{2,4}))$/, // any email address
	"letters":		/^([a-zA-Z]+)$/, // only letters
	"lettersnumbers":/^([a-zA-Z0-9]+)$/, // will validate letters and/or numbers
	"numbers":		/^\d+$/, // only numbers
	"float":		/^\d+(,|\.)?(\d+)?$/, // only numbers
	"dkphone":		/^(\d{8})(.*)/, 
	"dkzip":		/^(\d{4})$/, 
	"code":			/^[a-zA-Z]{3}\d{2}$/i,
	"maxamount":	/^.{0,100}$/i,
	"amountnolessthan4":	/^(\d{4})$/, 
	"password":		/^.{5,999}$/i,
	"varchar":		/.+/ // At least one character
}

// Object of error messages (feel free to edit these) 
var errors = {
	"dkphone":		"skal begynde med et telefonnummer uden mellemrum (8 cifre)",
	"dkzip":		"skal indeholde et dansk postnummer (4 cifre)",
	"email":		"skal indeholde en gyldig e-mail adresse",
	"letters":		"skal udfyldes og m\345 kun indeholde bogstaver",
	"lettersnumbers":"skal udfyldes og m\345 kun indeholde bogstaver og tal",
	"numbers":		"skal udfyldes og m\345 kun indeholde tal",
	"float":		"skal udfyldes og m\345 kun indeholde tal eller kommatal",
	"code":			"skal indeholde en gyldig kode",
	"varchar":		"skal udfyldes",
	"maxamount":	"må ikke indeholde over 100 antal karakterer",
	"amountnolessthan4":	"skal indeholde 4 karakterer",
	"list":			"skal udfyldes",
	"box": 			"skal markeres",
	"password":		"skal markeres og indeholde over 4 karaktere",
	"similar":		"skal v\346re identisk med feltet ovenfor"
}

// Object to handle text input fields
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 minimum "+this.min+" and maximum "+this.max+" characters" : (this.min)?" and contain minimum "+this.min+" characters" : (this.max)? " and contain maximum "+this.max+" characters":"";
	return this;
}

// Object to detect two similar fields
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;
}

// Object to handle select boxes
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;
}

// Object to handle radio and check boxes
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){
	// Define error string
	var errors = new Array;
	var objects = new Array();
	var counter = 0;

	// Assigning the reference to the form to all instances of Field, List and Box
	Field.prototype.form=objForm;
	SimilarField.prototype.form=objForm;
	List.prototype.form=objForm;
	Box.prototype.form=objForm;

	// create an object of fields to validate
	arrFieldsToValidate = defineFields();
	// Check fields
	for(var i in arrFieldsToValidate){
		if(!arrFieldsToValidate[i].validated()){
			errors[counter] = "Feltet '"+i+"' "+arrFieldsToValidate[i].error;
			objects[counter] = arrFieldsToValidate[i].field;
			counter++;
		}
	}
	
	// Display possible errors or submit
	if(errors.length>0){
		notification('','','');
		document.getElementById('notificationarea').innerHTML=errors.join("<br>");
		// alert(errors.join("\n"));
		if(objects[0].type=="text") objects[0].focus();
		return false;
	} else {
		return true;
	}
}
