
var formValidation = function() {
    var max_img_size = 2000000; //байт
    var max_img_size_mb = max_img_size / 1000000; // М

    var img_dimantions = ["jpeg", "png"];

    var validate_classes = {
        'clsPhone': 'phone',
        'clsEmail': 'email',
        'clsDate' : 'date',
        'clsDateZagrankartaCabinet' : 'dateZagrankartaCabinet',
        'clsDateBirthday' : 'dateBirthday',
        'clsNaturalNumber' : 'naturalNumber',
        'clsTinyIntForm1To5' : 'tinyIntForm1To5',
        'clsPhoneIntOnly' : 'phoneIntOnly',
        'clsFloatNumber' : 'floatNumber',
        'clsSkype' : 'skype',
        'clsDateDay' : 'dateDay',
        'clsDateMonth' : 'dateMonth',
        'clsDateYear' : 'dateYear',
        'clsTime' : 'time',
        'clsOnlyAZAndSymbols' : 'onlyAZAndSymbols',
        'clsZagrancardNum': 'zagrancardNum',
        'clsHexColor' : 'hexColor',
        'clsStringFrom3': 'stringFrom3',
        'clsIsPassword': 'isPassword',
        'clsIsUniqe': 'isUniqe',
        'clsIsSameField': 'isSameField'
    };

    var errors_messages =
    {
        'ru' : {
            'is_required': 'Поле обязательно для заполнения',
            'phone': 'Поле заполнено неверно',
            'email': 'Поле заполнено неверно',
            'date': 'Поле заполнено неверно',
            'naturalNumber': 'Поле заполнено неверно',
            'tinyIntForm1To5': 'Допустимые значения поля - 1, 2, 3, 4, 5',
            'phoneIntOnly': 'Поле заполнено неверно',
            'dateZagrankartaCabinet': 'Поле заполнено неверно. Формат даты: 22.11.2002',
            'dateBirthday' : 'Год рождения должен быть не старше 1905 года',
            'floatNumber': 'Поле заполнено неверно. В качестве десятичного разделителя используйте символ "."',
            'skype': 'Поле заполнено неверно',
            'dateDay' : 'Поле заполнено неверно',
            'dateMonth' : 'Поле заполнено неверно',
            'dateYear' : 'Поле заполнено неверно',
            'time' : 'Поле заполнено неверно',
            'onlyAZAndSymbols': 'Допустимые значения поля: все буквы от А до z, включая пробелы, апострофы и дефисы.',
            'zagrancardNum': 'Допускаются только цифры. Количество цыфр - 8',
            'hexColor' : 'Цвет должен быть указан в формате #640e0e',
            'stringFrom3': 'Строка должна содержать от 3-ох символов',
            'isPassword': 'Пароль должен содержать не меньше 5 символов. Допустимые значения: символы англ. все буквы от А до z, цифры, символы -_',
            'isUniqe': 'Такое значение в базе уже есть',
            'isSameField': 'Поля не идентичны'
        },
        'en' : {
            'is_required': 'Required field',
            'phone': 'The text you entered is not valid',
            'email': 'The text you entered is not valid',
            'date': 'The text you entered is not valid',
            'naturalNumber': 'The text you entered is not valid',
            'tinyIntForm1To5': 'Допустимые значения поля - 1, 2, 3, 4, 5',
            'phoneIntOnly': 'The text you entered is not valid',
            'dateZagrankartaCabinet': 'Поле заполнено неверно. Формат даты: 22.11.2002',
            'dateBirthday' : 'Год рождения должен быть не старше 1905 года',
            'floatNumber': 'Поле заполнено неверно. В качестве десятичного разделителя используйте символ "."',
            'skype': 'The text you entered is not valid',
            'dateDay' : 'The text you entered is not valid',
            'dateMonth' : 'The text you entered is not valid',
            'dateYear' : 'The text you entered is not valid',
            'time' : 'The text you entered is not valid',
            'onlyAZAndSymbols': 'The possible field values: all the letters from A to z, including spaces, apostrophes and hyphens.',
            'zagrancardNum': 'Допускаются только цифры. Количество цыфр - 8',
            'hexColor' : 'Цвет должен быть указан в формате #640e0e',
            'stringFrom3': 'String need to have 3 and more symbols',
            'isPassword': 'Пароль должен содержать не меньше 5 символов. Допустимые значения: символы англ. все буквы от А до z, цифры, символы -_',
            'isUniqe': 'This value have already been in the database',
            'isSameField': 'Not same fields'
        },
        'fr' : {
            'is_required': 'Поле обязательно для заполнения',
            'phone': 'Поле заполнено неверно',
            'email': 'Поле заполнено неверно',
            'date': 'Поле заполнено неверно',
            'naturalNumber': 'Поле заполнено неверно',
            'tinyIntForm1To5': 'Допустимые значения поля - 1, 2, 3, 4, 5',
            'phoneIntOnly': 'Поле заполнено неверно',
            'dateZagrankartaCabinet': 'Поле заполнено неверно. Формат даты: 22.11.2002',
            'dateBirthday' : 'Год рождения должен быть не старше 1905 года',
            'floatNumber': 'Поле заполнено неверно. В качестве десятичного разделителя используйте символ "."',
            'skype': 'Поле заполнено неверно',
            'dateDay' : 'Поле заполнено неверно',
            'dateMonth' : 'Поле заполнено неверно',
            'dateYear' : 'Поле заполнено неверно',
            'time' : 'Поле заполнено неверно',
            'onlyAZAndSymbols': 'The possible field values: all the letters from A to z, including spaces, apostrophes and hyphens.',
            'zagrancardNum': 'Допускаются только цифры. Количество цыфр - 8',
            'hexColor' : 'Цвет должен быть указан в формате #640e0e',
            'stringFrom3': 'String need to have 3 and more symbols',
            'isPassword': 'Пароль должен содержать не меньше 5 символов. Допустимые значения: символы англ. все буквы от А до z, цифры, символы -_',
            'isUniqe': 'This value have already been in the database',
            'isSameField': 'Not same fields'
        }

    };



    this.validateForm = function(form_container, lang, field) {
        var isError = false;

        lang = (lang == undefined) ? 'ru' : lang;
        var validateFields = (field == undefined) ? $(form_container).find(':input[type!=hidden], select, textarea') : field;
        if (field == undefined) {
            $(form_container).find('div.error').remove();
        }
        else{
            $(field).next().remove();
        }

        validateFields.each(function () {
            var thisObj = $(this);
            if (thisObj.attr('type') == "button" || $(this).attr('type') == "submit" || !thisObj.is(':visible'))
                return;

            var is_required = thisObj.hasClass('ClsRequired');
            var validate_types = getValidateType(thisObj);
            var value = '';

            if(!is_required && !validate_types.length){
                return;
            }

            switch (thisObj.prop('tagName')){
                case 'INPUT' : value = $.trim(thisObj.val()); break;
                case 'SELECT' : value = $.trim(thisObj.val()); break;
                case 'TEXTAREA': value = $.trim(thisObj.val()); break;
            }

            if (!value && is_required) {
                thisObj.after('<div class="error">'+errors_messages[lang]['is_required']+'</div>');

                isError = true;
                return;
            }

           // $(this).parent().find('div.error-text').empty();

            if (validate_types.length && value) {
                for(var ruleItem in validate_types) {
                    var validate_type = validate_types[ruleItem];

                    var res = rule(value, validate_type, thisObj);
                    if(typeof(res) == 'object'){
                        if(res.responseText == 1){
                            res = true;
                        }
                        else{
                            res = false;
                        }
                    }
                    if (!res) {
                        thisObj.after('<div class="error">'+errors_messages[lang][validate_type]+'</div>');
                        isError = true;
                    }
                }
            }
        });

        if (isError) {
            return false;
        }

        return true;
    }

    this.getFormData = function(form_container){
        var data = {};

        $(form_container).find(':input').each(function () {
            if ($(this).attr('type') == "button" || $(this).attr('type') == "submit")
                return;

            data[$(this).attr('name')] = $(this).val();
        });

        return data;
    }

    this.validateImg = function(img_id, result_container_id){
        $('form').on('change', '#'+img_id, function(){
            var fileInput = document.getElementById(img_id);
            var fileDisplayArea = document.getElementById(result_container_id);
            var file = fileInput.files[0];
            var file_size = file.size;
            var found = false;
            var errors = new Array();

            img_dimantions.forEach(function(extension) {
                if (file.type.match('image/'+extension)) {
                    found = true;
                }
            })
            if(!found){
                errors[errors.length] = 'Разрешены только файлы с разширениями: '+ img_dimantions.join(', ');
            }

            if(file_size > max_img_size){
                errors[errors.length] = 'Размер изображения не должен привышать '+ max_img_size_mb + ' М';
            }

            if (errors.length == 0) {
                var reader = new FileReader();

                reader.onload = function(e) {
                    fileDisplayArea.innerHTML = "";

                    var img = new Image(200);
                    img.src = reader.result;

                    fileDisplayArea.appendChild(img);
                }

                reader.readAsDataURL(file);
            } else {
                var input = $("#"+img_id);
                input.replaceWith(input.val('').clone(true));
                fileDisplayArea.innerHTML = errors.join('<br>');
            }
        });
    }

    var getValidateType = function(el) {
        var rules = new Array();
        for (var i in validate_classes) {
            if (el.hasClass(i)) {
                rules.push(validate_classes[i]);
            }
        }
        return rules;
    }

    var rule = function(value, type, thisObj) {

        if (type == 'phone') {
            var reg = /^[0-9-()+ ]{4,}$/;
            var result = reg.test(value);

            return result;
        }

        if (type == 'phoneIntOnly') {
            var reg = /^[\+0-9]{5,}$/;
            var result = reg.test(value);

            return result;
        }

        if (type == 'email') {
            var reg = /^(([a-z0-9])(_)?(-)?(\.)?){1,20}@(([a-z0-9-]+\.)+(com|net|org|mil|edu|gov|arpa|info|biz|inc|name|[a-z]{2,4})|[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})$/i;
            var result = reg.test(value);

            return result;
        }

        if (type == 'date'){
            var reg = /^[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{4,4}$/i;
            var result = reg.test(value);

            return result;
        }

        if (type == 'dateZagrankartaCabinet'){
            var reg = /^[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{4,4}$/i;
            var result = reg.test(value);

            return result;
        }

        if (type == 'dateBirthday'){
            var dateTmp = value.split('.')
            var date = new Date(dateTmp[2], dateTmp[1] - 1, dateTmp[0]);

            return date.getFullYear() >= 1905 ? true : false;
        }

        if(type == 'naturalNumber'){
            var reg = /^[0-9]+$/i;
            var result = reg.test(value);

            return result;
        }

        if(type == 'tinyIntForm1To5'){
            var reg = /^[1-5]{1,1}$/i;
            var result = reg.test(value);

            return result;
        }

        if(type == 'floatNumber'){
            var reg = /^[0-9]+(\.)?[0-9]+$/i;
            var result = reg.test(value);

            return result;
        }

        if(type == 'skype'){
            var reg = /^\S{3,}$/i;
            var result = reg.test(value);

            return result;
        }

        if(type == 'dateDay'){
            var number = parseInt(value);

            if(isNaN(number) || number<1 || number > 31){
                return false;
            }
        }

        if(type == 'dateMonth'){
            var number = parseInt(value);

            if(isNaN(number) || number<1 || number > 12){
                return false;
            }
        }

        if(type == 'dateYear'){
            var year = parseInt(value);

            if(isNaN(year) || year != value || value.length != 4){
                return false;
            }
        }

        if(type == 'time'){
            var reg = /^[0-9]{2,2}\:[0-9]{2,2}$/i;
            var result = reg.test(value);

            return result;
        }

        if(type == 'onlyAZAndSymbols'){
            var reg = /^[A-z\s'-]+$/i;
            var result = reg.test(value);

            return result;
        }

        if(type == 'zagrancardNum'){
            var reg = /^[0-9]{8,8}$/i;
            var result = reg.test(value);

            return result;
        }

        if(type == 'hexColor'){
            var reg = /^#{1,1}[A-z0-9]{6,6}$/i;
            var result = reg.test(value);

            return result;
        }

        if(type == 'stringFrom3'){
            var reg = /^[A-zА-я\s']{3,}$/i;
            var result = reg.test(value);

            return result;
        }

        if(type == 'isPassword'){
            var reg = /^[A-z0-9\-\_]{5,}$/i;
            var result = reg.test(value);

            return result;
        }

        if(type == 'isUniqe'){
            var data = {};
            data.field = (thisObj.attr('name') != undefined) ? thisObj.attr('name') : '';
            data.value = thisObj.val();

           return $.ajax({
                async: false,
                type: 'POST',
                url: (thisObj.attr('data-method') != undefined) ? thisObj.attr('data-method') : '',
                data: data,
                success: function(data){
                }
            });
        }

        if(type == 'isSameField'){
            if (value == $('input[name='+thisObj.attr('data-same-field')+']').val()){
                var result = true;
            }
            else{
                var result = false;
            }
            return result;
        }

        return true;
    }
}