//Keydown EventHadler
document.onkeydown = catchIt;
//Is Gecko Browser (Mozilla/FireFox)
var is_gecko = /gecko/i.test(navigator.userAgent);
//Is IE Browser
var is_ie    = /MSIE/i.test(navigator.userAgent);
//Indicate when cursor in input text box
var isInTextBox = false;
//Return object of current text box
var currentTextBox = null;
//Return mask of current text box
var currentMask = null;
//Return cursor position in current text box
var currentPosition = 0;
var allowClear = true;

/*	OnBlur:
		Disable global varibles
		Validate value				*/
function setParams(input) {
	if ( allowClear == true )	{
		clearTextBox(input);
		isInTextBox = false;
		currentTextBox = null;
		currentMask = null;
		currentPosition = 0;
	}
	else
		allowClear = true;	
};

function clearTextBox(input) {
	var result = new String();
	for (var count = 0; count <= input.value.length; count++ ) {
		if (input.value.charAt(count) == '_') {
			result += ' ';
		}
		else
			result += input.value.charAt(count);
	}
	input.value = result;
};

/*	OnKeypress:
		Get Mask
		Set Value	*/
function setMask(input, mask)
{
	currentMask = mask;
	var position = getPosition(input);
	
	if (position <= input.value.length) {
		var result = new String();
		var numberOfExceptions = getRelativePosition(currentMask, position);
		var maskPosition = numberOfExceptions+position;	
		var maskChar = currentMask.charAt(maskPosition);
		var keyCodeArray = returnCharacter(maskChar);
				
		if ( currentMask.charAt(maskPosition-1) == '\\' ) {
			result = input.value.substring(0,position);
			result += input.value.substring(position+1, input.value.length);
			input.value = result;
			setCursorPosition(input, position);
		}
		else if ((keyCodeArray[0] == "TONEXT") & (position != input.value.length)) {
			position ++;
			setCursorPosition(input, position);
			setMask(input, mask);
		}
		else if (keyCodeArray[0] == "SAVESYMBOL") {
			position++;
			setCursorPosition(input, position);
			setMask(input, mask);
		}
		else if ((keyCodeArray[0] == "TOUPPER") || (keyCodeArray[0] == "TOLOWER")) {
			result = input.value.substring(0,position);
			result += input.value.substring(position+1, input.value.length);
			input.value = result;
			setCursorPosition(input, position);
		}
		else if (findKeyCode(event.keyCode, keyCodeArray) != true) {
			event.returnValue = false;
		}
		else {
			result = input.value.substring(0, position);
			result += input.value.substring(position + 1, input.value.length);
			input.value = result;
			setCursorPosition(input, position);
		}
		currentPosition = position+1;
	}
};

/*	
	OnKeyup:
		Format field (upperCase, lowerCase)
											*/
function formatField(input) {
	if ( ((event.keyCode != 8) && (event.keyCode != 46)) && ((currentMask.indexOf('>') != -1) || (currentMask.indexOf('<') != -1) )) {
		var result = new String();
		var numberOfUppers = 0;
		var numberOfLowers = 0;
		var firstMentionUpper = true;
		var firstMentionLower = true;
		var toUpper = false;
		var toLower = false;
		var sacred = false;
		var position = 0;
		currentPosition = getPosition(input);
		
		if ( currentMask != null ) {
			for (var count = 0; count <= currentMask.length; count++) {
				if (currentMask.charAt(count) == '>') {
					numberOfUppers++;
				}
				if (currentMask.charAt(count) == '<') {
					numberOfLowers++;
				}
			}
			if (numberOfUppers > 0 || numberOfLowers > 0) {
				for (count = 0; count <= currentMask.length; count++) {
					if ( currentMask.charAt(count) == '>' ) {
						toLower = false;
						toUpper = true;
						sacred = false;
					}
					else if ( currentMask.charAt(count) == '<') {
						toLower = true;
						toUpper = false;
						sacred = false;
					}
					else if (currentMask.charAt(count) == '\\') {
						sacred = true;
					}
					else {
						if ((toUpper) & (!toLower) & (!sacred)) {
							result += input.value.charAt(position).toUpperCase();
						}
						else if ((toLower) & (!toUpper) & (!sacred)) {
							result += input.value.charAt(position).toLowerCase();
							
						}
						else {
							result += input.value.charAt(position);
						}
						sacred = false;
						position++;
					}
				}
			input.value = result;
			setCursorPosition(input, currentPosition);	
			}
		}
	}
};

/*	
	OnClick:
		Set field format
				*/
function setCursorPosition(input) {
	if (input.createTextRange) {
		var range = field.createTextRange();
		range.collapse(false);
		range.moveEnd("character", 0);
		range.moveStart("character", 0);
	}
};

/*
	On Text Box focus event
*/
function setDefaultValue(textBox, mask) {
	currentTextBox = textBox;
	currentMask = mask;
	
	//Check value and set mask	
	if ((textBox.value.indexOf('_') != -1) || (textBox.value == '') || (textBox.value.indexOf(' ') != -1)) {
		//Set default value
		textBox.value = getDefaultValue(currentMask);
		//Set max length
		textBox.maxLength = textBox.value.length;
	}
	//Set Button
	isInTextBox = true;
	//Set cursor position
	setCursorPosition(textBox);
};

function replaceSymbol(string, char, replaceChar) {
	var result = new String();
	if (string != null) {
		for (var count = 0; count <= string.length; count++) {
			if (string.charAt(count) == char) {
				result += replaceChar;
			}
			else {
				result += string.charAt(count);
			}
		}
	}
	return result;
};

//Contain key codes
var toNextSymbol = new Array("TONEXT"); // Other Symbol
var toUpper = new Array("TOUPPER"); // >
var toLower = new Array("TOLOWER"); // <
var toSaveSymbol = new Array("SAVESYMBOL");

	/****** ANSI placeholder ******/
var ANSIPlaceHolder = new Array(); // &
	fillANSIPlaceHolder(ANSIPlaceHolder);

	/***** A - alphanumeric requried *****/
var alphanumericRequerd = new Array();
	fillAlphanumeric(alphanumericRequerd);

	/***** a - alphanumeric optional *****/
var alphanumericOptional = new Array(); // a
	fillAlphanumeric(alphanumericOptional);

	/***** # - digit place holder required *****/
var digitPlaceHolder = new Array();
	fillDigit(digitPlaceHolder);
	
	/***** To ignore nexth symbol ******/
var literalMaskPlaceHolder = new Array();
	fillLiteralMaskPlaceHolder(literalMaskPlaceHolder);
	
	/***** 9 - entry optional ******/
var digitOptional = new Array();
	fillDigit(digitOptional);
	
	/***** C - entry optional *****/
var charSpacePlaceHolder = new Array();
	fillCharSpacePlaceHolder(charSpacePlaceHolder);

	/***** ? - character place holder *****/
var letterPlaceHolder = new Array(); // ?
	fillLetterPlaceHolder(letterPlaceHolder);
	
	
function fillCharSpacePlaceHolder(charSpaceArray) {
	var i = 0;
	/******** FOR ALL LANGUAGES *************/
	/*********    ?    **********/
	for (var count = 32; count <= 126; count++) {
		charSpaceArray[i] = count;
		i++;
	}
	
	for (count = 128; count <= 255; count++) {
		charSpaceArray[i] = count;
		i++;
	}
	
	for (count = 256; count <= 591; count++) {
		charSpaceArray[i] = count;
		i++;
	}
	
	for (count = 7680; count <= 7929; count++) {
		charSpaceArray[i] = count;
		i++;
	}

};
	
	
function fillANSIPlaceHolder(ANSIArray) {
	var i = 0;
	/******** FOR ALL LANGUAGES *************/
	for (var count = 32; count <= 126; count++) {
		ANSIArray[i] = count;
		i++;
	}
	
	for (count = 128; count <=255; count++) {
		ANSIArray[i] = count;
		i++;
	}
	
	for (count = 256; count <= 591; count++) {
		ANSIArray[i] = count;
		i++;
	}
	
	for (count = 7680; count <= 7929; count++) {
		ANSIArray[i] = count;
		i++;
	}
}
	
function fillLiteralMaskPlaceHolder(literalArray) {
	var i = 0;
	/********* FOR LANGUAGES *************/
	for (var count = 48; count <= 57; count++) {
		literalArray[i] = count;
		i++;
	}
	
	for (count = 65; count <= 90; count++) {
		literalArray[i] = count;
		i++;
	}
	
	for (count = 97; count <= 122; count++) {
		literalArray[i] = count;
		i++;
	}
	
	for (count = 256; count <= 591; count++) {
		literalArray[i] = count;
		i++;
	}
	
	for (count = 7680; count <= 7929; count++) {
		literalArray[i] = count;
		i++;
	}
	
};

function fillAlphanumeric(alphanumericArray) {
	var i = 0;
	/*********** FOR ALL LANGUAGES ************/
	for (var count = 48; count <= 57; count++) {
		alphanumericArray[i] = count;
		i++;
	}
	
	for (count = 65; count <= 90; count++) {
		alphanumericArray[i] = count;
		i++;
	}
	
	for (count = 97; count <= 122; count++) {
		alphanumericArray[i] = count;
		i++;
	}
	
	for (count = 256; count <= 591; count++) {
		alphanumericArray[i] = count;
		i++;
	}
	
	for (count = 7680; count <= 7929; count++) {
		alphanumericArray[i] = count;
		i++;
	}
}


function fillLetterPlaceHolder(letterPlaceHolderArray) {
	var i = 0;
	/******* FOR ENGLISH LANGUAGE **********/
	for (var count = 65; count <= 90; count++) {
		letterPlaceHolderArray[i] = count;
		i++;
	}
	
	for (count = 97; count <= 122; count++) {
		letterPlaceHolderArray[i] = count;
		i++;
	}
	
	for (count = 256; count <= 591; count++) {
		letterPlaceHolderArray[i] = count;
		i++;
	}
	
	for (count = 7680; count <= 7929; count++) {
		letterPlaceHolderArray[i] = count;
		i++;
	}	
}

function fillDigit(digitPlaceHolderArray) {
	var i = 0;
	/************ FOR ALL LANGUAGES ***********/
	for (count = 48; count <= 57; count++) {
			digitPlaceHolderArray[i] = count;
			i++;
	}
}

function deleteRange(currentMask, count) {
	var maskPosition = 0;
	var numberOfException = 0;
	numberOfException = getRelativePosition(currentMask, count);
	maskPosition = numberOfException + count;
	if ((currentMask.charAt(maskPosition) == '\\') && (count == 0)) {
		return getDefaultValue(currentMask.substring(maskPosition, maskPosition+2));
	}
	else if (currentMask.charAt(maskPosition) == '\\') {
		return getDefaultValue(currentMask.substring(maskPosition, maskPosition+2));
	}
	else if (currentMask.charAt(maskPosition-1) == '\\') {
		return getDefaultValue(currentMask.substring(maskPosition+1, maskPosition+3));
	}
	else if (maskPosition == -1) {
		return getDefaultValue(currentMask.charAt(maskPosition+2));
	}
	else {
		return getDefaultValue(currentMask.charAt(maskPosition));
	}
};

function deleteChar(currentMask, count) {
	var maskPosition = 0;
	var numberOfException = 0;
	numberOfException = getRelativePosition(currentMask, count);
	maskPosition = numberOfException + count;
	if (((currentMask.charAt(maskPosition) == '\\') && (count == 0))) {
		return getDefaultValue(currentMask.substring(maskPosition, maskPosition+2));
	}
	else if ((currentMask.charAt(maskPosition) == '\\')) {
		return getDefaultValue(currentMask.substring(maskPosition, maskPosition+2));
	}
	else if (maskPosition == -1) {
		return getDefaultValue(currentMask.charAt(maskPosition+2));
	}
	else {
		return getDefaultValue(currentMask.charAt(maskPosition));
	}
};


function catchIt() {
	if ( (isInTextBox == true) && (currentTextBox != null) && (is_ie) )
	{
		currentPosition = getPosition(currentTextBox);
		//Delete key functionality
		if ( (window.event.keyCode == 46) && (currentMask != 'undefined') && (getSelectionStart(currentTextBox) <= currentTextBox.value.length) ) {
			
			//Get selection range
			if (getSelectionStart(currentTextBox) != getSelectionEnd(currentTextBox)) {
				//get start position for end position process symbols
				
				var startPosition = getSelectionStart(currentTextBox);
				var endPosition = getSelectionEnd(currentTextBox);
				
				var result = new String();;
				result = currentTextBox.value.substring(0, startPosition);
				
				for (var count = startPosition; count <= endPosition -1; count++) {
					result += deleteRange(currentMask, count);
				}								
				result += currentTextBox.value.substring(endPosition, currentTextBox.value.length);
				currentTextBox.value = result;
				setCursorPosition(currentTextBox, startPosition);
				allowClear = true;
				return false;
			}
			else {
				var position = getSelectionStart(currentTextBox);
				var maskPosition = 0;
				var numberOfExceptions = 0;
				var result = new String();
				numberOfExceptions = getRelativePosition(currentMask, position);
				maskPosition = numberOfExceptions+position;
					
				result = currentTextBox.value.substring(0, position);
				
				result += deleteChar(currentMask, position);

				result += currentTextBox.value.substring(position+1, currentTextBox.value.length);
			
				currentTextBox.value = result;
				setCursorPosition(currentTextBox, position+1);
				return false;
			}
		}
		//Backspace key functionality
		else if ((window.event.keyCode == 8) && (currentPosition > 0) && (currentMask != 'undefined') ) {
				var	position = getPosition(currentTextBox);
				var maskPosition = 0;
				var numberOfExceptions = 0;
				var result = new String();
				
				numberOfExceptions = getRelativePosition(currentMask, position);
				maskPosition = numberOfExceptions+position;
				result = currentTextBox.value.substring(0,position);
							
				if (maskPosition == 0) {
					result += getDefaultValue(currentMask.charAt(maskPosition));
				}
				else if ( (currentMask.charAt(maskPosition-2) == '>') || (currentMask.charAt(maskPosition-1) == '<') ) {
					result += getDefaultValue(currentMask.charAt(maskPosition));
				}
				else if (currentMask.charAt(maskPosition-2) == '\\') {
					result += currentMask.charAt(maskPosition);
				}
				else {
					result += getDefaultValue(currentMask.charAt(maskPosition-1));
				}
				
				result += currentTextBox.value.substring(position, currentTextBox.value.length);		
				currentTextBox.value = result;
				setCursorPosition(currentTextBox, position);
		}
	}
};

function getRelativePosition(mask, position) {
	var numberOfException = 0;
	var count = 0;
	while (position > 0) {
		if ( (mask.charAt(count) == '\\') || (mask.charAt(count) == '>') || (mask.charAt(count) == '<')) {}
		else
			position--;
		count++;
	}
	
	count--;
	
	for (var numb = 0; numb  <= count; numb++) {
		if ( (mask.charAt(numb) == '\\') || (mask.charAt(numb) == '>') || (mask.charAt(numb) == '<') ) {
			numberOfException++;
		}
	}
	return numberOfException;
};


function getMaskCharRelatively(mask, position) {
	var number = 0;
	for (var count = 0; count <= position; count++) {
		if ( (mask.charAt(count) == '>') || (mask.charAt(count) == '<') ) {
			number++;
		}
	}
	
	for (var count = 0; count < position; count++) {
		if ( (mask.charAt(count) == '\\') ) {
			number++;

		}
	}
	position += number;
	return position;
};


function findKeyCode(keyCode, codeArray) {
	var result = false;
	for (var count = 0; count < codeArray.length; count++) {
		if (codeArray[count] == keyCode) {
			result = true;
		}
	}
	return result;
};

function returnCharacter(maskChar)
{
	var result = null;
	switch (maskChar)
	{
		case "#":
				result = digitPlaceHolder;
				break;
		case ".":
				result = toNextSymbol;
				break;
		case ",":
				result = toNextSymbol;
				break;
		case ":":
				result = toNextSymbol;
				break;
		case "/":
				result = toNextSymbol;
				break;
		case "\\":
				result = toSaveSymbol;
				break;
		case "&":
				result = ANSIPlaceHolder;
				break;
		case ">":
				result = toUpper;
				break;
		case "<":
				result = toLower;
				break;
		case "A":
				result = alphanumericRequerd;
				break;
		case "a":
				result = alphanumericOptional;
				break;
		case "9":
				result = digitOptional;
				break;
		case "C":
				result = charSpacePlaceHolder;
				break;
		case "?":
				result = letterPlaceHolder;
				break;
		default : 
				result = toNextSymbol;
				break;
	}
	return result;
}

function processMask(textBox, mask, position)
{
	var result = textBox.value;
	var inputChar = result.charAt(position);
	var maskChar = mask.charAt(position);
}

/*
	On Text Box click event
*/
function setCursorPosition(textBox, position)
{
	setCursorPosition(textBox, position);
}

function getDefaultValue(mask)
{
	mask = mask.toString();
	var result = new String();
	for (var count = 0; count <= mask.length; count++)
	{
		if ((count != 0) & (mask.charAt(count-1) == '\\')) {
			result += mask.charAt(count);
		}
		else {
			switch(mask.charAt(count)) {
				case "#":
						result += "_";
						break;
				case ".":
						result += ".";
						break;
				case ",":
						result += ",";
						break;
				case ":":
						result += ":";
						break;
				case "/":
						result += "/";
						break;
				case "\\":
						result += "";
						break;
				case "\&":
						result += "_";
						break;
				case ">":
						result += "";
						break;
				case "<":
						result += "";
						break;
				case "A":
						result += "_";
						break;
				case "a":
						result += "_";
						break;
				case "9":
						result += "_";
						break;
				case "C":
						result += "_";
						break;
				case "?":
						result += "_";
						break;
				default : 
						result += mask.charAt(count);
						break;
			}
		}
	}
	return result;
};

function getPosition(input) {
	var cursorPos = -1;
	if (document.selection && document.selection.createRange) {
		var range = document.selection.createRange().duplicate();
		if (range.parentElement() == input) {
			range.moveStart('textedit', -1);
			cursorPos = range.text.length;
		}
   }
   return cursorPos;
};

function setSelectionRange(input, start, end) {
	var range = input.createTextRange();
	range.collapse(true);
	range.moveStart("character", start);
	range.moveEnd("character", end - start);
	range.select();
};

function setCursorPosition(input, position) {
	var range = input.createTextRange();
	range.collapse(true);
	range.moveStart("character", position);
	range.moveEnd("character", position - position);
	range.select();
}

function getSelectionStart(input) {
	var range = document.selection.createRange();
	var result = 0;
	var isCollapsed = range.compareEndPoints("StartToEnd", range) == 0;
	if (!isCollapsed)
		range.collapse(true);
	var b = range.getBookmark();
	result = parseInt((range.offsetLeft - 1) / 7);
	return result;	
};

function getSelectionEnd(input) {
	var range = document.selection.createRange();
	var result = 0;
	var isCollapsed = range.compareEndPoints("StartToEnd", range) == 0;
	if (!isCollapsed)
		range.collapse(false);
	var b = range.getBookmark();
	result = parseInt((range.offsetLeft - 1) / 7);
	return result;
};
