/*
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);
  }
  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 oTo0 (keyCode, key) {
  if ("o".indexOf(key) != -1 || "O".indexOf(key) != -1) {
    return { replaceKey: true,
             newKeyCode: "0".charCodeAt(),
             newKey: "0" };
  }
  else {
    return lettersToUpperCase(keyCode, key);
    //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 = {
    "Ã¤": "ae",
    "Ã¶": "oe",
    "Ã¼": "ue",
    "Ã?": "Ae",
    "Ã?": "Oe",
    "Ã?": "Ue"
  };
  if ("Ã¤Ã¶Ã¼Ã?Ã?Ã?".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 };
}

/*
<p>
<label>
Letters should be converted to upper case:
<input type="text" 
       onkeypress="return changeKey(this, event, lettersToUpperCase);">
</label>
</p>

<p>
<label>
Digits should be cancelled:
<input type="text" 
       onkeypress="return changeKey(this, event, cancelDigits);">
</label>
</p>

<p>
<label>
Digits should be replaced with "X":
<input type="text"
       onkeypress="return changeKey(this, event, digitsToX);">
</label>
</p>

<p>
<label>
German one letter umlauts should be replaced with two letter ASCII
sequence (only for Mozilla):
<input type="text" 
       onkeypress="return changeKey(this, event, umlautsToASCII);">
</label>
</p>
*/
