import TabContextMenu from "./TabContextMenu";
import { hasClass, addClass, removeClass } from "@matdata/yasgui-utils";
import sortablejs from "sortablejs";
import "./TabElements.scss";
const MOON_ICON = `<svg viewBox="0 0 24 24" fill="currentColor">
  <path d="M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9c0-.46-.04-.92-.1-1.36-.98 1.37-2.58 2.26-4.4 2.26-2.98 0-5.4-2.42-5.4-5.4 0-1.81.89-3.42 2.26-4.4-.44-.06-.9-.1-1.36-.1z"/>
</svg>`;
const SUN_ICON = `<svg viewBox="0 0 24 24" fill="currentColor">
  <path d="M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zM2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1zm18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1zM11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1zm0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1zM5.99 4.58c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41L5.99 4.58zm12.37 12.37c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0 .39-.39.39-1.03 0-1.41l-1.06-1.06zm1.06-10.96c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06zM7.05 18.36c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06z"/>
</svg>`;
export class TabListEl {
    constructor(yasgui, tabList, tabId) {
        this.tabList = tabList;
        this.yasgui = yasgui;
        this.tabId = tabId;
    }
    delete() {
        var _a;
        if (this.tabEl) {
            (_a = this.tabList._tabsListEl) === null || _a === void 0 ? void 0 : _a.removeChild(this.tabEl);
            delete this.tabList._tabs[this.tabId];
        }
    }
    startRename() {
        if (this.renameEl) {
            const tab = this.yasgui.getTab(this.tabId);
            if (tab) {
                this.renameEl.value = tab.name();
                addClass(this.tabEl, "renaming");
                this.renameEl.focus();
            }
        }
    }
    active(active) {
        if (!this.tabEl)
            return;
        if (active) {
            addClass(this.tabEl, "active");
            this.tabEl.children[0].setAttribute("aria-selected", "true");
            this.tabEl.children[0].setAttribute("tabindex", "0");
        }
        else {
            removeClass(this.tabEl, "active");
            this.tabEl.children[0].setAttribute("aria-selected", "false");
            this.tabEl.children[0].setAttribute("tabindex", "-1");
        }
    }
    rename(name) {
        if (this.nameEl) {
            this.nameEl.textContent = name;
        }
    }
    setAsQuerying(querying) {
        if (querying) {
            addClass(this.tabEl, "querying");
        }
        else {
            removeClass(this.tabEl, "querying");
        }
    }
    draw(name) {
        this.tabEl = document.createElement("div");
        this.tabEl.setAttribute("role", "presentation");
        this.tabEl.ondblclick = () => {
            this.startRename();
        };
        addClass(this.tabEl, "tab");
        this.tabEl.addEventListener("keydown", (e) => {
            if (e.code === "Delete")
                handleDeleteTab();
        });
        const handleDeleteTab = (e) => {
            var _a;
            e === null || e === void 0 ? void 0 : e.preventDefault();
            (_a = this.yasgui.getTab(this.tabId)) === null || _a === void 0 ? void 0 : _a.close();
        };
        const tabLinkEl = document.createElement("a");
        tabLinkEl.setAttribute("role", "tab");
        tabLinkEl.href = "#" + this.tabId;
        tabLinkEl.id = "tab-" + this.tabId;
        tabLinkEl.setAttribute("aria-controls", this.tabId);
        tabLinkEl.addEventListener("blur", () => {
            if (!this.tabEl)
                return;
            if (this.tabEl.classList.contains("active")) {
                tabLinkEl.setAttribute("tabindex", "0");
            }
            else {
                tabLinkEl.setAttribute("tabindex", "-1");
            }
        });
        tabLinkEl.addEventListener("focus", () => {
            if (!this.tabEl)
                return;
            if (this.tabEl.classList.contains("active")) {
                const allTabs = Object.keys(this.tabList._tabs);
                const currentTabIndex = allTabs.indexOf(this.tabId);
                this.tabList.tabEntryIndex = currentTabIndex;
            }
        });
        tabLinkEl.addEventListener("click", (e) => {
            e.preventDefault();
            this.yasgui.selectTabId(this.tabId);
        });
        this.nameEl = document.createElement("span");
        this.nameEl.textContent = name;
        tabLinkEl.appendChild(this.nameEl);
        const closeBtn = document.createElement("div");
        closeBtn.innerHTML = "&#x2716;";
        closeBtn.title = "Close tab";
        closeBtn.setAttribute("tabindex", "-1");
        closeBtn.setAttribute("aria-hidden", "true");
        addClass(closeBtn, "closeTab");
        closeBtn.addEventListener("click", handleDeleteTab);
        tabLinkEl.appendChild(closeBtn);
        const renameEl = (this.renameEl = document.createElement("input"));
        renameEl.type = "text";
        renameEl.value = name;
        renameEl.onkeyup = (event) => {
            var _a;
            if (event.key === "Enter") {
                (_a = this.yasgui.getTab(this.tabId)) === null || _a === void 0 ? void 0 : _a.setName(renameEl.value);
                removeClass(this.tabEl, "renaming");
            }
        };
        renameEl.onblur = () => {
            var _a;
            (_a = this.yasgui.getTab(this.tabId)) === null || _a === void 0 ? void 0 : _a.setName(renameEl.value);
            removeClass(this.tabEl, "renaming");
        };
        tabLinkEl.appendChild(this.renameEl);
        tabLinkEl.oncontextmenu = (ev) => {
            var _a;
            (_a = this.tabList.tabContextMenu) === null || _a === void 0 ? void 0 : _a.closeConfigMenu();
            this.openTabConfigMenu(ev);
            ev.preventDefault();
            ev.stopPropagation();
        };
        this.tabEl.appendChild(tabLinkEl);
        const loaderEl = document.createElement("div");
        addClass(loaderEl, "loader");
        this.tabEl.appendChild(loaderEl);
        return this.tabEl;
    }
    openTabConfigMenu(event) {
        var _a;
        (_a = this.tabList.tabContextMenu) === null || _a === void 0 ? void 0 : _a.openConfigMenu(this.tabId, this, event);
    }
    redrawContextMenu() {
        var _a;
        (_a = this.tabList.tabContextMenu) === null || _a === void 0 ? void 0 : _a.redraw();
    }
}
export class TabList {
    constructor(yasgui) {
        this._tabs = {};
        this.handleKeydownArrowKeys = (e) => {
            if (e.code === "ArrowLeft" || e.code === "ArrowRight") {
                if (!this._tabsListEl)
                    return;
                const numOfChildren = this._tabsListEl.childElementCount;
                if (typeof this.tabEntryIndex !== "number")
                    return;
                const tabEntryDiv = this._tabsListEl.children[this.tabEntryIndex];
                if (!tabEntryDiv.classList.contains("active")) {
                    tabEntryDiv.children[0].setAttribute("tabindex", "-1");
                }
                if (e.code === "ArrowLeft") {
                    this.tabEntryIndex--;
                    if (this.tabEntryIndex < 0) {
                        this.tabEntryIndex = numOfChildren - 1;
                    }
                }
                if (e.code === "ArrowRight") {
                    this.tabEntryIndex++;
                    if (this.tabEntryIndex >= numOfChildren) {
                        this.tabEntryIndex = 0;
                    }
                }
                const newTabEntryDiv = this._tabsListEl.children[this.tabEntryIndex];
                newTabEntryDiv.children[0].setAttribute("tabindex", "0");
                newTabEntryDiv.children[0].focus();
            }
        };
        this.handleAddNewTab = (event) => {
            event.preventDefault();
            this.yasgui.addTab(true);
        };
        this.yasgui = yasgui;
        this.registerListeners();
        this.tabEntryIndex = this.getActiveIndex();
    }
    get(tabId) {
        return this._tabs[tabId];
    }
    registerListeners() {
        this.yasgui.on("query", (_yasgui, tab) => {
            const id = tab.getId();
            if (this._tabs[id]) {
                this._tabs[id].setAsQuerying(true);
            }
        });
        this.yasgui.on("queryResponse", (_yasgui, tab) => {
            const id = tab.getId();
            if (this._tabs[id]) {
                this._tabs[id].setAsQuerying(false);
            }
        });
        this.yasgui.on("queryAbort", (_yasgui, tab) => {
            const id = tab.getId();
            if (this._tabs[id]) {
                this._tabs[id].setAsQuerying(false);
            }
        });
    }
    getActiveIndex() {
        if (!this._selectedTab)
            return;
        const allTabs = Object.keys(this._tabs);
        const currentTabIndex = allTabs.indexOf(this._selectedTab);
        return currentTabIndex;
    }
    drawTabsList() {
        this._tabsListEl = document.createElement("div");
        addClass(this._tabsListEl, "tabsList");
        this._tabsListEl.setAttribute("role", "tablist");
        this._tabsListEl.addEventListener("keydown", this.handleKeydownArrowKeys);
        sortablejs.create(this._tabsListEl, {
            group: "tabList",
            animation: 100,
            onUpdate: (_ev) => {
                const tabs = this.deriveTabOrderFromEls();
                this.yasgui.emit("tabOrderChanged", this.yasgui, tabs);
                this.yasgui.persistentConfig.setTabOrder(tabs);
            },
            filter: ".addTab",
            onMove: (ev, _origEv) => {
                return hasClass(ev.related, "tab");
            },
        });
        this.addTabEl = document.createElement("div");
        this.addTabEl.setAttribute("role", "presentation");
        const addTabLink = document.createElement("button");
        addTabLink.className = "addTab";
        addTabLink.textContent = "+";
        addTabLink.title = "Add tab";
        addTabLink.setAttribute("aria-label", "Add a new tab");
        addTabLink.addEventListener("click", this.handleAddNewTab);
        addTabLink.addEventListener("focus", () => {
            if (!this._tabsListEl)
                return;
            this.tabEntryIndex = this._tabsListEl.childElementCount - 1;
        });
        addTabLink.addEventListener("blur", () => {
            addTabLink.setAttribute("tabindex", "0");
        });
        this.addTabEl.appendChild(addTabLink);
        this._tabsListEl.appendChild(this.addTabEl);
        this.tabContextMenu = TabContextMenu.get(this.yasgui, this.yasgui.config.contextMenuContainer ? this.yasgui.config.contextMenuContainer : this._tabsListEl);
        return this._tabsListEl;
    }
    addTab(tabId, index) {
        return this.drawTab(tabId, index);
    }
    deriveTabOrderFromEls() {
        const tabs = [];
        if (this._tabsListEl) {
            for (let i = 0; i < this._tabsListEl.children.length; i++) {
                const child = this._tabsListEl.children[i];
                const anchorTag = child.children[0];
                if (anchorTag) {
                    const href = anchorTag.href;
                    if (href && href.indexOf("#") >= 0) {
                        tabs.push(href.substr(href.indexOf("#") + 1));
                    }
                }
            }
        }
        return tabs;
    }
    selectTab(tabId) {
        this._selectedTab = tabId;
        for (const id in this._tabs) {
            this._tabs[id].active(this._selectedTab === id);
        }
    }
    drawTab(tabId, index) {
        var _a, _b;
        this._tabs[tabId] = new TabListEl(this.yasgui, this, tabId);
        const tabConf = this.yasgui.persistentConfig.getTab(tabId);
        if (index !== undefined && index < this.yasgui.persistentConfig.getTabs().length - 1) {
            (_a = this._tabsListEl) === null || _a === void 0 ? void 0 : _a.insertBefore(this._tabs[tabId].draw(tabConf.name), this._tabs[this.yasgui.persistentConfig.getTabs()[index + 1]].tabEl || null);
        }
        else {
            (_b = this._tabsListEl) === null || _b === void 0 ? void 0 : _b.insertBefore(this._tabs[tabId].draw(tabConf.name), this.addTabEl || null);
        }
    }
    destroy() {
        var _a, _b;
        for (const tabId in this._tabs) {
            const tab = this._tabs[tabId];
            tab.delete();
        }
        this._tabs = {};
        (_a = this.tabContextMenu) === null || _a === void 0 ? void 0 : _a.destroy();
        (_b = this._tabsListEl) === null || _b === void 0 ? void 0 : _b.remove();
        this._tabsListEl = undefined;
    }
}
export default TabList;
//# sourceMappingURL=TabElements.js.map