"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 Widget
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.useDrag = exports.WidgetTabBar = void 0;
require("./TabBar.scss");
const classnames_1 = require("classnames");
const React = require("react");
const core_bentley_1 = require("@itwin/core-bentley");
const core_react_1 = require("@itwin/core-react");
const DragManager_1 = require("../base/DragManager");
const NineZone_1 = require("../base/NineZone");
const usePointerCaptor_1 = require("../base/usePointerCaptor");
const Buttons_1 = require("./Buttons");
const Tabs_1 = require("./Tabs");
const Widget_1 = require("./Widget");
const Grip_1 = require("../widget-panels/Grip");
const FloatingWidget_1 = require("./FloatingWidget");
const useMaximizedWidget_1 = require("../../preview/enable-maximized-widget/useMaximizedWidget");
/** @internal */
function WidgetTabBar(props) {
    const dispatch = React.useContext(NineZone_1.NineZoneDispatchContext);
    const id = React.useContext(Widget_1.WidgetIdContext);
    const floatingWidgetId = (0, FloatingWidget_1.useFloatingWidgetId)();
    (0, core_bentley_1.assert)(!!id);
    const widgetId = floatingWidgetId === undefined ? id : floatingWidgetId;
    const handleDoubleClick = React.useCallback(() => {
        floatingWidgetId &&
            dispatch({
                type: "FLOATING_WIDGET_CLEAR_USER_SIZED",
                id: floatingWidgetId,
            });
    }, [dispatch, floatingWidgetId]);
    const handleActionAreaClick = (0, Grip_1.useDoubleClick)(handleDoubleClick);
    const onDrag = React.useCallback((dragBy) => {
        floatingWidgetId !== undefined &&
            dispatch({
                type: "WIDGET_DRAG",
                dragBy,
                floatingWidgetId,
            });
    }, [dispatch, floatingWidgetId]);
    const onDragEnd = React.useCallback((target) => {
        floatingWidgetId !== undefined && handleActionAreaClick();
        floatingWidgetId !== undefined &&
            dispatch({
                type: "WIDGET_DRAG_END",
                floatingWidgetId,
                target,
            });
    }, [dispatch, floatingWidgetId, handleActionAreaClick]);
    const handleWidgetDragStart = (0, DragManager_1.useDragWidget)({
        widgetId,
        onDrag,
        onDragEnd,
    });
    const containerRef = React.useRef(null);
    const handleDragStart = React.useCallback((initialPointerPosition, pointerPosition) => {
        handleWidgetDragStart({
            initialPointerPosition,
            pointerPosition,
        });
    }, [handleWidgetDragStart]);
    const handleTouchStart = React.useCallback(() => {
        floatingWidgetId &&
            dispatch({
                type: "FLOATING_WIDGET_BRING_TO_FRONT",
                id: floatingWidgetId,
            });
    }, [dispatch, floatingWidgetId]);
    const ref = useDrag(handleDragStart, undefined, undefined, handleTouchStart, handleDoubleClick);
    const maximizedWidgetHandle = (0, useMaximizedWidget_1.useMaximizedWidgetTabBarHandle)();
    const className = (0, classnames_1.default)("nz-widget-tabBar", props.separator && "nz-separator");
    const handleClassName = (0, classnames_1.default)("nz-handle", maximizedWidgetHandle);
    return (React.createElement("div", { ref: containerRef, className: className },
        React.createElement("div", { className: handleClassName, ref: ref }),
        React.createElement(Tabs_1.WidgetTabs, null),
        React.createElement(Buttons_1.TabBarButtons, null)));
}
exports.WidgetTabBar = WidgetTabBar;
/** Hook to control drag interactions.
 * Starts drag interaction after pointer moves or after timeout.
 * @internal
 */
function useDrag(onDragStart, onDrag, onDragEnd, onTouchStart, onDoubleClick) {
    // eslint-disable-next-line deprecation/deprecation
    const doubleClickTimer = React.useRef(new core_react_1.Timer(300));
    const clickCount = React.useRef(0);
    const initialPointerPosition = React.useRef();
    React.useEffect(() => {
        const handleExecute = () => {
            if (clickCount.current === 2)
                onDoubleClick && onDoubleClick();
            clickCount.current = 0;
        };
        const timer = doubleClickTimer.current;
        timer.setOnExecute(handleExecute);
        return () => {
            timer.setOnExecute(undefined);
        };
    }, [onDoubleClick]);
    const handlePointerDown = React.useCallback((args, e) => {
        initialPointerPosition.current = new core_react_1.Point(args.clientX, args.clientY);
        e.type === "touchstart" && onTouchStart && onTouchStart();
    }, [onTouchStart]);
    const handlePointerMove = React.useCallback((args) => {
        if (initialPointerPosition.current) {
            onDragStart &&
                onDragStart(initialPointerPosition.current, new core_react_1.Point(args.clientX, args.clientY));
            initialPointerPosition.current = undefined;
            return;
        }
        onDrag && onDrag(new core_react_1.Point(args.clientX, args.clientY));
    }, [onDragStart, onDrag]);
    const handlePointerUp = React.useCallback(() => {
        clickCount.current++;
        doubleClickTimer.current.start();
        initialPointerPosition.current = undefined;
        onDragEnd && onDragEnd();
    }, [onDragEnd]);
    const ref = (0, usePointerCaptor_1.usePointerCaptor)(handlePointerDown, handlePointerMove, handlePointerUp);
    return ref;
}
exports.useDrag = useDrag;
//# sourceMappingURL=TabBar.js.map