/*
 * Copyright (c) 1995-2005 Macromedia, Inc. All rights reserved. 
*/
var KT_focusedEl = null;

/********** 
KT_validateSingle function
description:
Validates single character agains single mask component
params: 
ascchar: character
single character, to test if it is correct in the context of the mask character 
maskchar: character
single mask character, see below for meaning
returns: 
boolean
 **********/
function KT_validateSingle(ascchar, maskchar) {
var cchar = ascchar.charCodeAt(0);
switch (maskchar) {
case "9": //numeric
if (cchar < 58 && cchar > 47) {
return true;
}
break;
case "A": //letter
if ((cchar < 91 && cchar > 64) || (cchar < 123 && cchar > 96)) {
return true;
}
break;
case "X": //letter or numeric
if ((cchar < 91 && cchar > 64) || (cchar < 123 && cchar > 96) || (cchar < 58 && cchar > 47)) {
return true;
}
break;
case "?": //any character
return true;
break;
default:
return true;
break;
}
}

/********** 
KT_maskDefaultValue function
description:
Called with a special mask character, returns the default value for that type of mask
params:
maskchar: character
single mask character, see below for meaning
returns:
character
**********/
function KT_maskDefaultValue(maskchar) {
switch (maskchar) {
case "9": //numeric
return '0';
break;
case "A": //letter
return 'a';
break;
case "X": //letter or numeric
return '0';
break;
case "?": //any character
return '0';
break;
default:
return '0';
break;
}
}

/********** 
KT_isSpecialChar function
description:
Checks if the parameter is a special mask character
params:
ascchar: character
Special mask characters: 
9 - numeric
A - letters
X - letter or number
? - any character
returns:
boolean
**********/
function KT_isSpecialChar(ascchar) {
if (ascchar == '9' || ascchar == 'A' || ascchar == 'X' || ascchar == '?')  {
return true;
} else {
return false;
}
}

/**********
mask_onValueChanged function
description:
Called when 
- the user types something in the input
- the input loses the focus
It validates the input's value against the input's mask
params: 
none
returns:
none
**********/
function mask_onValueChanged() {
if ((typeof window.getSelection == 'undefined' && typeof document.selection == 'undefined')) {
// if the current browser is not compatible, do nothing
return;
}

if (KT_focusedEl == null || KT_focusedEl.mask == null || KT_focusedEl.mask == '') {
return;
}

var mask = KT_focusedEl.mask;
var val = KT_focusedEl.value;
var i = 0;
var moveCursor = false;

if (val == KT_focusedEl.oldText) {
// if the field content did not change since the last update, do nothing
return;
}
if (val.length > mask.length) {
// strip trailing characters if text length is bigger than mask length
val = val.substr(0, mask.length);
moveCursor = true;
}
for (; i < mask.length ; i++) {
if (val.charCodeAt(i).toString() != 'NaN') {
//if the char is inserted
if (KT_isSpecialChar(mask.charAt(i))) {
if (KT_validateSingle(val.charAt(i), mask.charAt(i))) {
//character is correct, go to next
continue;
} else {
//revert to the last known good value, increase index to break loop
val = KT_focusedEl.oldText;
i = mask.length;
break;
}
} else {
//normal character in the mask
if (val.charAt(i) != mask.charAt(i)) {
//if the character is different from the mask
if (i == val.length - 1) {
//append last character and move cursor to the end
var lastChar = val.substr(val.length -1, val.length);
val = val.substr(0, val.length -1) + mask.charAt(i) + lastChar;
moveCursor = true;
continue;
} else {
//revert to the last known good value, increase index to break loop
val = KT_focusedEl.oldText;
i = mask.length;
}
break;
}
}
} else {
//if the current char is not inserted
if (val.length < KT_focusedEl.oldText.length) {
//deleted character
break;
}
for (;i<mask.length;i++) {
if (!KT_isSpecialChar(mask.charAt(i))) {
//re-enter the mask characters if it has been deleted
val += mask.charAt(i);
moveCursor = true;
} else {
break;
}
}
break;
}
}
if (val.length > mask.length) {
// strip trailing characters if text length is bigger than mask length
val = val.substr(0, mask.length);
moveCursor = true;
}
if (KT_focusedEl.value != val) {
KT_focusedEl.value = val; //last calculated correct value
}
KT_focusedEl.oldText = val; //update so we can check on next character
if (moveCursor) {
// no need to move the cursor, it is automatically moved at the end of the sellection by IE and Mozilla
}
}

/********** 
mask_parseFirstTime function
description:
Called from mask_onSetFocus, only the first time ( when obj.mask is undefined)
Tries to parse the initial value into a valid format, with the following algorithm:
- normalizes the string adding non special mask characters if they do not exist
- it strips the mask of all non special characters
- rebuilds the string using the stripped mask
- compares the string with the stripped mask and changes the values if they are invalid
- rebuild the string and returns
params:
none
returns:
none
**********/
function mask_parseFirstTime(value, mask) {
var strippedmask = ''; var strippedvalue = '';
cond = 1;imask = 0; ival = 0;cnt = 0;

//NORMALIZE VALUE: add non special characters
while (cond == 1) {
cond = 1;
if (!KT_isSpecialChar(mask.charAt(imask))) {
if (value.charCodeAt(ival).toString() != 'NaN') {
if (mask.charAt(imask) == value.charAt(ival)) {
imask++;ival++;
} else {
value = value.substr(0, ival) + mask.charAt(imask) + value.substr(ival, value.length);
imask = 0; ival = 0; cond = 1;
}
} else {
value += KT_maskDefaultValue(mask.charAt(imask));
}
} else {
imask++;ival++;
}
if (imask >= mask.length || ival >= value.length) {
cond = 0;
}
}

//save only the special chars in a mask
for (i=0;i<mask.length;i++) {
if (KT_isSpecialChar(mask.charAt(i))) {
strippedmask += mask.charAt(i);
if (value.charCodeAt(i).toString() != 'NaN') {
strippedvalue += value.charAt(i);
} else {
strippedvalue += KT_maskDefaultValue(mask.charAt(i));
}
}
}

oldvalue = value; //save the old value for reference
value = strippedvalue;
var newvalue = '';

//rebuild the string removing invalid values and replacing them with defaults
for (i=0;i<strippedmask.length;i++) {
if (!KT_validateSingle(value.charAt(i), strippedmask.charAt(i))) {
newvalue += KT_maskDefaultValue(strippedmask.charAt(i));
} else {
newvalue += value.charAt(i);
}
}

//rebuild the value,by adding the initial non special mask characters
var toret = ''; var j = 0; //j holds the index in the stripped mask
for (i=0;i<mask.length;i++) {
if (KT_isSpecialChar(mask.charAt(i))) {
toret += newvalue.charAt(j++);
} else {
toret += mask.charAt(i);
}
}
return toret;
}

/********** 
mask_onSetFocus function
description:
Called when the input gets the focus
Saved the current input in a global variable and also the current value
params:
none
returns:
none
**********/
function mask_onSetFocus(obj, mask) {
if ((typeof window.getSelection == 'undefined' && typeof document.selection == 'undefined')) {
// if the current browser is not compatible, do nothing
return;
}
if (typeof obj.mask == 'undefined') {
ret = '';
if (obj.value != '') {
ret = mask_parseFirstTime(obj.value, mask);
}
obj.value = ret;
obj.mask = mask;
}
KT_focusedEl = obj; // store the current input object in a global variable
if (typeof KT_focusedEl.oldText == 'undefined') {
KT_focusedEl.oldText = obj.value; // save the input current value
mask_onValueChanged(); // validates the current input value
}
}

/********** 
mask_onKillFocus function
description:
Called when the input loses the focus
Verifies the input's value
params:
none
returns:
none
**********/
function mask_onKillFocus() {
if ((typeof window.getSelection == 'undefined' && typeof document.selection == 'undefined')) {
// if the current browser is not compatible, do nothing
return;
}
mask_onValueChanged(); // validates the current input value
KT_focusedEl = null;
}
