var KeyHook = {};

KeyHook.ShortCut = function(reaction) {
  this._reaction = reaction || document;
  this._keymap = new Array();
  this._initialize();
}

KeyHook.ShortCut.prototype = {
  _initialize: function() {
    var self = this;
    var listener = function(e) {
      e = (e) ? e : event;
      var tag = (e.target || e.srcElement).tagName.toUpperCase();
      var code = (e.keyCode != 0) ? e.keyCode : e.charCode;
      var type = (code == 27) ? "ESC" :
                 (code == 13) ? "ENTER" :
                 (code == 32) ? "SPC" :
                 (code == 33) ? "PAGEUP" :
                 (code == 34) ? "PAGEDOWN" :
                 (code == 35) ? "END" :
                 (code == 36) ? "HOME" :
                 (code == 37) ? "LEFT" :
                 (code == 38) ? "UP" :
                 (code == 39) ? "RIGHT" :
                 (code == 40) ? "DOWN" :
                 String.fromCharCode(code);
      if (type != "ESC" && (tag == "INPUT" || tag == "TEXTAREA")) { return; }
      if (self._keymap.hasOwnProperty(type)) {
        if (document.addEventListener) {
          e.preventDefault();
          e.stopPropagation();
        } else {
          event.returnValue = false;
          event.cancelBubble = true;
        }
        self._keymap[type].call(self, e);
      }
    }

    if (document.addEventListener) {
      this._reaction.addEventListener("keypress", listener, true);
    }else{
      this._reaction.attachEvent("onkeypress", listener);
    }
  },
  add: function(code, callback) {
    if(code.constructor == Array){
      for (var i=0; i<code.length; i++) {
        this._keymap[code[i]] = callback;
      }
    } else {
      this._keymap[code] = callback;
    }
  }
};
