HECK_DATE = "^[0-9]{2}(/|[ ])[0-9]{2}(/|[ ])[0-9]{4}$"; //ja slordig
var CHECK_EMAIL = "^[0-9a-zA-Z._-]*[@][0-9a-zA-Z._-]*[.][a-z]{2,4}$"; //voldoet
var CHECK_AMOUNT = "^[-]?[0-9]+$";
var CHECK_NUMBER = "^[-]?[0-9,.]+$";
var CHECK_TELEPHONE = "^[0-9 ./\\\\,;-]+$"; //0,1,2,3,4,5,6,7,8,9, [.], [/], [\], [-] [,], [;], [' spatie']
var CHECK_ALFANUM = "^[0-9a-zA-Z ,.-_\\s\?]+$";
var CHECK_ANYTHING = ".*";
var CHECK_WORDS = "^[A-Za-z]+[A-Za-z \\s]*$";
var CHECK_ZIP = "^[0-9a-zA-Z ,.-_\\s\?]+$"; //"^[1-9][0-9]{3}[ ]?[a-zA-Z]{2}$";
var CHECK_PLATE = "^([0-9a-zA-Z]{2}[-]){2}[0-9a-zA-Z]{2}$";
var CHECK_PRICE = "^[0-9.,]*(([.,][-])|([.,][0-9]{2}))?$";

//additions Anders, 11 dec 2002
var CHECK_LETTERS = "^[a-zA-ZÀÂÄÇÉËÍÏÒÔÖÙÛÝàãæéìïóùÿ ']+$";
var CHECK_PURENUMBERS = "^[0-9]+$";
var CHECK_PHONE = "^[+]?[0-9 ./\\,;-]+$";
var CHECK_PC1 = "^[0-9]{4}$";
var CHECK_PC2 = "^[a-zA-Z]{2}$";

var legalDependency = [];
var currentWarning = "";
var dependencyWarnings = [
	' ',
	'  ',
	' mag niet in de toekomst liggen',
	' mag niet in het verleden liggen'
]
var formRules = {
	'if':'if(', 'else':');} else {', 'or':') || ', 'and':') && ', 'setvalue':'setValue(', 
	'not':'!', 'then':')) {', 'enable':'setEnabled(', 'submitting':'isSubmitting(this.parent',
	'getvalue':'getValueOf(0,', 'getintvalue':'getValueOf(1,', 'disable':'setDisabled(', 
	'isempty':'isEmpty(', 'sum':'sumOf(', 'int':'getInt(', 'match':'tryRegMatch(', 
	'focus':'focusOn(',	'warnuser':'warnUser(this.parent', '(':'(',')':')','>':') > ','<':') < '
}

// FormValidator Object
// ----------------------------------------------
function formValidator(name, layer) {
	var target = document;


	this.form = target.forms[name];
	this.form.validator = this;
	this.form.onsubmit = validateForm;
	this.canSubmit = true;
	this.submitting = false;
	this.elementChecks = [];
	this.setOnchanges();
}
	fvProto = formValidator.prototype;
	fvProto.submit = function() {
		if(this.form.onsubmit()) this.form.submit();
	}
	
	fvProto.setRule = function(rule, warning) 
		{ new formRule(this, rule, warning); }
	fvProto.setCheck = function(elm, reg, req, warning) 
		{ new formCheck(this, elm, reg, req, warning); }
	fvProto.setDependency = function(names, type, req, warning)
		{ new formDependency(this, names, type, req, warning); }

	fvProto.insertCheck = function(name, check) {
		var checks = this.elementChecks;
		if(!checks[name]) checks[name] = [];
		checks[name][checks[name].length] = check;
	}

	fvProto.setOnchanges = function() {
		for(var i=0; i<this.form.elements.length; i++) {
			var el = this.form.elements[i];
			if(el.type == 'radio' || el.type == 'checkbox') {
				el.onclick = handleOnchange;
			} else el.onchange = handleOnchange;
		}
	}

	// Check Object
	// ------------------------------------------
	function formCheck(parent, elm, reg, req, warning) {
		this.parent = parent;
		this.name = elm;
		this.reg = reg;
		this.req = (req == "required")? true:false;
		this.warning = warning;
		this.parent.insertCheck(elm, this);
	}
		fcProto = formCheck.prototype;
		fcProto.execute = function() {
			var el = this.parent.form.elements[this.name];
			if(!el) return;
			var val = el.value;

			if((this.req && val == "" && !el.disabled) || (val != ''
			  && ! new RegExp(this.reg).exec(val))) {
				this.parent.canSubmit = false;
				alert(this.warning + dependencyWarnings[(val=='')?1:0]);
				focusElement(el);
			}
		}

	// Rule Object
	// ------------------------------------------
	function formRule(parent, rule, warning) {
		this.parent = parent;
		this.affected = [];
		this.warning = warning;
		this.rule = this.processRule(rule);
		this.applyAffected();
		this.execute();
	}
		frProto = formRule.prototype;
		frProto.processRule = function(rule) {
			formRules['and'] = ') && '
			var parts = rule.split(' ');
			var affected = "";
			var newRule = "";

			for(var i=0; i<parts.length; i++) {
				var part = parts[i];
				if(part == 'then') formRules['and'] = '); '
				if(formRules[part]) newRule += formRules[part];
				else newRule += 'this.parent.form, "'+part.replace(/:/g,'","')+'"';

				var list = (part.indexOf(':') > -1)? part.split(':'):[part]
				for(var j=0; j<list.length; j++) {
					if(this.parent.form.elements[list[j]] 
						&& affected.indexOf(list[j]) < 0) {
						affected += ' '+list[j];
						this.affected[this.affected.length] = list[j]
					}
				}
			}	newRule += ");}";
			return newRule;
		}

		frProto.applyAffected = function() {
			for(var i=0; i<this.affected.length; i++) {
				var name = this.affected[i];
				this.parent.insertCheck(name, this);
			}
		}

		frProto.execute = function() {
			currentWarning = this.warning;
			eval(this.rule);
		}

		// Dependency Object
		// --------------------------------------
		function formDependency(parent, names, type, req, warning) {
			this.parent = parent;
			this.names = names;
			this.type = type.split('.')[0];	
			this.param = type.split('.')[1];
			this.warning = warning;
			this.req = (req == "required")? true:false;

			for(var i=0; i<names.length; i++) {
				this.parent.insertCheck(names[i], this);
			}
		}
			fdProto = formDependency.prototype;
			fdProto.execute = function(post) {
				var result = legalDependency[this.type](this.parent.form, this.names, this.param);
				if(result == 4 || (!post && result == 1) || 
					(post && ((!this.req && result == 1) || (this.req && result == 5)))) return;

				this.parent.canSubmit = false;
				alert(this.warning + dependencyWarnings[result]);

			}

// Global stuff
// ----------------------------------------------
function validateForm() {
	var validator = this.validator;
	validator.canSubmit = true;
	validator.submitting = true;

	for(var i in validator.elementChecks) {
		var checks = validator.elementChecks[i];
		for(var j=0; j<checks.length; j++) {
			checks[j].execute(true);
			if(!validator.canSubmit) {
				validator.submitting = false;
				return false;
			}
		}
	}	return true;
}

function handleOnchange() {
	var validator = this.form.validator;
	var checks = validator.elementChecks[this.name];
	
	if(!checks) return
	for(var i=0; i<checks.length; i++) {
		checks[i].execute();
	}
}

function focusElement(elm) {
	if(!elm.disabled && elm.type != 'hidden') elm.focus();
}

// Rule functions
// ----------------------------------------------
function isEmpty(form, elm) { return (form.elements[elm].value == '')? true:false; }
function getInt(notUsed, value) { return parseInt(value); }
function focusOn(form, elm) { focusElement(form.elements[elm]); }
function setEnabled(form, elm) { elmEnabled(form, arguments, true); }
function setDisabled(form, elm) { elmEnabled(form, arguments, false);}
function elmEnabled(form, collection, way) {
	for(var i=1; i<collection.length; i++) {
		var el = form.elements[collection[i]];
		if(!el[1] || el.options) el = [el];
		for(var j=0; j<el.length; j++)
			el[j].disabled = !way;
	}
}

function warnUser(validator) {
	validator.canSubmit = false;
	if(currentWarning) alert(currentWarning);
}

function getValueOf(isInt, form, elm, value) {
	var el = form.elements[elm];
	var val = (el[0])? findValue(el, value):el.value;
	return isInt? parseInt(val):(val == parseValue(form, value));
}
	function findValue(elm, pref) {
		for(var i=0; i<elm.length; i++) {
			if((elm[i].checked && elm[i].value == pref)
				|| elm.selectedIndex == i)
				return elm[i].value;
		}
	}

function setValue(form, elm, value) {
	var el = form.elements[elm];
	form.elements[elm].value = parseValue(form, value);
}
	function parseValue(form, value) {
		if(value.indexOf('[') < 0) return value;
		var res = value.substring(1,value.length-1);
		return eval(res.replace( /([a-z]+)/gi, 'getValueOf(1,form,"$1")'));
	}

function isSubmitting(validator) {
	return validator.submitting;
}

function tryRegMatch(form, elm, reg) {
	var val = form.elements[elm].value;
	if(val == '') return false;
	return (new RegExp(window['CHECK_'+reg]).exec(form.elements[elm].value))? true:false; 
}

// Dependency functions
// ----------------------------------------------
legalDependency['date'] = function(frm, names, param) {
	var list = getListValues(frm, names);
	if(!list[1]) return list;
	var mn = new Date(list[0], list[1]-1, list[2]);
	if(mn.getMonth() - (list[1]-1) != 0) return 0;
	
	if(param) {
		var current = (new Date()).getTime();
			current -= current%86400000 + 7200000
		var entered = mn.getTime();
		if (entered > current && param == 'past') return 2;
		else if(entered < current && param == 'future')	return 3;
	}	return 4;
}

legalDependency['plate'] = function(frm, names) {
	var list = getListValues(frm, names);
	if(!list) return 1;
	
	for(var i=0; i<list.length; i++) {
		if((!regExec(CHECK_AMOUNT, list[i])
			&& !regExec(CHECK_WORDS, list[i]))
			|| list[i].length != 2) return 0;
	}	return 4;
}

function getListValues(frm, names) {
	var el, list = [];
	for(var i=0; i<names.length; i++) {
		list[i] = (el = frm.elements[names[i]]).value;
		if(el.disabled) return 5;
		if(list[i] == '') return 1;
	}	return list;
}
