/* jQuery Password Strength Plugin (PStrength) - A jQuery plugin to provide accessibility functions
 * Author: Tane Piper (digitalspaghetti@gmail.com) 
 * Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php
 * This code uses a modified version of Steve Moitozo's algorithm (http://www.geekwisdom.com/dyn/passwdmeter)
 * Modified by Chris Ellingsworth (abezydar@gmail.com)
 */
(function($){
	$.PStrength = $.PStrength || {}
	// Create object containing project details
	$.PStrength.codedetails = {
		version: "1.3b",		
		licenceType: "MIT",
		licenceURL: "http://www.opensource.org/licenses/mit-license.php"
	};

	/**
	* $.fn.PStrength.defaults
	* These are the default values that can be overidden
	*/
	$.PStrength.defaults = {
		verdicts:	["Unsafe Password!","Too Short","Very Weak","Weak","Good","Great","Excellent!"],		
		acceptableIndex: 4,
		barWidths:  ["1%","1%","1%","64px","102px","165px","254px"],
		colors: 	["#c00","#c00","#c00","#c06", "#f60","#9c3","#3c0"],
		minCharMsg:	"The minimum number of characters is",		
		scores: 	[0,10,15,30,40],
		powMax: 	1.4,
		common:		["password","password1","123456","123","liverpool","letmein","qwerty","monkey","asdfasdf"],
		minChar:	8,
		displayMin: false
	};

    $.PStrength.usernameObj = null;
    $.PStrength.passwordObj = null;
	/** @name pstrength
	* @var mixed options An object of options
	* @returns object jQuery Returns the output to the screen
	*/
	$.PStrength.init = function(el, options) {
		// Take the passed options and merge with default options
		var options = $.extend({}, $.PStrength.defaults, options);
		
		$.PStrength.passwordObj = el;
		
		// Main logic
		// Check to see if any options have been attached as expandos
		var o = $.meta ? $.extend({}, options, $(el).data()) : options;
		// Get the ID of the password field
		var infoarea = $(el).attr('id');
		// Check to see if we should display the minimum number of characters
		if (o.displayMin) {
			$(el).after('<div class="pstrength-minchar" id="' + infoarea + '_minchar">' +  options.minCharMsg +' '+ o.minChar + '</div>');
		}
		// Add in the text to show the bar and text		
		//$(el).parent().after('<div class="pstrength"><div class="pstrength-bar" id="' + infoarea + '_bar" style="overflow:hidden; height: 4px; width: 0px;"></div><div class="pstrength-info" id="' + infoarea + '_text"></div></div>');
		
		$.PStrength.usernameObj = $(".username").get(0);

		// Check the password on each KeyUp
		$(el).keyup(function(){
			$.PStrength.runPassword($(this).val(), 'pstrength', o);
		});
	};
	$.PStrength.runPassword = function (p, id, o){
       	// Check password
		nPerc = $.PStrength.checkPassword(p,o);
		
		// Color and text
		if (nPerc == -200) $.PStrength.setMessage(0,o,id);		
		else if (nPerc < 0 && nPerc > -199) $.PStrength.setMessage(1,o,id);
		else if(nPerc <= o.scores[1]) $.PStrength.setMessage(2,o,id);
		else if (nPerc > o.scores[1] && nPerc <= o.scores[2]) $.PStrength.setMessage(3,o,id);
		else if (nPerc > o.scores[2] && nPerc <= o.scores[3]) $.PStrength.setMessage(4,o,id);
		else if (nPerc > o.scores[3] && nPerc <= o.scores[4]) $.PStrength.setMessage(5,o,id);
		else $.PStrength.setMessage(6,o,id);
		
	}
	$.PStrength.setMessage = function(i,o,id){
	    // Get controls
	   	var ctlBar = "#" + id + "_bar";
	   	var ctlText = "#" + id + "_text";
	   	
	   	strColor = o.colors[i];
	    strText = o.verdicts[i];
		$(ctlBar).css({width: o.barWidths[i]});
		
		// Style text for an error if unacceptable
		var errorClass = (i>=o.acceptableIndex) ? "" : " class='error'";
		
		// Change bar color and text
		$(ctlBar).css({backgroundColor: strColor});
		$(ctlText).html("<span" + errorClass +" style='color: " + strColor + ";'>" + strText + "</span>");
		
		if (i>=o.acceptableIndex){ // Clear any errors that are visible
		    $p = $($.PStrength.passwordObj);		    
		    $p.parent().get(0).className="input";
		    $p.parent().parent().find(".error").hide();		   
		}	
		
	}
	$.PStrength.checkPassword = function(p, o)
	{
		var intScore = 0;
		// PASSWORD LENGTH
		intScore = Math.pow(p.length, o.powMax);
		if (p.length < o.minChar)                         // Password too short
		{
			intScore = (intScore - 100)
		}
		// CHARACTER CLASSES
		if (p.match(/[a-z]/)) intScore += 1;
		if (p.match(/[A-Z]/)) intScore += 5;
		if (p.match(/\d+/)) intScore += 5;
		if (p.match(/(.*[0-9].*[0-9].*[0-9])/)) intScore += 5;
		if (p.match(/.[!,@,#,$,%,^,&,*,?,_,~]/)) intScore += 5;
		if (p.match(/(.*[!,@,#,$,%,^,&,*,?,_,~].*[!,@,#,$,%,^,&,*,?,_,~])/)) intScore += 5;
		if (p.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/)) intScore += 2;
		if (p.match(/([a-zA-Z])/) && p.match(/([0-9])/)) intScore += 2;
		if (p.match(/([a-zA-Z0-9].*[!,@,#,$,%,^,&,*,?,_,~])|([!,@,#,$,%,^,&,*,?,_,~].*[a-zA-Z0-9])/)) intScore += 2;
		var username = $.PStrength.usernameObj.value;
		username = (username.length==0) ? "" : username.toLowerCase();
		for (var i=0; i < o.common.length; i++) {
			if (p.toLowerCase() == o.common[i] || (p.toLowerCase()==username && username!="")) {
				intScore = -200;
				break;
			}
		}
		return intScore;
	}
	$.fn.pstrength = function(options) {
		return this.each(function(){
			new $.PStrength.init(this, options);
	 	});
	}
})(jQuery);
