/* --------------------------------------------------------------
 shortcuts.js 2016-09-13
 Gambio GmbH
 http://www.gambio.de
 Copyright (c) 2016 Gambio GmbH
 Released under the GNU General Public License (Version 2)
 [http://www.gnu.org/licenses/gpl-2.0.html]
 --------------------------------------------------------------
 */

/**
 * ## Shortcuts Extension
 *
 * This extensions handles the invocation of custom registered shortcut callbacks.
 * You can also register your own shortcuts by using the library function.
 * Please refer to the library file for further information.
 *
 * @module Admin/Extensions/shortcuts
 */
gx.extensions.module(
    'shortcuts',

    [
        `${gx.source}/libs/shortcuts`
    ],

    function (data) {
        // ------------------------------------------------------------------------
        // VARIABLES
        // ------------------------------------------------------------------------

        // Module element.
        const $this = $(this);

        // Module default parameters.
        const defaults = {
            // Milliseconds to wait after pressing a key (for the shortcut check).
            delay: 100
        };

        // Module options.
        const options = $.extend(true, {}, defaults, data);

        // Module instance.
        const module = {};

        // List of currently pressed keys.
        let pressedKeys = [];

        // ------------------------------------------------------------------------
        // FUNCTIONS
        // ------------------------------------------------------------------------

        /**
         * Handles the key down event (when a key has been pressed down).
         *
         * @param {jQuery.Event} event Triggered event.
         * @private
         */
        function _onKeyDown(event) {
            // Register pressed keys.
            pressedKeys.push(event.which);
        }

        /**
         * Handles the key up event (when a key has been released).
         *
         * @private
         */
        function _onKeyUp() {
            // Perform the shortcut check after a certain delay.
            setTimeout(_checkShortcut, options.delay);
        }

        /**
         * Performs a shortcut check by matching the shortcuts in the register object.
         *
         * @private
         */
        function _checkShortcut() {
            for (const shortcut of jse.libs.shortcuts.registeredShortcuts) {
                if (_checkArrayEquality(shortcut.combination, pressedKeys)) {
                    shortcut.callback();
                    break;
                }
            }

            // Reset pressed keys array.
            pressedKeys = [];
        }

        /**
         * Returns whether the provided arrays are equal.
         *
         * @param {Array} a Array to compare.
         * @param {Array} b Other array to compare.
         * @returns {Boolean} Are the arrays equal?
         * @private
         */
        function _checkArrayEquality(a, b) {
            if (a === b) {
                return true;
            }
            if (a == null || b === null) {
                return false;
            }
            if (a.length !== b.length) {
                return false;
            }

            for (var i = 0; i < a.length; ++i) {
                if (a[i] !== b[i]) {
                    return false;
                }
            }

            return true;
        }

        // ------------------------------------------------------------------------
        // INITIALIZATION
        // ------------------------------------------------------------------------

        /**
         * Initialize method of the widget, called by the engine.
         */
        module.init = done => {
            // Bind key press event handlers.
            $this
                .on('keydown', _onKeyDown)
                .on('keyup', _onKeyUp);

            // Finish initialization.
            done();
        };

        return module;
    }
);