
"use strict";
/**
 * Bind triggers to field inputs
 * @returns {undefined}
 */

var validationFields = {};
/**
 * Validate form
 *
 * Call this function from jQuery bind "submit" and send in event, ex:
 * $('#form-register').submit(function(e){ validateForm(e); });
 *
 * @param {object} event - the jquery submitEvent
 * @returns {Boolean}
 */
function validateForm(event)
{
    /* var alerts = ''; */
    var currentFormId = $(event.currentTarget).attr('id');
    //-- Validate input fields having data-validation set
    $('#' + currentFormId + ' input[data-validation]').each(function() {
        validateField(currentFormId, $(this));
    });

    if ($('#g-recaptcha').length && typeof(validateGReCaptcha) === 'function') {
        if (!validateGReCaptcha()) {
            $('#g-recaptcha').focus();
            alert('Du måste validera dig via reCAPTCHA');
            event.preventDefault();
            return false;
        }
    }

    //-- Check if validation is complete
    if (checkValidation(currentFormId) === false) {
        //-- Remove old validations
        $('.alert-validation').remove();
        $('.has-error:first input:first').focus();
        event.preventDefault();
        return false;
    } else {
        return true;
    }

}

/**
 * Validate Google ReCaptcha
 * @return boolean
 */
function validateGReCaptcha()
{
    if (!isRecaptchaLoaded()) {
        if ($('#use_email_verification').length && $('#use_email_verification').val() === 'true'){
            validationFields['recaptcha'] = true;
            return true;
        }
    } else {
        $('#use_email_verification').remove();
    }

    if (isReCaptchaValid()) {
        $('.form-recaptcha').removeClass('has-error has-feedback');
        validationFields['recaptcha'] = true;
        return true;
    } else {
        $('.form-recaptcha').addClass('has-error has-feedback');
        return false;
    }
}

/**
 * Callback for success recaptcha
 * @returns {undefined}
 */
function grecatpchaCallback() {
    $('.form-recaptcha').removeClass('has-error has-feedback');
    validationFields['recaptcha'] = true;
    checkValidation();
}

/**
 * Validation of field
 * @argument {string} currentFormId id of the form that contains the field being validated
 * @htmlElemet data-validation = validation type (string, email, password, checkbox, username)
 * @htmlElemet data-validation-confirm = validation confirm field (ex password and confirm password)
 * @htmlElemet data-validation-option = option for the selected validation (like min lenght for string-validation)
 *
 * @param {type} field
 * @returns {Boolean}
 */
function validateField(currentFormId, field)
{
    var error = false;
    var validationType = field.data('validation');
    var labelalert = false; //-- if field is using labal with alerts for validation visualization

    //-- Check if fields is a confirm field, (meaning a fields value should be the same as another field (reenter password f.ex.))
    if (field.data('validation-confirm') !== undefined) {
        if (field.val() === '' || field.val() !== $('input[name="' + field.data('validation-confirm') + '"]').val()) {
            var fieldToConfirm = $('input[name="' + field.data('validation-confirm') + '"]');

            var fieldToConfirmLabel = $('label[for="' + field.data('validation-confirm') + '"]');
            error = [{type: 'validation-confirm', message: 'Fältet matchar inte \"%label%\"'.replace('%label%', fieldToConfirmLabel.html())}];
        }
    } else { //-- Do standard validation
        switch (validationType) {
            case 'string': //-- Simple !empty or minlength validation
                if (field.val() === '') {
                    error = [{type: 'string'}];
                    break;
                }
                var options = field.data('validation-option');
                if ((options !== undefined) && (!isNaN(options))) {
                    if (field.val().length < options) {
                        error = [{type: 'string'}];
                        break;
                    }
                }
                break;
            case 'checkbox': //-- Checkbox validation
                labelalert = true;
                if (!field.prop('checked')) {
                    error = [{type: 'checkbox'}];
                }
                break;
            case 'password':
                if (field.val() === '') {
                    error = [{type: 'password', message: 'Ditt lösenord måste innehålla minst 6 tecken. '}];
                    break;
                }
                if (field.val().length < 6) {
                    error = [{type: 'password', message: 'Ditt lösenord måste innehålla minst 6 tecken. '}];
                    break;
                }
                break;
            case 'email':
                /* This is a "dumb" check for valid email, if you need to confirm that email is
                 * NOT already in use - use type username below */
                if (field.val() === '') {
//                    error = true;
                    error = [{type: 'email', message: 'Epostadressen är felaktig!'}];
                    break;
                }
                var acceptedEmailPattern = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
                if (acceptedEmailPattern.test(field.val()) === false) {
//                    error = true;
                    error = [{type: 'email', message: 'Epostadressen är felaktig!'}];
                }
                break;
            case 'username':
                var acceptedEmailPattern = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
//                error = false;
                if (acceptedEmailPattern.test(field.val()) === false) {
//                    error = true;
                    error = [{type: 'username', message: 'Epostadressen är felaktig!'}];
                    break;
                }
                /*username seems to be an ok email, now check if it's unused.
                 Should really not use /register/validatefield/ but a more general module */
                $.ajax({
                    type: 'POST',
                    url: '/register/validatefield/',
                    data: {field: 'username', data: '{"username":"' + field.val().trim() + '"}'},
                    success: function(data) {
                        if (data.status === 'error') {
//                            error = true;
                            error = [{type: 'username', message: 'E-post finns redan'}];
                        }
                    },
                    dataType: 'json',
                    async: false
                });
                break;
        }

        //-- Check if field has a confirm field, if it has, make fieldvalidation
        $('#' + currentFormId + ' input[data-validation-confirm]').each(function() {
            if ($(this).data('validation-confirm') === field.attr('name')) {
                if ($(this).val() !== '') {
                    validateField(currentFormId, $(this));
                }
            }
        });
    }

    //-- Remove all icons from field
    field.parent().find('i').remove();

    //-- If error
    if (error) {
        field.closest('.form-group').addClass('has-error has-feedback').removeClass('has-success');
        field.after('<i class="fa fa-remove form-control-feedback"></i>');

        if (labelalert) {
            field.closest('label').removeClass('alert-success alert-default');
            field.closest('label').addClass('alert-danger');
            field.closest('label').fadeTo('fast', 0.5).fadeTo('fast', 1.0);
        }

        field.closest('.form-group').find('.error-message').remove();

        $.each(error, function(k, v) {
            if (v.message) {
                field.after('<div class="alert alert-danger error-message mt-xs">' + v.message + '</div>');
            }
        });


        //-- If sucesss
    } else {
        field.closest('.form-group').addClass('has-success has-feedback').removeClass('has-error');
        field.closest('.form-group').find('.error-message').remove();
        field.after('<i class="fa fa-check form-control-feedback"></i>');

        if (labelalert) {
            field.closest('.form-group').removeClass('has-error has-feedback');
            field.closest('label').removeClass('alert-danger alert-default');
            field.closest('label').addClass('alert-success');
        }
    }

    //-- Set global form valid to true/false
    if (typeof validationFields[currentFormId] == 'undefined') {
        validationFields[currentFormId] = [];
    }

    if (error) {
        validationFields[currentFormId][field.attr('id')] = false;
    } else {
        validationFields[currentFormId][field.attr('id')] = true;
    }
    //-- Check if validation is complete
    checkValidation(currentFormId);
    return error;
}

/**
 * @param {string} currentFormId Id if the form being validated
 * Check if validation is complete
 * @returns boolean
 */
function checkValidation(currentFormId)
{
    var errors = false;
    $.each(validationFields[currentFormId], function(j, val) {
        if (val === false) {
            errors = true;
        }
    });
    if (!errors) {
        $('.alert-validation').remove();
    }
    if (errors) {
        return false;
    } else {
        return true;
    }
}

function addFormFieldValidators()
{
    //Loop all forms to group validationsFields
    var formFieldId = '';
    $('form').each(function() {
        formFieldId = $(this).attr('id');
        if (typeof validationFields[formFieldId] === "undefined") {
            validationFields[formFieldId] = {};
        }
        //-- Loop each validation field
        $('#' + formFieldId + ' input[data-validation]').each(function() {
            var validationElement = $(this);
            $(this).change(function() {

                var errors = validateField(formFieldId, $(this));

                //-- Allways remove erlier messages
                validationElement.closest('.form-group').find('.error-message').remove();

                if (errors) {
                    $.each(errors, function(k, v) {
                        var errorMessage = null;
                        if (v.message) {
                            errorMessage = v.message;
                        }
                        if (errorMessage) {
                            validationElement.after('<div class="alert alert-danger error-message mt-xs">' + errorMessage + '</div>');
                        }
                    });
                }

            });
            validationFields[formFieldId][$(this).attr('id')] = false;
        });
    });
}


$(function() {

    $('form input.check-password-strength').on('input change onpropertychange', function() {
        var password = $(this).val();
        if (password.length < 6) {
            $('.check-password-strength-result').closest('.check-password-strength-result').html(
                    '<div class="progress">' +
                    '<div title="För kort" class="progress-bar  progress-bar-danger" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%;">' +
                    'För kort</div>' +
                    '</div>');
            return false;
        }

        var pwStrength = checkPasswordStrength(password);
        if (pwStrength < 2) {
            // $('.check-password-strength-result').closest('.check-password-strength-result').html('Svagt');
            $('.check-password-strength-result').closest('.check-password-strength-result').html(
                    '<div class="progress">' +
                    '<div title="Svagt" class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100" style="width: 50%;">' +
                    'Svagt</div>' +
                    '</div>');

        }
        if (pwStrength === 2) {
            //  $('.check-password-strength-result').closest('.check-password-strength-result').html('Bra');
            $('.check-password-strength-result').closest('.check-password-strength-result').html(
                    '<div class="progress">' +
                    '<div title="Bra" class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100" style="width: 50%;">' +
                    'Bra</div>' +
                    '</div>');
        }
        if (pwStrength > 2) {
            //$('.check-password-strength-result').closest('.check-password-strength-result').html('Starkt');
            $('.check-password-strength-result').closest('.check-password-strength-result').html(
                    '<div class="progress">' +
                    '<div title="Starkt" class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%;">' +
                    'Starkt</div>' +
                    '</div>');
        }

    });


});




/**
 * Builds upon: http://code.runnable.com/UfJrnXtk2tZXAAA1/how-to-check-password-strength-using-jquery
 * @param {String} password
 * @returns {Number} < 2 = weak, 2 = good, > 2 = strong. Max = 5
 */
function checkPasswordStrength(password)
{
    /* initial strength */
    var strength = 0;
    /* if length is 8 characters or more, increase strength value */
    if (password.length > 7) {
        strength += 1;
    }
    /* if password contains both lower and uppercase characters, increase strength value */
    if (password.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/)) {
        strength += 1;
    }
    /* if it has numbers and characters, increase strength value */
    if (password.match(/([a-zA-Z])/) && password.match(/([0-9])/)) {
        strength += 1;
    }
    /* if it has one special character, increase strength value */
    if (password.match(/([!,%,&,@,#,$,^,*,?,_,~])/)) {
        strength += 1;
    }
    /* if it has two special characters, increase strength value */
    if (password.match(/(.*[!,%,&,@,#,$,^,*,?,_,~].*[!,%,&,@,#,$,^,*,?,_,~])/)) {
        strength += 1;
    }
    return strength;
}

