"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const dockview_core_1 = require("dockview-core");
const SideBySideEditor_1 = __importDefault(require("./SideBySideEditor"));
const DEFAULT_CONFIG = {
    showConsole: true,
    persistLayout: true,
    storageKey: "notations-playground-layout",
    layoutVersion: 1,
    syncScroll: true,
};
class DockViewPlayground {
    constructor(container, config = {}) {
        var _a;
        this.dockview = null;
        this.sideBySideEditor = null;
        this.consoleOutput = null;
        this.consoleEntries = [];
        this.container = container;
        this.config = Object.assign(Object.assign({}, DEFAULT_CONFIG), config);
        this._consoleVisible = (_a = this.config.showConsole) !== null && _a !== void 0 ? _a : true;
        this.init();
    }
    get editor() {
        return this.sideBySideEditor;
    }
    get source() {
        var _a;
        return ((_a = this.sideBySideEditor) === null || _a === void 0 ? void 0 : _a.source) || "";
    }
    set source(value) {
        if (this.sideBySideEditor) {
            this.sideBySideEditor.source = value;
        }
    }
    log(message, level = "info") {
        const entry = {
            timestamp: new Date(),
            level,
            message,
        };
        this.consoleEntries.push(entry);
        this.renderConsoleEntry(entry);
    }
    clearConsole() {
        this.consoleEntries = [];
        if (this.consoleOutput) {
            this.consoleOutput.innerHTML = "";
        }
    }
    render() {
        var _a;
        return ((_a = this.sideBySideEditor) === null || _a === void 0 ? void 0 : _a.render()) || false;
    }
    destroy() {
        var _a, _b;
        (_a = this.sideBySideEditor) === null || _a === void 0 ? void 0 : _a.destroy();
        (_b = this.dockview) === null || _b === void 0 ? void 0 : _b.dispose();
        this.container.innerHTML = "";
    }
    resetLayout() {
        if (this.config.storageKey) {
            localStorage.removeItem(this.config.storageKey);
        }
        if (this.dockview) {
            this.dockview.clear();
            this.createDefaultLayout();
        }
    }
    isConsoleVisible() {
        return this._consoleVisible;
    }
    showConsole() {
        var _a;
        if (this._consoleVisible || !this.dockview)
            return;
        this.dockview.addPanel({
            id: "console",
            component: "console",
            title: "Console",
            position: { direction: "below", referencePanel: "editor" },
        });
        const consolePanel = this.dockview.getPanel("console");
        const containerHeight = this.container.clientHeight || 600;
        if ((_a = consolePanel === null || consolePanel === void 0 ? void 0 : consolePanel.group) === null || _a === void 0 ? void 0 : _a.api) {
            consolePanel.group.api.setSize({ height: Math.floor(containerHeight * 0.1) });
        }
        this._consoleVisible = true;
    }
    hideConsole() {
        if (!this._consoleVisible || !this.dockview)
            return;
        const consolePanel = this.dockview.getPanel("console");
        if (consolePanel) {
            consolePanel.api.close();
        }
        this._consoleVisible = false;
    }
    toggleConsole() {
        if (this._consoleVisible) {
            this.hideConsole();
        }
        else {
            this.showConsole();
        }
        return this._consoleVisible;
    }
    init() {
        if (!this.container.style.height && !this.container.offsetHeight) {
            this.container.style.height = "100%";
        }
        this.container.style.width = this.container.style.width || "100%";
        const isDark = this.isDarkMode();
        this.container.classList.add(isDark ? "dockview-theme-dark" : "dockview-theme-light");
        const observer = new MutationObserver(() => {
            const dark = this.isDarkMode();
            this.container.classList.remove("dockview-theme-dark", "dockview-theme-light");
            this.container.classList.add(dark ? "dockview-theme-dark" : "dockview-theme-light");
        });
        observer.observe(document.documentElement, {
            attributes: true,
            attributeFilter: ["class"],
        });
        const dockviewComponent = new dockview_core_1.DockviewComponent(this.container, {
            createComponent: (options) => this.createComponent(options),
        });
        this.dockview = dockviewComponent.api;
        if (!this.config.persistLayout || !this.loadLayout()) {
            this.createDefaultLayout();
        }
        if (this.config.persistLayout) {
            this.dockview.onDidLayoutChange(() => {
                this.saveLayout();
            });
        }
        this.log("Playground initialized", "info");
    }
    isDarkMode() {
        if (this.config.isDarkMode) {
            return this.config.isDarkMode();
        }
        return document.documentElement.classList.contains("dark");
    }
    saveLayout() {
        if (!this.dockview || !this.config.storageKey)
            return;
        try {
            const layout = this.dockview.toJSON();
            const data = {
                version: this.config.layoutVersion,
                layout,
            };
            localStorage.setItem(this.config.storageKey, JSON.stringify(data));
        }
        catch (e) {
            console.warn("Failed to save layout:", e);
        }
    }
    loadLayout() {
        if (!this.dockview || !this.config.storageKey)
            return false;
        try {
            const saved = localStorage.getItem(this.config.storageKey);
            if (saved) {
                const data = JSON.parse(saved);
                if (data.version !== this.config.layoutVersion) {
                    localStorage.removeItem(this.config.storageKey);
                    return false;
                }
                this.dockview.fromJSON(data.layout);
                return true;
            }
        }
        catch (e) {
            console.warn("Failed to load layout:", e);
            if (this.config.storageKey) {
                localStorage.removeItem(this.config.storageKey);
            }
        }
        return false;
    }
    createComponent(options) {
        switch (options.name) {
            case "editor":
                return this.createEditorPanel();
            case "output":
                return this.createOutputPanel();
            case "console":
                return this.createConsolePanel();
            default:
                return {
                    element: document.createElement("div"),
                    init: () => { },
                };
        }
    }
    createDefaultLayout() {
        var _a, _b, _c;
        if (!this.dockview)
            return;
        const containerHeight = this.container.clientHeight || 600;
        const containerWidth = this.container.clientWidth || 800;
        this.dockview.addPanel({
            id: "editor",
            component: "editor",
            title: "Editor",
        });
        if (this._consoleVisible) {
            this.dockview.addPanel({
                id: "console",
                component: "console",
                title: "Console",
                position: { direction: "below", referencePanel: "editor" },
            });
        }
        this.dockview.addPanel({
            id: "output",
            component: "output",
            title: "Notation Output",
            position: { direction: "right", referencePanel: "editor" },
        });
        const editorPanel = this.dockview.getPanel("editor");
        const consolePanel = this.dockview.getPanel("console");
        const outputPanel = this.dockview.getPanel("output");
        if ((_a = consolePanel === null || consolePanel === void 0 ? void 0 : consolePanel.group) === null || _a === void 0 ? void 0 : _a.api) {
            consolePanel.group.api.setSize({ height: Math.floor(containerHeight * 0.1) });
        }
        if ((_b = editorPanel === null || editorPanel === void 0 ? void 0 : editorPanel.group) === null || _b === void 0 ? void 0 : _b.api) {
            editorPanel.group.api.setSize({ width: Math.floor(containerWidth * 0.5) });
        }
        if ((_c = outputPanel === null || outputPanel === void 0 ? void 0 : outputPanel.group) === null || _c === void 0 ? void 0 : _c.api) {
            outputPanel.group.api.setSize({ width: Math.floor(containerWidth * 0.5) });
        }
    }
    createEditorPanel() {
        const element = document.createElement("div");
        element.className = "dvp-panel dvp-editor-panel";
        element.style.cssText = "display: flex; flex-direction: column; height: 100%; padding: 0.5rem;";
        return {
            element,
            init: (_params) => {
                const editorConfig = Object.assign(Object.assign({ initialSource: this.config.initialSource, debounceDelay: 300, syncScroll: this.config.syncScroll, markdownParser: this.config.markdownParser }, this.config.editorConfig), { onSourceChange: (source) => {
                        var _a, _b, _c, _d;
                        this.log(`Source changed (${source.length} chars)`, "info");
                        (_b = (_a = this.config).onSourceChange) === null || _b === void 0 ? void 0 : _b.call(_a, source);
                        (_d = (_c = this.config.editorConfig) === null || _c === void 0 ? void 0 : _c.onSourceChange) === null || _d === void 0 ? void 0 : _d.call(_c, source);
                    }, onNotationParsed: (notation, beatLayout) => {
                        var _a, _b, _c, _d;
                        const lineCount = beatLayout.gridModelsForLine.size;
                        this.log(`Parsed: ${lineCount} line${lineCount !== 1 ? "s" : ""}`, "info");
                        (_b = (_a = this.config).onNotationParsed) === null || _b === void 0 ? void 0 : _b.call(_a, notation, beatLayout);
                        (_d = (_c = this.config.editorConfig) === null || _c === void 0 ? void 0 : _c.onNotationParsed) === null || _d === void 0 ? void 0 : _d.call(_c, notation, beatLayout);
                    }, onParseError: (errors) => {
                        var _a, _b, _c, _d;
                        errors.forEach((e) => {
                            this.log(`Parse error: ${e.message || e}`, "error");
                        });
                        (_b = (_a = this.config).onParseError) === null || _b === void 0 ? void 0 : _b.call(_a, errors);
                        (_d = (_c = this.config.editorConfig) === null || _c === void 0 ? void 0 : _c.onParseError) === null || _d === void 0 ? void 0 : _d.call(_c, errors);
                    }, editorClass: this.config.editorClass });
                this.sideBySideEditor = new SideBySideEditor_1.default(editorConfig);
                const editorEl = this.sideBySideEditor.editorElement;
                editorEl.style.cssText = `
          width: 100%;
          height: 100%;
          resize: none;
          font-family: "SF Mono", "Monaco", "Inconsolata", "Fira Code", monospace;
          font-size: 14px;
          padding: 0.5rem;
          border: 1px solid var(--dv-separator-border, #ddd);
          border-radius: 4px;
          outline: none;
        `;
                element.appendChild(editorEl);
            },
        };
    }
    createOutputPanel() {
        const element = document.createElement("div");
        element.className = "dvp-panel dvp-output-panel";
        element.style.cssText = "display: flex; flex-direction: column; height: 100%;";
        return {
            element,
            init: (_params) => {
                if (this.sideBySideEditor) {
                    const outputEl = this.sideBySideEditor.outputElement;
                    outputEl.style.cssText = `
            width: 100%;
            height: 100%;
            overflow: auto;
            padding: 1rem;
          `;
                    element.appendChild(outputEl);
                }
            },
        };
    }
    createConsolePanel() {
        const element = document.createElement("div");
        element.className = "dvp-panel dvp-console-panel";
        element.style.cssText = "display: flex; flex-direction: column; height: 100%;";
        return {
            element,
            init: (_params) => {
                const header = document.createElement("div");
                header.className = "dvp-console-header";
                header.style.cssText = `
          display: flex;
          align-items: center;
          justify-content: space-between;
          padding: 0.25rem 0.5rem;
          font-size: 0.75rem;
        `;
                const clearBtn = document.createElement("button");
                clearBtn.className = "dvp-console-clear-btn";
                clearBtn.textContent = "Clear";
                clearBtn.style.cssText = `
          padding: 0.125rem 0.5rem;
          font-size: 0.75rem;
          border-radius: 3px;
          cursor: pointer;
        `;
                clearBtn.onclick = () => this.clearConsole();
                header.appendChild(clearBtn);
                element.appendChild(header);
                this.consoleOutput = document.createElement("div");
                this.consoleOutput.className = "dvp-console-output";
                this.consoleOutput.style.cssText = `
          flex: 1;
          overflow: auto;
          padding: 0.5rem;
          font-family: "SF Mono", "Monaco", "Inconsolata", monospace;
          font-size: 0.75rem;
        `;
                element.appendChild(this.consoleOutput);
                this.consoleEntries.forEach((entry) => this.renderConsoleEntry(entry));
            },
        };
    }
    renderConsoleEntry(entry) {
        if (!this.consoleOutput)
            return;
        const line = document.createElement("div");
        line.style.cssText = `
      padding: 0.125rem 0;
      border-bottom: 1px solid var(--dv-separator-border, rgba(0,0,0,0.1));
    `;
        if (entry.level === "error") {
            line.style.color = "#f44336";
        }
        else if (entry.level === "warning") {
            line.style.color = "#ff9800";
        }
        const time = entry.timestamp.toLocaleTimeString();
        line.textContent = `[${time}] ${entry.message}`;
        this.consoleOutput.appendChild(line);
        this.consoleOutput.scrollTop = this.consoleOutput.scrollHeight;
    }
}
exports.default = DockViewPlayground;
//# sourceMappingURL=DockViewPlayground.js.map