import { calculateDimensions } from "./menuHelpers";
import { FEAGlobals } from "../../../common/Globals";
/**
 * To make sure that MenuPortal.tsx remain small
 * I have isolated the auto resize logic in this class.
 */
export class MenuAutoResizer {
    constructor(childWindow, menuId, width, maxHeight = Infinity, minHeight = 0) {
        this.width = width;
        this.maxHeight = maxHeight;
        this.minHeight = minHeight;
        this.childWindow = childWindow;
        this.menuId = menuId;
        this.updateWindowDimensions = this.updateWindowDimensions.bind(this);
        /* The external window does not have a URL and so its origin
        will not match the toolbar's origin, in that case
        we won't have onload, DOMContentLoaded or any other events.
        That makes it hard to know when the content are loaded, we cant
        even inject custom JS as it will be already late.
        The only way to know about a DOM change was MutationObserver!
        */
        this.observer = new MutationObserver(this.updateWindowDimensions);
        /* Now we watch for any DOM changes in the childWindow
        Knowing the height of the window contents is crucial for
        making decision about its position (below/above the toolbar).
        */
        this.observer.observe(this.childWindow.document, {
            childList: true,
            characterData: false,
            subtree: true,
        });
        // Initialize the window to the correct height
        setTimeout(this.updateWindowDimensions, 0);
    }
    disconnect() {
        this.observer.disconnect();
    }
    /**
     * Callback for MutationObserver
     */
    async updateWindowDimensions() {
        if (window.glue42gd) {
            return this.updateWindowDimensionsIOCD();
        }
        // If the original menu button has been removed then bypass updating the window dimensions.
        // Probably the menu itself is in the process of being removed but the mutation observer has
        // not yet disconnected
        if (!document.querySelector(`#${this.menuId}-menu-toggle`)) {
            return;
        }
        const { left, top, height } = await calculateDimensions(this.childWindow, this.menuId, 0, this.maxHeight, this.minHeight);
        const params = {
            monitor: "mine",
            position: "absolute",
            left: left,
            top: top,
            width: this.width,
            height: height,
            setBoundsOnly: true,
            forceOntoMonitor: "monitorRect",
        };
        /**
         * See comment in MenuPortal.tsx on why we use showWindow() here instead of childWindow.moveTo()
         */
        //this.childWindow.moveTo(left, top);
        //this.childWindow.resizeTo(this.width, height);
        FEAGlobals.FSBL.Clients.LauncherClient.showWindow({ windowName: this.childWindow.window.name }, params);
        this.childWindow.document.body.setAttribute("resizing", "false");
    }
    async updateWindowDimensionsIOCD() {
        var _a, _b, _c;
        const { name } = this.childWindow;
        const iop = window.iop;
        const me = iop.windows.my();
        const menu = iop.windows.find(name);
        const { width = 200 } = await menu.getBounds();
        const selector = `#${this.menuId}-menu-toggle`;
        const menuToggle = document.querySelector(selector);
        if (!menuToggle) {
            console.error(`showHideResizeWindowIOCD() can't find selector "${selector}"`);
            return;
        }
        const displays = await iop.displays.all();
        const primaryDisplay = displays.find((d) => d.isPrimary);
        const targetBounds = menuToggle.getBoundingClientRect();
        const myDisplay = await me.getDisplay();
        const displayBounds = myDisplay.workArea;
        const toolbarBounds = await me.getBounds();
        const menuBounds = await menu.getBounds();
        const scalingFactor = ((_a = myDisplay === null || myDisplay === void 0 ? void 0 : myDisplay.scaleFactor) !== null && _a !== void 0 ? _a : 1) / ((_b = primaryDisplay === null || primaryDisplay === void 0 ? void 0 : primaryDisplay.scaleFactor) !== null && _b !== void 0 ? _b : 1);
        const spaceAboveToolbar = toolbarBounds.top * scalingFactor - displayBounds.top * scalingFactor;
        const spaceBelowToolbar = displayBounds.height +
            displayBounds.top * scalingFactor -
            toolbarBounds.top * scalingFactor -
            toolbarBounds.height;
        const contentHeight = this.childWindow.document.documentElement.offsetHeight;
        const CHROMIUM_MIN_HEIGHT = (_c = this.minHeight) !== null && _c !== void 0 ? _c : 0;
        const minimumContentHeight = Math.max(contentHeight, CHROMIUM_MIN_HEIGHT);
        let height = Math.min(minimumContentHeight, this.maxHeight);
        // Unlike the code in MenuPortal, the autosizer never changes the location of the menu, just the height
        const targetLocation = menuBounds.top < toolbarBounds.top ? "top" : "bottom";
        if (targetLocation === "bottom" && height > spaceBelowToolbar) {
            height = spaceBelowToolbar;
        }
        if (targetLocation === "top" && height > spaceAboveToolbar) {
            height = spaceAboveToolbar;
        }
        // This can be moved up to the top of the function after the iocd windowing API is made asynchronous
        // Until then, this isVisible may not be updated in time
        if (!menu.isVisible) {
            this.childWindow.document.body.setAttribute("resizing", "false");
            return;
        }
        me.showPopup({
            size: {
                height,
                width,
            },
            targetBounds,
            targetLocation,
            windowId: menu.id,
        });
        this.childWindow.document.body.setAttribute("resizing", "false");
    }
}
//# sourceMappingURL=MenuAutoResizer.js.map