var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { load } from "../../loader";
export default class NotationBlock {
    constructor(container, config) {
        var _a, _b, _c, _d, _e, _f;
        this.container = container;
        this.config = config;
        this.caption = "";
        this.isEditing = false;
        this.editTextarea = null;
        this.sourceCodeElement = null;
        this.id = (container.getAttribute("id") || "").trim();
        this.caption = (container.getAttribute("caption") || "").trim();
        const sourceFrom = (container.getAttribute("sourceFrom") || "").trim();
        this.source = container.textContent || "";
        if (sourceFrom.length > 0) {
            const sourceElem = document.getElementById(sourceFrom);
            if (sourceElem) {
                this.source = sourceElem.textContent || "";
            }
        }
        this.height = container.getAttribute("height") || "";
        this.showSource = (container.getAttribute("showSource") || "false") == "true";
        const parent = container.parentNode;
        const newRoot = document.createElement("div");
        newRoot.classList.add("notationBlockRoot");
        if ((_a = config.cssClasses) === null || _a === void 0 ? void 0 : _a.root) {
            newRoot.className += " " + config.cssClasses.root;
        }
        this.newRoot = newRoot;
        let html = "";
        if (this.showSource) {
            const sourceLines = this.source.split("\n");
            const sourceClass = ((_b = config.cssClasses) === null || _b === void 0 ? void 0 : _b.sourceContainer) || "";
            const captionClass = ((_c = config.cssClasses) === null || _c === void 0 ? void 0 : _c.sourceCaption) || "";
            const codeClass = ((_d = config.cssClasses) === null || _d === void 0 ? void 0 : _d.sourceCode) || "";
            html += `
        <figure class="notation-source-block ${sourceClass}">
          <div class="notation-source-header">
            <figcaption class="notation-caption ${captionClass}">${this.caption}</figcaption>
            <div class="notation-source-actions">
              <button class="notation-btn notation-copy-btn" id="copyBtn_${this.id}" title="Copy to clipboard">
                <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
                  <path d="M4 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V2zm2-1a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H6zM2 5a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-1h1v1a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h1v1H2z"/>
                </svg>
                <span class="notation-btn-text">Copy</span>
              </button>
              <button class="notation-btn notation-edit-btn" id="editBtn_${this.id}" title="Edit notation">
                <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
                  <path d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/>
                </svg>
                <span class="notation-btn-text">Edit</span>
              </button>
            </div>
          </div>
          <div class="notation-source" id="notationSource_${this.id}">
            <pre class="notation-source-pre">
              <code class="${codeClass}" id="sourceCode_${this.id}">${sourceLines.map((x) => `<span>${x}</span>`).join("\n")}</code>
            </pre>
            <textarea class="notation-edit-textarea" id="editTextarea_${this.id}" style="display: none;"></textarea>
          </div>
          <div class="notation-edit-actions" id="editActions_${this.id}" style="display: none;">
            <button class="notation-btn notation-apply-btn" id="applyBtn_${this.id}">Apply</button>
            <button class="notation-btn notation-cancel-btn" id="cancelBtn_${this.id}">Cancel</button>
          </div>
        </figure>`;
        }
        const outputLabelClass = ((_e = config.cssClasses) === null || _e === void 0 ? void 0 : _e.outputLabel) || "";
        const outputClass = ((_f = config.cssClasses) === null || _f === void 0 ? void 0 : _f.outputContainer) || "";
        html += `
      <div class="notation-output">
        <span class="notation-output-label ${outputLabelClass}"><strong>Output:</strong></span>
        <div id="notationViewer_${this.id}" class="notation-view ${outputClass}">
        </div>
      </div>`;
        newRoot.innerHTML = html;
        parent.insertBefore(newRoot, container);
        parent.removeChild(container);
        const notationViewerBlock = newRoot.querySelector(".notation-view");
        this.notationView = config.createViewer(notationViewerBlock);
        if (this.showSource) {
            this.sourceCodeElement = newRoot.querySelector(`#sourceCode_${this.id}`);
            this.editTextarea = newRoot.querySelector(`#editTextarea_${this.id}`);
            const copyBtn = newRoot.querySelector(`#copyBtn_${this.id}`);
            if (copyBtn) {
                copyBtn.addEventListener("click", () => this.copyToClipboard());
            }
            const editBtn = newRoot.querySelector(`#editBtn_${this.id}`);
            if (editBtn) {
                editBtn.addEventListener("click", () => this.toggleEditMode());
            }
            const applyBtn = newRoot.querySelector(`#applyBtn_${this.id}`);
            if (applyBtn) {
                applyBtn.addEventListener("click", () => this.applyEdit());
            }
            const cancelBtn = newRoot.querySelector(`#cancelBtn_${this.id}`);
            if (cancelBtn) {
                cancelBtn.addEventListener("click", () => this.cancelEdit());
            }
        }
        this.updatePreview();
        console.log("Done Rendering... Adjusting height");
    }
    updatePreview() {
        const fullContents = this.source;
        this.notationView.tableElement.innerHTML = "";
        const [notation, beatLayout, errors, timings] = load(fullContents, { log: true });
        if (errors.length > 0) {
            console.log("Errors: ", errors);
        }
        else {
            console.log("Rendering notation...");
            this.notationView.renderNotation(notation, beatLayout);
        }
        const msg = `Document parsed (${Math.trunc(timings.parseTime * 100) / 100} ms) and built (${Math.trunc(timings.buildTime * 100) / 100} ms)`;
        console.log(msg);
    }
    get captionId() {
        return "notationCaption_" + this.id;
    }
    copyToClipboard() {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                yield navigator.clipboard.writeText(this.source);
                const copyBtn = this.newRoot.querySelector(`#copyBtn_${this.id}`);
                if (copyBtn) {
                    const btnText = copyBtn.querySelector(".notation-btn-text");
                    const originalText = btnText === null || btnText === void 0 ? void 0 : btnText.textContent;
                    if (btnText) {
                        btnText.textContent = "Copied!";
                        setTimeout(() => {
                            if (btnText)
                                btnText.textContent = originalText || "Copy";
                        }, 2000);
                    }
                }
            }
            catch (err) {
                console.error("Failed to copy to clipboard:", err);
                alert("Failed to copy to clipboard");
            }
        });
    }
    toggleEditMode() {
        this.isEditing = !this.isEditing;
        if (this.isEditing) {
            this.enterEditMode();
        }
        else {
            this.exitEditMode();
        }
    }
    enterEditMode() {
        if (!this.editTextarea || !this.sourceCodeElement)
            return;
        this.editTextarea.value = this.source;
        if (this.sourceCodeElement.parentElement) {
            this.sourceCodeElement.parentElement.style.display = "none";
        }
        this.editTextarea.style.display = "block";
        this.editTextarea.style.height = "auto";
        this.editTextarea.style.height = this.editTextarea.scrollHeight + "px";
        const editActions = this.newRoot.querySelector(`#editActions_${this.id}`);
        if (editActions) {
            editActions.style.display = "flex";
        }
        const editBtn = this.newRoot.querySelector(`#editBtn_${this.id}`);
        const btnText = editBtn === null || editBtn === void 0 ? void 0 : editBtn.querySelector(".notation-btn-text");
        if (btnText) {
            btnText.textContent = "Editing...";
        }
        this.editTextarea.focus();
    }
    exitEditMode() {
        if (!this.editTextarea || !this.sourceCodeElement)
            return;
        this.editTextarea.style.display = "none";
        if (this.sourceCodeElement.parentElement) {
            this.sourceCodeElement.parentElement.style.display = "block";
        }
        const editActions = this.newRoot.querySelector(`#editActions_${this.id}`);
        if (editActions) {
            editActions.style.display = "none";
        }
        const editBtn = this.newRoot.querySelector(`#editBtn_${this.id}`);
        const btnText = editBtn === null || editBtn === void 0 ? void 0 : editBtn.querySelector(".notation-btn-text");
        if (btnText) {
            btnText.textContent = "Edit";
        }
    }
    applyEdit() {
        if (!this.editTextarea)
            return;
        this.source = this.editTextarea.value;
        if (this.sourceCodeElement) {
            const sourceLines = this.source.split("\n");
            this.sourceCodeElement.innerHTML = sourceLines.map((x) => `<span>${x}</span>`).join("\n");
        }
        this.updatePreview();
        this.isEditing = false;
        this.exitEditMode();
    }
    cancelEdit() {
        this.isEditing = false;
        this.exitEditMode();
    }
}
//# sourceMappingURL=NotationBlock.js.map