/**
 * A hook for building WindowTitleBars.
 */
import { useState } from "react";
import { FEAGlobals } from "../../common";
/**
 * Creates a drag region that interacts with Finsemble's useDOMBasedMovement for moving windows.
 * Functions are returned which must be set on the drag region's React onMouseDown and onMouseUp event handlers.
 *
 * Note that this component doesn't need to worry about stopping the window movement because that is handled by FEA
 * via its own mouseup and blur event handlers (see electron-adapter/src/render/Window.ts).
 *
 * A mouseDown followed by a mouseMove is required to start window movement. By waiting for mouseMove we avoid accidentally
 * slipping into window movement mode due to a click or double click on the titlebar.
 *
 * Once in window movement mode, a requestAnimationFrame begins running in e2o.ts that tracks mouse movement and causes
 * the window to follow that movement (by reporting the mouse position up to the window service, which then decides based
 * on it's snapping algorithm whether to allow the window to move, or do other things like cause grouped windows to also move).
 *
 * We don't allow dragging a window when it is maximized. While operating systems do allow dragging a maximized window (on
 * Mac the window moves at its full maximized state, on Windows it unmaximizes to normal state and then moves) we can't allow
 * this because a maximized window may be part of a group, and if we were to move the window then the group would become indeterminate.
 */
export const useDragRegion = (maximized) => {
    const [isMousePressed, setIsMousePressed] = useState(false);
    const [hasStartedMoving, setHasStartedMoving] = useState(false);
    // Create a reference to the isMousePressed value so that it can be accessed from within setTimeout
    // https://medium.com/programming-essentials/how-to-access-the-state-in-settimeout-inside-a-react-function-component-39a9f031c76f
    const onMouseMove = (event) => {
        if (isMousePressed && !hasStartedMoving) {
            setHasStartedMoving(true);
            FEAGlobals.FSBL.Clients.WindowClient.startMovingWindow(event.nativeEvent);
        }
    };
    const stopMovingWindow = () => {
        FEAGlobals.FSBL.Clients.WindowClient.stopMovingWindow();
        setIsMousePressed(false);
        setHasStartedMoving(false);
        document.removeEventListener("mouseup", stopMovingWindow);
        document.removeEventListener("dragend", stopMovingWindow);
        window.removeEventListener("blur", stopMovingWindow);
    };
    const onMouseDown = () => {
        if (maximized)
            return;
        // Preemptively stop any previous moves, just in case a mouseup event was missed for instance
        FEAGlobals.FSBL.Clients.WindowClient.stopMovingWindow();
        setIsMousePressed(true);
        /**
         * Set listeners document wide to make sure that we catch all conditions where the mouse is lifted.
         * See also electron-adapter src/renderer/Window.ts where mouse position polling is used to keep track
         * of the mouse position.
         */
        document.addEventListener("mouseup", stopMovingWindow);
        /**
         * The 'dragend' event will fire if the text of the titlebar is selected, and then dragged. This
         * can occur if someone selects the text of the page and pulls up above the window. Then, when the
         * user clicks the titlebar, chrome will drag the element, and never fire mouseup.
         */
        document.addEventListener("dragend", stopMovingWindow);
        /**
         * The window can blur while the user is moving the window. If the user is moving the window
         * and a native application or notification steals focus, the window would get "stuck" to the
         * mouse, because mouseup wouldn't fire.
         * An easy way to simulate this bad behavior is to remove this listener and start moving the window.
         * Then hit alt+tab.
         * Alternatively, you can press the windows key while moving a window (this will bring up the
         * cortana search menu and focus it).
         */
        window.addEventListener("blur", stopMovingWindow);
    };
    return { onMouseDown, onMouseMove };
};
//# sourceMappingURL=useDragRegion.js.map