//язык страницы - необходим для определения языка сообщений
var validateFormLang = 1;

//массив для результатов валидации
var validate_errors = new Array();


//Преобразует в верхний регистр первую букву из строки
function ucwords(string)
{  
	return string.charAt(0).toUpperCase() + string.substr(1).toLowerCase();  
}


// Метод определяет форму через свойство form одного из элемента с id из check_list_fields
function getForm()
{
    for (i = 0; i < check_list_fields.length; i++)
    {
    	if (check_list_fields[i]['id'] != '' && check_list_fields[i]['id'] != 'true')
    	{
    		// Пытаемся обратиться к элементу по id
    		if ($('#' + check_list_fields[i]['id']).get(0) != null)
    		{
    			return $('#' + check_list_fields[i]['id']).get(0).form;
    		}
    		//если не существует элемента с таким id, то пытаемся обратиться по имени
    		else if(document.getElementsByName(check_list_fields[i]['id']).length > 0)
    		{
               	return document.getElementsByName(check_list_fields[i]['id'])[0].form;
    		}
    	}
    }
}


//Определяем есть ли среди валидируемых полей Captcha
function hasCaptcha()
{
    for (i = 0; i < check_list_fields.length; i++)
    {
    	if (check_list_fields[i]['type'] == 'captcha')
    	{
    		return true;
    	}
    }
    
    return false;
}


//Метод инициализации элемента для валидации
function init_validate_field(id, label, type)
{
    this.id = id;
    this.label = label;
    this.type = type;
}


//Метод инициализации вообщения о ошибке валидации для валидации
function init_validate_error(name, message, label)
{
    this.name = name;
    this.message = message;
    this.label = label;
}


//Метод производит валидацию полей на клиентской стороне 
function validate_form(check_list_fields)
{
	//Очищаем массив для сообщений об ошибках валидации
	validate_errors = new Array();
	
	//Скрываем старые сообщения
	hideErrors();
	
    for (i = 0; i < check_list_fields.length; i++)
    {
        var element_opt = check_list_fields[i];
        
        if ($('#' + element_opt['id']))
        {
        	var element = $('#' + element_opt['id'])[0];
        }

        //если не существует элемента с таким id, то пытаемся обратиться по имени
        if(element == null)
        {
            if(document.getElementsByName(element_opt['id']).length > 0)
            {
                element = document.getElementsByName(element_opt['id'])[0];
            }
        }
        
        //Имя метода делающего проверку, формируется на основе имени типа проверки с префиксом _is
        method_name = '_is' + ucwords(element_opt['type'].toLowerCase());

        //Имя метода делающего проверку, формируется на основе имени типа проверки с префиксом _is
        if (!window[method_name](element, element_opt))
        {
        	//Обработчик каптчи сам выводит текст ошибки
        	if (element_opt['type'] != 'captcha')
        	{
        		addError([{"name":element_opt['id'],"type":element_opt['type'],"title":element_opt['label']}][0]);
        	}
        }
    }

    return true;
}


//Метод производит валидацию полей на серверной стороне
function validate_form_on_server()
{
	//Очищаем массив для сообщений об ошибках валидации
	validate_errors = new Array();
	
	//Скрываем старые сообщения
	hideErrors();
	
	data = '';
	
	// На сервер надо передавать все данные формы, так как некотроые поля могут управлять логикой валидации
	form_el = getForm().elements;
	
	for (i = 0; i < form_el.length; i++)
	{
		// Поле action фильтруем
		if (form_el[i].name.toLowerCase() != 'action')
		{
			tagname = form_el[i].tagName.toLowerCase();
			type = form_el[i].type.toLowerCase();
			checked = form_el[i].checked;
			
			// Для полей типа radio и checkbox - проверяем выделено ли оно			
			if (tagname == 'input' && (type == 'checkbox' || type == 'radio'))
			{
				if (checked)
				{
					data += '&' +  form_el[i].name + '=' + form_el[i].value;
				}
			}
			else
			{
				data += '&' +  form_el[i].name + '=' + form_el[i].value;
			}
		}
	}
    
    // Один модуль может использовать несколько типов валидации - указываем текущий тип
    data += '&validateType=' + validateType;
    	
    
    // столкнулся со следующей проблемой - если валидация проходит не на главной странице модуля
    // а на одной из внутренних - action может быть переопределен в htaccess.
    // поэтому парсим текущий путь и определяем путь к главной странице модуля - 
    // обычно action у них не указывается, а в коде берется по-умолчанию первый - 
    // считаем что это имя первой директории после имени сайта
    var dirs = document.location.pathname.split('/');
    var module_main_page = '/' + dirs[1] + '/';
	       
	var queryUrl = module_main_page + '?action=998';
	
	$.ajax({ 
		  type: "POST", 
		  url: queryUrl, 
		  dataType: "json",
		  data: data,
		  success: function(data)
		  { 
			 
			 //alert('data:'+data);
			 
			 //валидация не пройдена
	    	 if (data.length)
	    	 {
	    		 fillErrorsFromJSON(data);
	    		 viewErrors();
	    	 }
	    	 //валидация пройдена - сабмитим форму
	    	 else
	    	 {
	    		 //обращаемся к форме по свойству form первого валидиуемого элемента
	    		 //$('#' + check_list_fields[0]['id'])[0].form.submit();
	    		 //alert('z');
	    		 getForm().submit();
	    	 }
	  	  } 
		});

	return false;
}


//Метод заполняет результатами валидации на сервере массив validate_errors
function fillErrorsFromJSON(data)
{
	for (i = 0; i < data.length; i++)
	{
		addError(data[i]);
	}
}


//Отображает результат валидации
function viewErrors()
{
	//alert(validate_errors);
	
	for (i = 0; i < validate_errors.length; i++)
	{
		//alert('z2');
		
		// Результат выводим посредством alert'a
		if (view_errors_style == 1)
		{
			//alert(validate_errors[i]['message']);
			
			return true;
		}
		
		//alert(validate_errors[i]['message']);
		
		//Результат показываем в одном месте документа
		if (view_errors_style == 2)
		{
			if ($('#errors').length == 0)
			{
				alert('Не создан контейнер для ошибок с идентификатором "errors"');
				return;
			}

			$('#errors').html($('#errors').html() + validate_errors[i]['message'] + '<br />');
		}
		
		//Каждый результат показываем на своем месте документа
		if (view_errors_style == 3)
		{
			curr_fieldname = 'error_' + validate_errors[i]['name'];
			
			if ($('#' + curr_fieldname).length == 0)
			{
				alert('Не создан контейнер для ошибок с идентификатором "' + curr_fieldname + '"');
			}
			
			$('#' + curr_fieldname).html(validate_errors[i]['message']);
			$('#' + curr_fieldname).show();
		}
	}
    
    // Добавляем перевод строки снизу для красоты
    if (validate_errors.length > 0 && view_errors_style == 2)
    {
        $('#errors').html($('#errors').html() + '<br />');
    }
	
	if ((view_errors_style == 2) && (validate_errors.length > 0))
	{
		$('#errors').show();
	}
}


// Для стилей вывода ошибок view_errors_style 2 или 3 - скрываем блоки где отображаются ошибки 
function hideErrors()
{
	//скрываем общий блок для вывода ошибок
	if ($('#errors'))
	{
		$('#errors').hide();
		$('#errors').html('');
	}
	
	//скрываем индивидуальные блоки
	for (i = 0; i < check_list_fields.length; i++)
	{
		element_opt = check_list_fields[i];
		if ($('#error_' + element_opt['id']))
		{
			$('#error_' + element_opt['id']).hide();
			$('#error_' + element_opt['id']).html('');
		}
	}
}

//Добавляет сообщение об ошибке
function addError(rule)
{
	if (! messages[rule.type])
	{
		alert('В справочнике не обнаружен текст ошибки для типа валидации"' + rule.type + '"');
		
		return;
	}
	
	error = replaceFromJSON(rule, messages[rule.type]);
	
	validate_errors[validate_errors.length] = new init_validate_error(name, error);
}


// Делает замены параметров JSON в тексте
//TODO: каких параметров?
function replaceFromJSON(data, text)
{
	for (var i in data)
	{
		//alert('i:'+i+', data: '+data[i]);
		
		text = text.replace(new RegExp('#' + i + '#', 'i'), data[i]);
	}
	
	return text;
}


//Функция делает проверку проверочного кода
function _isCaptcha(element, options)
{
	var params = {   
		GCODE: element.value
	};
	
	path = document.location.pathname;
       
	var queryUrl = path + '?action=999';
    
	$.get(queryUrl, params, function(data) 
	{
		//если проверочный код неверен
		if (data != 1)
		{
			addError([{"name":element_opt['id'],"type":element_opt['type'],"title":element_opt['label']}][0]);
			viewErrors();
		}
		//если валидация остальных полей не пройдена
		else if (validate_errors.length > 0)
		{
			viewErrors();
		}
		//если проверочный код верен и остальные поля валидированы успешно - сабмитим форму
		else
		{   
			element.form.submit();
		}

	}); 

	return false;
}


// Провека на заполненность
function _isRequired(element, options)
{
    if (element.value == '')
    {
    	return false;
    }
    
    return true;
}


//Функция проверяет, является ли переданное значение числом
function _isNumber(element, options)
{
	var re =/[^0-9.]/g;
	
	if (!re.test(element.value))
	{			
		return false;
	}
	
	return true;
}


//Проверка E-Mail на корректность
function _isEmail(element, options)
{
	//if (!(/\w+@\w+\.[a-z]{2,4}/.test(element.value)))
	if (!(/^.+@.+\..+$/.test(element.value)))
	{
		return false;
	}
	
	return true;
}


//Проверка на совпадение введенных паролей
function _isPasswordsMatch(element, options)
{
    for (j = 0; j < check_list_fields.length; j++)
    {
        var element_opt_curr = check_list_fields[j];
        var element_curr = $('#' + element_opt['id'])[0];

        var password = element.value;
        
        //ищем остальные элементы с типом password
        if (element_opt_curr['type'] == 'password' && element_opt_curr['id'] != options['id'])
        {
            //пароли не сходятся
            if(password != element_curr.value)
            {               
                return false;
            }
        }
        
        return true;
    }
}
