import { KeybindingsRegistry as K2 } from 'monaco-editor/esm/vs/platform/keybinding/common/keybindingsRegistry.js';
import { EditorContextKeys } from 'monaco-editor/esm/vs/editor/common/editorContextKeys.js';
import * as _ from 'lodash';
import { compareChords } from './utils';
import { BaseObserver } from '@journeyapps-labs/common-utils';
export class CommandBindings extends BaseObserver {
    constructor() {
        super();
        this.custom = [];
    }
    updated() {
        this.iterateListeners((cb) => { var _a; return (_a = cb.updated) === null || _a === void 0 ? void 0 : _a.call(cb); });
    }
    addKeybinding(binding) {
        this.custom.push(binding);
        this.updated();
    }
    deleteKeybinding(binding) {
        const index = this.custom.findIndex((c) => compareChords(c, binding));
        this.custom.splice(index, 1);
        this.updated();
    }
}
export class CustomCommandBindings extends CommandBindings {
    constructor(command) {
        super();
        this.command = command;
    }
    serialize() {
        if (!this.custom) {
            return [];
        }
        return this.custom.map((c) => {
            return {
                command: this.command,
                keybinding: c,
                when: EditorContextKeys.editorTextFocus
            };
        });
    }
    getDefaults() {
        return [];
    }
}
export class ExistingCommandBindings extends CommandBindings {
    constructor(command, defaults) {
        super();
        this.command = command;
        this.defaults = defaults;
        this.touched = false;
    }
    addKeybinding(binding) {
        this.touched = true;
        super.addKeybinding(binding);
    }
    deleteKeybinding(binding) {
        this.touched = true;
        super.deleteKeybinding(binding);
    }
    serialize() {
        if (!this.touched) {
            return this.defaults;
        }
        return this.custom.map((c) => {
            // first try existing
            const existing = this.defaults.find((b) => {
                return compareChords(b.keybinding, c);
            });
            if (existing) {
                return existing;
            }
            // okay there's one, this is easy
            if (this.defaults.length === 1) {
                return Object.assign(Object.assign({}, this.defaults[0]), { keybinding: c });
            }
            // rip, just make a new one, even though the 'when' condition might not contain other
            // required entries such as EditorContextKeys.XYZ
            return {
                command: this.command,
                keybinding: c,
                when: EditorContextKeys.editorTextFocus
            };
        });
    }
    getDefaults() {
        return this.defaults.map((d) => d.keybinding);
    }
}
export class KeybindingsRegistry extends BaseObserver {
    constructor() {
        super();
        this.save = _.debounce(() => {
            K2._cachedMergedKeybindings = [];
            for (let [command, group] of this.map.entries()) {
                group.serialize().forEach((e) => {
                    K2._cachedMergedKeybindings.push(command, e);
                });
            }
            this.iterateListeners((cb) => { var _a; return (_a = cb.saved) === null || _a === void 0 ? void 0 : _a.call(cb); });
        }, 100);
        this.map = new Map();
    }
    getCommandKeybinding(id) {
        if (!this.map.has(id)) {
            const binding = new CustomCommandBindings(id);
            binding.registerListener({
                updated: () => {
                    this.save();
                }
            });
            this.map.set(id, binding);
        }
        return this.map.get(id);
    }
    load() {
        this.map.clear();
        _.chain(K2.getDefaultKeybindings())
            .groupBy('command')
            .forEach((commands, key) => {
            const c = new ExistingCommandBindings(key, commands);
            c.registerListener({
                updated: () => {
                    this.save();
                }
            });
            this.map.set(key, c);
        })
            .value();
    }
}
//# sourceMappingURL=KeybindingsRegistry.js.map