/* ************************************************************
Created: 20060120
Author:  Steve Moitozo <god at zilla dot us>
Description: This is a quick and dirty password quality meter 
		 written in JavaScript so that the password does 
		 not pass over the network.


Password Strength Factors and Weightings

password length:
level 0 (3 point): less than 4 characters
level 1 (6 points): between 5 and 7 characters
level 2 (12 points): between 8 and 15 characters
level 3 (18 points): 16 or more characters

letters:
level 0 (0 points): no letters
level 1 (5 points): all letters are lower case
level 2 (7 points): letters are mixed case

numbers:
level 0 (0 points): no numbers exist
level 1 (5 points): one number exists
level 1 (7 points): 3 or more numbers exists

special characters:
level 0 (0 points): no special characters
level 1 (5 points): one special character exists
level 2 (10 points): more than one special character exists

combinatons:
level 0 (1 points): letters and numbers exist
level 1 (1 points): mixed case letters
level 1 (2 points): letters, numbers and special characters 
					exist
level 1 (2 points): mixed case letters, numbers and special 
					characters exist


NOTE: Because I suck at regex the code below is incomplete and 
	  does not accurately assess the intScore of passwords 
	  according to the above factors and weightings
	  
NOTE: Instead of putting out all the logging information,
	  the score, and the verdict it would be nicer to stretch
	  a graphic as a method of presenting a visual intScore
	  guage.

************************************************************ */
var getStrength = function(password) {
		var intScore   = 0
		var strVerdict = "weak"
		var strLog     = ""
		
		// PASSWORD LENGTH
		if (password.length<5)                         // length 4 or less
		{
			intScore = (intScore+3)
			strLog   = strLog + "3 points for length (" + password.length + ")\n"
		}
		else if (password.length>4 && password.length<8) // length between 5 and 7
		{
			intScore = (intScore+6)
			strLog   = strLog + "6 points for length (" + password.length + ")\n"
		}
		else if (password.length>7 && password.length<16)// length between 8 and 15
		{
			intScore = (intScore+12)
			strLog   = strLog + "12 points for length (" + password.length + ")\n"
		}
		else if (password.length>15)                    // length 16 or more
		{
			intScore = (intScore+18)
			strLog   = strLog + "18 point for length (" + password.length + ")\n"
		}
		
		
		// LETTERS (Not exactly implemented as dictacted above because of my limited understanding of Regex)
		if (password.match(/[a-z]/))                              // [verified] at least one lower case letter
		{
			intScore = (intScore+1)
			strLog   = strLog + "1 point for at least one lower case char\n"
		}
		
		if (password.match(/[A-Z]/))                              // [verified] at least one upper case letter
		{
			intScore = (intScore+5)
			strLog   = strLog + "5 points for at least one upper case char\n"
		}
		
		// NUMBERS
		if (password.match(/\d+/))                                 // [verified] at least one number
		{
			intScore = (intScore+5)
			strLog   = strLog + "5 points for at least one number\n"
		}
		
		if (password.match(/(.*[0-9].*[0-9].*[0-9])/))             // [verified] at least three numbers
		{
			intScore = (intScore+5)
			strLog   = strLog + "5 points for at least three numbers\n"
		}
		
		
		// SPECIAL CHAR
		if (password.match(/.[!,@,#,$,%,^,&,*,?,_,~]/))            // [verified] at least one special character
		{
			intScore = (intScore+5)
			strLog   = strLog + "5 points for at least one special char\n"
		}
		
																 // [verified] at least two special characters
		if (password.match(/(.*[!,@,#,$,%,^,&,*,?,_,~].*[!,@,#,$,%,^,&,*,?,_,~])/))
		{
			intScore = (intScore+5)
			strLog   = strLog + "5 points for at least two special chars\n"
		}
	
		
		// COMBOS
		if (password.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/))        // [verified] both upper and lower case
		{
			intScore = (intScore+2)
			strLog   = strLog + "2 combo points for upper and lower letters\n"
		}

		if (password.match(/(\d.*\D)|(\D.*\d)/))                    // [FAILED] both letters and numbers, almost works because an additional character is required
		{
			intScore = (intScore+2)
			strLog   = strLog + "2 combo points for letters and numbers\n"
		}
 
																  // [verified] letters, numbers, and special characters
		if (password.match(/([a-zA-Z0-9].*[!,@,#,$,%,^,&,*,?,_,~])|([!,@,#,$,%,^,&,*,?,_,~].*[a-zA-Z0-9])/))
		{
			intScore = (intScore+2)
			strLog   = strLog + "2 combo points for letters, numbers and special chars\n"
		}

    if(password.length == 0)
    {
       strVerdict = ""
    }
    else if(intScore < 16)
    {
       strVerdict = "WEAK"
    }
    else if (intScore > 15 && intScore < 25)
    {
       strVerdict = "MEDIUM"
    }
    else if (intScore > 24 && intScore < 35)
    {
       strVerdict = "GOOD"
    }
    else if (intScore > 34 && intScore < 45)
    {
       strVerdict = "STRONG"
    }
    else
    {
       strVerdict = "BEST"
    }

  return {score: intScore, verdict: strVerdict, log: strLog};	
}

var updateStrength = function(password) {

  var strength = getStrength(password);	
  var bar = $("strengthMeter").select("div.bar")[0];
  var label = $("strengthMeter").select("div.text")[0];

  if(!password) Element.hide("strengthMeter");
  else {
    label.innerHTML = strength.verdict;
    Element.show("strengthMeter");
    var width = (100/50)*strength.score;
    new Effect.Morph(bar, {style:'width:'+width+'px', duration:'0.4'}); 
	  //userForm.matchlog.value = (strLog)
	}
}

