PasswordStrength = function(param)
{
	this.init(param);
}

PasswordStrength.prototype = {
	
	debug				: false,
	min_length			: 6,		// minimum number of chars in password
	password_field		: null,		// password text field
	username_field		: null,		// username text field
	username			: null,		// actual username instead of a text field
	bar					: null,		// bar html element
	text				: null,		// text element
	messages			: null,		// messages for text element
	classNames			: ['weak', 'good', 'secure', 'verysecure'],
	classContainer		: null,		// containing element for meter - if present add class names
	
	password			: '',		// password text
	percent				: 0,
	
	
	init : function(param)
	{
		param				= param || {};
		this.min_length		= param.min_length || this.min_length;
		this.password_field	= document.getElementById(param.password_field);
		this.username_field	= param.username_field ? document.getElementById(param.username_field) : null;
		this.username		= param.username;
		this.classContainer	= param.container ? document.getElementById(param.container) : null;
		this.bar			= document.getElementById(param.bar);
		this.text			= document.getElementById(param.text);
		this.messages		= param.messages || ['weak', 'good', 'secure', 'very secure'];
		
		if (!window.console) { this.debug = false; }
		
		var that			= this;
		this.password_field.onkeyup = function() { that.check(); }
	},
	
	
	
	check : function()
	{
		this.password	= this.password_field.value;
		this.display(this.evaluate());
	},
	
	
	
	evaluate : function()
	{
		var strength	= 0;
		var length		= this.password.length;
		var percent		= 0;
		var username	= this.username_field ? this.username_field.value : this.username;
		
		
		if (!this.has_unique_chars()) {
			percent	= 0;
		} else if (username && username == this.password) {
			percent	= 0;
		} else {
			strength += this.check_length() * 5;					// check_length returns 0, 1 or 2
			if (strength && this.has_numeric()) {					// password stays weak until min requirements are met
				if (this.has_lowercase()) 		{ strength += 4; }
				if (this.has_uppercase())		{ strength += 10; }
				if (this.has_numeric())			{ strength += 10; }
				if (this.has_punctuation())		{ strength += 16; }
			}
		}
		
		if (this.debug) { console.log('strength: ' + strength + ', percent: ' + (strength * 2)); }
		
		return strength * 2;									// max score of 50
	},
	
	
	
	display : function(percent)
	{
		var num	= 0;
		var max	= 100;
		//var min	= this.password.length * 5;
		
		if (percent > max) { percent = max; }
		//if (percent && percent < min) { percent += min; }
		
		if (percent >= 30) { num = 1; }
		if (percent >= 70) { num = 2; }
		if (percent > 95) { num = 3; }
		
		this.text.innerHTML 	= this.messages[num];
		this.bar.style.width	= percent + '%';
		if (this.classContainer) { this.classContainer.className = this.classNames[num]; }
	},
	
	
	
	has_lowercase : function()
	{
		if (this.password.search(/[a-z]/) > -1) {
			if (this.debug) { console.log('has lower'); }
			return true;
		}
		
		return false;
	},
	
	
	
	has_uppercase : function()
	{
		if (this.password.search(/[A-Z]/) > -1) {
			if (this.debug) { console.log('has upper'); }
			return true;
		}
		
		return false;
	},
	
	
	
	has_numeric : function()
	{
		if (this.password.search(/[0-9]/) > -1) {
			if (this.debug) { console.log('has numeric'); }
			return true;
		}
		
		return false;
	},
	
	
	
	has_punctuation : function()
	{
		if (this.password.search(/[^a-zA-Z0-9'\\]/) > -1) {			// ' and \ not allowed
			if (this.debug) { console.log('has punctuation'); }
			return true;
		}
		
		return false;
	},
	
	
	
	check_length : function()
	{
		var length	= this.password.length;
		
		if (length <= this.min_length) {
			return 0;
		}
		
		if (length <= 9) {
			return 1
		}
		
		return 2;
	},
	
	
	
	check_consecutive : function()
	{
		var num			= 3;				// minimum number of consecutive characters
		var count		= 1;
		var tmp			= '';
		var password	= this.password;
		var char		= password.charAt(0);
		
		for (var i = 1, l = password.length; i < l; ++i) {
			if ((tmp = password.charAt(i)) == char) {
				++count;
				if (count == num) { 
					if (this.debug) { console.log('has consecutive'); }
					return true;
				}
			} else {
				char	= tmp;
				count	= 1;
			}
		}
		
		return false;
	},
	
	
	
	has_unique_chars : function()
	{
		var password	= this.password;
		var char		= password.charAt(0);
		
		for (var i = password.length; --i > 0; ) {
			if (password.charAt(i) != char) {
				if (this.debug) { console.log('chars are unique'); }
				return true;
			}
		}
		
		return false;
	}
}