"use strict";

Object.defineProperty(exports, "__esModule", {
    value: !0
}), exports.MenuManager = void 0;

const vrender_1 = require("@visactor/vtable/es/vrender"), styles_1 = require("./styles");

class MenuManager {
    constructor() {
        this.menuContainer = null, this.activeSubmenus = [], this.clickCallback = null, 
        this.table = null, this.context = {}, this.hideTimeout = null, this.showTimeout = null, 
        this.submenuShowDelay = 100, this.submenuHideDelay = 500, this.handleDocumentClick = event => {
            if (!this.menuContainer || event.target !== this.menuContainer && !this.menuContainer.contains(event.target)) {
                for (const submenu of this.activeSubmenus) if (event.target === submenu || submenu.contains(event.target)) return;
                this.release();
            }
        };
    }
    showMenu(menuItems, x, y, context, table) {
        this.context = context, this.table = table, this.release(), this.menuContainer = (0, 
        styles_1.createElement)("div", styles_1.MENU_CONTAINER_CLASS), (0, styles_1.applyStyles)(this.menuContainer, styles_1.MENU_STYLES.menuContainer), 
        document.body.appendChild(this.menuContainer), this.createMenuItems(menuItems, this.menuContainer), 
        this.positionMenu(this.menuContainer, x, y), setTimeout((() => {
            vrender_1.vglobal.addEventListener("click", this.handleDocumentClick);
        }), 0);
    }
    setClickCallback(callback) {
        this.clickCallback = callback;
    }
    createMenuItems(items, container, parentItem) {
        items.forEach((item => {
            if ("string" == typeof item && "---" === item) {
                const separator = (0, styles_1.createElement)("div", styles_1.MENU_ITEM_SEPARATOR_CLASS);
                (0, styles_1.applyStyles)(separator, styles_1.MENU_STYLES.menuItemSeparator), container.appendChild(separator);
            } else if ("object" == typeof item) {
                const menuItem = item, menuItemElement = (0, styles_1.createElement)("div", styles_1.MENU_ITEM_CLASS);
                (0, styles_1.applyStyles)(menuItemElement, styles_1.MENU_STYLES.menuItem);
                const leftContainer = (0, styles_1.createElement)("div");
                if (leftContainer.style.display = "flex", leftContainer.style.alignItems = "center", 
                menuItem.iconName) {
                    const icon = (0, styles_1.createIcon)(menuItem.iconName);
                    leftContainer.appendChild(icon);
                } else if (menuItem.iconPlaceholder) {
                    const placeholder = (0, styles_1.createElement)("span");
                    (0, styles_1.applyStyles)(placeholder, styles_1.MENU_STYLES.menuItemIcon), leftContainer.appendChild(placeholder);
                }
                const text = (0, styles_1.createElement)("span");
                if (text.textContent = menuItem.text, (0, styles_1.applyStyles)(text, styles_1.MENU_STYLES.menuItemText), 
                leftContainer.appendChild(text), item.inputDefaultValue) {
                    const input = (0, styles_1.createElement)("input");
                    input.type = "number", input.min = "1", input.value = item.inputDefaultValue.toString(), 
                    (0, styles_1.applyStyles)(input, styles_1.MENU_STYLES.inputField), leftContainer.appendChild(input), 
                    input.addEventListener("keydown", (e => {
                        "Enter" === e.key && this.handleMenuItemClick(Object.assign({
                            menuKey: menuItem.menuKey,
                            menuText: menuItem.text,
                            inputValue: parseInt(input.value, 10)
                        }, this.context));
                    }));
                }
                menuItemElement.appendChild(leftContainer);
                const rightContainer = (0, styles_1.createElement)("div");
                if (rightContainer.style.display = "flex", rightContainer.style.alignItems = "center", 
                menuItem.shortcut) {
                    const shortcut = (0, styles_1.createElement)("span");
                    shortcut.textContent = menuItem.shortcut, (0, styles_1.applyStyles)(shortcut, styles_1.MENU_STYLES.menuItemShortcut), 
                    rightContainer.appendChild(shortcut);
                }
                if (menuItem.children && menuItem.children.length > 0) {
                    menuItemElement.classList.add(styles_1.MENU_ITEM_SUBMENU_CLASS);
                    const arrow = (0, styles_1.createElement)("span");
                    arrow.textContent = "▶", (0, styles_1.applyStyles)(arrow, styles_1.MENU_STYLES.submenuArrow), 
                    rightContainer.appendChild(arrow);
                }
                menuItemElement.appendChild(rightContainer), menuItem.disabled && (menuItemElement.classList.add(styles_1.MENU_ITEM_DISABLED_CLASS), 
                (0, styles_1.applyStyles)(menuItemElement, styles_1.MENU_STYLES.menuItemDisabled)), 
                menuItem.disabled || (menuItem.children && 0 !== menuItem.children.length || menuItemElement.addEventListener("click", (e => {
                    e.target instanceof HTMLInputElement || this.handleMenuItemClick(Object.assign({
                        menuKey: menuItem.menuKey,
                        menuText: menuItem.text
                    }, this.context));
                })), menuItemElement.addEventListener("mouseenter", (() => {
                    (0, styles_1.applyStyles)(menuItemElement, styles_1.MENU_STYLES.menuItemHover), 
                    null !== this.hideTimeout && (clearTimeout(this.hideTimeout), this.hideTimeout = null), 
                    null !== this.showTimeout && (clearTimeout(this.showTimeout), this.showTimeout = null), 
                    menuItem.children && menuItem.children.length > 0 ? (this.closeAllSubmenus(), this.showTimeout = setTimeout((() => {
                        document.body.contains(menuItemElement) && this.showSubmenu(menuItem.children, menuItemElement, menuItem);
                    }), this.submenuShowDelay)) : parentItem || this.closeAllSubmenus();
                })), menuItemElement.addEventListener("mouseleave", (() => {
                    Object.keys(styles_1.MENU_STYLES.menuItemHover).forEach((key => {
                        menuItemElement.style[key] = "";
                    })), menuItem.children && menuItem.children.length > 0 && (this.hideTimeout = setTimeout((() => {
                        this.closeAllSubmenus();
                    }), this.submenuHideDelay));
                }))), container.appendChild(menuItemElement);
            }
        }));
    }
    showSubmenu(items, parentElement, parentItem) {
        const parentRect = parentElement.getBoundingClientRect(), submenu = (0, styles_1.createElement)("div", styles_1.MENU_CONTAINER_CLASS);
        (0, styles_1.applyStyles)(submenu, styles_1.MENU_STYLES.submenuContainer), this.createMenuItems(items, submenu, parentItem), 
        document.body.appendChild(submenu);
        const submenuRect = submenu.getBoundingClientRect();
        let left = parentRect.right, top = parentRect.top;
        left + submenuRect.width > window.innerWidth && (left = parentRect.left - submenuRect.width), 
        top + submenuRect.height > window.innerHeight && (top = window.innerHeight - submenuRect.height), 
        submenu.style.left = `${left}px`, submenu.style.top = `${top}px`, submenu.addEventListener("mouseenter", (() => {
            null !== this.hideTimeout && (clearTimeout(this.hideTimeout), this.hideTimeout = null);
        })), submenu.addEventListener("mouseleave", (() => {
            this.hideTimeout = setTimeout((() => {
                this.closeAllSubmenus();
            }), this.submenuHideDelay);
        })), this.activeSubmenus.push(submenu);
    }
    closeAllSubmenus() {
        this.activeSubmenus.forEach((submenu => {
            submenu && submenu.parentNode && submenu.parentNode.removeChild(submenu);
        })), this.activeSubmenus = [];
    }
    positionMenu(menu, x, y) {
        const menuRect = menu.getBoundingClientRect();
        let left = x, top = y;
        left + menuRect.width > window.innerWidth && (left = window.innerWidth - menuRect.width), 
        top + menuRect.height > window.innerHeight && (top = window.innerHeight - menuRect.height), 
        menu.style.left = `${left}px`, menu.style.top = `${top}px`;
    }
    handleMenuItemClick(args) {
        this.release(), this.clickCallback && this.table && this.clickCallback(args, this.table);
    }
    release() {
        this.closeAllSubmenus(), this.menuContainer && this.menuContainer.parentNode && (this.menuContainer.parentNode.removeChild(this.menuContainer), 
        this.menuContainer = null), null !== this.hideTimeout && (clearTimeout(this.hideTimeout), 
        this.hideTimeout = null), vrender_1.vglobal.removeEventListener("click", this.handleDocumentClick);
    }
}

exports.MenuManager = MenuManager;