/*---------------------------------------------------------------------------------------------
 * 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 * as React from "react";
import { ProcessDetector } from "@itwin/core-bentley";
import { DrawingViewState, OrthographicViewState, SheetViewState, SpatialViewState, } from "@itwin/core-frontend";
import { useProximityToMouse, useWidgetOpacityContext, WidgetElementSet, WidgetOpacityContext, } from "@itwin/core-react";
import { CubeNavigationAid, DrawingNavigationAid, ViewportComponentEvents, } from "@itwin/imodel-components-react";
import { NavigationArea } from "../layout/widget/NavigationArea";
import { UiFramework } from "../UiFramework";
import { useActiveViewport } from "../hooks/useActiveViewport";
import { ViewUtilities } from "../utils/ViewUtilities";
import { SheetNavigationAid } from "../navigationaids/SheetNavigationAid";
function createNavigationAidControl(
// eslint-disable-next-line deprecation/deprecation
activeContentControl, navigationAidId, activeViewport
// eslint-disable-next-line deprecation/deprecation
) {
    if (!activeContentControl ||
        !navigationAidId ||
        activeViewport !== activeContentControl.viewport)
        return undefined;
    const viewport = activeContentControl.viewport;
    const imodel = viewport ? viewport.iModel : UiFramework.getIModelConnection();
    // eslint-disable-next-line deprecation/deprecation
    const navigationAidControl = UiFramework.controls.create(navigationAidId, navigationAidId, { imodel, viewport }
    // eslint-disable-next-line deprecation/deprecation
    );
    navigationAidControl.initialize();
    return navigationAidControl;
}
/** Component that is used as a default navigation aid.
 * Uses registered navigation aids and the active content control to determine if or which navigation aid to display.
 * If an active content is defined without a content control (`classId` is set to an empty string) renders a default navigation aid based on an active viewport view state.
 * @public
 */
export function NavigationAidHost(props) {
    const [activeContentControl, setActiveContentControl] = React.useState(() => 
    // eslint-disable-next-line deprecation/deprecation
    UiFramework.content.getActiveContentControl());
    const [activeContentViewport, setActiveContentViewport] = React.useState(() => activeContentControl?.viewport);
    const [navigationAidId, setNavigationAidId] = React.useState(() => activeContentControl ? activeContentControl.navigationAidControl : "");
    React.useEffect(() => {
        // eslint-disable-next-line deprecation/deprecation
        return UiFramework.frontstages.onContentControlActivatedEvent.addListener((args) => {
            setActiveContentControl(args.activeContentControl);
            setActiveContentViewport(args.activeContentControl.viewport);
            setNavigationAidId(args.activeContentControl.navigationAidControl);
        });
    }, []);
    React.useEffect(() => {
        return UiFramework.content.onActiveContentChangedEvent.addListener((args) => {
            args.id;
            const frontstageDef = UiFramework.frontstages.activeFrontstageDef;
            if (!frontstageDef)
                return;
            const contentGroup = frontstageDef.contentGroup;
            if (!contentGroup)
                return;
            const content = contentGroup.contentPropsList.find((contentProps) => contentProps.id === args.id);
            if (!content?.content)
                return;
            // Content w/o a control is activated - reset the navigation.
            setActiveContentControl(undefined);
            setActiveContentViewport(undefined);
            setNavigationAidId("");
        });
    }, []);
    const [activeViewClass, setActiveViewClass] = React.useState(() => {
        // eslint-disable-next-line deprecation/deprecation
        const content = UiFramework.content.getActiveContentControl();
        if (content && content.viewport)
            return content.viewport.view.classFullName;
        return "";
    });
    React.useEffect(() => {
        return ViewportComponentEvents.onViewClassFullNameChangedEvent.addListener((args) => {
            setActiveViewClass(args.newName);
        });
    }, [activeViewClass]);
    const navigationAidControl = React.useMemo(() => createNavigationAidControl(activeContentControl, navigationAidId, activeContentViewport), [activeContentControl, navigationAidId, activeContentViewport]);
    const ref = React.useRef(null);
    const isInitialMount = React.useRef(true);
    const { onElementRef, proximityScale } = useWidgetOpacityContext();
    React.useEffect(() => {
        if (isInitialMount.current) {
            isInitialMount.current = false;
            onElementRef(ref);
        }
    }, [onElementRef]);
    const divStyle = {
        minWidth: props.minWidth ? props.minWidth : "64px",
        minHeight: props.minHeight ? props.minHeight : "64px",
    };
    if ((UiFramework.visibility.useProximityOpacity || // eslint-disable-line deprecation/deprecation
        UiFramework.visibility.snapWidgetOpacity) &&
        !ProcessDetector.isMobileBrowser) {
        const navigationAidOpacity = 0.3 * proximityScale + 0.7;
        divStyle.opacity = `${navigationAidOpacity}`;
    }
    const navigationAid = navigationAidControl?.reactNode ?? (React.createElement(DefaultNavigationAid, null));
    return (React.createElement("div", { style: divStyle, ref: ref }, navigationAid));
}
function DefaultNavigationAid() {
    const viewport = useActiveViewport();
    if (!viewport)
        return null;
    const className = ViewUtilities.getBisBaseClass(viewport.view.classFullName);
    switch (className) {
        case SheetViewState.className:
            return React.createElement(SheetNavigationAid, { iModelConnection: viewport.iModel });
        case DrawingViewState.className:
            return (React.createElement(DrawingNavigationAid, { iModelConnection: viewport.iModel, viewport: viewport }));
        case SpatialViewState.className:
        case OrthographicViewState.className:
            return (React.createElement(CubeNavigationAid, { iModelConnection: viewport.iModel, viewport: viewport }));
    }
    return null;
}
/**
 * Component that Composes a NavigationWidget typically using toolbars generated via [[ToolbarComposer]] class. The Navigation widget is shown in the top right of the content area
 * and typically holds tools to visually navigate, orient, and zoom to specific content.
 * @public
 */
export function NavigationWidgetComposer(props) {
    const { navigationAidHost, horizontalToolbar, verticalToolbar, hideNavigationAid, ...otherProps } = props;
    const [elementSet] = React.useState(new WidgetElementSet());
    const handleChildRef = React.useCallback((elementRef) => {
        elementSet.add(elementRef);
    }, [elementSet]);
    const proximityScale = useProximityToMouse(elementSet, UiFramework.visibility.snapWidgetOpacity);
    const navigationAid = hideNavigationAid
        ? undefined
        : // eslint-disable-next-line deprecation/deprecation
            navigationAidHost ?? React.createElement(NavigationAidHost, null);
    return (React.createElement(WidgetOpacityContext.Provider, { value: {
            onElementRef: handleChildRef,
            proximityScale,
        } },
        React.createElement(NavigationArea, { navigationAid: navigationAid, horizontalToolbar: horizontalToolbar, verticalToolbar: verticalToolbar, ...otherProps, onMouseEnter: UiFramework.visibility.handleWidgetMouseEnter })));
}
//# sourceMappingURL=NavigationWidgetComposer.js.map