FormCheck = new Class.create ();
FormCheck.prototype = {
	firstrun: true,
	error: false,
	elements: [],


	initialize: function (form) {
		this.form = $(form);
		this.form.name = this.form.id;
		this.id = this.form.id;
		this.error = false;
		this.elements = [];

		// ----- ids
		this.makeIds (form);

		// ----- submit button
		this.submit = false;
		var buttons = $(form).getElementsByTagName ("input");
		for (var i = 0; i < buttons.length; i++) {
			if ($(buttons[i]).type == "submit") {
				this.submit = $(buttons[i]);
				break;
			}
		}
	},


	makeIds: function (element) {
		for (var i = 0; i < $(element).elements.length; i++) {
			if ($(element).elements[i].name && !$(element).elements[i].id) {
				$(element).elements[i].id = $(element).elements[i].name;
			}
		}
	},


	addToHighlighter: function (element) {
		var formInputs = $(element).getElementsByTagName ("input");
		var formSelects = $(element).getElementsByTagName ("select");
		for (var i = 0; i < formInputs.length; i++) {
			this.highLighter.add ($(formInputs[i]).id);
		}
		for (var i = 0; i < formSelects.length; i++) {
			this.highLighter.add ($(formSelects[i]).id);
		}
	},


	addToRadioChecker: function (element) {
		var formInputs = $(element).getElementsByTagName ("input");
		for (var i = 0; i < formInputs.length; i++) {
			if (formInputs[i].type == "radio") {
				this.radioChecker.add ($(formInputs[i]).id);
			}
		}
		this.radioChecker.init ();
	},


	setLabelRequired: function (element) {
		var labels = $(this.form).getElementsByTagName ("label");
		for (var i = 0; i < labels.length; i++) {
			if (labels[i].htmlFor == $(element).id) {
				$(labels[i]).addClassName ("required");
				$(labels[i]).innerHTML = "* " + $(labels[i]).innerHTML;
				break;
			}
		}
	},


	getLabel: function (element) {
		var labels = $(this.form).getElementsByTagName ("label");
		for (var i = 0; i < labels.length; i++) {
			if (labels[i].htmlFor == $(element).id) return labels[i];
		}
		return false;
	},

	getLabelText: function (element) {
		return $(element).firstChild.data;
	},


	setError: function (element, constraint, text) {
		this.error = true;
		for (var i = 0; i < this.elements.length; i++) {
			if (this.elements[i].id == element) {
				this.elements[i].error = true;
				break;
			}
		}
		if ($(this.getLabel (element))) $(this.getLabel (element)).addClassName ("error");
		if ($(element + "_error")) $(element + "_error").innerHTML = '<img src="static/images/icons/error.png" class="icon" /> <span>' + text + '</span>';
		if (constraint != "staticdate" && constraint != "datevalue" && constraint != "date" || !$(element + "_day") || !$(element + "_month") || !$(element + "_year")) {
			$(element).addClassName ("error");
			if ($(element).up ().nodeName == "DIV" && $(element).up ().hasClassName ("input")) {
				$(element).up ().addClassName ("error");
			}
		} else {
			$(element + "_day").addClassName ("error");
			$(element + "_month").addClassName ("error");
			$(element + "_year").addClassName ("error");
		}
	},

	setOk: function (element, constraint) {
		for (var i = 0; i < this.elements.length; i++) {
			if (this.elements[i].id == element) {
				this.elements[i].error = false;
				break;
			}
		}
		if ($(this.getLabel (element))) $(this.getLabel (element)).removeClassName ("error");
		if ($(element + "_error")) $(element + "_error").innerHTML = '';
		if (constraint != "staticdate" && constraint != "datevalue" && constraint != "date" || !$(element + "_day") || !$(element + "_month") || !$(element + "_year")) {
			$(element).removeClassName ("error");
			if ($(element).up ().nodeName == "DIV" && $(element).up ().hasClassName ("input")) {
				$(element).up ().removeClassName ("error");
			}
		} else {
			$(element + "_day").removeClassName ("error");
			$(element + "_month").removeClassName ("error");
			$(element + "_year").removeClassName ("error");
		}
	},


	finish: function (element) {
		this.firstrun = false;
		return !this.error;
	},



	add: function (element, constraint, options) {
		var elementIndex = -1;
		for (var i = 0; i < this.elements.length; i++) {
			if (this.elements[i].id == element) {
				elementIndex = i;
				break;
			}
		}
		if (elementIndex == -1) {
			this.elements.push ({
				id: $(element).id,
				constraints: [{
					type: constraint,
					options: options,
					error: false
				}]
			});
			if (constraint != "staticdate" && constraint != "datevalue" && constraint != "date" || !$(element + "_day") || !$(element + "_month") || !$(element + "_year")) {
				Event.observe ($(element), "change", this.check.bindAsEventListener (this, element));
				Event.observe ($(element), "keyup", this.check.bindAsEventListener (this, element));
				if (options != undefined && options.field2 != undefined) {
					Event.observe ($(options.field2), "change", this.check.bindAsEventListener (this, options.field2));
					Event.observe ($(options.field2), "keyup", this.check.bindAsEventListener (this, options.field2));
				}
			} else {
				Event.observe ($(element + "_day"), "change", this.check.bindAsEventListener (this, element));
				Event.observe ($(element + "_month"), "change", this.check.bindAsEventListener (this, element));
				Event.observe ($(element + "_year"), "change", this.check.bindAsEventListener (this, element));
				Event.observe ($(element + "_day"), "keyup", this.check.bindAsEventListener (this, element));
				Event.observe ($(element + "_month"), "keyup", this.check.bindAsEventListener (this, element));
				Event.observe ($(element + "_year"), "keyup", this.check.bindAsEventListener (this, element));
				if (options != undefined && options.field2 != undefined) {
					Event.observe ($(options.field2 + "_day"), "change", this.check.bindAsEventListener (this, options.field2));
					Event.observe ($(options.field2 + "_month"), "change", this.check.bindAsEventListener (this, options.field2));
					Event.observe ($(options.field2 + "_year"), "change", this.check.bindAsEventListener (this, options.field2));
					Event.observe ($(options.field2 + "_day"), "keyup", this.check.bindAsEventListener (this, options.field2));
					Event.observe ($(options.field2 + "_month"), "keyup", this.check.bindAsEventListener (this, options.field2));
					Event.observe ($(options.field2 + "_year"), "keyup", this.check.bindAsEventListener (this, options.field2));
				}
			}
		} else {
			this.elements[i].constraints.push ({
				type: constraint,
				options: options,
				error: false
			});
		}
		if (constraint == "textvalue" || constraint == "selectvalue" || constraint == "datevalue") this.setLabelRequired (element);
	},

	remove: function (element, constraint) {
		var elementIndex = -1;
		for (var i = 0; i < this.elements.length; i++) {
			if (this.elements[i].id == element) {
				elementIndex = i;
				break;
			}
		}
		if (elementIndex != -1) {
			if (constraint == undefined) {
				this.elements.splice (elementIndex, 1);
			} else {
				var constraintIndex = -1;
				for (var i = 0; i < this.elements[elementIndex].constraints.length; i++) {
					if (this.elements[elementIndex].constraints[i].type == constraint) {
						constraintIndex = i;
						break;
					}
				}
				if (constraintIndex != -1) {
					this.elements[elementIndex].constraints.splice (constraintIndex, 1);
				}
			}
		}
		this.check (undefined, element);
	},


	check: function (e, element) {
		if (element == undefined) {
			this.error = false;
			for (var i = 0; i < this.elements.length; i++) {
				this.check (undefined, this.elements[i].id);
			}
			if (this.error) $(this.submit).setOpacity (0.5).disabled = "disabled";
			this.firstrun = false;
		} else {
			var error = undefined;
			for (var i = 0; i < this.elements.length; i++) {
				if (this.elements[i].id == element) {
					for (var j = 0; j < this.elements[i].constraints.length; j++) {
						var constraint = this.elements[i].constraints[j].type;
						if (this.firstrun || constraint != "ajax" || (e != undefined && e.type == "change")) {
			//if (element == "newzipcode2lotnrreason" && e != undefined) alert (e.type + " -> " + constraint);
							eval ("var error = this.check" + constraint + " (element, this.elements[i].constraints[j].options);");
							if (error != undefined) {
								//alert ("error on " + element + " with constraint " + constraint);
								break;
							}
						}
					}
					if (error == undefined) this.setOk (element, constraint);
					else this.setError (element, constraint, error);
					break;
				}
			}
		}

		var errors = 0;
		for (var i = 0; i < this.elements.length; i++) {
			if (this.elements[i].error) errors++;
		}

		if (errors) {
			$(this.submit).setOpacity (0.5).disabled = "disabled";
			return false;
		} else {
			$(this.submit).setOpacity (1).disabled = "";
			return true;
		}
	},


	checkstatic:		function (element, options) { if ($(element).value == options.value) return options.text; },
	checkstaticdate:	function (element, options) {
							if (parseInt ($(element + "_day").value) == options.value_day && parseInt ($(element + "_month").value) == options.value_month && parseInt ($(element + "_year").value) == options.value_year) return "Ungültiges Datum";
						},
	checkstaticcheckbox:function (element, options) { if ($(element).checked != "checked") { if (options != undefined && options.text != undefined) return options.text; else return "Muss selektiert werden"; } },
	checkajax:			function (element, options) { postPage (options.url, { form: this.form, element: "none" }); },
	checktextvalue:		function (element) { if (!$(element).value) return "Muss eingegeben werden"; },
	checkselectvalue:	function (element) { if (!$(element).value || $(element).value == 0) return "Muss ausgewählt werden"; },
	checkcheckbox:		function (element) { if (!$(element).checked) return "Muss selektiert werden"; },
	checkminlength:		function (element, options) { if ($(element).value && $(element).value.length < options.minlength) return "Muss mindestens " + options.minlength + " Zeichen lang sein"; },
	checkmatch:			function (element, options) { if ($(element).value && $(element).value.match (options.regex)) return options.error; },
	checknomatch:		function (element, options) { if ($(element).value && !$(element).value.match (options.regex)) return options.error; },
	checknumber:		function (element) { if ($(element).value && $(element).value.match (/[^0-9]/)) return "Ungültiges Format"; },
	checkfloat:			function (element) { if ($(element).value && !$(element).value.match (/^\d+(\.\d+)?$/)) return "Ungültiges Format"; },
	checksameas:		function (element, options) { if ($(element).value && $(element).value != $(options.field2).value) return options.error; },
	checkemail:			function (element) { if ($(element).value && !$(element).value.match (/^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/)) return "Ungültiges Format"; },
	checkurl: 			function (element) { if ($(element).value && !$(element).value.match (/^http(|s):\/\/([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,6}(|\/.*)$/)) return "Ungültiges Format (http:// muss enthalten sein)"; },
	checkplzx:			function (element) { if ($(element).value && !$(element).value.match (/^[0-9]{4,5}$/)) return "Ungültiges Format"; },
	checkplzde:			function (element) { if ($(element).value && !$(element).value.match (/^[0-9]{5}$/)) return "Ungültiges Format"; },
	checkplzatch:		function (element) { if ($(element).value && !$(element).value.match (/^[0-9]{4}$/)) return "Ungültiges Format"; },
	checktel:			function (element) { if ($(element).value && !$(element).value.match (/^(0|\+)[0-9-\/ ]+$/)) return "Ungültiges Format (bitte mit Vorwahl angeben)"; },
	checkdatevalue:		function (element) {
							if ($(element + "_day") && $(element + "_month") && $(element + "_year")) {
								var value_day = parseInt ($(element + "_day").value);
								var value_month = parseInt ($(element + "_month").value);
								var value_year = parseInt ($(element + "_year").value);
								if (!value_day || !value_month || !value_year) return "Muss ausgewählt werden";
							} else {
								if (!$(element).value) return "Muss eingegeben werden";
							}
						},
	checkdate:			function (element) {
							if ($(element + "_day") && $(element + "_month") && $(element + "_year")) {
								var value_day = parseInt ($(element + "_day").value);
								var value_month = parseInt ($(element + "_month").value) - 1;
								var value_year = parseInt ($(element + "_year").value);
							} else if ($(element).value) {
								var regex1 = /^(\d{4})-(\d{1,2})-(\d{1,2})$/;
								var regex2 = /^(\d{2})-(\d{1,2})-(\d{1,2})$/;
								var regex3 = /^(\d{1,2})\.(\d{1,2})\.(\d{4})$/;
								var regex4 = /^(\d{1,2})\.(\d{1,2})\.(\d{2})$/;
								var regex5 = /^(\d{2})(\d{2})(\d{4})$/;
								var regex6 = /^(\d{2})(\d{2})(\d{2})$/;
								if ($(element).value.match (regex1)) {
									var arr = regex1.exec ($(element).value);
									var value_day = arr[3];
									var value_month = arr[2] - 1;
									var value_year = arr[1];
								} else if ($(element).value.match (regex2)) {
									var arr = regex2.exec ($(element).value);
									var value_day = arr[3];
									var value_month = arr[2] - 1;
									var value_year = "20" + arr[1];
								} else if ($(element).value.match (regex3)) {
									var arr = regex3.exec ($(element).value);
									var value_day = arr[1];
									var value_month = arr[2] - 1;
									var value_year = arr[3];
								} else if ($(element).value.match (regex4)) {
									var arr = regex4.exec ($(element).value);
									var value_day = arr[1];
									var value_month = arr[2] - 1;
									var value_year = "20" + arr[3];
								} else if ($(element).value.match (regex5)) {
									var arr = regex5.exec ($(element).value);
									var value_day = arr[1];
									var value_month = arr[2] - 1;
									var value_year = arr[3];
								} else if ($(element).value.match (regex6)) {
									var arr = regex6.exec ($(element).value);
									var value_day = arr[1];
									var value_month = arr[2] - 1;
									var value_year = "20" + arr[3];
								} else {
									return "Ungültiges Format";
								}
							}
							var date = new Date (value_year, value_month, value_day);
							if ((value_day > 0 || value_month >= 0 || value_year > 0) && (value_day != date.getDate () || value_month != date.getMonth () || value_year != date.getFullYear ())) return "Ungültiges Datum";
						},
	checkdatecmp:		function (element, options) {
							var value1_day = parseInt ($(element + "_day").value);
							var value1_month = parseInt ($(element + "_month").value) - 1;
							var value1_year = parseInt ($(element + "_year").value);
							var date1 = new Date (value1_year, value1_month, value1_day);
							var value2_day = parseInt ($(options.field2 + "_day").value);
							var value2_month = parseInt ($(options.field2 + "_month").value) - 1;
							var value2_year = parseInt ($(options.field2 + "_year").value);
							var date2 = new Date (value2_year, value2_month, value2_day);
							var validdates = (value1_day > 0 && value1_month >= 0 && value1_year > 0 && value2_day > 0 && value2_month >= 0 && value2_year > 0);
							if (validdates && (options.cmp == "<" && date1 >= date2 || options.cmp == "<=" && date1 > date2 || options.cmp == "=" && date1 != date2 || options.cmp == ">=" && date1 < date2 || options.cmp == ">" && date1 <= date2)) return options.error.replace (/\$cmp/, options.cmp);
						},
	checknospace:		function (element) { if ($(element).value && $(element).value.match (/ /)) return "Ungültiges Format"; },
	checkdateinput:		function (element) { if ($(element).value && !$(element).value.match (/^\d{1,2}\.\d{1,2}\.(19|20|)\d{2}$/)) return "Ungültiges Format"; }
}

