/*---------------------------------------------------------------------------------------------
 * 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
 */
import "./TabBar.scss";
import classnames from "classnames";
import * as React from "react";
import { assert } from "@itwin/core-bentley";
import { Timer } from "@itwin/core-react";
import { Point } from "@itwin/core-react/internal";
import { useDragWidget } from "../base/DragManager.js";
import { NineZoneDispatchContext } from "../base/NineZone.js";
import { usePointerCaptor } from "../base/usePointerCaptor.js";
import { WidgetTabs } from "./Tabs.js";
import { WidgetIdContext } from "./Widget.js";
import { useDoubleClick } from "../widget-panels/Grip.js";
import { useFloatingWidgetId } from "./FloatingWidget.js";
import { useMaximizedWidgetTabBarHandle } from "../../preview/enable-maximized-widget/useMaximizedWidget.js";
import { WidgetActions } from "./WidgetActions.js";
import { ConfigurableUiContext } from "../../configurableui/ConfigurableUiContent.js";
/** @internal */
export function WidgetTabBar(props) {
    const dispatch = React.useContext(NineZoneDispatchContext);
    const id = React.useContext(WidgetIdContext);
    const { widgetActions } = React.useContext(ConfigurableUiContext);
    const floatingWidgetId = useFloatingWidgetId();
    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 = 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 = 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 = useMaximizedWidgetTabBarHandle();
    const className = classnames("nz-widget-tabBar", props.separator && "nz-separator");
    const handleClassName = classnames("nz-handle", maximizedWidgetHandle);
    return (React.createElement("div", { ref: containerRef, className: className },
        React.createElement("div", { className: handleClassName, ref: ref }),
        React.createElement(WidgetTabs, null),
        widgetActions ?? React.createElement(WidgetActions, null)));
}
/** Hook to control drag interactions.
 * Starts drag interaction after pointer moves or after timeout.
 * @internal
 */
export function useDrag(onDragStart, onDrag, onDragEnd, onTouchStart, onDoubleClick) {
    // eslint-disable-next-line @typescript-eslint/no-deprecated
    const doubleClickTimer = React.useRef(new Timer(300));
    const clickCount = React.useRef(0);
    const initialPointerPosition = React.useRef(undefined);
    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 Point(args.clientX, args.clientY);
        e.type === "touchstart" && onTouchStart && onTouchStart();
    }, [onTouchStart]);
    const handlePointerMove = React.useCallback((args) => {
        if (initialPointerPosition.current) {
            onDragStart &&
                onDragStart(initialPointerPosition.current, new Point(args.clientX, args.clientY));
            initialPointerPosition.current = undefined;
            return;
        }
        onDrag && onDrag(new Point(args.clientX, args.clientY));
    }, [onDragStart, onDrag]);
    const handlePointerUp = React.useCallback(() => {
        clickCount.current++;
        doubleClickTimer.current.start();
        initialPointerPosition.current = undefined;
        onDragEnd && onDragEnd();
    }, [onDragEnd]);
    const ref = usePointerCaptor(handlePointerDown, handlePointerMove, handlePointerUp);
    return ref;
}
//# sourceMappingURL=TabBar.js.map