$.validator.messages.required = Translator.trans('cs_common_base.form.messages.errors.required');
$.validator.messages.email = Translator.trans('cs_common_base.form.messages.errors.email');
$.validator.messages.url = Translator.trans('cs_common_base.form.messages.errors.url');
$.validator.messages.minlength = Translator.trans('cs_common_base.form.messages.errors.minlength');
$.validator.messages.maxlength = Translator.trans('cs_common_base.form.messages.errors.maxlength');

//$.validator.messages.url = Translator.trans('cs_common_base.form.messages.errors.date');
//$.validator.messages.url = Translator.trans('cs_common_base.form.messages.errors.number');
//$.validator.messages.url = Translator.trans('cs_common_base.form.messages.errors.digits');
//$.validator.messages.url = Translator.trans('cs_common_base.form.messages.errors.minlength');
//$.validator.messages.url = Translator.trans('cs_common_base.form.messages.errors.maxlength');
//$.validator.messages.url = Translator.trans('cs_common_base.form.messages.errors.rangelength');
//$.validator.messages.url = Translator.trans('cs_common_base.form.messages.errors.max');
//$.validator.messages.url = Translator.trans('cs_common_base.form.messages.errors.min');

$.validator.addMethod("maxlength", function(value, element) {

    var max = parseInt($(element).attr('maxlength'));

    if (max > 0) {
        value = $.trim(value);
        var text = $(element).is('textarea') ? value.replace( /<.*?>|\n/g, '' ) : value;

        if (text.length > max) {
            return false;
        }
    }

    return true;
});

var FormValidation = (function($) {
    'use strict';

    function FormValidation() {
        SignalsAbstract.call(this);

        this.form = null;
        this.successElement = null;
        this.errorElement = null;
        this.ignoreValues = null;
        this.tabClass = null;
        this.nextSelector = null;
        this.previousSelector = null;
        this.onNext = null;
        this.onPrevious = null;
        this.onTabClick = null;
        this.onTabShow = null;
        this.bootstrapWizard = null;
        this.hiddenErrorMessage = null;
        this.validateHidden = null;
        this.onfocusout = null;
        this.doNotHideMessage = null;
        this.errorValidationElement = null;
        this.errorClass = null;
        this.focusInvalid = null;
        this.errorPlacement = null;
        this.invalidHandler = null;
        this.highlight = null;
        this.unhighlight = null;
        this.success = null;
        this.ignoreValues = null;
    }

    FormValidation.prototype = Object.create(SignalsAbstract.prototype);

    FormValidation.prototype.constructor = FormValidation;

    FormValidation.prototype.constants = {
        'ON_CHANGE' : 'onChange',
        'AFTER_VALIDATE' : 'afterValidate'
    };

    /**
     * Initialize the FormValidation Library
     *
     * @param {string|HTMLElement} [selector]
     * @param {object} [options]
     */
    FormValidation.prototype.init = function(selector, options) {
        this.form = $(selector);
        this.initSignals();
        this.parseOptions(options);
        this.initFormWizard();
        this.initValidation();
        this.addValidationRulesToCkEditor();
    };

    FormValidation.prototype.parseOptions = function(options) {
        var $this = this;
        var defaults = {
            'successElement' : $('.alert-danger', this.form),
            'errorElement' : $('.alert-success', this.form),
            'ignoreValues' : '', //':hidden'
            'tabClass' : '',
            'nextSelector': '[data-btn-type="continue"]',
            'previousSelector': '[data-btn-type="back"]',
            'stepElement' : '[data-action="tab"]',
            'onTabClick' : function(tab, navigation, index) {
            },
            'onNext' : function(tab, navigation, index) {
                $this.successElement.hide();
                $this.errorElement.hide();

                $this.refreshWizardPosition(tab, navigation, index);
            },
            'onPrevious' :  function (tab, navigation, index) {
                $this.successElement.hide();
                $this.errorElement.hide();

                $this.refreshWizardPosition(tab, navigation, index);
            },
            'onTabShow': function (tab, navigation, index) {
                var total = navigation.find('li').length;
                var current = index + 1;
                var $percent = (current / total) * 100;

                $('#form-wizard').find('.progress-bar').css({
                    width: $percent + '%'
                });

                $this.refreshWizardPosition(tab, navigation, index);
                $this.events.onChange.dispatch(tab, navigation, index);
            },
            'onfocusout': false,
            'doNotHideMessage' : true,
            'errorValidationElement': 'span',
            'errorClass': 'help-block help-block-error',
            'focusInvalid': false,
            'errorPlacement': function(error, element) {
                if( element.parents('.input-daterange-container:first').length > 0 ) {
                    if( !element.parents('.input-daterange-container:first').next().hasClass('help-block-error')) {
                        error.insertAfter(element.parents('.input-daterange-container:first'));
                    }
                } else if( element.parents('.radio-list:first').length > 0) {
                    if( !element.parents('.radio-list:first').next().hasClass('help-block-error')) {
                        error.insertAfter(element.parents('.radio-list:first'));
                    }
                } else if( element.parents('.checkbox-list:first').length > 0) {
                    if( !element.parents('.checkbox-list:first').next().hasClass('help-block-error')) {
                        element.parents('.checkbox-list:first').append(error);
                    }
                } else {
                    if (element.hasClass("select2-offscreen") === true) {
                        error.text($.validator.messages.required);
                        element.attr("title", $.validator.messages.required);
                    }
                    error.insertAfter(element);
                }
            },
            'invalidHandler': function(event, validator) {
                $this.successElement.hide();
                $this.errorElement.hide();
                $this.parseErrors(validator.errorList);

                if ($this.validateHidden) {
                    validator.currentElements.each(function(k,v){
                       if ($(v).prop('type') == 'hidden') {
                           showToastrNotification('error', $this.hiddenErrorMessage);
                       }
                    });
                }
            },
            'highlight': function(element) {
                $(element)
                        .closest('.form-group').removeClass('has-success').addClass('has-error');
            },
            'unhighlight': function(element) {
                $(element)
                    .closest('.form-group')
                    .removeClass('has-error');
            },
            'success' : function(label) {
                if (label.attr("for") == "gender" || label.attr("for") == "payment[]") {
                    label
                        .closest('.form-group').removeClass('has-error').addClass('has-success');
                    label.remove();
                } else {
                    label
                        .addClass('valid')
                        .closest('.form-group').removeClass('has-error').addClass('has-success');
                }
            }
        };

        options = $.extend(defaults, options);

        for(var key in options) {
            if(key === this.constants.ON_CHANGE || key === this.constants.AFTER_VALIDATE) {
                this.addHandler(key, options[key]);
            } else {
                this[key] = options[key];
            }
        }
    };

    FormValidation.prototype.initSignals = function() {
        this.events[this.constants.ON_CHANGE] = new signals.Signal();
        this.events[this.constants.AFTER_VALIDATE] = new signals.Signal();
    };

    FormValidation.prototype.initFormWizard = function() {

        this.form.bootstrapWizard({
            'nextSelector': this.nextSelector,
            'previousSelector': this.previousSelector,
            'onNext' : this.onNext,
            'onPrevious' : this.onPrevious,
            'onTabShow' : this.onTabShow,
            'onTabClick' : this.onTabClick,
            'tabClass' : this.tabClass
        });

        this.bootstrapWizard = this.form.data('bootstrapWizard');
    };

    FormValidation.prototype.initValidation = function() {
        this.form.validate({
            'submitHandler' : this.submitHandler.bind(this),
            'onfocusout': this.onfocusout,
            'doNotHideMessage': this.doNotHideMessage,
            'errorElement': this.errorValidationElement,
            'errorClass': this.errorClass,
            'focusInvalid': this.focusInvalid,
            'errorPlacement': this.errorPlacement,
            'invalidHandler': this.invalidHandler,
            'highlight': this.highlight,
            'unhighlight': this.unhighlight,
            'success': this.success,
            'ignore': this.ignoreValues
        });
    };

    FormValidation.prototype.setHiddenErrorMessage = function(hiddenErrorMessage) {
        hiddenErrorMessage = typeof hiddenErrorMessage !== 'undefined' ? '' : hiddenErrorMessage;

        this.hiddenErrorMessage = hiddenErrorMessage;
    };

    FormValidation.prototype.setValidateHidden = function(validateHidden) {
        validateHidden = typeof validateHidden !== 'undefined' ? false : validateHidden;

        this.validateHidden = !!validateHidden;
    };

    FormValidation.prototype.setIgnoreValues = function(ignoreValues) {
        ignoreValues = typeof ignoreValues !== 'undefined' ? false : ignoreValues;

        this.ignoreValues = ignoreValues;
    };

    FormValidation.prototype.submitHandler = function(form, event) {
        event.preventDefault();
        $('.alert-danger').remove();
        $('li.error').removeClass('error');

        var success = true,
            $this = this,
            elements = $this.form.serializeArray(),
            otherElements = $('select, input[type="checkbox"], textarea, [data="asset"]');

        if(otherElements.length > 0) {
            otherElements = [].map.call(otherElements, function(element) {return { name: $(element).attr('name'), value: $(element).val() }});
            elements = $.merge(elements, otherElements);
        }


        $.each(elements, function(key, field) {
            if( typeof field.name !== 'undefined' && field !== null) {
                success = $this.checkField(field);
            }

            return success;
        });

        if (!success) {
            return false;
        }

        $('button[type="submit"]', $this.form).prop('disabled', true);

        form.submit();
    };

    /**
     * Get the field and returns if it is valid
     *
     * @param {Array} formField
     * @returns {boolean}
     */
    FormValidation.prototype.checkField = function(formField) {
        var success = true;
        var field = $('[name="'+formField.name+'"]');

        if (!field.valid()) {
            var tab = field.parents('.tab-pane');
            var tabId = tab.parents('.tab-pane').length ? tab.parents('.tab-pane').attr('id') : tab.attr('id');

            if (tabId) {
                $('[href="#'+tabId+'"]').tab('show');

            }
            success = false;
        }

        return success;
    };

    /**
     * Adds required rule for jquery validation plugin because CKEDITOR remove required attribute.
     */
    FormValidation.prototype.addValidationRulesToCkEditor = function() {
        if(typeof CKEDITOR !== 'undefined') {
            CKEDITOR.on('instanceReady', function(event) {
                var domElement = $(event.editor.element.$);

                if(domElement.data('required') === 'required') {
                    domElement.rules('add', {'required' : true});
                }
            });
        }
    };

    FormValidation.prototype.refreshWizardPosition = function(tab, navigation, index) {

        var current = index + 1;
        $('.current-step').text(current);

        $('li', this.form).removeClass("done");
        var li_list = navigation.find('li');
        for (var i = 0; i < index; i++) {
            $(li_list[i]).addClass("done");
        }

        Metronic.scrollTo($('.page-title'));
    };

    FormValidation.prototype.parseErrors = function(errorList) {
        $('.alert-danger').remove();
        $('li.error').removeClass('error');
        var firstError = false,
            bindGoToError = function(errorText, errorElement, errorContainer){
                $('<li>'+errorText+'</li>').on('click', function() {
                    //Metronic.scrollTo(errorElement.closest('.form-group'));
                    $('[data-role="c-main-container"]').animate({scrollTop: errorElement.closest('.form-group').offset().top}, 400);
                }).appendTo(errorContainer);
            };

        for(var error in errorList) {
            console.log(this.stepElement);
            var errorElement = $(errorList[error].element),
                stepElement = errorElement.closest(this.stepElement),
                step = stepElement.attr('id'),
                tabElement = $('a[href="#'+step+'"]'),
                tab = tabElement.closest('li');

            if(!firstError) {
                firstError = true;
                tabElement.trigger('click');
                // Metronic.scrollTo(errorElement.closest('.form-group'));
                $('[data-role="c-main-container"]').animate({scrollTop: errorElement.closest('.form-group').offset().top}, 400);
            }

            if(!tab.hasClass('error')) {
                tab.addClass('error');
            }

            var errorText = $('label', $(errorElement).closest('.form-group')).first().text().replace('*', '');
            if(errorText !== '') {
                var errorContainer = $('.alert-danger', stepElement);
                if(errorContainer.length < 1) {
                    errorContainer = $('<ul class="form-steps alert-danger"></ul>').prependTo(stepElement);
                    $('<li class="msg">'+Translator.trans('cs_core.wizard.validation.message')+'</li>').appendTo(errorContainer);
                }
                bindGoToError(errorText, errorElement, errorContainer);
            }
        }
    };

    FormValidation.prototype.enableStep = function(step) {
        var tabs = $('[data-tab] a', '#form-wizard'),
            element = tabs.eq(step-1);

        element.attr('data-toggle', 'tab');
        element.closest('li').removeClass('disabled');
        $('[data-btn-type="continue"]').removeClass('disabled');
    };

    FormValidation.prototype.disableStep = function (step) {
        var element = $('[data-tab] a', '#form-wizard').eq(step-1);
        element.removeAttr('data-toggle');
        element.closest('li').addClass('disabled');
    };

    return FormValidation;

}(jQuery));


jQuery.fn.CSFormValidation = function(options) {
    this.each(function() {
        var formValidation = new FormValidation();
        $(this).data('cs-form-validation', formValidation);
        formValidation.init(this, options);
    });

    return this;
};
