var FormCheck = new Class(
		{
			Implements : [ Options, Events ],
			options : {
				tipsClass : "fc-tbx",
				errorClass : "fc-error",
				fieldErrorClass : "fc-field-error",
				submit : true,
				trimValue : false,
				validateDisabled : false,
				submitByAjax : false,
				ajaxResponseDiv : false,
				ajaxEvalScripts : false,
				onAjaxRequest : $empty,
				onAjaxSuccess : $empty,
				onAjaxFailure : $empty,
				onSubmit : $empty,
				onValidateSuccess : $empty,
				onValidateFailure : $empty,
				display : {
					showErrors : 0,
					titlesInsteadNames : 0,
					errorsLocation : 1,
					indicateErrors : 1,
					indicateErrorsInit : 0,
					keepFocusOnError : 0,
					checkValueIfEmpty : 1,
					addClassErrorToField : 0,
					removeClassErrorOnTipClosure : 0,
					fixPngForIe : 1,
					replaceTipsEffect : 1,
					flashTips : 0,
					closeTipsButton : 1,
					tipsPosition : "right",
					tipsOffsetX : -45,
					tipsOffsetY : 0,
					listErrorsAtTop : false,
					scrollToFirst : true,
					fadeDuration : 300
				},
				alerts : {
					required : "This field is required.",
					alpha : "This field accepts alphabetic characters only.",
					alphanum : "This field accepts alphanumeric characters only.",
					nodigit : "No digits are accepted.",
					digit : "Please enter a valid integer.",
					digitltd : "The value must be between %0 and %1",
					number : "Please enter a valid number.",
					email : "Please enter a valid email.",
					image : "This field should only contain image types",
					phone : "Please enter a valid phone.",
					phone_inter : "Please enter a valid international phone number.",
					url : "Please enter a valid url.",
					confirm : "This field is different from %0",
					differs : "This value must be different of %0",
					length_str : "The length is incorrect, it must be between %0 and %1",
					length_fix : "The length is incorrect, it must be exactly %0 characters",
					lengthmax : "The length is incorrect, it must be at max %0",
					lengthmin : "The length is incorrect, it must be at least %0",
					words_min : "This field must concain at least %0 words, currently: %1 words",
					words_range : "This field must contain %0-%1 words, currently: %2 words",
					words_max : "This field must contain at max %0 words, currently: %1 words",
					checkbox : "Please check the box",
					radios : "Please select a radio",
					select : "Please choose a value"
				},
				regexp : {
					required : /[^.*]/,
					alpha : /^[a-z ._-]+$/i,
					alphanum : /^[a-z0-9 ._-]+$/i,
					digit : /^[-+]?[0-9]+$/,
					nodigit : /^[^0-9]+$/,
					number : /^[-+]?\d*\.?\d+$/,
					email : /^([a-zA-Z0-9_\.\-\+%])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/,
					image : /.(jpg|jpeg|png|gif|bmp)$/i,
					phone : /^[\d\s ().-]+$/,
					phone_inter : /^\+{0,1}[0-9 \(\)\.\-]+$/,
					url : /^(http|https|ftp)\:\/\/[a-z0-9\-\.]+\.[a-z]{2,3}(:[a-z0-9]*)?\/?([a-z0-9\-\._\?\,\'\/\\\+&amp;%\$#\=~])*$/i
				}
			},
			initialize : function(form, options) {
				if (this.form = $(form)) {
					this.form.isValid = true;
					this.regex = [ "length" ];
					this.setOptions(options);
					if (typeof (formcheckLanguage) != "undefined") {
						this.options.alerts = $merge(this.options.alerts,
								formcheckLanguage)
					}
					this.validations = [];
					this.alreadyIndicated = false;
					this.firstError = false;
					var regex = new Hash(this.options.regexp);
					regex.each(function(el, key) {
						this.regex.push(key)
					}, this);
					this.form.getElements("*[class*=validate]").each(
							function(el) {
								if (el.get("tag") == "select"
										|| el.get("tag") == "input"
										|| el.get("tag") == "textarea") {
									this.register(el)
								}
							}, this);
					this.form.addEvents( {
						submit : this.onSubmit.bind(this)
					});
					if (this.options.display.fixPngForIe) {
						this.fixIeStuffs()
					}
					document.addEvent("mousewheel", function() {
						this.isScrolling = false
					}.bind(this))
				}
			},
			register : function(el, position) {
				el.validation = [];
				el
						.getProperty("class")
						.split(" ")
						.each(
								function(classX) {
									if (classX.match(/^validate(\[.+\])$/)) {
										var valid = true;
										if (el.type == "radio") {
											this.validations.each(function(
													valider) {
												if (valider.name == el.name) {
													valid = false
												}
											}, this)
										}
										var validators = eval(classX
												.match(/^validate(\[.+\])$/)[1]);
										for ( var i = 0; i < validators.length; i++) {
											el.validation.push(validators[i]);
											if (validators[i]
													.match(/^confirm\[/)) {
												var field = eval(validators[i]
														.match(/^.+(\[.+\])$/)[1]
														.replace(
																/([A-Z0-9\._-]+)/i,
																"'$1'"));
												if (this.form[field].validation
														.contains("required")) {
													el.validation
															.push("required")
												}
											}
											if (validators[i]
													.match(/^target:.+/)) {
												el.target = validators[i]
														.match(/^target:(.+)/)[1]
											}
										}
										if (position
												&& position <= this.validations.length) {
											var newValidations = [];
											this.validations
													.each(
															function(valider, i) {
																if (position == i + 1
																		&& valid) {
																	newValidations
																			.push(el);
																	this
																			.addListener(el)
																}
																newValidations
																		.push(valider)
															}, this);
											this.validations = newValidations
										} else {
											if (valid) {
												this.validations.push(el);
												this.addListener(el)
											}
										}
									}
								}, this)
			},
			dispose : function(element) {
				this.validations.erase(element)
			},
			addListener : function(el) {
				el.errors = [];
				if (this.options.display.indicateErrorsInit) {
					this.validations.each(function(el) {
						if (!this.manageError(el, "submit")) {
							this.form.isValid = false
						}
					}, this);
					return true
				}
				if (el.validation[0] == "submit") {
					el.addEvent("click", function(e) {
						if (this.onSubmit(e)) {
							this.form.submit()
						}
					}.bind(this));
					return true
				}
				if (this.isChildType(el) == false) {
					el
							.addEvent(
									"blur",
									function() {
										(function() {
											if (!this.fxRunning
													&& (el.element || this.options.display.showErrors == 1)
													&& (this.options.display.checkValueIfEmpty || el.value)) {
												this.manageError(el, "blur")
											}
										}.bind(this)).delay(100)
									}.bind(this))
				} else {
					if (this.isChildType(el) == true) {
						var nlButtonGroup = this.form
								.getElements('input[name="' + el
										.getProperty("name") + '"]');
						nlButtonGroup
								.each(
										function(radio) {
											radio
													.addEvent(
															"blur",
															function() {
																(function() {
																	if ((el.element || this.options.display.showErrors == 1)
																			&& (this.options.display.checkValueIfEmpty || el.value)) {
																		this
																				.manageError(
																						el,
																						"click")
																	}
																}.bind(this))
																		.delay(100)
															}.bind(this))
										}, this)
					}
				}
			},
			validate : function(el) {
				el.errors = [];
				el.isOk = true;
				if (!this.options.validateDisabled && el.get("disabled")) {
					return true
				}
				if (this.options.trimValue && el.value) {
					el.value = el.value.trim()
				}
				el.validation
						.each(
								function(rule) {
									if (this.isChildType(el)) {
										if (this.validateGroup(el) == false) {
											el.isOk = false
										}
									} else {
										var ruleArgs = [];
										if (rule.match(/target:.+/)) {
											return
										}
										if (rule.match(/^.+\[/)) {
											var ruleMethod = rule.split("[")[0];
											ruleArgs = eval(rule
													.match(/^.+(\[.+\])$/)[1]
													.replace(
															/([A-Z0-9\._-]+)/i,
															"'$1'"))
										} else {
											var ruleMethod = rule
										}
										if (this.regex.contains(ruleMethod)
												&& el.get("tag") != "select") {
											if (this.validateRegex(el,
													ruleMethod, ruleArgs) == false) {
												el.isOk = false
											}
										}
										if (ruleMethod == "confirm") {
											if (this.validateConfirm(el,
													ruleArgs) == false) {
												el.isOk = false
											}
										}
										if (ruleMethod == "differs") {
											if (this.validateDiffers(el,
													ruleArgs) == false) {
												el.isOk = false
											}
										}
										if (ruleMethod == "words") {
											if (this
													.validateWords(el, ruleArgs) == false) {
												el.isOk = false
											}
										}
										if (el.get("tag") == "select"
												|| (el.type == "checkbox" && ruleMethod == "required")) {
											if (this.simpleValidate(el) == false) {
												el.isOk = false
											}
										}
										if (rule.match(/%[A-Z0-9\._-]+$/i)
												|| (el.isOk && rule
														.match(/~[A-Z0-9\._-]+$/i))) {
											if (eval(rule.slice(1) + "(el)") == false) {
												el.isOk = false
											}
										}
									}
								}, this);
				if (el.isOk) {
					return true
				} else {
					return false
				}
			},
			simpleValidate : function(el) {
				if (el.get("tag") == "select" && el.selectedIndex <= 0) {
					el.errors.push(this.options.alerts.select);
					return false
				} else {
					if (el.type == "checkbox" && el.checked == false) {
						el.errors.push(this.options.alerts.checkbox);
						return false
					}
				}
				return true
			},
			validateRegex : function(el, ruleMethod, ruleArgs) {
				var msg = "";
				if (ruleArgs[1] && ruleMethod == "length") {
					if (ruleArgs[1] == -1) {
						this.options.regexp.length = new RegExp("^[\\s\\S]{"
								+ ruleArgs[0] + ",}$");
						msg = this.options.alerts.lengthmin.replace("%0",
								ruleArgs[0])
					} else {
						if (ruleArgs[0] == ruleArgs[1]) {
							this.options.regexp.length = new RegExp(
									"^[\\s\\S]{" + ruleArgs[0] + "}$");
							msg = this.options.alerts.length_fix.replace("%0",
									ruleArgs[0])
						} else {
							this.options.regexp.length = new RegExp(
									"^[\\s\\S]{" + ruleArgs[0] + ","
											+ ruleArgs[1] + "}$");
							msg = this.options.alerts.length_str.replace("%0",
									ruleArgs[0]).replace("%1", ruleArgs[1])
						}
					}
				} else {
					if (ruleArgs[0] && ruleMethod == "length") {
						this.options.regexp.length = new RegExp("^.{0,"
								+ ruleArgs[0] + "}$");
						msg = this.options.alerts.lengthmax.replace("%0",
								ruleArgs[0])
					} else {
						msg = this.options.alerts[ruleMethod]
					}
				}
				if (ruleArgs[1] && ruleMethod == "digit") {
					var regres = true;
					if (!this.options.regexp.digit.test(el.value)) {
						el.errors.push(this.options.alerts[ruleMethod]);
						regres = false
					}
					if (ruleArgs[1] == -1) {
						var valueres = (el.value.toInt() >= ruleArgs[0].toInt());
						msg = this.options.alerts.digitmin.replace("%0",
								ruleArgs[0])
					} else {
						var valueres = (el.value.toInt() >= ruleArgs[0].toInt() && el.value
								.toInt() <= ruleArgs[1].toInt());
						msg = this.options.alerts.digitltd.replace("%0",
								ruleArgs[0]).replace("%1", ruleArgs[1])
					}
					if (regres == false || valueres == false) {
						el.errors.push(msg);
						return false
					}
				} else {
					if (this.options.regexp[ruleMethod].test(el.value) == false) {
						el.errors.push(msg);
						return false
					}
				}
				return true
			},
			validateConfirm : function(el, ruleArgs) {
				var confirm = ruleArgs[0];
				if (el.value != this.form[confirm].value) {
					if (this.options.display.titlesInsteadNames) {
						var msg = this.options.alerts.confirm.replace("%0",
								this.form[confirm].getProperty("title"))
					} else {
						var msg = this.options.alerts.confirm.replace("%0",
								confirm)
					}
					el.errors.push(msg);
					return false
				}
				return true
			},
			validateDiffers : function(el, ruleArgs) {
				var differs = ruleArgs[0];
				if (el.value == this.form[differs].value) {
					if (this.options.display.titlesInsteadNames) {
						var msg = this.options.alerts.differs.replace("%0",
								this.form[differs].getProperty("title"))
					} else {
						var msg = this.options.alerts.differs.replace("%0",
								differs)
					}
					el.errors.push(msg);
					return false
				}
				return true
			},
			validateWords : function(el, ruleArgs) {
				var min = ruleArgs[0];
				var max = ruleArgs[1];
				var words = el.value.replace(/[ \t\v\n\r\f\p]/m, " ").replace(
						/[,.;:]/g, " ").clean().split(" ");
				if (max == -1) {
					if (words.length < min) {
						el.errors.push(this.options.alerts.words_min.replace(
								"%0", min).replace("%1", words.length));
						return false
					}
				} else {
					if (min > 0) {
						if (words.length < min || words.length > max) {
							el.errors.push(this.options.alerts.words_range
									.replace("%0", min).replace("%1", max)
									.replace("%2", words.length));
							return false
						}
					} else {
						if (words.length > max) {
							el.errors.push(this.options.alerts.words_max
									.replace("%0", max).replace("%1",
											words.length));
							return false
						}
					}
				}
				return true
			},
			isFormValid : function() {
				this.form.isValid = true;
				this.validations.each(function(el) {
					var validation = this.manageError(el, "testonly");
					if (!validation) {
						this.form.isValid = false
					}
				}, this);
				return this.form.isValid
			},
			isChildType : function(el) {
				return ($defined(el.type) && el.type == "radio") ? true : false
			},
			validateGroup : function(el) {
				el.errors = [];
				var nlButtonGroup = this.form[el.getProperty("name")];
				el.group = nlButtonGroup;
				var cbCheckeds = false;
				for ( var i = 0; i < nlButtonGroup.length; i++) {
					if (nlButtonGroup[i].checked) {
						cbCheckeds = true
					}
				}
				if (cbCheckeds == false) {
					el.errors.push(this.options.alerts.radios);
					return false
				} else {
					return true
				}
			},
			listErrorsAtTop : function(obj) {
				if (!this.form.element) {
					this.form.element = new Element("div", {
						id : "errorlist",
						"class" : this.options.errorClass
					}).injectTop(this.form)
				}
				if ($type(obj) == "collection") {
					new Element("p").set(
							"html",
							"<span>" + (obj[0].title ? obj[0].title : obj[0].name) + " : </span>"
									+ obj[0].errors[0]).injectInside(
							this.form.element)
				} else {
					if ((obj.validation.contains("required") && obj.errors.length > 0)
							|| (obj.errors.length > 0 && obj.value && obj.validation
									.contains("required") == false)) {
						obj.errors.each(function(error) {
							new Element("p").set("html",
									"<span>" + (obj.title ? obj.title : obj.name) + " : </span>" + error)
									.injectInside(this.form.element)
						}, this)
					}
				}
				window.fireEvent("resize")
			},
			manageError : function(el, method) {
				var isValid = this.validate(el);
				if (method == "testonly") {
					return isValid
				}
				if ((!isValid && el.validation.flatten()[0]
						.contains("confirm["))
						|| (!isValid && el.validation.contains("required"))
						|| (!el.validation.contains("required") && el.value && !isValid)) {
					if (this.options.display.listErrorsAtTop == true
							&& method == "submit") {
						this.listErrorsAtTop(el)
					}
					if (this.options.display.indicateErrors == 2
							|| this.alreadyIndicated == false
							|| el.name == this.alreadyIndicated.name) {
						if (!this.firstError) {
							this.firstError = el
						}
						this.alreadyIndicated = el;
						if (this.options.display.keepFocusOnError
								&& el.name == this.firstError.name) {
							(function() {
								el.focus()
							}).delay(20)
						}
						this.addError(el);
						return false
					}
				} else {
					if ((isValid || (!el.validation.contains("required") && !el.value))) {
						this.removeError(el);
						return true
					}
				}
				return true
			},
			addError : function(obj) {
				var coord = obj.target ? $(obj.target).getCoordinates() : obj
						.getCoordinates();
				if (!obj.element && this.options.display.indicateErrors != 0) {
					if (this.options.display.errorsLocation == 1) {
						var pos = (this.options.display.tipsPosition == "left") ? coord.left
								: coord.right;
						var options = {
							opacity : 0,
							position : "absolute",
							"float" : "left",
							left : pos + this.options.display.tipsOffsetX
						};
						obj.element = new Element("div", {
							"class" : this.options.tipsClass,
							styles : options
						}).injectInside(document.body);
						this.addPositionEvent(obj)
					} else {
						if (this.options.display.errorsLocation == 2) {
							obj.element = new Element("div", {
								"class" : this.options.errorClass,
								styles : {
									opacity : 0
								}
							}).injectBefore(obj)
						} else {
							if (this.options.display.errorsLocation == 3) {
								obj.element = new Element("div", {
									"class" : this.options.errorClass,
									styles : {
										opacity : 0
									}
								});
								if ($type(obj.group) == "object"
										|| $type(obj.group) == "collection") {
									obj.element
											.injectAfter(obj.group[obj.group.length - 1])
								} else {
									obj.element.injectAfter(obj)
								}
							}
						}
					}
				}
				if (obj.element && obj.element != true) {
					obj.element.empty();
					if (this.options.display.errorsLocation == 1) {
						var errors = [];
						obj.errors.each(function(error) {
							errors.push(new Element("p").set("html", error))
						});
						var tips = this.makeTips(errors).injectInside(
								obj.element);
						if (this.options.display.closeTipsButton) {
							tips.getElements("a.close").addEvent("mouseup",
									function() {
										this.removeError(obj, "tip")
									}.bind(this))
						}
						obj.element.setStyle("top", coord.top
								- tips.getCoordinates().height
								+ this.options.display.tipsOffsetY)
					} else {
						obj.errors.each(function(error) {
							new Element("p").set("html", error).injectInside(
									obj.element)
						})
					}
					if (!this.options.display.fadeDuration
							|| Browser.Engine.trident
							&& Browser.Engine.version == 5
							&& this.options.display.errorsLocation < 2) {
						obj.element.setStyle("opacity", 1)
					} else {
						obj.fx = new Fx.Tween(obj.element, {
							duration : this.options.display.fadeDuration,
							ignore : true,
							onStart : function() {
								this.fxRunning = true
							}.bind(this),
							onComplete : function() {
								this.fxRunning = false;
								if (obj.element
										&& obj.element.getStyle("opacity")
												.toInt() == 0) {
									obj.element.destroy();
									obj.element = false
								}
							}.bind(this)
						});
						if (obj.element.getStyle("opacity").toInt() != 1) {
							obj.fx.start("opacity", 1)
						}
					}
				}
				if (this.options.display.addClassErrorToField
						&& this.isChildType(obj) == false) {
					obj.addClass(this.options.fieldErrorClass);
					obj.element = obj.element || true
				}
			},
			addPositionEvent : function(obj) {
				if (this.options.display.replaceTipsEffect) {
					obj.event = function() {
						var coord = obj.target ? $(obj.target).getCoordinates()
								: obj.getCoordinates();
						new Fx.Morph(obj.element, {
							duration : this.options.display.fadeDuration
						})
								.start( {
									left : [
											obj.element.getStyle("left"),
											coord.right
													+ this.options.display.tipsOffsetX ],
									top : [
											obj.element.getStyle("top"),
											coord.top
													- obj.element
															.getCoordinates().height
													+ this.options.display.tipsOffsetY ]
								})
					}.bind(this)
				} else {
					obj.event = function() {
						var coord = obj.target ? $(obj.target).getCoordinates()
								: obj.getCoordinates();
						obj.element.setStyles( {
							left : coord.right
									+ this.options.display.tipsOffsetX,
							top : coord.top
									- obj.element.getCoordinates().height
									+ this.options.display.tipsOffsetY
						})
					}.bind(this)
				}
				window.addEvent("resize", obj.event)
			},
			removeError : function(obj, method) {
				if ((this.options.display.addClassErrorToField
						&& !this.isChildType(obj) && this.options.display.removeClassErrorOnTipClosure)
						|| (this.options.display.addClassErrorToField
								&& !this.isChildType(obj)
								&& !this.options.display.removeClassErrorOnTipClosure && method != "tip")) {
					obj.removeClass(this.options.fieldErrorClass)
				}
				if (!obj.element) {
					return
				}
				this.alreadyIndicated = false;
				obj.errors = [];
				obj.isOK = true;
				window.removeEvent("resize", obj.event);
				if (this.options.display.errorsLocation >= 2 && obj.element) {
					new Fx.Tween(obj.element, {
						duration : this.options.display.fadeDuration
					}).start("height", 0)
				}
				if (!this.options.display.fadeDuration
						|| Browser.Engine.trident
						&& Browser.Engine.version == 5
						&& this.options.display.errorsLocation == 1
						&& obj.element) {
					this.fxRunning = true;
					obj.element.destroy();
					obj.element = false;
					(function() {
						this.fxRunning = false
					}.bind(this)).delay(200)
				} else {
					if (obj.element && obj.element != true) {
						obj.fx.start("opacity", 0)
					}
				}
			},
			focusOnError : function(obj) {
				if (this.options.display.scrollToFirst && !this.alreadyFocused
						&& !this.isScrolling) {
					if (!this.options.display.indicateErrors
							|| !this.options.display.errorsLocation) {
						var dest = obj.getCoordinates().top - 30
					} else {
						if (this.alreadyIndicated.element) {
							switch (this.options.display.errorsLocation) {
							case 1:
								var dest = obj.element.getCoordinates().top;
								break;
							case 2:
								var dest = obj.element.getCoordinates().top - 30;
								break;
							case 3:
								var dest = obj.getCoordinates().top - 30;
								break
							}
							this.isScrolling = true
						}
					}
					if (window.getScroll.y != dest) {
						new Fx.Scroll(window, {
							onComplete : function() {
								this.isScrolling = false;
								if (obj.getProperty("type") != "hidden") {
									obj.focus()
								}
							}.bind(this)
						}).start(0, dest)
					} else {
						this.isScrolling = false;
						obj.focus()
					}
					this.alreadyFocused = true
				}
			},
			fixIeStuffs : function() {
				if (Browser.Engine.trident4) {
					var rpng = new RegExp("url\\(([.a-zA-Z0-9_/:-]+.png)\\)");
					var search = new RegExp("(.+)formcheck.css");
					for ( var i = 0; i < document.styleSheets.length; i++) {
						if (document.styleSheets[i].href
								.match(/formcheck\.css$/)) {
							var root = document.styleSheets[i].href.replace(
									search, "$1");
							var count = document.styleSheets[i].rules.length;
							for ( var j = 0; j < count; j++) {
								var cssstyle = document.styleSheets[i].rules[j].style;
								var bgimage = root
										+ cssstyle.backgroundImage.replace(
												rpng, "$1");
								if (bgimage && bgimage.match(/\.png/i)) {
									var scale = (cssstyle.backgroundRepeat == "no-repeat") ? "crop"
											: "scale";
									cssstyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, src='"
											+ bgimage
											+ "', sizingMethod='"
											+ scale + "')";
									cssstyle.backgroundImage = "none"
								}
							}
						}
					}
				}
			},
			makeTips : function(txt) {
				var table = new Element("table");
				table.cellPadding = "0";
				table.cellSpacing = "0";
				table.border = "0";
				var tbody = new Element("tbody").injectInside(table);
				var tr1 = new Element("tr").injectInside(tbody);
				new Element("td", {
					"class" : "tl"
				}).injectInside(tr1);
				new Element("td", {
					"class" : "t"
				}).injectInside(tr1);
				new Element("td", {
					"class" : "tr"
				}).injectInside(tr1);
				var tr2 = new Element("tr").injectInside(tbody);
				new Element("td", {
					"class" : "l"
				}).injectInside(tr2);
				var cont = new Element("td", {
					"class" : "c"
				}).injectInside(tr2);
				var errors = new Element("div", {
					"class" : "err"
				}).injectInside(cont);
				txt.each(function(error) {
					error.injectInside(errors)
				});
				if (this.options.display.closeTipsButton) {
					new Element("a", {
						"class" : "close"
					}).injectInside(cont)
				}
				new Element("td", {
					"class" : "r"
				}).injectInside(tr2);
				var tr3 = new Element("tr").injectInside(tbody);
				new Element("td", {
					"class" : "bl"
				}).injectInside(tr3);
				new Element("td", {
					"class" : "b"
				}).injectInside(tr3);
				new Element("td", {
					"class" : "br"
				}).injectInside(tr3);
				return table
			},
			reinitialize : function(forced) {
				this.validations.each(function(el) {
					if (el.element) {
						el.errors = [];
						el.isOK = true;
						if (this.options.display.flashTips == 1
								|| forced == "forced") {
							el.element.destroy();
							el.element = false
						}
					}
				}, this);
				if (this.form.element) {
					this.form.element.empty()
				}
				this.alreadyFocused = false;
				this.firstError = false;
				this.elementToRemove = this.alreadyIndicated;
				this.alreadyIndicated = false;
				this.form.isValid = true
			},
			submitByAjax : function() {
				var url = this.form.getProperty("action");
				this.fireEvent("ajaxRequest");
				new Request( {
					url : url,
					method : this.form.getProperty("method"),
					data : this.form.toQueryString(),
					evalScripts : this.options.ajaxEvalScripts,
					onFailure : function(instance) {
						this.fireEvent("ajaxFailure", instance)
					}.bind(this),
					onSuccess : function(result) {
						this.fireEvent("ajaxSuccess", result);
						if (this.options.ajaxResponseDiv) {
							$(this.options.ajaxResponseDiv).set("html", result)
						}
					}.bind(this)
				}).send()
			},
			onSubmit : function(event) {
				this.reinitialize();
				this.fireEvent("onSubmit");
				this.validations.each(function(el) {
					var validation = this.manageError(el, "submit");
					if (!validation) {
						this.form.isValid = false
					}
				}, this);
				if (this.form.isValid) {
					if (this.options.submitByAjax) {
						new Event(event).stop();
						this.submitByAjax()
					} else {
						if (!this.options.submit) {
							new Event(event).stop()
						}
					}
					this.fireEvent("validateSuccess");
					return true
				} else {
					new Event(event).stop();
					if (this.elementToRemove
							&& this.elementToRemove != this.firstError
							&& this.options.display.indicateErrors == 1) {
						this.removeError(this.elementToRemove)
					}
					this.focusOnError(this.firstError);
					this.fireEvent("validateFailure");
					return false
				}
			}
		});
