/*****************************************************************
General Javascript Validation
BAR - February 23, 2010
This file includes a few common validation requirements and the inlineValidationDisplay function
These are simplistic functions and are not specific so external validation that calls these files on a field by field basis is required.
You can place the validation on an inline basis with onblur event or a cumulative via the onsubmit of form function
	or onclick event of the submission object whether that be button image or link.
*****************************************************************/
//We use this for displaying errors in the errorMessage div
var errMessageArray = new Array();
Array.prototype.indexOf = function(obj){  
     for(var i = 0;i<this.length;i++){  
        if(this[i] == obj){  
           return i;  
         }  
     }  
     return -1;  
} 
Array.prototype.exclude = function(obj){
	var index=this.indexOf(obj);
	if(index<0)
		{return this;}
	else if(index==0)
	{
		if(this.length > 1)
		{
			return this.slice(0,index).concat(this.slice(index+1,this.length));	}	
		else
			{this.length = 0;return this;}
	}else
	{
		return this.slice(0,index).concat(this.slice(index+1,this.length));
	}
		
		
}
//Simple non-empty test
function TestRequired(val) {
	if (val.replace(/^\s+|\s+$/g,'').length > 0) return true;
	return false;
}
//Simple length test the length Maximum is optional
function TestLength(val, minimum, maximum) {
	maximum = maximum || 0; // Set maximum to post by default, if not specified.
	val = val.replace(/^\s+|\s+$/g,''); //trim this we do not want whitespace to count begining or end
	if (val.length >= minimum && (val.length <= maximum || maximum == 0)) return true;
	return false;
}
//Simple compare of two values
function TestCompareValues(val1, val2) {
	if (val1 == val2) return true;
	return false;
}
//Simple e-Mail validator
function TestEmail(val) {
	var expression = /^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$/
	return expression.test(val);
}
//Simple zip/postal code tester onlyu recognizes US CA and UK please expand if you know others
//Takes the value to test and 2 char country code
function TestCode(val, country) {
	var  expression = /^\w+$/;
	if (country == 'US') expression = /^\d{5}$|^\d{5}-\d{4}$/;
	if (country == 'CA') expression =  /^[ABCEGHJKLMNPRSTVXY]\d[A-Z] \d[A-Z]\d$/;
	if (country =='UK') expression = /^[A-Z]{1,2}\d[A-Z\d]? \d[ABD-HJLNP-UW-Z]{2}$/;
	return expression.test(val);
}
//Test for Valid US states
function TestStateAbbrUS(val) {
	expression=/^(AL|AK|AS|AZ|AR|CA|CO|CT|DE|DC|FM|FL|GA|GU|HI|ID|IL|IN|IA|KS|KY|LA|ME|MH|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|MP|OH|OK|OR|PW|PA|PR|RI|SC|SD|TN|TX|UT|VT|VI|VA|WA|WV|WI|WY)$/;
	return expression.test(val);
}
//Simple Phone test
function TestPhone(val) {
	var expression = /^((\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,5})|(\(?\d{2,6}\)?))(-| )?(\d{3,4})(-| )?(\d{4})(( x| ext)\d{1,5}){0,1}$/;
	return expression.test(val);
}
//Simple Credit card validation
//Takes number to test and the Truition single card code and the
function TestCreditCard(number, type) {
    var number = number.replace(/[^0-9]+/,'');
	var ccCheckRegExp = /[^\d ]/;
	if (!ccCheckRegExp.test(number)) return false;
    var patternRegExp;
    switch(type) {
		case 'M': //MasterCard
			patternRegExp = /^5[1-5][0-9]{14}$/;
			break;
		case 'V': //Visa
			patternRegExp = /^4[0-9]{12}(?:[0-9]{3})?$/;
			break;
		case 'A': //American Express
			patternRegExp = /^3[47][0-9]{13}$/;
			break;
		case 'D': //Discover
			patternRegExp = /^6(?:011|5[0-9]{2})[0-9]{12}$/;
			break;
/* If we ever support these card types just add the CardType Value in the case and uncomment
		case '': //Diners Club
			patternRegExp = /^3(?:0[0-5]|[68][0-9])[0-9]{11}$/;
			break;
		case '': //JCB
			patternRegExp = /^(?:2131|1800|35\d{3})\d{11}$/;
			break;
*/
		default:
			prefixRegExp = /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/;
			break;
    }
	if (!patternRegExp.test(number)) return false;
    var numberProduct;
    var numberProductDigitIndex;
    var checkSumTotal = 0;
    for (digitCounter = number.length - 1; digitCounter >= 0; digitCounter--) {
      checkSumTotal += parseInt (cardNumbersOnly.charAt(digitCounter));
      digitCounter--;
      numberProduct = String((cardNumbersOnly.charAt(digitCounter) * 2));
      for (var productDigitCounter = 0; productDigitCounter < numberProduct.length;  productDigitCounter++) {
        checkSumTotal += parseInt(numberProduct.charAt(productDigitCounter));
      }
    }
    return (checkSumTotal % 10 == 0);
}
//Simple Credit card validation for string format does both 2 and 4 digit years
function TestCreditCardExpirationString(val) {
	var vals = val.split('/');
	if (vals[1].length == 2) vals[1] = '20' + vals[1];
	return TestCreditCardExpiration(vals[0], vals[1]);
}
//Simple Credit card validation for two numbers
function TestCreditCardExpiration(month, year) {
	var curDate = new Date();
	var curYear = curDate.getFullYear();
	var curMonth = curDate.getMonth();
	if (year.length == 2) year = '20' + year;
	if (parseInt(year) > curYear) return true;
	if (parseInt(year) == curYear && parseInt(month) >= curMonth) return true;
	return false;
}
//Simple Credit card validation for CVV
function TestCreditCardCVV(val) {
	var val = val.replace(/[^0-9]+/,'');
	return (val.length == 3)
}
//Simple Credit card validation for CSC
function TestCreditCardCSC(val) {
	return TestCreditCardCVV(val);
}
function stateToAbbrUS(state) {
	var newstate = '';
	switch(state) {
		case 'ALABAMA':
			newstate = 'AL';
			break;
		case 'ALASKA':
			newstate = 'AK';
			break;
		case 'AMERICANSAMOA':
			newstate = 'AS';
			break;
		case 'ARIZONA':
			newstate = 'AZ';
			break;
		case 'ARKANSAS':
			newstate = 'AR';
			break;
		case 'CALIFORNIA':
			newstate = 'CA';
			break;
		case 'COLORADO':
			newstate = 'CO';
			break;
		case 'CONNECTICUT':
			newstate = 'CT';
			break;
		case 'DELAWARE':
			newstate = 'DE';
			break;
		case 'DISTRICTOFCOLUMBIA':
			newstate = 'DC';
			break;
		case 'FEDERATEDSTATESOFMICRONESIA':
			newstate = 'FM';
			break;
		case 'FLORIDA':
			newstate = 'FL';
			break;
		case 'GEORGIA':
			newstate = 'GA';
			break;
		case 'GUAM':
			newstate = 'GU';
			break;
		case 'HAWAII':
			newstate = 'HI';
			break;
		case 'IDAHO':
			newstate = 'ID';
			break;
		case 'ILLINOIS':
			newstate = 'IL';
			break;
		case 'INDIANA':
			newstate = 'IN';
			break;
		case 'IOWA':
			newstate = 'IA';
			break;
		case 'KANSAS':
			newstate = 'KS';
			break;
		case 'KENTUCKY':
			newstate = 'KY';
			break;
		case 'LOUISIANA':
			newstate = 'LA';
			break;
		case 'MAINE':
			newstate = 'ME';
			break;
		case 'MARSHALL ISLANDS':
			newstate = 'MH';
			break;
		case 'MARYLAND':
			newstate = 'MD';
			break;
		case 'MASSACHUSETTS':
			newstate = 'MA';
			break;
		case 'MICHIGAN':
			newstate = 'MI';
			break;
		case 'MINNESOTA':
			newstate = 'MN';
			break;
		case 'MISSISSIPPI':
			newstate = 'MS';
			break;
		case 'MISSOURI':
			newstate = 'MO';
			break;
		case 'MONTANA':
			newstate = 'MT';
			break;
		case 'NEBRASKA':
			newstate = 'NE';
			break;
		case 'NEVADA':
			newstate = 'NV';
			break;
		case 'NEWHAMPSHIRE':
			newstate = 'NH';
			break;
		case 'NEWJERSEY':
			newstate = 'NJ';
			break;
		case 'NEWMEXICO':
			newstate = 'NM';
			break;
		case 'NEWYORK':
			newstate = 'NY';
			break;
		case 'NORTHCAROLINA':
			newstate = 'NC';
			break;
		case 'NORTHDAKOTA':
			newstate = 'ND';
			break;
		case 'NORTHERNMARIANAISLANDS':
			newstate = 'MP';
			break;
		case 'OHIO':
			newstate = 'OH';
			break;
		case 'OKLAHOMA':
			newstate = 'OK';
			break;
		case 'OREGON':
			newstate = 'OR';
			break;
		case 'PALAU':
			newstate = 'PW';
			break;
		case 'PENNSYLVANIA':
			newstate = 'PA';
			break;
		case 'PUERTORICO':
			newstate = 'PR';
			break;
		case 'RHODEISLAND':
			newstate = 'RI';
			break;
		case 'SOUTHCAROLINA':
			newstate = 'SC';
			break;
		case 'SOUTHDAKOTA':
			newstate = 'SD';
			break;
		case 'TENNESSEE':
			newstate = 'TN';
			break;
		case 'TEXAS':
			newstate = 'TX';
			break;
		case 'UTAH':
			newstate = 'UT';
			break;
		case 'VERMONT':
			newstate = 'VT';
			break;
		case 'VIRGINISLANDS':
			newstate = 'VI';
			break;
		case 'VIRGINIA':
			newstate = 'VA';
			break;
		case 'WASHINGTON':
			newstate = 'WA';
			break;
		case 'WESTVIRGINIA':
			newstate = 'WV';
			break;
		case 'WISCONSIN':
			newstate = 'WI';
			break;
		case 'WYOMING':
			newstate = 'WY';
			break;
		default:
			break;
	}
	return newstate;
}
function phoneAlphaToNumeric(char) {
	var val = null;
	switch (char.toLowerCase()) {
	case "a": case "b": case "c":
		val = "2";
		break;
	case "d": case "e": case "f":
		val = "3";
		break;
	case "g": case "h": case "i":
		val = "4";
		break;
	case "j": case "k": case "l":
		val = "5";
		break;
	case "m": case "n": case "o":
		val = "6";
		break;
	case "p": case "q": case "r": case "s":
		val = "7";
		break;
	case "t": case "u": case "v":
		val = "8";
		break;
	case "w": case "x": case "y": case "z":
		val = "9";
		break;
	}
	return rtrnVal;
}

/**********************************************
This is the Work Horse of the inline validation
it takes either a DOM object name or a DOM id
a title for the validation to replace in the errorTextPattern
The result of your validation must be boolean true or false
An optional errorTextPattern if you wish to use the title in this you may by specifying in your pattern {title}
	if you do not the title will not display
Another optional variable is errorTextClass if you would like to specify an extra class on your text
All Styling can be done using css with
img.inlinevalidator{} and div.inlinevalidator{}
This will insert an image valid or invalid based upon your results after the element specified in the name
If you specify a name it will insert after the last member of the group if id it will place directly after that object
If the result is false it will also insert an error message the default for this is 'A valid "{title}" is required.'
{title} will of course be replaced by the passed in title variable
This must be called on a field by field basis meaning you require unique validation per object or a function to make a unique call
Possible upgrade could be switches for turning images off and on and text off and on
	this might come in handy for a password strength validator
***********************************************/
var doc = document;
var win = window;
function inlineValidationDisplay(name, title, result, errorTextPattern, errorTextClass) {
	errorTextPattern = errorTextPattern ||  validationDefaultMessage; // Set the default error text pattern
	errorTextClass = errorTextClass || ''; //set default for error text class
	var active = false;
	var currentforminput = '';
	if (doc.getElementsByName(name).length != 0) {
		currentforminput = doc.getElementsByName(name);
		active = true;
	}
	else if (doc.getElementById(name)) {
		currentforminput = doc.getElementById(name);
		active = true;
	}
	else return true;
	var modifier = 'valid';
	var textDisplay = '';
	if (currentforminput.length) {
		for (var i = 0; i < currentforminput.length; i++) {
			if (doc.getElementById(name + i + '_testimg')) currentforminput[i].parentNode.removeChild(doc.getElementById(name + i + '_testimg'));
			if (doc.getElementById(name + i + '_testp')) currentforminput[i].parentNode.removeChild(doc.getElementById(name + i + '_testp'));
		}
	} else {
		if (doc.getElementById(name + '_testimg')) currentforminput.parentNode.removeChild(doc.getElementById(name + '_testimg'));
		if (doc.getElementById(name + '_testp')) currentforminput.parentNode.removeChild(doc.getElementById(name + '_testp'));
	}
	if (!result) {
		modifier = 'invalid';
		textDisplay = errorTextPattern.replace('{title}',title);
	}
	if (textDisplay != '') {
		if (currentforminput.length) {
			for (var i = 0; i < currentforminput.length; i++) {
				var p = doc.createElement('div');
				var newtext = doc.createTextNode(textDisplay);
				p.appendChild(newtext);
				p.setAttribute('id', name + i + '_testp');
				if (errorTextClass == '') {
					p.setAttribute('class', 'inlinevalidator');
					p.setAttribute('className', 'inlinevalidator');
				} else {
					p.setAttribute('class', 'inlinevalidator ' + errorTextClass);
					p.setAttribute('className', 'inlinevalidator ' + errorTextClass);
				}
				currentforminput[i].parentNode.insertBefore(p, currentforminput[i].nextSibling);
			}
		} else {
			var p = doc.createElement('div');
			var newtext = doc.createTextNode(textDisplay);
			p.appendChild(newtext);
			p.setAttribute('id', name + '_testp');
			if (errorTextClass == '') {
				p.setAttribute('class', 'inlinevalidator');
				p.setAttribute('className', 'inlinevalidator');
			} else {
				p.setAttribute('class', 'inlinevalidator ' + errorTextClass);
				p.setAttribute('className', 'inlinevalidator ' + errorTextClass);
			}
			currentforminput.parentNode.insertBefore(p, currentforminput.nextSibling);
		}
	}
	if (currentforminput.length) {
		for (var i = 0; i < currentforminput.length; i++) {
			var img = doc.createElement('img');
			img.setAttribute('src', validationImagePath + modifier + validationImageType);
			img.setAttribute('alt', modifier);
			img.setAttribute('id', name + i + '_testimg');
			img.setAttribute('class', 'inlinevalidator');
			img.setAttribute('className', 'inlinevalidator');
			currentforminput[i].parentNode.insertBefore(img, currentforminput[i].nextSibling);
		}
	} else {
		var img = doc.createElement('img');
		img.setAttribute('src', validationImagePath + modifier + validationImageType);
		img.setAttribute('alt', modifier);
		img.setAttribute('id', name + '_testimg');
		img.setAttribute('class', 'inlinevalidator');
		img.setAttribute('className', 'inlinevalidator');
		currentforminput.parentNode.insertBefore(img, currentforminput.nextSibling);
	}
	return false;
}
function inlineValidationTextboxBGDisplay(name, title, result, errorTextPattern) {
	errorTextPattern = errorTextPattern || validationDefaultMessage; // Set the default error text pattern
	var active = false;
	var currentforminput = '';
	if (doc.getElementsByName(name).length != 0) {
		currentforminput = doc.getElementsByName(name);
		active = true;
	}
	else if (doc.getElementById(name)) {
		currentforminput = doc.getElementById(name);
		active = true;
	}
	else return true;
	var modifier = 'valid';
	var textDisplay = '';
	if (currentforminput.length) {
		for (var i = 0; i < currentforminput.length; i++) {
			currentforminput[i].title = title;
			currentforminput[i].className = currentforminput[i].className.replace(' invalid','');
			currentforminput[i].className = currentforminput[i].className.replace(' valid','');
		}
	} else {
		currentforminput.title = title;
		currentforminput.className = currentforminput.className.replace(' invalid','');
		currentforminput.className = currentforminput.className.replace(' valid','');
	}
	if (!result) {
		modifier = 'invalid';
		textDisplay = errorTextPattern.replace('{title}',title);
	}
	if (textDisplay != '') {
		if (currentforminput.length)
			for (var i = 0; i < currentforminput.length; i++)
				currentforminput[i].title = textDisplay;
		else
			currentforminput.title = textDisplay;
	}
	if (currentforminput.length)
		for (var i = 0; i < currentforminput.length; i++)
			currentforminput[i].className = currentforminput[i].className + ' ' + modifier;
	else
		currentforminput.className = currentforminput[i].className + ' ' + modifier;
	return false;
}
function submitValidationDisplay(name, title, result, errorTextPattern) {
	errorTextPattern = errorTextPattern ||  validationDefaultMessage; // Set the default error text pattern
	if (!result) {
		modifier = 'invalid';
		textDisplay = errorTextPattern.replace('{title}',title);
		if (textDisplay != '')
		{	
			if(errMessageArray.length ==0 ||(errMessageArray.length>0 && errMessageArray.indexOf(textDisplay)<0)) errMessageArray.push(textDisplay);
		}
	}else{
		textToExclude = errorTextPattern.replace('{title}',title);		
		if(textToExclude != '')
		{
			if(errMessageArray.length>0 && errMessageArray.indexOf(textToExclude)>-1) errMessageArray = errMessageArray.exclude(textToExclude);
		}
	}
	if (validationInline) return false;
	var active = false;
	var currentforminput = '';
	if (doc.getElementsByName(name).length != 0) {
		currentforminput = doc.getElementsByName(name);
		active = true;
	}
	else if (doc.getElementById(name)) {
		currentforminput = doc.getElementById(name);
		active = true;
	}
	else return true;
	var modifier = 'valid';
	var textDisplay = '';
	if (currentforminput.length) {
		for (var i = 0; i < currentforminput.length; i++) {
			if (doc.getElementById(name + i + '_testimg')) currentforminput[i].parentNode.removeChild(doc.getElementById(name + i + '_testimg'));
		}
	} else {
		if (doc.getElementById(name + '_testimg')) currentforminput.parentNode.removeChild(doc.getElementById(name + '_testimg'));
	}
	if (currentforminput.length) {
		for (var i = 0; i < currentforminput.length; i++) {
			var img = doc.createElement('img');
			img.setAttribute('src', validationImagePath + modifier + validationImageType);
			img.setAttribute('alt', modifier);
			img.setAttribute('id', name + i + '_testimg');
			img.setAttribute('class', 'inlinevalidator');
			img.setAttribute('className', 'inlinevalidator');
			currentforminput[i].parentNode.insertBefore(img, currentforminput[i].nextSibling);
		}
	} else {
		var img = doc.createElement('img');
		img.setAttribute('src', validationImagePath + modifier + validationImageType);
		img.setAttribute('alt', modifier);
		img.setAttribute('id', name + '_testimg');
		img.setAttribute('class', 'inlinevalidator');
		img.setAttribute('className', 'inlinevalidator');
		currentforminput.parentNode.insertBefore(img, currentforminput.nextSibling);
	}
	return false;
}
function writeErrorMessage(errorHeader) {
	errorHeader = errorHeader || validationDefaultErrorHeader; // Set the default error text pattern
	if (!doc.getElementById('errorMessage')) return true;
	if (errMessageArray.length > 0) {
		var errorMessageArea = doc.getElementById('errorMessage');
		errorMessageArea.innerHTML = "";
		var header = doc.createElement("p");
		header.innerHTML = errorHeader;
		errorMessageArea.style.display = "block";
		errorMessageArea.appendChild(header);
		if (!validationInline) {
			var errorList = doc.createElement("ul");
			for (error in errMessageArray) {
				var li = doc.createElement("li");
				li.innerHTML = errMessageArray[error];
				errorList.appendChild(li);
			}
			errorMessageArea.appendChild(errorList);
		}
		errMessageArray.length = 0
		return false;
	}
	return true;
}

