import { Plugin } from './plugin.js';
import { MetaModule } from '../meta-api/module.js';
export class ToolboxEntry {
    constructor(toolbox, entry) {
        this.toolbox = toolbox;
        this.entry = entry;
    }
    dispose() {
        this.toolbox.removeEntry(this.entry);
    }
    update(entry) {
        this.toolbox.updateEntry(this.entry, entry);
        this.entry = entry;
    }
}
export class Toolbox extends Plugin {
    constructor() {
        super(...arguments);
        this.entries = [];
        this.whitelist = null;
    }
    onInstall(editor) {
        this.editor = editor;
        this.renderer = this.editor.sourceEditor.getApiRenderer();
    }
    setEntries(entries) {
        this.entries = entries;
    }
    addEntry(entry, position) {
        const mod = this.editor.output.runner.getModule(entry.id || entry.name);
        const injectIndex = typeof position === 'undefined' ? this.entries.length : position;
        const disposableEntry = new ToolboxEntry(this, entry);
        this.entries.splice(injectIndex, 0, entry);
        if (typeof entry.onInstall === 'function') {
            entry.onInstall(this.editor, mod);
        }
        this.update();
        return disposableEntry;
    }
    removeEntry(entry) {
        const index = this.entries.indexOf(entry);
        this.entries.splice(index, 1);
        this.update();
    }
    updateEntry(oldEntry, entry) {
        const index = this.entries.indexOf(oldEntry);
        this.entries.splice(index, 1, entry);
        this.update();
    }
    setWhitelist(whitelist) {
        this.whitelist = whitelist;
        this.update();
    }
    whitelistEntry(id, whitelist) {
        this.whitelist = this.whitelist || {};
        this.whitelist[id] = whitelist;
        this.update();
    }
    removeWhitelistEntry(id) {
        if (!this.whitelist || !this.whitelist[id]) {
            return;
        }
        delete this.whitelist[id];
        this.update();
    }
    update() {
        // Not injected yet, let the inject callback generate the toolbox
        if (!this.editor || !this.editor.injected) {
            return;
        }
        this.onInject();
    }
    onInject() {
        if (!this.editor || !this.renderer) {
            return;
        }
        let entries = this.entries;
        if (this.whitelist) {
            const modules = Object.keys(this.whitelist);
            entries = this.entries.filter(e => modules.indexOf(e.name) !== -1);
        }
        const toolbox = entries
            .map(entry => {
            if (typeof entry === 'function' && this.editor) {
                entry = entry(this.editor);
            }
            let moduleWhitelist = null;
            if (this.whitelist && this.whitelist[entry.name]) {
                moduleWhitelist = this.whitelist[entry.name];
            }
            return this.renderer.renderToolboxEntry(new MetaModule(entry, undefined), moduleWhitelist);
        })
            .filter(entry => entry);
        this.editor.sourceEditor.setToolbox(toolbox);
    }
    registerQueryHandlers(engine) {
    }
}
export default Toolbox;
//# sourceMappingURL=toolbox.js.map