/*

Mask	| Explanation
----------------------------------------------------------------------------------------------------
#		| allow numbers with '.' , ',' and '-'  $######## -1,234.5 $-1,234 
9		| allow numbers only  Feb 99 2099 1202 Feb 12 2002 
A		| allow alpha only (insluding space)  AAAAAA male9 male 
?		| allow numbers/letters and space  ???????????? 1. Street 11-a 1 Street 11a 
>		| converts alphanumeric to lower case  A>>A> PANAM PanAm 
<		| converts alphanumeric to upper case  <AA<A panam PanAm 
\		| treat reserved character that follows as text  Number: \#99999 12345 Number: #12345 
----------------------------------------------------------------------------------------------------
Special mask modifiers (first character of the mask) 
----------------------------------------------------------------------------------------------------
*		| applies the rule that follows to all input  *9 12 Feb 2002 122002 
@		| adds leading zeroes to the numeric (0-9) input; number that follows is total number of places  @12 123456 000000123456 
^		| replaces all input with the character that follows  ^* this is masked text ******************* 
~		| reverse masking; after entering characters, any existing characters are shifted to the left ~999999-99-9 12345 12-34-5 
----------------------------------------------------------------------------------------------------

  phone number:
    <input type="text" name="test" mask="999-999-9999">
*/

function maskInput(strInput, strMask) {
// Syntax Example:	maskInput( '1203', 'Feb 99 2099' )
//         Output:	'Feb 12 2003'

	var strMasked, strTmp, LenStr, LenMsk, blnReverse;

	strMasked = '';
	LenStr = strInput.length;
	LenMsk = strMask.length;

	if (LenStr==0) return('');
	if (LenMsk==0) return(strInput);

	if (LenMsk>1) {
		if ((strMask.charAt(LenMsk)=='\\') && (strMask.charAt(LenMsk-1)!='\\')) strMask = strMask.substring(0, LenMsk-1);
	}

	blnReverse = false;
	if (strMask.charAt(0) == '~') {							// Reverse masking from right to left instead of from left to right
		if (LenMsk==1) return(strInput);
		strMask = strMask.substring(1, LenMsk);
		LenMsk = strMask.length;
		if (LenStr > LenMsk) return(strInput.substring(0, LenMsk));
		strMask = reverseString(strMask);
		strInput = reverseString(strInput);
		blnReverse = true;
	} else if (strMask.charAt(0) == '^') {					// Replace all characters in input string with
		if (LenMsk==1) return(strInput);					// the second character (real mask)
		strMasked = '';
		for (i=0; i<LenStr; i++) {
			strMasked = strMasked + strMask.charAt(1);
		}
		return(strMasked);
	} else if (strMask.charAt(0) == '*') {					// Treat all characters in input string by the rule
		if (LenMsk==1) return(strInput);					// of the second character (mask)
		var multiChar, i;
		multiChar = strMask.charAt(1);
		if (!isMaskChar(multiChar)) return(strInput);
		strMask = ''
		for (i=0; i<=LenStr; i++) {
			strMask = strMask + multiChar;
		}
		LenMsk = strMask.length;
	} else if (strMask.charAt(0) == '@') {					// Fill all empty place holders to the left with zeroes
		if (LenMsk==1) return(strInput);					// ('leading zeroes'); Second character is number of place holders
		var zeroNum, i;
		zeroNum = strMask.substring(1, LenMsk);
		if (isNaN(zeroNum)) return(strInput);
		strMask = '';
		var i;
		for (i=0; i<zeroNum; i++) {
			strMask = strMask + '9';
		}
		for (i=0; i<LenStr; i++) {
			if (isNumberChar(strInput.charAt(i))) strMasked = strMasked + strInput.charAt(i);
		}
		i=0;
		while (strMasked.charAt(i)=='0') i++;
		if (i>0) strMasked = strMasked.substring(i, LenStr);
		strMasked = strMasked.substring(0, zeroNum);
		LenStr = strMasked.length;
		if (LenStr<zeroNum) {
			for (i=LenStr; i<zeroNum; i++) strMasked = '0' + strMasked;
		}
		return(strMasked);
	}
	var MskOffset, Count, SubStr, Mask, newChar, newCharLen;
	MskOffset = 0;
	for (Count=0; Count<LenStr; Count++) {
		SubStr = strInput.charAt(Count);
		if (MskOffset<LenMsk) {
			newChar = '';
			Mask = strMask.substring(MskOffset, LenMsk);
			newChar = checkMask(Mask, SubStr);
			newCharLen = newChar.length;
			if (newCharLen!=0) strMasked = strMasked + newChar;
			if (Mask.charAt(0)=='\\') MskOffset++;
			MskOffset = MskOffset + newCharLen;
		}
	}
	if (blnReverse) return(reverseString(strMasked));
	return(strMasked);
}

function unMaskInput(strMaskedInput, strUnMask) {
// Syntax Example:	unMaskInput( "Feb 12 2003", "Feb 99 2099" )
//         Output:	"1203"

	var strUnMasked, LenStr, LenMsk, blnReverse;

	strUnMasked = '';
	LenStr = strMaskedInput.length;
	LenMsk = strUnMask.length;

	if (LenStr==0) return('');
	if (LenMsk==0) return(strMaskedInput);

	if (LenMsk>1) {
		if ((strUnMask.charAt(LenMsk)=='\\') && (strUnMask.charAt(LenMsk-1)!='\\')) strUnMask = strUnMask.substring(0, LenMsk-1);
	}
	if (strUnMask.charAt(0) == '~') {						// Revert masking from right to left instead of left from right
		if (LenMsk==1) return(strMaskedInput);
		strUnMask = strUnMask.substring(1, LenMsk);
		LenMsk = strUnMask.length;
		if (LenStr > LenMsk) return(strMaskedInput.substring(0, LenMsk));
		strUnMask = reverseString(strUnMask);
		strMaskedInput = reverseString(strMaskedInput);
		blnReverse = true;
	} else if (strUnMask.charAt(0) == '^') {				// Replace all characters in input string with
		return(strMaskedInput);								// the second character (real mask) IGNORED FOR UnMask
	} else if (strUnMask.charAt(0) == '*') {				// Treat all characters in input string by the rule
		if (LenMsk==1) return(strMaskedInput);				// of the second character (mask)
		var multiChar;
		multiChar = strUnMask.charAt(1);
		if (!isMaskChar(multiChar)) return(strMaskedInput);
		strUnMask = '';
		var i;
		for (i=0; i<LenStr; i++) {
			strUnMask = strUnMask + multiChar;
		}
		LenMsk = strUnMask.length;
	} else if (strUnMask.charAt(0) == '@') {				// Fill all empty place holders to the left with zeroes
		var i;												// ('leading zeroes'); Second character is number of place holders
		i=0;
		while (strMaskedInput.charAt(i)=='0') i++;
		strUnMasked = strMaskedInput.substring(i, LenStr);
		return(strUnMasked);
	}
	var MskOffset, Count, SubStr;
	MskOffset = 0;
	for (Count=0; Count<LenStr; Count++) {
		SubStr = strMaskedInput.charAt(Count);
		if (MskOffset<LenMsk) {
			if (isMaskChar(strUnMask.charAt(MskOffset))) {
				strUnMasked = strUnMasked + SubStr;
				MskOffset++;
			} else if (strUnMask.charAt(MskOffset++)=='\\') MskOffset++;
		}
	}
	if (blnReverse) return(reverseString(strUnMasked));
	return(strUnMasked);
}

function checkMask(strCheckMask, strInpChar) {
	var strOut;

	strOut = strCheckMask.charAt(0);
	switch (strOut) {
		case '\\':
			strOut = strCheckMask.charAt(1);
			if (strOut!='\\') {
				if ((strCheckMask.length>2) && (strOut!=strInpChar)) {
					strOut = strOut + checkMask(strCheckMask.substring(2, strCheckMask.length), strInpChar);
				}
			} else {
				if ((strCheckMask.length>3) && (strOut!=strInpChar)) {
					strOut = '\\' + checkMask(strCheckMask.substring(3, strCheckMask.length), strInpChar);
				}
			}
			return(strOut);
			brake;
		case '#':		// Numeric: ".,-1234567890"
			if (isNumericChar(strInpChar)) return(strInpChar);
			return('');
			brake;
		case '9':		// Number: "1234567890"
			if (isNumberChar(strInpChar)) return(strInpChar);
			return('');
			brake;
		case '>':		// ToLoverCase: A -> a
			if (isAlphabeticChar(strInpChar)) return(strInpChar.toLowerCase());
			return(strInpChar);
			brake;
		case '<':		// ToUpperCase: a -> A
			if (isAlphabeticChar(strInpChar)) return(strInpChar.toUpperCase());
			return(strInpChar);
			brake;
		case 'A':		// Alphabetic: "abcdefghijklmnopqrstuvwxyz"
			if (isAlphabeticChar(strInpChar)) return(strInpChar);
			return('');
			brake;
		case '?':		// AlphaNumeric: "1234567890abcdefghijklmnopqrstuvwxyz"
			if (isNumOrChar(strInpChar)) return(strInpChar);
			return('');
			brake;
		default :		// Enything else
			if ((strCheckMask.length>1) && (strOut!=strInpChar)) {
				strOut = strOut + checkMask(strCheckMask.substring(1, strCheckMask.length), strInpChar);
			} 
			return(strOut);
			brake;
	}
}

function isMaskChar(InString) {
	if (InString.length!=1) return(false);
	var RefString;
	RefString="#9><A?";
	if (RefString.indexOf(InString, 0)==-1) return(false);
	return(true);
}

function isAlphabeticChar(InString) {
	if (InString.length!=1) return(false);
	var RefString;
	InString=InString.toLowerCase();
	RefString="abcdefghijklmnopqrstuvwxyz ";
	if (RefString.indexOf(InString.toLowerCase(), 0)==-1) return(false);
	return(true);
}

function isNumberChar(InString) {
	if (InString.length!=1) return(false);
	var RefString;
	RefString="1234567890";
	if (RefString.indexOf(InString, 0)==-1) return(false);
	return(true);
}

function isNumericChar(InString) {
	if (InString.length!=1) return(false);
	var RefString;
	RefString=".,-1234567890";
	if (RefString.indexOf(InString, 0)==-1) return(false);
	return(true);
}

function isNumOrChar(InString) {
	if (InString.length!=1) return(false);
	var RefString;
	InString=InString.toLowerCase();
	RefString="1234567890abcdefghijklmnopqrstuvwxyz ";
	if (RefString.indexOf(InString, 0)==-1) return(false);
	return(true);
}

function reverseString(string) {
	if (string == '') return(string);
	var strTemp;
	strTemp='';
	for (i=string.length; i>=0; i--) {
		strTemp = strTemp + string.charAt(i-1);
	}
	return(strTemp)
}

function setupMask() {
  var arr_inputs = document.getElementsByTagName('input');
  for (var i = 0; i < arr_inputs.length; i++) {
    if (arr_inputs[i].getAttribute('type')=='text') {
      if (arr_inputs[i].getAttribute('mask')) {
        arr_inputs[i].onkeyup = function() {
          this.value = maskInput(this.value, this.getAttribute('mask'));
        }
      }
    }
  }
}


// DOM2
if ( typeof window.addEventListener != "undefined" )
	window.addEventListener( "load", setupMask, false );

// IE 
else if ( typeof window.attachEvent != "undefined" ) {
	window.attachEvent( "onload", setupMask);
}

else {
	if ( window.onload != null ) {
		var oldOnload = window.onload;
		window.onload = function ( e ) {
			oldOnload( e );
			setupMask();
		};
	}
	else 
		window.onload = setupMask;
}