/* --------------------------------------------------------------
 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;
	}
);