"use strict";
/*---------------------------------------------------------------------------------------------
 * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
 * See LICENSE.md in the project root for license terms and full copyright notice.
 *--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Base
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.usePointerCaptor = void 0;
const React = require("react");
const core_react_1 = require("@itwin/core-react");
const DragManager_1 = require("./DragManager");
/** Captures mouse and touch events of an element. Used in drag or resize interactions.
 * @internal
 */
const usePointerCaptor = (onPointerDown, onPointerMove, onPointerUp) => {
    const dragManager = React.useContext(DragManager_1.DragManagerContext);
    const isDown = React.useRef(false);
    React.useEffect(() => {
        const mouseMove = (e) => {
            isDown.current && onPointerMove && onPointerMove(e, e);
        };
        document.addEventListener("mousemove", mouseMove);
        return () => {
            document.removeEventListener("mousemove", mouseMove);
        };
    }, [onPointerMove]);
    React.useEffect(() => {
        const mouseUp = (e) => {
            isDown.current && onPointerUp && onPointerUp(e);
            isDown.current = false;
        };
        document.addEventListener("mouseup", mouseUp);
        return () => {
            document.removeEventListener("mouseup", mouseUp);
        };
    }, [onPointerUp]);
    const setRef = (0, core_react_1.useRefEffect)((instance) => {
        let touchTarget = null;
        const mouseDown = (e) => {
            const isSecondaryButton = (e.button & 2) === 2;
            if (isSecondaryButton)
                return;
            onPointerDown && onPointerDown(e, e);
            isDown.current = true;
        };
        const touchMove = (e) => {
            if (e.touches.length !== 1)
                return;
            isDown.current && onPointerMove && onPointerMove(e.touches[0], e);
            isDown.current &&
                dragManager.handleDrag(e.touches[0].clientX, e.touches[0].clientY);
        };
        const targetTouchMove = (e) => {
            e.cancelable && e.preventDefault();
            touchMove(e);
        };
        const documentTouchMove = (e) => {
            // Do not handle document touch move if it was handled by target handler.
            if (touchTarget === e.target)
                return;
            touchMove(e);
        };
        const touchEnd = (e) => {
            isDown.current && onPointerUp && onPointerUp(e);
            isDown.current && dragManager.handleDragEnd();
            isDown.current = false;
            touchTarget = null;
            if (e.target instanceof HTMLElement) {
                e.target.removeEventListener("touchmove", targetTouchMove);
                e.target.removeEventListener("touchend", touchEnd);
            }
            document.removeEventListener("touchmove", documentTouchMove);
            document.removeEventListener("touchend", documentTouchEnd);
        };
        const documentTouchEnd = (e) => {
            // Do not handle document touch move if it was handled by target handler.
            if (touchTarget === e.target)
                return;
            touchEnd(e);
        };
        const touchStart = (e) => {
            e.cancelable && e.preventDefault();
            if (e.touches.length !== 1)
                return;
            touchTarget = e.target;
            // In case of implicit pointer capture attach to event target.
            if (e.target instanceof HTMLElement) {
                e.target.addEventListener("touchmove", targetTouchMove);
                e.target.addEventListener("touchend", touchEnd);
            }
            // Add to document in case the target looses capture (i.e. is removed)
            document.addEventListener("touchmove", documentTouchMove);
            document.addEventListener("touchend", documentTouchEnd);
            onPointerDown && onPointerDown(e.touches[0], e);
            isDown.current = true;
        };
        instance && instance.addEventListener("mousedown", mouseDown);
        instance && instance.addEventListener("touchstart", touchStart);
        return () => {
            instance && instance.removeEventListener("mousedown", mouseDown);
            instance && instance.removeEventListener("touchstart", touchStart);
        };
    }, [onPointerDown, onPointerMove, onPointerUp, dragManager]);
    return setRef;
};
exports.usePointerCaptor = usePointerCaptor;
//# sourceMappingURL=usePointerCaptor.js.map