import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/
import "../output.css";
import { ArrowDownIcon, ArrowUpIcon, Button, CrossIcon, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Flex, FullscreenIcon, HelpIcon, Icon, Label, MoreMenuIcon, NormalText, SubHeader, Tooltip, } from "@luxonis/common-fe-components";
import { CiFilter } from "react-icons/ci";
import { FaCaretDown, FaCaretUp } from "react-icons/fa";
import { ImCheckboxChecked, ImCheckboxUnchecked } from "react-icons/im";
import { RiNumbersFill } from "react-icons/ri";
import { useDetections } from "./Panel.js";
import { createEventLoopDelaySampler } from "./measure-event-loop-delay";
import { useConnections } from "../context/ConnectionsProvider.js";
import "@luxonis/common-fe-components/styles";
import { constructKeyForTopicRenderMetrics, globalInputEventMetricsManager, globalRenderMetricsManager, } from "../utils/metrics-manager";
function PointCloudPanelInstructions() {
    return (_jsxs(_Fragment, { children: [_jsx(Label, { text: "To move camera:" }), _jsxs("ul", { children: [_jsxs("li", { children: [_jsx("b", { className: "font-semibold", children: "Scroll:" }), " Zoom In and Out"] }), _jsxs("li", { children: [_jsx("b", { className: "font-semibold", children: "Left-click + Drag:" }), " Rotate Camera"] }), _jsxs("li", { children: [_jsx("b", { className: "font-semibold", children: "Right-click + Drag:" }), " Move Camera (X and Y axes)"] }), _jsxs("li", { children: [_jsx("b", { className: "font-semibold", children: "WASD:" }), " Pan Camera"] }), _jsxs("li", { children: [_jsx("b", { className: "font-semibold", children: "SHIFT+WASD:" }), " Pan Camera (Faster)"] }), _jsxs("li", { children: [_jsx("b", { className: "font-semibold", children: "O:" }), " Orbit Camera"] }), _jsxs("li", { children: [_jsx("b", { className: "font-semibold", children: "SHIFT+O:" }), " Orbit Camera (Opposite Direction)"] })] }), _jsx(Label, { text: "While orbiting:" }), _jsxs("ul", { children: [_jsxs("li", { children: [_jsx("b", { className: "font-semibold", children: "Q:" }), " Slow Down"] }), _jsxs("li", { children: [_jsx("b", { className: "font-semibold", children: "E:" }), " Speed Up"] })] })] }));
}
const METRICS_UPDATE_INTERVAL = 500;
function PanelToolbarMetrics({ targetFps, metrics, inDropdown, topic, isPointcloud, }) {
    const [renderMetricsKey, annotationsMetricsKey] = React.useMemo(() => {
        return [
            constructKeyForTopicRenderMetrics(isPointcloud ? "renderPointCloudFrame" : "renderImageFrame", topic),
            constructKeyForTopicRenderMetrics("renderAnnotationsFrame", topic),
        ];
    }, [isPointcloud, topic]);
    const [renderedFps, setRenderedFps] = React.useState(globalRenderMetricsManager.calculate(renderMetricsKey));
    const [annotationsFps, setAnnotationsFps] = React.useState(globalRenderMetricsManager.calculate(annotationsMetricsKey));
    const [variant, setVariant] = React.useState(inDropdown ? "compact" : "full");
    const eventLoopDelay = createEventLoopDelaySampler();
    const panelRef = React.useRef(null);
    React.useEffect(() => {
        if (inDropdown) {
            return;
        }
        if (panelRef.current && panelRef.current.offsetWidth < 800) {
            setVariant("compact");
        }
        else {
            setVariant("full");
        }
    }, [panelRef.current?.offsetWidth, inDropdown]);
    // Effect to update the metrics periodically
    React.useEffect(() => {
        const interval = setInterval(() => {
            setRenderedFps(globalRenderMetricsManager.calculate(renderMetricsKey));
            setAnnotationsFps(globalInputEventMetricsManager.calculate(annotationsMetricsKey));
        }, METRICS_UPDATE_INTERVAL);
        return () => {
            clearInterval(interval);
        };
    }, [renderMetricsKey, annotationsMetricsKey]);
    const parentContainer = panelRef.current ?? document.body;
    const metricsItems = [
        Number.isFinite(targetFps) ? { label: "Camera", value: targetFps, unit: "FPS" } : null,
        Number.isFinite(metrics?.incomingMessagesFps)
            ? {
                label: "Network",
                value: metrics.incomingMessagesFps,
                unit: "FPS",
            }
            : null,
        Number.isFinite(metrics?.decodedMessagesFps)
            ? {
                label: "Decoding",
                value: metrics.decodedMessagesFps,
                unit: "FPS",
            }
            : null,
        Number.isFinite(renderedFps) ? { label: "Rendering", value: renderedFps, unit: "FPS" } : null,
        Number.isFinite(annotationsFps)
            ? { label: "Annotations", value: annotationsFps, unit: "FPS" }
            : null,
        Number.isFinite(metrics?.messageThroughput)
            ? {
                label: "Throughput",
                value: metrics.messageThroughput,
                unit: "Mbps",
            }
            : null,
        { label: "Frontend Delay", value: eventLoopDelay.toFixed(2), unit: "ms" },
    ].filter(Boolean);
    return (_jsx(Flex, { direction: "row", gap: "sm", align: "start", justify: "end", ref: panelRef, width: "full", children: variant === "compact" ? (_jsx(Tooltip, { parentContainer: parentContainer, content: _jsx("ul", { children: metricsItems.map((item) => (_jsxs("li", { children: [_jsxs("b", { className: "font-semibold", children: [item.label, ": "] }), item.value, "\u00A0", item.unit] }, item.label))) }), direction: "bottom", className: inDropdown ? "w-full" : "ml-auto", children: inDropdown ? (_jsx(DropdownMenuItem, { onClick: (e) => {
                    e.preventDefault();
                    e.stopPropagation();
                }, cursor: "help", icon: RiNumbersFill, children: "Stream Stats" })) : (_jsx(Button, { icon: RiNumbersFill, variant: "outline", colorVariant: "white", size: "sm", className: "text-gray-700" })) })) : (_jsx(_Fragment, { children: metricsItems.map((item) => (_jsx(Label, { text: `${item.label}: ${item.value}\u00A0${item.unit}` }, item.label))) })) }));
}
const PanelAnnotationButton = ({ topic, onClick }) => {
    const handleClick = React.useCallback((event) => {
        event.preventDefault();
        onClick();
    }, [onClick]);
    return (_jsx(DropdownMenuItem, { onClick: handleClick, children: _jsxs(Flex, { align: "center", gap: "sm", children: [_jsx(Icon, { color: "active", icon: topic.enabled ? ImCheckboxChecked : ImCheckboxUnchecked }), _jsx(NormalText, { text: topic.name })] }) }));
};
export const PanelToolbar = ({ topic, fakedAs, kind, setDetections, disableAnnotations = false, targetFps, triggerToast, toggleTopic, toggleFullscreen, canMoveUp, moveUp, canMoveDown, moveDown, touchesBreakpoint, isPointcloud, actions, }) => {
    const [metrics, setMetrics] = React.useState();
    const [fakedMetrics, setFakedMetrics] = React.useState();
    const [showResolution, setShowResolution] = React.useState(false);
    const { detections } = useDetections();
    const connections = useConnections();
    const wrapperRef = React.useRef(null);
    const wrapperWidth = wrapperRef.current?.clientWidth;
    const wrapperBreakpointRef = React.useRef(null);
    const parentContainer = wrapperBreakpointRef.current ?? wrapperRef.current ?? document.body;
    React.useEffect(() => {
        if (!metrics) {
            setMetrics(connections.at(0)?.getTopicMetrics(topic));
        }
        const interval = setInterval(() => {
            const m = connections[0]?.getTopicMetrics(topic);
            setMetrics(m);
            if (fakedAs) {
                const mFakedAs = connections[0]?.getTopicMetrics(fakedAs);
                if (mFakedAs) {
                    setFakedMetrics({
                        resolutions: m?.resolutions ?? new Map(),
                        incomingMessagesFps: mFakedAs.incomingMessagesFps,
                        decodedMessagesFps: mFakedAs.decodedMessagesFps,
                        messageThroughput: mFakedAs.messageThroughput,
                    });
                }
            }
        }, 500);
        return () => {
            clearInterval(interval);
        };
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [connections, topic, fakedAs]);
    React.useEffect(() => {
        if (wrapperWidth && wrapperWidth < 600) {
            setShowResolution(false);
        }
        else {
            setShowResolution(true);
        }
    }, [wrapperWidth]);
    const hasExtra = React.useMemo(() => detections.some((detection) => detection.extra && !detection.enabled), [detections]);
    const [extraVisible, setExtraVisible] = React.useState(false);
    const onToggleTopic = React.useCallback((toggleTopicName) => {
        setDetections?.((current) => current.map((detection) => ({
            ...detection,
            ...(toggleTopicName === detection.name && {
                enabled: !detection.enabled,
            }),
        })));
    }, [setDetections]);
    const name = React.useMemo(() => {
        return topic;
    }, [topic]);
    const resolution = metrics?.resolutions.get(topic);
    React.useEffect(() => {
        if (targetFps && metrics?.incomingMessagesFps && targetFps > metrics.incomingMessagesFps) {
            const timeout = setTimeout(() => {
                if (metrics.incomingMessagesFps && targetFps * 0.8 > metrics.incomingMessagesFps) {
                    triggerToast?.();
                }
            }, 10_000);
            return () => {
                clearTimeout(timeout);
            };
        }
        return;
    }, [targetFps, metrics?.incomingMessagesFps, triggerToast]);
    const makeDetection = React.useCallback((detection, { extra }) => (extra ? detection.extra && !detection.enabled : !detection.extra || detection.enabled) && (_jsx(PanelAnnotationButton, { topic: detection, onClick: () => {
            onToggleTopic(detection.name);
        } }, detection.name)), [onToggleTopic]);
    return (_jsx(Flex, { direction: "row", gap: "xs", align: "center", justify: "space-between", className: "px-4 bg-white", ref: wrapperRef, children: _jsxs(Flex, { direction: "row", gap: "xs", align: "center", justify: touchesBreakpoint ? "space-between" : "start", width: "full", paddingY: "xs", children: [_jsxs(Flex, { width: "fit", gap: "xxs", className: "flex-col xl:flex-row items-start xl:items-end", children: [_jsx(Tooltip, { content: resolution, children: _jsx(SubHeader, { text: name, className: "whitespace-nowrap text-[20px]/[20px]" }) }), showResolution && resolution && (_jsx(Label, { text: `(${resolution})`, className: "text-[14px]/[14px] xl:pb-[2px]" }))] }), touchesBreakpoint ? (_jsxs(Flex, { direction: "row", gap: "xs", align: "center", children: [actions, _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { icon: MoreMenuIcon, variant: "outline", colorVariant: "white", size: "sm" }) }), _jsxs(DropdownMenuContent, { ref: wrapperBreakpointRef, children: [_jsx(PanelToolbarMetrics, { targetFps: targetFps, metrics: fakedMetrics ?? metrics, topic: topic, inDropdown: true, isPointcloud: kind === "pointCloud" }), kind === "pointCloud" && (_jsx(Tooltip, { parentContainer: parentContainer, side: "bottom", content: _jsx(PointCloudPanelInstructions, {}), children: _jsx(DropdownMenuItem, { icon: HelpIcon, onClick: (e) => {
                                                    e.stopPropagation();
                                                    e.preventDefault();
                                                }, cursor: "help", children: "Point Cloud Details" }) })), !disableAnnotations && kind === "image" && (_jsxs(DropdownMenuSub, { children: [_jsx(DropdownMenuSubTrigger, { disabled: detections.length === 0, style: { opacity: detections.length === 0 ? 0.5 : 1 }, children: "Annotations" }), _jsxs(DropdownMenuSubContent, { children: [detections.map((detection) => makeDetection(detection, { extra: false })), hasExtra && (_jsx(Button, { width: "full", paddingY: "xs", variant: "ghost", "aria-expanded": extraVisible ? "true" : undefined, onClick: () => {
                                                                setExtraVisible((current) => !current);
                                                            }, icon: extraVisible ? ArrowUpIcon : ArrowDownIcon, style: {
                                                                borderRadius: 4,
                                                            }, children: extraVisible ? "Less" : "More" })), extraVisible &&
                                                            detections.map((detection) => makeDetection(detection, { extra: true }))] })] })), _jsx(DropdownMenuItem, { onClick: moveUp, disabled: !canMoveUp, icon: FaCaretUp, children: "Move Panel Up" }), _jsx(DropdownMenuItem, { onClick: moveDown, disabled: !canMoveDown, icon: FaCaretDown, children: "Move Panel Down" }), toggleFullscreen && (_jsx(DropdownMenuItem, { onClick: toggleFullscreen, icon: FullscreenIcon, children: "Fullscreen" })), _jsx(DropdownMenuItem, { onClick: () => toggleTopic?.(name), disabled: !canMoveDown, icon: CrossIcon, children: "Close Stream" })] })] })] })) : (_jsxs(_Fragment, { children: [_jsx(PanelToolbarMetrics, { targetFps: targetFps, metrics: fakedMetrics ?? metrics, topic: topic, isPointcloud: isPointcloud }), _jsxs(Flex, { direction: "row", gap: "xs", align: "center", justify: "start", marginLeft: "auto", width: "fit", children: [!disableAnnotations && kind === "image" && (_jsxs(DropdownMenu, { children: [_jsx(Tooltip, { content: "Annotations", parentContainer: parentContainer, children: _jsx(DropdownMenuTrigger, { asChild: true, disabled: detections.length === 0, children: _jsx(Button, { variant: "outline", colorVariant: "white", size: "sm", icon: CiFilter, disabled: detections.length === 0 }) }) }), _jsxs(DropdownMenuContent, { parentContainer: parentContainer, children: [detections.map((detection) => makeDetection(detection, { extra: false })), hasExtra && (_jsx(Button, { width: "full", paddingY: "xs", variant: "ghost", "aria-expanded": extraVisible ? "true" : undefined, onClick: () => {
                                                        setExtraVisible((current) => !current);
                                                    }, icon: extraVisible ? ArrowUpIcon : ArrowDownIcon, style: {
                                                        borderRadius: 4,
                                                    }, children: extraVisible ? "Less" : "More" })), extraVisible &&
                                                    detections.map((detection) => makeDetection(detection, { extra: true }))] })] })), kind === "pointCloud" && (_jsx(Flex, { children: _jsx(Tooltip, { parentContainer: parentContainer, side: "bottom", content: _jsx(PointCloudPanelInstructions, {}), children: _jsx(Button, { icon: HelpIcon, variant: "outline", colorVariant: "white", size: "sm", className: "text-gray-700" }) }) })), _jsx(Tooltip, { content: "Move Panel Up", parentContainer: parentContainer, children: _jsx(Button, { icon: FaCaretUp, variant: "outline", colorVariant: "white", size: "sm", disabled: !canMoveUp, onClick: moveUp }) }), _jsx(Tooltip, { content: "Move Panel Down", parentContainer: parentContainer, children: _jsx(Button, { icon: FaCaretDown, variant: "outline", colorVariant: "white", size: "sm", disabled: !canMoveDown, onClick: moveDown }) }), toggleFullscreen && (_jsx(Tooltip, { content: "Fullscreen", parentContainer: parentContainer, children: _jsx(Button, { icon: FullscreenIcon, variant: "outline", colorVariant: "white", size: "sm", onClick: toggleFullscreen }) })), actions, _jsx(Tooltip, { content: "Close Stream", parentContainer: parentContainer, children: _jsx(Button, { icon: CrossIcon, variant: "outline", colorVariant: "white", size: "sm", onClick: () => toggleTopic?.(name) }) })] })] }))] }) }));
};
//# sourceMappingURL=PanelToolbar.js.map