/*:
 * @target MZ
 * @author Aerosys
 * @plugindesc [Tier 1] [Version 1.0.0] [MV & MZ]
 * 
 * @param globalHotKeys
 * @text Global Hot Keys
 * @type struct<HotKey>[]
 * @desc These Hot Keys are always available when being on Map Scene
 */

/*~struct~HotKey:
 * 
 * @param keyId
 * @text Key ID
 * @type number
 * @desc You can get the KeyIDs from here: https://keyjs.dev/
 * 
 * @param commonEventId
 * @text Common Event
 * @type common_event
 * @desc Common Event to start
 * 
 * @param switchId
 * @text Switch?
 * @type switch
 * @desc When a Switch is selected, this Switch must be ON to trigger the Common Event
 */


(function() {

const PLUGIN_NAME = 'MK_HotKeys';

const reject = (reason) => {
    const message = (
        "An Error has occurred in the Plugin %1: %2 " +
        "If the problem persists, contact the Plugin Creator."
    ).format(PLUGIN_NAME, reason);
    throw Error(message);
}

if (!PluginManager._parameters[PLUGIN_NAME.toLowerCase()]) {
    reject((
        "Please check that this plugin's filename is \"%1.js\". " +
        "Subdirectories (e.g.: js/plugins/xy/thisPlugin.js) are not allowed."
    ).format(PLUGIN_NAME));
}

const structure = (serialized, parameterName) => {
    if (!serialized) {
        reject((
            "The Plugin Parameter \"%1\" is missing. " +
            "Please check it in the Plugin Manager. It may help to re-install this Plugin (i.e.: remove, re-add)."
        ).format(parameterName));
    }
    try {
        return JSON.parse(serialized);
    
    } catch (e) {
        reject((
            "The Plugin Parameter \"%1\" is corrupted. " +
            "Please check it in the Plugin Manager. It may help to re-install this Plugin (i.e.: remove, re-add)."
        ).format(parameterName));
    }
}

const params = PluginManager.parameters(PLUGIN_NAME);
const globalHotKeys = structure(params.globalHotKeys || '[ ]')
    .map(JSON.parse)
    .map((data) => ({
        keyId:          Number(data.keyId) || 0,
        commonEventId:  Number(data.commonEventId) || 0,
        switchId:       Number(data.switchId) || 0,
    }));


Game_System.prototype.registerHotKey = function(keyId, commonEventId) {
    this._hotKeys = this._hotKeys || { };
    this._hotKeys[keyId] = {
        commonEventId,
    };
}

Game_System.prototype.unregisterHotKey = function(keyId) {
    this._hotKeys = this._hotKeys || { };
    this._hotKeys[keyId] = undefined;
}

const alias_SceneMap_update = Scene_Map.prototype.update;
Scene_Map.prototype.update = function() {
    alias_SceneMap_update.call(this);

    const systemHotKeys = Object
        .entries($gameSystem._hotKeys || { })
        .filter(([_, item]) => !!item)
        .map(([keyId, item]) => ({
            keyId,
            commonEventId: item.commonEventId,
        }));
    
    systemHotKeys.concat(globalHotKeys)
        .filter(item => !item.switchId || $gameSwitches.value(item.switchId))
        .forEach(item => {
            const label = 'C_%1'.format(item.commonEventId);
            Input.keyMapper[item.keyId] = label;

            if (Input.isTriggered(label)) {
                $gameTemp.reserveCommonEvent(item.commonEventId);
            }
        });
}


})();
