function DefaValidator() {
    this.checkBrowser();

    this.reBlank = new RegExp('^[\\s ]*$', 'i');
    this.reMail = new RegExp('^[a-z][a-z0-9_\\-\\.]+@[a-z0-9_\\-\\.]+\\.[a-z]{2,}$', 'i');
    this.reAlnum = new RegExp('^[a-z0-9_]*$', 'i');
}

DefaValidator.prototype.checkBrowser = function() {
    var browserStr = navigator.userAgent;

    if (browserStr.indexOf('Firefox') != -1) {
        this.browser = 'FF';
        var arr = /Firefox\/(\d+)\.(\d+)/.exec(browserStr);
        this.majorVersion = arr[1];
        this.minorVersion = arr[2];
    } else if (browserStr.indexOf('Opera') != -1) {
        this.browser = 'O';
        var arr = /Opera (\d+)\.(\d+)/.exec(browserStr);
        if (!arr) {
            var arr = /Opera\/(\d+)\.(\d+)/.exec(browserStr);
        }
        if (arr) {
            this.majorVersion = arr[1];
            this.minorVersion = arr[2];
        } else {
            this.majorVersion = 1;
            this.minorVersion = 0;
        }
    } else if (browserStr.indexOf('MSIE') != -1) {
        this.browser = 'IE';
        var arr = /MSIE (\d+)\.(\d+)/.exec(browserStr);
        this.majorVersion = arr[1];
        this.minorVersion = arr[2];
    } else {
        this.browser = 'smth';
        this.majorVersion = 0;
        this.minorVersion = 0;
    }

    //alert(this.browser+' '+this.majorVersion+'.'+this.minorVersion);
}

DefaValidator.prototype.catchEvent = function(input, event_type) {
    switch (event_type.type) {
        case 'change':
            this.catchOnChange(input);
            break;
        default:
            alert('Undefined event');
    }
}

DefaValidator.prototype.catchOnChange = function(input) {
    var validationType = this.getValidationType(input.id);
    if (validationType !== false) {
        if (this.checkField(input, validationType)) {
            this.makeCorrect(input);
        } else {
            this.makeIncorrect(input);
        }
    }
}

DefaValidator.prototype.getValidationType = function(id) {
    if (id.indexOf('validation_')) {
        var params = new Array();
        var re = new RegExp('validation_(.+)$');
        var arr = re.exec(id);
// DM //////////////////////////////////////////////////////////////////////////
// Добавил проверку на корректность arr
// Не отрабатывает RegExp
    // DB
//        if(arr && !isNull(arr)) {
        if (arr) {
    // /DB
            var tmp = this.explode(arr[1], '_');
            this.params = tmp;
            return tmp[0];
        }
        else {
            return false;
        }
// /DM /////////////////////////////////////////////////////////////////////////
    } else {
        return false;
    }
}

DefaValidator.prototype.checkField = function(input, type) {
    switch (type) {
        case 'file':
        case 'blank':
            return (!this.reBlank.test(input.value));
            break;
        case 'mail':
            return (this.reMail.test(input.value));
            break;
        case 'length':
            if (this.params[2] > 0) {
                return ((input.value.length >= this.params[1]) && (input.value.length <= this.params[2]));
            } else {
                return (input.value.length >= this.params[1]);
            }
            break;
        case 'alnum':
            if ((this.params[1] > 0) && (this.params[2] > 0)) {
                return ((input.value.length >= this.params[1]) && (input.value.length <= this.params[2]) && this.reAlnum.test(input.value));
            } else if (this.params[1] > 0) {
                return ((input.value.length >= this.params[1]) && this.reAlnum.test(input.value));
            } else {
                return (this.reAlnum.test(input.value));
            }
            break;
        case 'equal2':
            if (this.params[1] && (typeof(input.form[this.params[1]]) != 'undefined')) {
                return (input.value == input.form[this.params[1]].value);
            } else {
                return false;
            }
            break;
        case 'custom1':
            return this.custom1(input.form);
            break;
                //  [DB]: Проверка логина
        case 'custom2':
            return this.custom2(input);
            break;
                //  [/DB]: Проверка логина
                //  [DB]: Проверка каптчи
        case 'custom3':
            return this.custom3(input);
            break;
                //  [/DB]: Проверка каптчи
                //  [DB]: Навороченая проверка мыла
        case 'custom4':
            return this.custom4(input);
            break;
                //  [/DB]: Навороченая проверка мыла
        default:
            return false;
    }
}

DefaValidator.prototype.makeCorrect = function(input) {
    /* Костыль под Евраз */
    if (input.id.indexOf('USER_LOGIN') != -1) {
        var div = document.getElementById('USER_LOGIN_ERR');
        if (div && (typeof(div) != 'undefined')) {
            div.style.display = 'none';
        }
    }
    if (input.id.indexOf('USER_PASSWORD') != -1) {
        var div = document.getElementById('USER_PASSWORD_ERR');
        if (div && (typeof(div) != 'undefined')) {
            div.style.display = 'none';
        }
    }
    /* /Костыль под Евраз */

    if ((typeof(input.parentNode) != 'undefined') && input.parentNode) {
        if (input.parentNode.className.indexOf('err') != -1) {
            input.parentNode.className = input.parentNode.className.replace(/err/, 'ok');
        } else if (input.parentNode.className.indexOf('ok') == -1) {
            input.parentNode.className = input.parentNode.className+' ok';
        }
    }
}

DefaValidator.prototype.makeIncorrect = function(input) {
    /* Костыль под Евраз */
    if (input.id.indexOf('USER_LOGIN') != -1) {
        var div = document.getElementById('USER_LOGIN_ERR');
        if (div && (typeof(div) != 'undefined')) {
            div.style.display = 'block';
        }
    }
    if (input.id.indexOf('USER_PASSWORD') != -1) {
        var div = document.getElementById('USER_PASSWORD_ERR');
        if (div && (typeof(div) != 'undefined')) {
            div.style.display = 'block';
        }
    }
    /* /Костыль под Евраз */

    if ((typeof(input.parentNode) != 'undefined') && input.parentNode) {
        if (input.parentNode.className.indexOf('ok') != -1) {
            input.parentNode.className = input.parentNode.className.replace(/ok/, 'err');
        } else if (input.parentNode.className.indexOf('err') == -1) {
            input.parentNode.className = input.parentNode.className+' err';
        }
    }
}

DefaValidator.prototype.explode = function(str, sep) {
    var arr = new Array();

    if (str.indexOf(sep) != -1) {
        var pos;

        while ((pos = str.indexOf(sep)) != -1) {
            arr[arr.length] = str.slice(0, pos);
            str = str.slice(pos + 1, str.length);
        }

        arr[arr.length] = str;
    } else {
        arr[0] = str;
    }

    return arr;
}

DefaValidator.prototype.validateForm = function(form) {
    var ok = true;
    var focused = false;
    var i;
    for (i in form.elements) {
        if (form.elements[i] && (typeof(form.elements[i]) != 'undefined') && (typeof(form.elements[i].id) != 'undefined') && (/validation_/.test(form.elements[i].id))) {
            var validationType = this.getValidationType(form.elements[i].id);
            if (this.checkField(form.elements[i], validationType)) {
                this.makeCorrect(form.elements[i]);
            } else {
                this.makeIncorrect(form.elements[i]);
                if (!focused && (form.elements[i].type != 'hidden')) {
                    form.elements[i].focus();
                    focused = true;
                }
                ok = false;
            }
        }
    }

    return ok;
}

DefaValidator.prototype.custom1 = function(form) {
    var err_block = document.getElementById('news_filter_err');
    var ok = true;
    var mnth_begin = form.m_from;
    var year_begin = form.y_from;
    var mnth_ends = form.m_to;
    var year_ends = form.y_to;

    var mnth_begin_value = Number(mnth_begin.value);
    var year_begin_value = Number(year_begin.value);
    var mnth_ends_value = Number(mnth_ends.value);
    var year_ends_value = Number(year_ends.value);

    if (mnth_begin && year_begin && mnth_ends && year_ends && (typeof(mnth_begin) != 'undefined') && (typeof(year_begin) != 'undefined') && (typeof(mnth_ends) != 'undefined') && (typeof(year_ends) != 'undefined')) {
        if (((mnth_begin_value > 0) && (year_begin_value == 0)) || ((mnth_begin_value == 0) && (year_begin_value > 0)) || ((mnth_ends_value > 0) && (year_ends_value == 0)) || ((mnth_ends_value == 0) && (year_ends_value > 0))) {
            ok = false;
        } else if (year_begin_value > year_ends_value) {
            ok = false;
        } else if ((year_begin_value == year_ends_value) && (mnth_begin_value > mnth_ends_value)) {
            ok = false;
        }
    }

    if (ok) {
        if (err_block && (typeof(err_block) != 'undefined')) {
            err_block.style.display = 'none';
        }
    } else {
        if (err_block && (typeof(err_block) != 'undefined')) {
            err_block.style.display = 'block';
        }
    }

    return ok;
}

//  [DB]: Проверка логина
DefaValidator.prototype.custom2 = function(input) {
    if (!this.reAlnum.test(input.value)) {
        document.getElementById('login_error_field').innerHTML = document.getElementById('login_error_1').innerHTML;
        return false;
    }
    if ((input.value.length < 3)) {
        document.getElementById('login_error_field').innerHTML = document.getElementById('login_error_2').innerHTML;
        return false;
    }
    try {
        var request = new XHR({method: 'get', async: false}).send('/defa/ajax/check_login?username='+input.value);
        if (request.response.text.length>0) {
            try {
                var response = eval('(' + request.response.text + ')');
                if (response.exist) {
                    document.getElementById('login_error_field').innerHTML = document.getElementById('login_error_3').innerHTML;
                    return false;
                }
            }
            catch (e) {
                // do nothing
            }

        }
    }
    catch (e) {
        // do nothing
    }
    return true;
}
//  [/DB]: Проверка логина

// [DB]: Проверка каптчи
DefaValidator.prototype.custom3 = function(input) {
    var sid = input.form.captcha_sid.value;
    var code = input.value;
    try {
        var request = new XHR({method: 'get', async: false}).send('/defa/ajax/check_captcha?captcha_sid='+sid+'&code='+code);
        if (request.response.text.length>0) {
            try {
                var response = eval('(' + request.response.text + ')');
                if (!response.captcha) {
                    // выводим ошибку
                    document.getElementById('captcha_image').src = '/bitrix/tools/captcha.php?captcha_sid='+response.sid;
                    input.value = '';
                    input.form.captcha_sid.value = response.sid;
                    return false;
                }
            }
            catch (e) {
                // do nothing
            }

        }
    }
    catch (e) {
        // do nothing
    }
    return true;
}
// [/DB]: Проверка каптчи

// [DB]: Навороченая проверка мыла
DefaValidator.prototype.custom4 = function(input) {
    var form = input.form;
    var userId = input.form.uid.value;
    if (!this.reMail.test(input.value)) {
        errorMess = document.getElementById('email_error_wrong').innerHTML;
        var elem;
        for (var i in input.parentNode.childNodes) {
            elem = input.parentNode.childNodes[i];
            if (typeof(elem.className)!='undefined' && elem.className.indexOf('err') != -1) {
                input.parentNode.childNodes[i].innerHTML = errorMess;
                break;
            }
        }
        return false;
    }
    try {
        var request = new XHR({method: 'get', async: false}).send('/defa/ajax/check_email?email='+input.value+'&uid='+userId);
        if (request.response.text.length>0) {
            try {
                var response = eval('(' + request.response.text + ')');
                switch (response.email_error) {
                    case 'wrong_format':
                        var errorMess = document.getElementById('email_error_wrong').innerHTML;
                        var elem;
                        for (var i in input.parentNode.childNodes) {
                            elem = input.parentNode.childNodes[i];
                            if (typeof(elem.className)!='undefined' && elem.className.indexOf('err') != -1) {
                                input.parentNode.childNodes[i].innerHTML = errorMess;
                                break;
                            }
                        }
                        return false;
                    case 'busy':
                        var errorMess = document.getElementById('email_error_busy').innerHTML;
                        var elem;
                        for (var i in input.parentNode.childNodes) {
                            elem = input.parentNode.childNodes[i];
                            if (typeof(elem.className)!='undefined' && elem.className.indexOf('err') != -1) {
                                input.parentNode.childNodes[i].innerHTML = errorMess;
                                break;
                            }
                        }
                        return false;
                }
            }
            catch (e) {
                // do nothing
            }

        }
    }
    catch (e) {
        // do nothing
    }
    return true;
}
// [/DB]: Навороченая проверка мыла

DefaValidator.prototype.proto = function() {
}

var defaValidator = new DefaValidator();