/* @projectDescription jQuery Password Strength Plugin - A jQuery plugin to provide accessibility functions
 * @author Tane Piper (digitalspaghetti@gmail.com)
 * @version 2.0
 * @website: http://digitalspaghetti.me.uk/digitalspaghetti
 * @license MIT License: http://www.opensource.org/licenses/mit-license.php
 * 
 * === Changelog ===
 * Version 2.1 (18/05/2008)
 * Added a jQuery method to add a new rule: jQuery('input[@type=password]').pstrength.addRule(name, method, score, active)
 * Added a jQuery method to change a rule score: jQuery('input[@type=password]').pstrength.changeScore('one_number', 50);
 * Added a jQuery method to change a rules active state: jQuery('input[@type=password]').pstrength.ruleActive('one_number', false);
 * Hide the 'password to short' span if the password is more than the min chars
 * 
 * Version 2.0 (17/05/2008)
 * Completly re-wrote the plugin from scratch.  Plugin now features lamda functions for validation and
 * custom validation rules 
 * Plugin now exists in new digitalspaghetti. namespace to stop any conflits with other plugins.
 * Updated documentation
 * 
 * Version 1.4 (12/02/2008)
 * Added some improvments to i18n stuff from Raffael Luthiger.
 * Version 1.3 (02/01/2008)
 * Changing coding style to more OO
 * Added default messages object for i18n
 * Changed password length score to Math.pow (thanks to Keith Mashinter for this suggestion)
 * Version 1.2 (03/09/2007)
 * Added more options for colors and common words
 * Added common words checked to see if words like 'password' or 'qwerty' are being entered
 * Added minimum characters required for password
 * Re-worked scoring system to give better results
 * Version 1.1 (20/08/2007)
 * Changed code to be more jQuery-like
 * Version 1.0 (20/07/2007)
 * Initial version.
 */
/**
 * Changed password strength calculator. The following rules are now used to calculate strength score:
 * If the password is less than 4 characters then TooShortPassword
 *   * Score += password length * 4
 *   * Score -= repeated characters in the password ( 1 char repetition )
 *   * Score -= repeated characters in the password ( 2 char repetition )
 *   * Score -= repeated characters in the password ( 3 char repetition )
 *   * Score -= repeated characters in the password ( 4 char repetition )
 *   * If the password has 3 numbers then score += 5
 *   * If the password has 2 special characters then score += 5
 *   * If the password has upper and lower character then score += 10
 *   * If the password has numbers and characters then score += 15
 *   * If the password has numbers and special characters then score += 15
 *   * If the password has special characters and characters then score += 15
 *   * If the password is only characters then score -= 10
 *   * If the password is only numbers then score -= 10
 *   * If score > 100 then score = 100
 */

// Create our namespaced object
/*global window */
/*global jQuery */
/*global digitalspaghetti*/
window.digitalspaghetti = window.digitalspaghetti || {};
digitalspaghetti.password = {
    'defaults' : {
        'displayMinChar': true,
        'colors': ["#000", "#ee1c24", "#f7941d", "#f9e400", "#128f35"],
        'scores': [10, 30, 50, 68],
        'verdicts':    ['Weak', 'Ok', 'Good', 'Strong', 'Very Strong']
    },
    'validationRules': function (password) {
        var score = 0;

        if (password.length < 4) {
            return score
        }
        //password length
        score += password.length * 4
        score += ( digitalspaghetti.password.checkRepetition(1, password).length - password.length ) * 1
        score += ( digitalspaghetti.password.checkRepetition(2, password).length - password.length ) * 1
        score += ( digitalspaghetti.password.checkRepetition(3, password).length - password.length ) * 1
        score += ( digitalspaghetti.password.checkRepetition(4, password).length - password.length ) * 1

        //password has 3 numbers
        if (password.match(/(.*[0-9].*[0-9].*[0-9])/))  score += 5

        //password has 2 sybols
        if (password.match(/(.*[!,@,#,$,%,^,&,*,?,_,~].*[!,@,#,$,%,^,&,*,?,_,~])/)) score += 5

        //password has Upper and Lower chars
        if (password.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/))  score += 10

        //password has number and chars
        if (password.match(/([a-zA-Z])/) && password.match(/([0-9])/))  score += 15
        //
        //password has number and symbol
        if (password.match(/([!,@,#,$,%,^,&,*,?,_,~])/) && password.match(/([0-9])/))  score += 15

        //password has char and symbol
        if (password.match(/([!,@,#,$,%,^,&,*,?,_,~])/) && password.match(/([a-zA-Z])/))  score += 15

        //password is just a nubers or chars
        if (password.match(/^\w+$/) || password.match(/^\d+$/))  score -= 10


        return score

    },
    'checkRepetition': function (pLen, str) {
        res = ""
        for (i = 0; i < str.length; i++) {
            repeated = true
            for (j = 0; j < pLen && (j + i + pLen) < str.length; j++)
                repeated = repeated && (str.charAt(j + i) == str.charAt(j + i + pLen))
            if (j < pLen) repeated = false
            if (repeated) {
                i += pLen - 1
                repeated = false
            }
            else {
                res += str.charAt(i)
            }
        }
        return res
    },
    'attachWidget': function (element) {
        var output = ['<div id="password-strength">'];
        /*if (digitalspaghetti.password.options.displayMinChar && !digitalspaghetti.password.tooShort) {
         output.push('<span class="password-min-char">' + digitalspaghetti.password.options.minCharText.replace('%d', digitalspaghetti.password.options.minChar) + '</span>');
         }*/
        output.push('<p>Password strength: <span></span></p>');
        output.push('<span class="password-strength-bar"></span>');
        output.push('</div>');
        output = output.join('');
        jQuery(element).after(output);
    },
    'init': function (element, options) {
        digitalspaghetti.password.options = jQuery.extend({}, digitalspaghetti.password.defaults, options);
        digitalspaghetti.password.attachWidget(element);
        jQuery(element).keyup(function () {
            digitalspaghetti.password.calculateScore(jQuery(this).val());
        });
    },
    'calculateScore': function (word) {
        digitalspaghetti.password.totalscore = 0;
        digitalspaghetti.password.width = 0;
        var result = digitalspaghetti.password.validationRules(word);
        if (result) {
            digitalspaghetti.password.totalscore += result;
        }

        if (digitalspaghetti.password.totalscore <= digitalspaghetti.password.options.scores[0]) {
            digitalspaghetti.password.strColor = digitalspaghetti.password.options.colors[0];
            digitalspaghetti.password.strText = digitalspaghetti.password.options.verdicts[0];
            digitalspaghetti.password.width = "0";
        } else if (digitalspaghetti.password.totalscore > digitalspaghetti.password.options.scores[0] && digitalspaghetti.password.totalscore <= digitalspaghetti.password.options.scores[1]) {
            digitalspaghetti.password.strColor = digitalspaghetti.password.options.colors[1];
            digitalspaghetti.password.strText = digitalspaghetti.password.options.verdicts[1];
            digitalspaghetti.password.width = "52";
        } else if (digitalspaghetti.password.totalscore > digitalspaghetti.password.options.scores[1] && digitalspaghetti.password.totalscore <= digitalspaghetti.password.options.scores[2]) {
            digitalspaghetti.password.strColor = digitalspaghetti.password.options.colors[2];
            digitalspaghetti.password.strText = digitalspaghetti.password.options.verdicts[2];
            digitalspaghetti.password.width = "104";
        } else if (digitalspaghetti.password.totalscore > digitalspaghetti.password.options.scores[2] && digitalspaghetti.password.totalscore <= digitalspaghetti.password.options.scores[3]) {
            digitalspaghetti.password.strColor = digitalspaghetti.password.options.colors[3];
            digitalspaghetti.password.strText = digitalspaghetti.password.options.verdicts[3];
            digitalspaghetti.password.width = "156";
        } else {
            digitalspaghetti.password.strColor = digitalspaghetti.password.options.colors[4];
            digitalspaghetti.password.strText = digitalspaghetti.password.options.verdicts[4];
            digitalspaghetti.password.width = "208";
        }
        jQuery('.password-strength-bar').stop();

        if (digitalspaghetti.password.options.displayMinChar && !digitalspaghetti.password.tooShort) {
            jQuery('.password-min-char').hide();
        } else {
            jQuery('.password-min-char').show();
        }

        jQuery('.password-strength-bar').animate({opacity: 1}, 'fast', 'linear', function () {
            jQuery(this).css({'display': 'block', 'background-color': digitalspaghetti.password.strColor, 'width': digitalspaghetti.password.width + "px"});
            var className = (digitalspaghetti.password.strText).toLowerCase();
            className = className.split(" ").join("");
            jQuery(this).parent().find("p span").removeClass().addClass(className);
            jQuery(this).parent().find("p span").css("color", digitalspaghetti.password.strColor).text(digitalspaghetti.password.strText);
            jQuery(this).parent().slideDown();
        });
    }
}
        ;

jQuery.extend(jQuery.fn, {
    'pstrength': function (options) {
        return this.each(function () {
            digitalspaghetti.password.init(this, options);
        });
    }
});
jQuery.extend(jQuery.fn.pstrength, {
    'changeScore': function (rule, score) {
        digitalspaghetti.password.ruleScores[rule] = score;
        return true;
    },
    'ruleActive': function (rule, active) {
        digitalspaghetti.password.rules[rule] = active;
        return true;
    }
});