function FieldCheck(form, fieldname, regexp) {
	this.form = form;
	this.fieldname = fieldname;
	this.regexp = regexp;
	this.checkFail = new Event();
	this.checkSuccess = new Event();
	this.oldOnchange;
	this.isOk = false;
	this.enabled = true;
	
	this.element = form.elements[fieldname];
	
	this.check = __fieldCheckCheck;
	this.fieldChange = __fieldCheckFieldChange;
	this.fieldClick = __fieldCheckFieldClick;
	this.fieldBlur = __fieldCheckFieldBlur;
	this.fieldKeyUp = __fieldCheckFieldKeyUp;
	this.fieldMouseUp = __fieldCheckFieldMouseUp;
	
	if (this.element.onchange) this.oldChange = this.element.onchange.bind(this.element);
	if (this.element.onclick) this.oldClick = this.element.onclick.bind(this.element);
	if (this.element.onblur) this.oldBlur = this.element.onblur.bind(this.element);
	if (this.element.onmouseup) this.oldMouseUp = this.element.onmouseup.bind(this.element);
	if (this.element.onkeyup) this.oldKeyUp = this.element.onkeyup.bind(this.element);
	
	this.element.onchange = this.fieldChange.bind(this);
	this.element.onclick = this.fieldClick.bind(this);
	this.element.onblur = this.fieldBlur.bind(this);
	this.element.onmouseup = this.fieldMouseUp.bind(this);
	this.element.onkeyup = this.fieldKeyUp.bind(this);
}

function __fieldCheckCheck() {
	if (!this.enabled) {
		this.isOk = true;
		this.checkSuccess.trigger(this);
		return;
	}

	try {
		var value = this.element.value;
		if ((this.element.type == 'checkbox') || (this.element.type == 'radio')) {
			if (!this.element.checked) {
				value = '';
			}
		}
		var matches = value.match(this.regexp);
		if (matches != null) {
			if (matches[0] == this.element.value) {
				this.isOk = true;
				this.checkSuccess.trigger(this);
				return;
			}
		}
		this.isOk = false;
		this.checkFail.trigger(this);
	} catch (e) {
		this.isOk = false;
		this.checkFail.trigger(this);
	}
}

function __fieldCheckFieldChange(e) {
	if (this.oldChange == null) {
		this.check();
		return true;
	} else {
		if (this.oldChange()) {
			this.check();
			return true;
		} else return false;
	}
}

function __fieldCheckFieldClick(e) {
	if (this.oldClick == null) {
		this.check();
		return true;
	} else {
		if (this.oldClick()) {
			this.check();
			return true;
		} else return false;
	}
}

function __fieldCheckFieldBlur(e) {
	if (this.oldBlur == null) {
		this.check();
		return true;
	} else {
		if (this.oldBlur()) {
			this.check();
			return true;
		} else return false;
	}
}

function __fieldCheckFieldMouseUp(e) {
	if (this.oldMouseUp == null) {
		this.check();
		return true;
	} else {
		if (this.oldMouseUp(e)) {
			this.check();
			return true;
		} else return false;
	}
}

function __fieldCheckFieldKeyUp(e) {
	if (this.oldKeyUp == null) {
		this.check();
		return true;
	} else {
		if (this.oldKeyUp(e)) {
			this.check();
			return true;
		} else return false;
	}
}

function ExpCheck(exp) {
	this.exp = exp;
	this.check = __expCheckCheck;
}

function __expCheckCheck() {
	//alert(this.exp + ": " + eval(this.exp));
	return eval(this.exp);
}

function FormCheckRule(form, imageid) {
	this.form = form;
	this.fieldChecks = new Array();
	this.expChecks = new Array();
	this.checkFail = new Event();
	this.checkSuccess = new Event();
	this.isOk = false;
	this.addCheck = __formCheckRuleAddCheck;
	this.addExtCheck = __formCheckRuleAddExtCheck;
	this.onError = __formCheckRuleOnError;
	this.onOk = __formCheckRuleOnOk;
	this.imageId = imageid;
	this.errorMessage = '';
	this.getEnabled = function() { return true };
	
	this.doCheck = __formCheckRuleDoCheck;
}

function __formCheckRuleDoCheck() {
	for (var index = 0; index < this.fieldChecks.length; index++) {
		this.fieldChecks[index].fieldChanged();
	}
}

function __formCheckRuleAddCheck(fieldname, regexp) {
	var fieldCheck = new FieldCheck(this.form, fieldname, regexp);
	
	fieldCheck.checkFail.subscribe(this.onError.bind(this));
	fieldCheck.checkSuccess.subscribe(this.onOk.bind(this));
	
	this.fieldChecks.push(fieldCheck);
	fieldCheck.check();
	
	return fieldCheck;
}

function __formCheckRuleAddExtCheck(fieldname, jexp) {
	try {
	var jCheck = new ExpCheck(jexp);
	
	this.expChecks.push(jCheck);
	jCheck.check();
	} catch(e) { alert(e); }
	return jCheck;
}

function __formCheckRuleOnError(check) {
	this.isOk = false;
	this.checkFail.trigger(this, check);
}

function __formCheckRuleOnOk(check) {
	var result = true;
	for (var index = 0; index < this.fieldChecks.length; index++) {
		result &= this.fieldChecks[index].isOk;
	}
	
	if (result) {
		for (var index = 0; index < this.expChecks.length; index++) {
			result &= this.expChecks[index].check();
		}
		if (!result) {
			this.checkFail.trigger(this, check);
		} else {
			this.isOk = true;
			this.checkSuccess.trigger(this, check);
		}
	}
}

function FormChecker(form) {
	this.oldSubmit = form.onsubmit;
	this.form = form;
	this.failImage = '/wp-content/themes/schiphol-parkeren/images/fail.gif';
	this.successImage = '/wp-content/themes/schiphol-parkeren/images/ok.gif';
	this.isOk = false;
	this.rules = new Array();
	this.onError = __formCheckerOnError;
	this.onOk = __formCheckerOnOk;
	this.errorRule = null;
	this.external = null;
	
	this.checkForm = function() {
		for (var index = 0; index < this.rules.length; index++) {
			this.errorRule = this.rules[index];
			if ((!this.errorRule.isOk) && (this.errorRule.getEnabled())) {				
				//get div for this stuff
				target = this.errorRule.fieldChecks[0].element;
				
				showPopup(target, this.errorRule.errorMessage);
				handleAsPopup($('form_help'), true, hidePopup);
				//this.form[this.errorRule.fieldChecks[0].fieldname].focus();
				
				//Element.scrollTo(target);
				scrollIntoView(target);
				scrollIntoView($('form_help'));
				
				return false;
			}
		}
		
		if (this.external != null) {
			return this.external();
		} else {
			return true;
		}
	}
	
	this.form.onsubmit = this.checkForm.bind(this);
	
	this.addRule = function(imageid) {
		var rule = new FormCheckRule(this.form, imageid);
		rule.checkFail.subscribe(this.onError.bind(this));
		rule.checkSuccess.subscribe(this.onOk.bind(this));
		this.rules.push(rule);
		
		return rule;
	}
}

function __formCheckerOnError(rule, check) {
	//alert('fail');
	document.getElementById(rule.imageId).src = this.failImage;
}

function __formCheckerOnOk(rule, check) {
	if (this.errorRule != null) {
		if (this.errorRule.imageId == rule.imageId) {
			hidePopup();
		}
	}
	//alert('ok');
	document.getElementById(rule.imageId).src = this.successImage;
}

