
/**
 * The main shorty service
 *
 * @package shorty
 * @copyright 2015 jtrussell
 */

angular.module('shorty')
  .provider('shorty', function() {
    'use strict';

    var mousetrap;

    /**
     * Optionally provide your own mousetrap instance
     *
     * @see https://github.com/ccampbell/mousetrap
     * @param {Object} m A Mousetrap "global"
     */
    this.setMousetrap = function(m) {
      mousetrap = m;
    };

    this.$get = ['$window', '$log', 'shortySortFilter', 'shortyGroupFilter',
        function($window, $log, shortySortFilter, shortyGroupFilter) {
      var exports = {}
        , trap = mousetrap || $window.Mousetrap;

      var shortcutsBuffer = []
        , activeShortcuts = [];

      /**
       * Register a keyboard shortuct combo
       *
       * @param {String} keyCombo The Mousetrap key combo string
       * @param {String} eventName The event to broadcast
       * @param {String} desc A description of the shortcut for help text
       * @param {String} group A group for help text
       * @return {shorty} This service for chaining
       */
      exports.on = function(keyCombo, eventName, desc, group, global) {
        shortcutsBuffer.push({
          combo: keyCombo,
          event: eventName,
          group: group || '',
          desc: desc || '',
          global: angular.isDefined(global) ? global : false
        });
        return exports;
      };

      /**
       * Register a global keyboard shortuct combo
       *
       * @param {String} keyCombo The Mousetrap key combo string
       * @param {String} eventName The event to broadcast
       * @param {String} desc A description of the shortcut for help text
       * @param {String} group A group for help text
       * @return {shorty} This service for chaining
       */
      exports.onGlobal = function(keyCombo, eventName, desc, group) {
        return exports.on(keyCombo, eventName, desc, group, true);
      };

      /**
       * De-register a keyboard shortcut
       *
       * @param {String} keyCombo The Mousetrap key combo string
       * @return {shorty} This service for chaining
       */
      exports.off = function(keyCombo) {
        trap.unbind(keyCombo);
        return exports;
      };

      /**
       * Close a shortcut registration chain by binding to a scope
       *
       * @param {$scope} scope An angular scope to broadcast to
       * @return {shorty} This service for chaining
       */
      exports.broadcastTo = function(scope) {

        // Register events, setup destroy handlers, add to list of active
        // shortcuts
        angular.forEach(shortcutsBuffer, function(c) {
          var bindFn = 'bind';
          if(c.global) {
            if(angular.isDefined(trap.bindGlobal)) {
              bindFn = 'bindGlobal';
            } else {
              $log.debug('Mousetrap plugin "bindGlobal" not available. Falling back to regular bind');
            }
          }

          trap[bindFn](c.combo, function() {
            scope.$broadcast(c.event);
            scope.$apply();
          });

          // Add to list or active shortcuts. First we must make sure there
          // doesn't already exist a shortuct with this key combo... if so kill
          // it (it may have a different group and/or description). Then, insert
          // this shortcut in the appropriate spot... could use some
          // optimization.
          var ix;
          for(ix = activeShortcuts.length; ix--;) {
            if(c.combo === activeShortcuts[ix].combo) {
              activeShortcuts.splice(ix, 1);
              ix = 0;
            }
          }
          activeShortcuts.push(c); // We'll do all our sorting at the end.

          // To optimize... one $destroy handler
          scope.$on('$destroy', function() {
            trap.unbind(c.combo);
          });
        });

        // Clean the temp shortcuts buffer
        shortcutsBuffer.length = 0;

        // Sort the list of active shortcuts
        shortySortFilter(activeShortcuts);

        return exports;
      };

      exports.getActiveShortcuts = function(group) {
        return shortyGroupFilter(activeShortcuts, group);
      };

      return exports;
    }];
  });

@@ -1011,32 +1011,190 @@
 p for help text%0A
+       * @param %7BBoolean%7D global Whether or not to register a global shortut%0A       * @param %7BString%7D keyboardEvent The specific keyboard event to listen for%0A
        * @return
@@ -1303,24 +1303,39 @@
 roup, global
+, keyboardEvent
 ) %7B%0A        
@@ -1530,16 +1530,56 @@
  : false
+,%0A          keyboardEvent: keyboardEvent
 %0A       
@@ -1609,32 +1609,510 @@
 orts;%0A      %7D;%0A%0A
+      exports.onKeyPress = function(keyCombo, eventName, desc, group) %7B%0A        return exports.on(keyCombo, eventName, desc, group, false, 'keypress');%0A      %7D;%0A%0A      exports.onKeyDown = function(keyCombo, eventName, desc, group) %7B%0A        return exports.on(keyCombo, eventName, desc, group, false, 'keydown');%0A      %7D;%0A%0A      exports.onKeyUp = function(keyCombo, eventName, desc, group) %7B%0A        return exports.on(keyCombo, eventName, desc, group, false, 'keyup');%0A      %7D;%0A%0A
       /**%0A      
@@ -2616,32 +2616,525 @@
 rue);%0A      %7D;%0A%0A
+      exports.onGlobalKeyPress = function(keyCombo, eventName, desc, group) %7B%0A        return exports.on(keyCombo, eventName, desc, group, true, 'keypress');%0A      %7D;%0A%0A      exports.onGlobalKeyDown = function(keyCombo, eventName, desc, group) %7B%0A        return exports.on(keyCombo, eventName, desc, group, true, 'keydown');%0A      %7D;%0A%0A      exports.onGlobalKeyUp = function(keyCombo, eventName, desc, group) %7B%0A        return exports.on(keyCombo, eventName, desc, group, true, 'keyup');%0A      %7D;%0A%0A
       /**%0A      

Add specific keyboard events to shorty exports