var exception = new FormException();

var checkbox = null;
var radio = null;
var password = null;

var prevCheckResult = new Array();

function getAttributeByName(elem, name)
{
	name = name.toUpperCase();
	try
	{
		var value = elem.getAttribute(name);
		return ( (value) ? value : '' );
	}
	catch(e)
	{
		return '';
	}	
	return '';
}

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 && obj.nodeName.toUpperCase() == 'FORM') 
			{
				form = obj;
			} 
			else if(obj.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 *****/
	var attrValue = getAttributeByName(form, 'LANG');				
	if(attrValue != '')
	{
		lang = attrValue;
	}		
	attrValue = getAttributeByName(form, 'AUTOSUBMIT');
	if(attrValue != '')
	{
		doSubmit = attrValue;
	}		
	attrValue = getAttributeByName(form, 'RESULT');
	if(attrValue != '')
	{
		resultTargetNamePrefix = attrValue;
	}				
	attrValue = getAttributeByName(form, 'TEMPLATE');
	if(attrValue != '')
	{
		template = attrValue;
	}		
	/***** set class parameters *****/		
		
	/***** set checkObjArr *****/
	for(var i=0; i<form.elements.length; i++) 
	{
		attrValue = getAttributeByName(form.elements[i], 'FORMAT');		
		if(attrValue != '') 
		{
			checkObjArr[checkObjArr.length] = form.elements[i];
		}
	}
	/***** /set checkObjArr *****/
		
	/***** check fields *****/
	if(checkObjArr.length > 0) 
	{
		for(var i=0; i<checkObjArr.length; i++) 
		{			
			var reqStrArr = getAttributeByName(checkObjArr[i], 'FORMAT').split('::');
			var type, name, required, size;
			try 
			{
				type = reqStrArr[0];
				name = reqStrArr[1];
				required = (reqStrArr[2] == 'opt') ? false : true;
				if( reqStrArr[2] != 'opt' && reqStrArr[2] != 'req' )
				{
					size = reqStrArr[2];
				}
				else
				{
					size = 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 String();
		for(var i=0; i<this.errMsg.length; i++) 
		{
			result += this.errMsg[i].text.replace('--fieldDesc--', '"' + this.errMsg[i].name + '"').replace('--fieldLen--', this.errMsg[i].size);
		}		
		return result;
	}
	
	this.getErrorStrArr = 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(prevCheckResult.length > 0)
    {
        for(var i=0; i<prevCheckResult.length; i++)
        {
            prevCheckResult[i].innerHTML = '';
        }
        prevCheckResult.length = 0;
    }

    if(this.errMsg.length > 0) {

		if(resultTargetNamePrefix != "null") {

			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")
					{
						var templateItems = template.split('::');
						text = templateItems[0].replace('text', text);
						name = templateItems[1].replace('name', name);
						size = templateItems[2].replace('size', size);
					}

					target.innerHTML = text.replace('--fieldDesc--', '<STRONG>' + name + '</STRONG>').replace('--fieldLen--', size);
					prevCheckResult[prevCheckResult.length] = target;
				}
				catch(e)
				{
					continue;
				}
			}
		}
		else
		{
			alert(this.getErrorStr());
		}
	}
	else if(doSubmit == "true")
	{
		form.submit();
	}
	/***** /show result *****/

	/***** обнуление глобальных переменных *****/
	checkbox = null;
	radio = null;
	password = null;
	/***** /обнуление глобальных переменных *****/
}

/***** constants *****/
var EMPTY = 0; 		// не может быть пустым
var MAXLEN = 1; 	// максимальное количество символов
var MINLEN = 2; 	// минимальное количество символов
var INVALID = 3; 	// заполнено некорректно
var ATLEAST = 4; 	// должно быть выбрано хотя бы одно значение
var INSET = 5; 		// должно быть выбрано от 1 до n значений
var PWD = 6; 		// разные пароли
var BAD_DAY = 7; 	// не правильный день
var BAD_MONTH = 8;	// не правильный месяц
var BAD_YEAR = 9;	// не правильный год
var BETWEEN = 10;	// не правильный год

var errTemplates = new Array();
errTemplates["ru"] = [
	'Поле --fieldDesc-- не может быть пустым\n',
	'Максимальным количеством символов в поле --fieldDesc-- является --fieldLen--\n',
	'Минимальным количеством символов в поле --fieldDesc-- является --fieldLen--\n',
	'Поле --fieldDesc-- заполнено некорректно\n',
	'В разделе --fieldDesc-- должно быть выбрано хотя бы одно значение\n',
	'В разделе --fieldDesc-- должно быть выбрано от 1 до --fieldLen-- значений\n',
	'Введенные пароли не совпадают, попробуйте еще раз\n',
	'В поле --fieldDesc-- значение дня установлено не верно\n',
	'В поле --fieldDesc-- значение месяца установлено не верно\n',
	'В поле --fieldDesc-- значение года установлено не верно\n',
	'Количество символов в поле --fieldDesc-- должно находится в пределах --fieldLen-- символов\n' ];
errTemplates["en"] = [
	'--fieldDesc-- cannot be empty\n',
	'Maximum length of --fieldDesc-- cannot be greater than --fieldLen--\n',
	'Minimum 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',
	'--fieldDesc-- contains incorrect day value\n',
	'--fieldDesc-- contains incorrect month value\n',
	'--fieldDesc-- contains incorrect year value\n',
	'Length of --fieldDesc-- must be between --fieldLen-- letters\n' ];
/***** constants *****/

function Errors(formItem, type, name, required, size, lang)
{
	this.bad = true; // field is bad by default
	var errorMsg = {field:formItem, text:"", name:"", size:""};

	function setErr(num)
	{
		errorMsg.text = errTemplates[lang][num];
		errorMsg.name = (name) ? name : '';
		if ( size < 0 ) size *= -1;
		errorMsg.size = (size) ? size : '';
	}
		
	if (required && isEmpty(formItem))
	{
		setErr(EMPTY);
	}
    else if( required && ( formItem.nodeName.toUpperCase() == 'TEXTAREA' || formItem.type.toUpperCase() == 'FILE' || formItem.nodeName.toUpperCase() == 'SELECT' ) )
	{
        if(formItem.value == '')
		{
			setErr(EMPTY);
		}
		else
		{
			this.bad = false;
		}
	}
    else if( required && ( formItem.type.toUpperCase() == "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( required && ( formItem.type.toUpperCase() == 'RADIO' && radio != formItem.name ) )
	{
		radio = formItem.name;
		if(!isValidRadio(formItem))
		{
			setErr(ATLEAST);
		}
		else
		{
			this.bad = false;
		}
	}
	else if(formItem.type.toUpperCase() == 'PASSWORD')
	{
		if(formItem.value == '')
		{
			setErr(EMPTY);
		}
		else if( password == null && formItem.name.indexOf('password') != -1 )
		{
			password = formItem.value;
			this.bad = false;
		}
		else
		{
			if( formItem.name.indexOf('password2') != -1 && password != formItem.value )
			{
				setErr(PWD);
			}
			else
			{
				this.bad = false;
			}
		}
	}
    else if(type)
	{
		if(type != 'date' && !isValid(formItem, type))
		{
			setErr(INVALID);
		}
		else if(type == 'date')
		{
			var typeOfError = isValid(formItem, type);
			if(typeOfError == 1)
			{
				setErr(INVALID);
			}
			else if(typeOfError == 2)
			{
				setErr(BAD_DAY);
			}
			else if(typeOfError == 3)
			{
				setErr(BAD_MONTH);
			}
			else if(typeOfError == 4)
			{
				setErr(BAD_YEAR);
			}
			else if(typeOfError == 0)
			{
				this.bad = false;
			}
		}
		else
		{
			this.bad = false;
		}
	}
	else
	{
		this.bad = false;
	}  
    if ( !this.bad && typeof( size ) != 'undefined' && parseInt( size ) != -1 && ( required  || formItem.value != '' ) )
	{								 						   
        this.bad = true;
		if ( size.toString().split( '-' )[0] )
		{
			var from = size.split('-')[0];
			var to = size.split('-')[1];			
			if ( !isMoreThan( formItem, from ) || isMoreThan( formItem, to ) )
			{
				setErr(BETWEEN);
			}
		}
		else if ( parseInt( size ) > 0 && !isMoreThan(formItem, size) )
		{	
			setErr(MINLEN);
		}
		else if ( parseInt( size ) < 0 && isMoreThan(formItem, size) )
		{
			setErr(MAXLEN);
		}
        else
		{
			this.bad = false;
		}
	}

	this.getErrorMsg = function()
	{
		return errorMsg;
	}
}

/***** check functions *****/
function isValid(elem, type)
{
	if(elem.type != 'text')
	{
		return true;
	}

	var result = true;
	var str = elem.value.toString();

	if(str.length == 0)
	{
		return true;
	}

	switch(type) {
		case 'email':
			var re = /^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/;
			result = str.match(re);
			break;
		case 'phone':
//			var re = /^[(]?[0-9 )-]{3,}$/;
            var re = /^[+]?[0-9 ]*[(]?[0-9 )-]{3,}$/;
            result = str.match(re);
			break;
		case 'number':
			var re = /^[-]?\d*\.?\d*$/;
			result = str.match(re);
			break;
        case 'int':
			var re = /^[-]?\d$/;
			result = str.match(re);
			break;
        case 'date':
			result = isValidDate(str);
			break;
	}
	return result;
}

function isEmpty(elem) 
{
	if(elem.type == 'text') 
	{
		var str = elem.value;
		var re = /.+/;
		if(!str.match(re)) return true;		
	}
	else 
	{
		return false;
	}
}

function isMoreThan(elem, size) 
{
	if ( size < 0 ) size *= -1;
	if( elem.value ) 
	{
		if(elem.value.toString().length > size) 
		{
			return true;
		}
		return false;
	}
	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;
}

function isValidDate(str) 
{ 
	// формат даты: DD.MM.YYYY || DD-MM-YYYY || DD/MM/YYYY
	if (str.search(/[0-9]{2}(\.|\/|\-)[0-9]{2}(\.|\/|\-)[0-9]{4}/g) == -1) 
	{ 
		return 1; // 'Hеправильный формат'
	} 

	var delim = str.substr(str.length - 5).slice(0,-4);
	var strArr = str.split(delim);
	
	if(strArr.length != 3)
	{
		return 1;
	}
	
	var dd = strArr[0];
	var mm = strArr[1];
	var yy = strArr[2];
	
	if(dd.substr(0, 1) == '0')
	{
		dd = dd.substr(1);
	}
	
	if(mm.substr(0, 1) == '0')
	{
		mm = mm.substr(1);
	}

	if(parseInt(dd) > 31 || parseInt(dd) < 1)
	{
		return 2;
	}
	else if(parseInt(mm) > 12 || parseInt(mm) < 1)
	{
		return 3;
	}
	else if( delim != '.' && delim != '-' && delim != '/' )
	{
		return 4;
	}

	var time = Date.parse(mm + '/' + dd + '/' + yy);
	var etalonDate = new Date(time);

	if(parseInt(dd) != etalonDate.getDate())
	{
		return 2; // Неправильная дата
	}
	else if(parseInt(mm) != etalonDate.getMonth() + 1)
	{
		return 3; // Неправильный месяц
	}
	else if(parseInt(yy) != etalonDate.getFullYear() || parseInt(yy) > 9999)
	{
		return 4; // Неправильный год
	}			

	return 0;
} 
/***** /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);
	}
}