/*
the third argument to changeKey should be a function
  function exampleKeyChecker (keyCode, key)
which returns an object 
  { cancelKey: boolean, replaceKey: boolean, newKeyCode: number, newKey:
string }
Not all properties need to be present, if cancelKey is set to true the
other properties are not needed.
If replaceKey is set to true then at least newKeyCode needs to be set.
*/
function changeKey (textControl, evt, keyChecker) {
  var keyCode = evt.keyCode ? evt.keyCode :
                evt.charCode ? evt.charCode :
		evt.which ? evt.which : void 0;
  var key;
  if (keyCode) {
    key = String.fromCharCode(keyCode);
  }
  //ignore some combination of keybord keys like backspace, arrows, etc.
  var ignoreKeyCodes = '8 33 34 35 36 37 38 39 40 46';
  if (ignoreKeyCodes.indexOf(keyCode) != -1) {
      return true;
  }
  var keyCheck = keyChecker(keyCode, key);
  if (keyCode && window.event && !window.opera) {
    if (keyCheck.cancelKey) {
      return false;
    } else if (keyCheck.replaceKey) {
      window.event.keyCode = keyCheck.newKeyCode;
      if (window.event.preventDefault) {
        window.event.preventDefault();
      }
      return true;
    } else {
      return true;
    }
  } else if (typeof textControl.setSelectionRange != 'undefined') {
    if (keyCheck.cancelKey) {
      if (evt.preventDefault) {
        evt.preventDefault();
      }
      return false;
    } else if (keyCheck.replaceKey) {
      // cancel the key event and insert the newKey for the current selection
      if (evt.preventDefault) {
        evt.preventDefault();
      }
      var oldSelectionStart = textControl.selectionStart;
      var oldSelectionEnd = textControl.selectionEnd;
      var selectedText = textControl.value.substring(oldSelectionStart, oldSelectionEnd);
      var newText = typeof keyCheck.newKey != 'undefined' ? keyCheck.newKey : String.fromCharCode(keyCheck.newKeyCode);
      textControl.value = 
        textControl.value.substring(0, oldSelectionStart) +
        newText +
        textControl.value.substring(oldSelectionEnd);
      textControl.setSelectionRange(oldSelectionStart + newText.length, oldSelectionStart + newText.length);
      return false;
    } else {
      return true;
    } 
  } else if (keyCheck.cancelKey) {
    if (evt.preventDefault) {
      evt.preventDefault();
    }
    return false;
  } else {
    return true;
  }
}

function lettersToUpperCase (keyCode, key) {
  var newKey = key.toUpperCase();
  if (newKey != key) {
    return { replaceKey: true, newKeyCode: newKey.charCodeAt(), newKey: newKey };
  } else {
    return { cancelKey: false };
  }
}

function digitsToX (keyCode, key) {
  if ("0123456789".indexOf(key) != -1) {
    return { replaceKey: true, newKeyCode: "X".charCodeAt(), newKey: "X" };
  } else {
    return { cancelKey: false };
  }
}

function umlautsToASCII (keyCode, key) {
  var asciiUmlauts = {
    "a": "ae",
    "o": "oe",
    "u": "ue",
    "A": "Ae",
    "O": "Oe",
    "U": "Ue"
  };
  if ("aouAOU".indexOf(key) != -1) {
    return { replaceKey: true, newKeyCode: keyCode, newKey: asciiUmlauts[key] };
  } else {
    return { cancelKey: false };
  }
}

function cancelDigits (keyCode, key) {
  return { cancelKey: "0123456789".indexOf(key) != -1 };
}

function insertOnlyDigits (keyCode, key) {
  return { cancelKey: "0123456789".indexOf(key) == -1 };
}

function cancelEnter (keyCode, key) {
  return { cancelKey: keyCode == 13 };
}

