'use strict';

var React = require('react');

/**
 * shortcuts.ts — Customizable keyboard shortcuts for all editors.
 *
 * Allows users to remap keyboard shortcuts and provides a central
 * registry for keybindings across all graphic editors.
 */
function parseKeyCombo(combo) {
    var _a;
    const parts = combo.toLowerCase().split("+").map((s) => s.trim());
    return {
        ctrl: parts.includes("ctrl"),
        shift: parts.includes("shift"),
        alt: parts.includes("alt"),
        meta: parts.includes("meta") || parts.includes("cmd"),
        key: (_a = parts.filter((p) => !["ctrl", "shift", "alt", "meta", "cmd"].includes(p))[0]) !== null && _a !== void 0 ? _a : "",
    };
}
function matchesEvent(parsed, e) {
    return (e.ctrlKey === parsed.ctrl &&
        e.shiftKey === parsed.shift &&
        e.altKey === parsed.alt &&
        e.metaKey === parsed.meta &&
        e.key.toLowerCase() === parsed.key);
}
/** Convert a keyboard event to a key combo string. */
function eventToKeyCombo(e) {
    const parts = [];
    if (e.ctrlKey)
        parts.push("Ctrl");
    if (e.shiftKey)
        parts.push("Shift");
    if (e.altKey)
        parts.push("Alt");
    if (e.metaKey)
        parts.push("Meta");
    const key = e.key.length === 1 ? e.key.toUpperCase() : e.key;
    if (!["Control", "Shift", "Alt", "Meta"].includes(e.key)) {
        parts.push(key);
    }
    return parts.join("+");
}
// ── Shortcut Registry ───────────────────────────────────────────
class ShortcutRegistryImpl {
    constructor() {
        this.shortcuts = new Map();
        this.overrides = {};
        this.listeners = new Set();
    }
    /** Register a shortcut. */
    register(def) {
        var _a;
        const currentKey = (_a = this.overrides[def.id]) !== null && _a !== void 0 ? _a : def.defaultKey;
        this.shortcuts.set(def.id, { ...def, currentKey });
        this.notify();
    }
    /** Register multiple shortcuts at once. */
    registerAll(defs) {
        var _a;
        for (const def of defs) {
            const currentKey = (_a = this.overrides[def.id]) !== null && _a !== void 0 ? _a : def.defaultKey;
            this.shortcuts.set(def.id, { ...def, currentKey });
        }
        this.notify();
    }
    /** Unregister a shortcut. */
    unregister(id) {
        this.shortcuts.delete(id);
        this.notify();
    }
    /** Remap a shortcut to a new key combo. */
    remap(id, newKey) {
        const def = this.shortcuts.get(id);
        if (def) {
            def.currentKey = newKey;
            this.overrides[id] = newKey;
            this.notify();
        }
    }
    /** Reset a shortcut to its default. */
    resetToDefault(id) {
        const def = this.shortcuts.get(id);
        if (def) {
            def.currentKey = def.defaultKey;
            delete this.overrides[id];
            this.notify();
        }
    }
    /** Reset all shortcuts to defaults. */
    resetAll() {
        this.overrides = {};
        for (const def of this.shortcuts.values()) {
            def.currentKey = def.defaultKey;
        }
        this.notify();
    }
    /** Handle a keyboard event, triggering matching shortcuts. */
    handleKeyEvent(e) {
        for (const def of this.shortcuts.values()) {
            const parsed = parseKeyCombo(def.currentKey);
            if (matchesEvent(parsed, e)) {
                e.preventDefault();
                def.action();
                return true;
            }
        }
        return false;
    }
    /** Get all registered shortcuts. */
    getAll() {
        return Array.from(this.shortcuts.values());
    }
    /** Get shortcuts by category. */
    getByCategory(category) {
        return this.getAll().filter((s) => s.category === category);
    }
    /** Get all categories. */
    getCategories() {
        return [...new Set(this.getAll().map((s) => s.category))];
    }
    /** Export custom overrides as JSON. */
    exportConfig() {
        return { overrides: { ...this.overrides } };
    }
    /** Import custom overrides from JSON. */
    importConfig(config) {
        var _a;
        this.overrides = { ...config.overrides };
        for (const def of this.shortcuts.values()) {
            def.currentKey = (_a = this.overrides[def.id]) !== null && _a !== void 0 ? _a : def.defaultKey;
        }
        this.notify();
    }
    /** Save overrides to localStorage. */
    save(storageKey = "nice2dev.graphics.shortcuts") {
        try {
            localStorage.setItem(storageKey, JSON.stringify(this.exportConfig()));
        }
        catch ( /* ignore */_a) { /* ignore */ }
    }
    /** Load overrides from localStorage. */
    load(storageKey = "nice2dev.graphics.shortcuts") {
        try {
            const raw = localStorage.getItem(storageKey);
            if (raw)
                this.importConfig(JSON.parse(raw));
        }
        catch ( /* ignore */_a) { /* ignore */ }
    }
    /** Subscribe to changes. Returns unsubscribe function. */
    subscribe(fn) {
        this.listeners.add(fn);
        return () => this.listeners.delete(fn);
    }
    notify() {
        this.listeners.forEach((fn) => fn());
    }
}
/** Global shortcuts registry singleton. */
const ShortcutRegistry = new ShortcutRegistryImpl();
// ── Default Shortcuts ───────────────────────────────────────────
const DEFAULT_SHORTCUTS = {
    // General
    undo: { id: "general.undo", label: "Undo", category: "General", defaultKey: "Ctrl+Z" },
    redo: { id: "general.redo", label: "Redo", category: "General", defaultKey: "Ctrl+Y" },
    copy: { id: "general.copy", label: "Copy", category: "General", defaultKey: "Ctrl+C" },
    paste: { id: "general.paste", label: "Paste", category: "General", defaultKey: "Ctrl+V" },
    cut: { id: "general.cut", label: "Cut", category: "General", defaultKey: "Ctrl+X" },
    delete: { id: "general.delete", label: "Delete", category: "General", defaultKey: "Delete" },
    selectAll: { id: "general.selectAll", label: "Select All", category: "General", defaultKey: "Ctrl+A" },
    save: { id: "general.save", label: "Save", category: "General", defaultKey: "Ctrl+S" },
    duplicate: { id: "general.duplicate", label: "Duplicate", category: "General", defaultKey: "Ctrl+D" },
    // View
    zoomIn: { id: "view.zoomIn", label: "Zoom In", category: "View", defaultKey: "Ctrl+=" },
    zoomOut: { id: "view.zoomOut", label: "Zoom Out", category: "View", defaultKey: "Ctrl+-" },
    zoomFit: { id: "view.zoomFit", label: "Zoom to Fit", category: "View", defaultKey: "Ctrl+0" },
    toggleGrid: { id: "view.toggleGrid", label: "Toggle Grid", category: "View", defaultKey: "Ctrl+'" },
    toggleRulers: { id: "view.toggleRulers", label: "Toggle Rulers", category: "View", defaultKey: "Ctrl+R" },
    toggleMinimap: { id: "view.toggleMinimap", label: "Toggle Minimap", category: "View", defaultKey: "Ctrl+M" },
};
// ── React Hook ──────────────────────────────────────────────────
/** Hook to use shortcuts in a component. Attaches keyboard listener. */
function useShortcuts(active = true) {
    const [shortcuts, setShortcuts] = React.useState(ShortcutRegistry.getAll());
    React.useEffect(() => {
        return ShortcutRegistry.subscribe(() => setShortcuts(ShortcutRegistry.getAll()));
    }, []);
    React.useEffect(() => {
        if (!active)
            return;
        const handler = (e) => ShortcutRegistry.handleKeyEvent(e);
        window.addEventListener("keydown", handler);
        return () => window.removeEventListener("keydown", handler);
    }, [active]);
    return shortcuts;
}

exports.DEFAULT_SHORTCUTS = DEFAULT_SHORTCUTS;
exports.ShortcutRegistry = ShortcutRegistry;
exports.eventToKeyCombo = eventToKeyCombo;
exports.useShortcuts = useShortcuts;
//# sourceMappingURL=shortcuts.js.map
