var exception = new FormException();

var checkbox = null;
var radio = null;
var password = null;

var prevCheckResult = new Array();

function FormCheckPro(obj) {
	
	this.errMsg = new Array();		
	
	/***** defaults *****/
	var doSubmit = true;	
	var lang = "ru"; 
	var resultTargetNamePrefix = "null";
	var template = "null";
	/***** /defaults *****/
	
	var form = null;
	var checkObjArr = new Array();
	
	/***** set form object *****/		
	try {		
		if(obj) {
			if(obj.nodeName == "FORM") {
				form = obj;
			} else if(obj.form == "FORM") {
				form = obj.form;
			} else if(typeof(obj) == "string" || typeof(obj) == "number") {
				form = document.forms[obj];			
			} else {
				form = findForm(obj);
			}			
			if(!form) throw exception.setMessage("Имя формы или ссылка на ее объект заданы неверно!");
		}				
		else throw exception.setMessage("Конструктру объекта не передана ссылка на форму!");
	} catch(e) {exception.getMessage();}
	/***** /set form object *****/
	/***** set class parameters *****/
	if(form) {		
		lang = form.getAttribute("LANG").substring(0,2) || lang;		
		doSubmit = form.getAttribute("AUTOSUBMIT") || doSubmit;				
		resultTargetNamePrefix = form.getAttribute("RESULT") || resultTargetNamePrefix;				
		template = form.getAttribute("TEMPLATE") || template;
	}	
	/***** set class parameters *****/		
		
	/***** set checkObjArr *****/
	if(form) {		
		for(var i=0; i<form.elements.length; i++) {
			if(form.elements[i].getAttribute("FORMAT")) {
				checkObjArr[checkObjArr.length] = form.elements[i];
			}
		}
	}
	/***** /set checkObjArr *****/
		
	/***** check fields *****/
	if(checkObjArr.length > 0) {
		for(var i=0; i<checkObjArr.length; i++) {
			var reqStrArr = checkObjArr[i].getAttribute("FORMAT").split('::');
			var type, name, required, size;
			try {
				type = reqStrArr[0];
				name = reqStrArr[1];
				required = (reqStrArr[2] == 'opt') ? false : true;
				size = parseInt(reqStrArr[2]) || reqStrArr[3];				
			} catch(e) {continue;}
			var err = new Errors(checkObjArr[i], type, name, required, size, lang);			
			if(err.bad) { // If field is bad				
				this.errMsg[this.errMsg.length] = err.getErrorMsg();				
			}
		}		
	}
	/***** /check fields *****/
	
	this.getErrorStr = function() {
		var result = new Array();
		for(var i=0; i<this.errMsg.length; i++) {
			result[result.length] = this.errMsg[i].text.replace('--fieldDesc--', '"' + this.errMsg[i].name + '"').replace('--fieldLen--', this.errMsg[i].size);
		}		
		return result;
	}
	
	this.getErrorObj = function() {
		var result = new Array();
		for(var i=0; i<this.errMsg.length; i++) {
			result[result.length] = this.errMsg[i].field;
		}		
		return result;		
	}
	
	this.getErrorObjFull = function() {
		var result = new Array();
		for(var i=0; i<this.errMsg.length; i++) {
			result[result.length] = this.errMsg[i];
		}
		return result;
	}
	
	/***** show result *****/
	if(this.errMsg.length > 0) {
		
		if(resultTargetNamePrefix != "null") {						
		
			if(prevCheckResult.length > 0) {
				for(var i=0; i<prevCheckResult.length; i++) {
					prevCheckResult[i].innerHTML = "&nbsp;";					
				}
				prevCheckResult.length = 0;
			}				
			for(var i=0; i<this.errMsg.length; i++) {
				try {
					var target = document.getElementById(resultTargetNamePrefix + this.errMsg[i].field.name);
					var text = this.errMsg[i].text;
					var name = this.errMsg[i].name;					
					var size = this.errMsg[i].size;
					
					if(template != "null") {
						text = template.split('::')[0].replace('text', text);
						name = template.split('::')[1].replace('name', name);
						size = template.split('::')[2].replace('size', size);
					} 									
					
					target.innerHTML = text.replace('--fieldDesc--', '<STRONG>' + name + '</STRONG>').replace('--fieldLen--', size);
					prevCheckResult[prevCheckResult.length] = target;
				} catch(e) {continue;}
			}
		} else {
			var alertStr = new String();
			for(var i=0; i<this.errMsg.length; i++) {				
				alertStr += this.errMsg[i].text.replace('--fieldDesc--', '"' + this.errMsg[i].name + '"').replace('--fieldLen--', this.errMsg[i].size);
			}
			alert(alertStr);
		}
	} else {		
		if(doSubmit.toString() == "true") {
			submit();
		}
	}
	/***** /show result *****/
	
	/***** обнуление глобальных переменных *****/
	checkbox = null;
	radio = null;
	password = null;
	/***** /обнуление глобальных переменных *****/
		
	/***** submit form *****/
	function submit(ok) {
		try {			
			form.submit();
		} catch(e) {
			exception.setMessage("Форма не может быть отправлена!");
			exception.getMessage();			
		}
	}			
	/***** /submit form *****/		
}

/***** constants *****/
var EMPTY = 0; // не может быть пустым
var MAXLEN = 1; // максимальным количеством символов в поле
var INVALID = 2; // заполнено некорректно
var ATLEAST = 3; // должно быть выбрано хотя бы одно значение
var INSET = 4; // должно быть выбрано от 1 до n значений
var PWD = 5; // разные пароли

var errTemplates = new Array();
errTemplates["ru"] = [
	'Поле --fieldDesc-- не может быть пустым\n', 
	'Максимальным количеством символов в поле --fieldDesc-- является --fieldLen--\n', 
	'Поле --fieldDesc-- заполнено некорректно\n', 
	'В разделе --fieldDesc-- должно быть выбрано хотя бы одно значение\n', 
	'В разделе --fieldDesc-- должно быть выбрано от 1 до --fieldLen-- значений\n',
	'Введенные пароли не совпадают, попробуйте еще раз\n'];
errTemplates["en"] = [
	'--fieldDesc-- cannot be empty\n', 
	'Maximum length of --fieldDesc-- cannot be greater than --fieldLen--\n', 
	'--fieldDesc-- is invalid\n', 
	'--fieldDesc-- section must have at least 1 value selected\n', 
	'--fieldDesc-- section must have 1 to --fieldLen-- values selected\n', 
	'The password and it’s confirmation are not identical\n'];
/***** constants *****/

function Errors(formItem, type, name, required, size, lang) {
	this.bad = true; // fields is bad by default
	var errorMsg = {field:formItem, text:"", name:"", size:""};
	
	function setErr(num) {
		errorMsg.text = errTemplates[lang][num];
		errorMsg.name = name || "";
		errorMsg.size = size || "";		
	}
	if (required && isEmpty(formItem)) {
		setErr(EMPTY);
	}	
	else if (size && isMoreThanMaxlen(formItem, size)) {
		setErr(MAXLEN);
	}	
	else if(type && !isValid(formItem, type)) {
		setErr(INVALID);
	}	
	else if(formItem.type.toLowerCase() == "checkbox" && checkbox != formItem.name) {
		checkbox = formItem.name;
		if(!isValidCheckbox(formItem, size)) {
			if(size > 1) {
				setErr(INSET);				
			} else {
				setErr(ATLEAST);
			}		
		} else {this.bad = false;}
	}
	else if(formItem.type.toLowerCase() == "radio" && radio != formItem.name) {
		radio = formItem.name;
		if(!isValidRadio(formItem)) {	
			setErr(ATLEAST);		
		} else {this.bad = false;}
	}
	else if(formItem.nodeName.toUpperCase() == "SELECT") {
		if(formItem.selectedIndex == 0) {
			setErr(ATLEAST);
		} else {this.bad = false;}
	}
	else if(formItem.type.toLowerCase() == "file") {
		var str = formItem.value;
		var re = /.+/;
		if(!str.match(re)) {
			setErr(EMPTY);
		} else {this.bad = false;}
	}
	else if(formItem.nodeName.toUpperCase() == "TEXTAREA") {
		if(formItem.value == '') {			
			setErr(EMPTY);
		} else {this.bad = false;}
	}
	else if(formItem.type.toLowerCase() == "password") {				
		if(formItem.value.toString().length == 0) {
			setErr(EMPTY);			
		}
		else if(password != null && password != formItem.value) {						
			setErr(PWD);				
		} 
		else {
			if(password == null) {					
				password = formItem.value;
			}
			this.bad = false;
		}
	}
	else this.bad = false;
	
	this.getErrorMsg = function() {
		return errorMsg;
	}
}

/***** check functions *****/
function isValid(elem, type) {
	if(elem.type == 'text') {
		var result = true;
		var str = elem.value.toString();
		switch(type) {
			case 'email':
				var re = /^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/;
				if(!str.match(re)) result = false;
				break;
			case 'phone':
				var re = /^((\+)?[0-9]{1,3}|)(\s)?[(]?[0-9 )-]{3,}$/;
				if(!str.match(re) && str!="") result = false;
				break;
			case 'number':
				var re = /^[-]?\d*\.?\d*$/;
				if(!str.match(re)) result = false;
				break;				
			case 'date':
				var re = /^[^\/][0-9 .:\/]+[^\/]$/; // syntax: [mm/dd/yy hh:mm] or [dd.mm.yy hh:mm]
				if(!str.match(re)) result = false;
				break;
		}
		return result;
	} else return true;
}

function isEmpty(elem) {
	if(elem.type == 'text') {
		var str = elem.value;
		var re = /.+/;
		if(!str.match(re)) return true;		
	}
	else return false;
}

function isMoreThanMaxlen(elem, size) {
	if(elem.type == 'text') {
		if(elem.value.toString().length > size) return true;
	}
	else return false;
}

function isValidCheckbox(elem, size) {
	var form = elem.form;
	var count = 0;
	for(var i=0; i<form.elements.length; i++) {
		if(form.elements[i].name == elem.name) {
			if(size > 1 && form.elements[i].checked) {							
				count++;				
			} else if(form.elements[i].checked) {
				return true;
			}
		}
	}		
	if(count >= 1 && count <= size) {
		return true;
	}
	return false;
}

function isValidRadio(elem) {
	var form = elem.form;
	for(var i=0; i<form.elements.length; i++) {
		if(form.elements[i].name == elem.name && form.elements[i].checked) {
			return true;
		}
	}
	return false;
}
/***** /check functions *****/

function findForm(elem) {
	while(elem.parentNode.nodeName != 'BODY') {
		if(elem.parentNode.nodeName == 'FORM') {			
			return elem.parentNode;
		} else {
			elem = elem.parentNode;
		}
	}
	return null;
}

function FormException() {
	this.message = "";
	this.setMessage = function(msg) {
		this.message = msg;
	}
	this.getMessage = function() {
		alert(this.message);
	}
}