var checkForm = {};

checkForm.buildRegExp = function(str) {
	if (str) {return new RegExp("^[" + str + "]{1,}$");}
	return false;
}

checkForm.invalidMsg = "I'm sorry, but submitted form isn't filled correctly.\nEither some fields contain incorrect data, or some required fields are blank.\nPlease, correct all highlighted fields and try to submit again.";
checkForm.fieldType = new Array();
checkForm.fieldType["safeChars"] =			checkForm.buildRegExp("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_");
checkForm.fieldType["numbers"] =			checkForm.buildRegExp("0123456789");
checkForm.fieldType["alphabetLowercase"] =	checkForm.buildRegExp("abcdefghijklmnopqrstuvwxyz");
checkForm.fieldType["alphabetUppercase"] =	checkForm.buildRegExp("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
checkForm.fieldType["alphabet"] =			checkForm.buildRegExp("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
checkForm.fieldType["alphanumeric"] =		checkForm.buildRegExp("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
checkForm.fieldType["date"] =				new RegExp("^[0-9]{1,2}[.][0-9]{1,2}[.][0-9]{4}$");	// in format (D)D.(M)M.YYYY
checkForm.fieldType["url"] =				new RegExp(/^(?:(?:ftp|https?):\/\/)?(?:[a-z0-9](?:[-a-z0-9]*[a-z0-9])?\.)+(?:com|edu|biz|org|gov|int|info|mil|net|name|museum|coop|aero|[a-z][a-z])\b(?:\d+)?(?:\/[^;"'<>()\[\]{}\s\x7f-\xff]*(?:[.,?]+[^;"'<>()\[\]{}\s\x7f-\xff]+)*)?/i);
checkForm.fieldType["email"] =				new RegExp(/^\w[-.\w]*\@[-a-zA-Z0-9]+(?:\.[-a-zA-Z0-9]+)*\.(?:com|edu|biz|org|gov|int|info|mil|net|name|museum|coop|aero|[a-zA-Z][a-zA-Z])\b/i);
checkForm.fieldType["login"] =				new RegExp("^[a-zA-Z0-9_-]{2,64}$");
checkForm.fieldType["password"] =           new RegExp("^.{5,64}$");
checkForm.fieldType["safeCharsWithSpace"] = new RegExp("^[a-zA-Z0-9_ ]{1,}$");
//checkForm.fieldType["url"] =				new RegExp("^http:\/\/[a-zA-Z0-9]+([-_\.]?[a-zA-Z0-9])*\.[a-zA-Z]{2,4}(\/{1}[-_~&=\?\.a-z0-9]*)*$");
//checkForm.fieldType["email"] =				new RegExp("^[a-z0-9]+[a-z0-9\._-]*[a-z0-9]+@[a-z0-9]+[a-z0-9\._-]*[a-z0-9]+\.[a-z]{2,4}$");

checkForm.defaultValue = new Array();
checkForm.defaultValue["url"] =						"http://www.";

checkForm.init = function() {
	var forms = document.getElementsByTagName("form");
	for (var i = 0; i < forms.length; i++) {
		addEvent(forms[i], "submit", checkForm.check);
		addEvent(forms[i], "reset", checkForm.check);
	}

	var fields = checkForm.findInputs();
	for (var i = 0; i < fields.length; i++) {
		checkForm.checkField(fields[i]);
		addEvent(fields[i], "blur", checkForm.checkField);
		addEvent(fields[i], "focus", checkForm.checkField);
		addEvent(fields[i], "keyup", checkForm.checkField);
		addEvent(fields[i], "change", checkForm.checkField);
	}
}

checkForm.findInputs = function(elm) {
	var fields = new Array();
	if (!elm) {elm = document;}

	var textareas = elm.getElementsByTagName("textarea");
	var inputs = elm.getElementsByTagName("input");

	for (var i = 0; i < textareas.length; i++) {
		fields[fields.length] = textareas[i];
	}
	for (var i = 0; i < inputs.length; i++) {
		if ((inputs[i].type == "text") || (inputs[i].type == "password")) {
			fields[fields.length] = inputs[i];
		}
	}

	return fields;
}

checkForm.check = function(e) {
	var obj;
	if (e && e.tagName) {
		obj = e;
	} else {
		e = fixE(e);
		obj = e.target;
	}
	while (obj.tagName != "FORM"&&obj.tagName!=topelement) {
		obj = obj.parentNode;
	}


	var fields = checkForm.findInputs(obj);
	for (var i = 0; i < fields.length; i++) {
		if (checkForm.checkField(fields[i]) == "invalid") {
			if (e.type == "submit") {
				//alert(checkForm.invalidMsg);
				if (document.getElementById('invalid_msg')) hide_show('invalid_msg',1);
				if (e.preventDefault) {
					e.preventDefault();
				}
			}
			return false;
		}
	}
	return true;
}

checkForm.checkField = function(e) {
	var obj;
	if (e && e.tagName) {
		obj = e;
	} else {
		e = fixE(e);
		obj = e.target;
	}
	var fieldOK = true;
	var classes = classMagic.get(obj);

	// required field can't be empty
	if (classMagic.has(obj, "required")) {
		fieldOK = (checkForm.isBlank(obj.value)) ? false : true;
	}

	// find classes of given field and check, if there are any rules for it
	var i = 0;
	while (fieldOK && i < classes.length) {
		if (checkForm.defaultValue[classes[i]]) {
			if ((e.type == "focus") && checkForm.isBlank(obj.value)) {
				obj.value = checkForm.defaultValue[classes[i]];
			}
			if ((e.type == "blur") && (obj.value == checkForm.defaultValue[classes[i]])) {
				obj.value = "";
			}
		}
		if (checkForm.fieldType[classes[i]]) {
			fieldOK = (!checkForm.isBlank(obj.value) && checkForm.checkChars(obj.value, checkForm.fieldType[classes[i]])) ? false : true;
		}
		i++;
	}

	(fieldOK) ? classMagic.remove(obj, "invalid") : classMagic.add(obj, "invalid");

	/*
	Function like this should return "true" or "false". But this would be
	blocking of keyboard input in case of incomplete content of the field
	(e.g. URL). That's why this function returns "valid" or "invalid".
	*/
	return (fieldOK) ? "valid" : "invalid";
}

checkForm.checkChars = function(str, re) {
	if (str && re) {
		return (str.search(re) == -1) ? true : false;
	}
	return true;
}

checkForm.isBlank = function(str) {
	return (str == "") ? true : false;
}


addEvent(window, "load", checkForm.init);