/*---------------------------------------------------------------------------------------------
 * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
 * See LICENSE.md in the project root for license terms and full copyright notice.
 *--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module ConfigurableUi
 */
import "./ConfigurableUiContent.scss";
import * as React from "react";
import { Point } from "@itwin/core-react/internal";
import { IModelConnectionProvider, QuantityEditorSpec, } from "@itwin/imodel-components-react";
import { ThemeProvider } from "@itwin/itwinui-react";
import { CursorInformation } from "../cursor/CursorInformation.js";
import { CursorPopupMenu } from "../cursor/cursormenu/CursorMenu.js";
import { CursorPopupRenderer } from "../cursor/cursorpopup/CursorPopupManager.js";
import { ModalDialogRenderer } from "../dialog/ModalDialogManager.js";
import { ModelessDialogRenderer } from "../dialog/ModelessDialogManager.js";
import { ElementTooltip } from "../feedback/ElementTooltip.js";
import { KeyboardShortcutMenu } from "../keyboardshortcut/KeyboardShortcutMenu.js";
import { InputFieldMessage } from "../messages/InputField.js";
import { PointerMessage } from "../messages/Pointer.js";
import { PopupRenderer } from "../popup/PopupManager.js";
import { WidgetPanelsFrontstage } from "../widget-panels/Frontstage.js";
import { ContentDialogRenderer } from "../dialog/ContentDialogManager.js";
import { appUi, UiFramework } from "../UiFramework.js";
import { InternalConfigurableUiManager } from "./InternalConfigurableUiManager.js";
import { MessageRenderer } from "../messages/MessageRenderer.js";
import { TOOLBAR_OPACITY_DEFAULT, WIDGET_OPACITY_DEFAULT, } from "../theme/ThemeId.js";
import { useReduxFrameworkState } from "../uistate/useReduxFrameworkState.js";
import { ChildWindowRenderer } from "../childwindow/ChildWindowRenderer.js";
import { useActiveFrontstageDef } from "../frontstage/FrontstageDef.js";
import { useActiveIModelConnection } from "../hooks/useActiveIModelConnection.js";
import { EditorsRegistryProvider } from "@itwin/components-react";
/** @internal */
export const ConfigurableUiContext = React.createContext({});
/**
 * Allows children to get the bounds or other properties of the wrapper element.
 * @internal
 */
export const WrapperContext = React.createContext(document.body);
/** The main component of `AppUI` that sets up the configurable UI.
 * @public
 */
// eslint-disable-next-line @typescript-eslint/no-deprecated
export function ConfigurableUiContent(props) {
    const frontstageDef = useActiveFrontstageDef();
    const layout = frontstageDef?.initialConfig?.layout;
    return (React.createElement(ConfigurableUiContext.Provider
    // eslint-disable-next-line react-hooks/exhaustive-deps
    , { 
        // eslint-disable-next-line react-hooks/exhaustive-deps
        value: React.useMemo(() => props, [...Object.values(props)]) }, layout ?? React.createElement(StandardLayout, null)));
}
/** The standard widget based layout used as a default layout for all frontstages.
 * @alpha
 */
export function StandardLayout(props) {
    const { widgetActions, visibleToolSettings = false, toolSettings } = props;
    const context = React.useContext(ConfigurableUiContext);
    const { appBackstage, widgetOpacity, toolbarOpacity, idleTimeout, intervalTimeout, } = context;
    const contentElementRef = React.useRef(null);
    useWidgetOpacity(widgetOpacity);
    useToolbarOpacity(toolbarOpacity);
    const [mainElement, setMainElement] = React.useState();
    const [portalContainer, setPortalContainer] = React.useState();
    React.useEffect(() => {
        UiFramework.keyboardShortcuts.setFocusToHome();
    }, []);
    React.useEffect(() => {
        InternalConfigurableUiManager.activityTracker.initialize({
            idleTimeout,
            intervalTimeout,
        });
        return () => {
            InternalConfigurableUiManager.activityTracker.terminate();
        };
    }, [idleTimeout, intervalTimeout]);
    useVisibleToolSettings(visibleToolSettings);
    return (React.createElement(ConfigurableUiContext.Provider, { value: React.useMemo(() => ({
            ...context,
            contentElementRef,
            widgetActions,
            toolSettings,
        }), [context, widgetActions, toolSettings]) },
        React.createElement("main", { role: "main", id: "uifw-configurableui-wrapper", className: context.className, style: context.style, onMouseMove: (e) => {
                const point = new Point(e.pageX, e.pageY);
                CursorInformation.handleMouseMove(point, e.view.document);
            }, ref: (el) => setMainElement(el ?? undefined) },
            React.createElement(WrapperContext.Provider, { value: mainElement ?? document.body },
                React.createElement(ThemeProvider, { style: { height: "100%" }, portalContainer: portalContainer },
                    React.createElement(IModelProvider, null,
                        React.createElement(EditorsRegistryProvider, { editors: defaultEditors },
                            appBackstage,
                            React.createElement(WidgetPanelsFrontstage, null),
                            React.createElement(PointerMessage, null),
                            React.createElement(KeyboardShortcutMenu, null),
                            React.createElement(InputFieldMessage, null),
                            React.createElement(CursorPopupMenu, null),
                            React.createElement(CursorPopupRenderer, null),
                            React.createElement(PopupRenderer, null),
                            React.createElement(ElementTooltip, null),
                            React.createElement(MessageRenderer, null),
                            React.createElement(ChildWindowRenderer, { windowManager: appUi.windowManager }),
                            React.createElement("div", { className: "uifw-configurableui-portalContainer", ref: (instance) => setPortalContainer(instance ?? undefined) },
                                React.createElement(ContentDialogRenderer, null),
                                React.createElement(ModelessDialogRenderer, null),
                                React.createElement(ModalDialogRenderer, null)))))))));
}
const defaultEditors = [QuantityEditorSpec];
function useWidgetOpacity(
/* eslint-disable-next-line @typescript-eslint/no-deprecated */
widgetOpacity) {
    const reduxWidgetOpacity = useReduxFrameworkState((state) => {
        // eslint-disable-next-line @typescript-eslint/no-deprecated
        return state?.configurableUiState.widgetOpacity;
    });
    const opacity = widgetOpacity ?? reduxWidgetOpacity ?? WIDGET_OPACITY_DEFAULT;
    React.useEffect(() => {
        const currentWidgetOpacity = document.documentElement.style.getPropertyValue("--buic-widget-opacity");
        if (currentWidgetOpacity === opacity.toString())
            return;
        document.documentElement.style.setProperty("--buic-widget-opacity", opacity.toString());
        return () => {
            document.documentElement.style.removeProperty("--buic-widget-opacity");
        };
    }, [opacity]);
}
function useToolbarOpacity(
/* eslint-disable-next-line @typescript-eslint/no-deprecated */
toolbarOpacity) {
    const reduxToolbarOpacity = useReduxFrameworkState((state) => {
        // eslint-disable-next-line @typescript-eslint/no-deprecated
        return state?.configurableUiState.toolbarOpacity;
    });
    const opacity = toolbarOpacity ?? reduxToolbarOpacity ?? TOOLBAR_OPACITY_DEFAULT;
    React.useEffect(() => {
        const currentToolbarOpacity = document.documentElement.style.getPropertyValue("--buic-toolbar-opacity");
        if (currentToolbarOpacity === opacity.toString())
            return;
        document.documentElement.style.setProperty("--buic-toolbar-opacity", opacity.toString());
        return () => {
            document.documentElement.style.removeProperty("--buic-toolbar-opacity");
        };
    }, [opacity]);
}
function useVisibleToolSettings(enabled) {
    React.useEffect(() => {
        if (!enabled)
            return;
        return UiFramework.frontstages.onToolSettingsReloadEvent.addListener(() => {
            const frontstage = UiFramework.frontstages.activeFrontstageDef;
            const toolSettings = frontstage?.toolSettings;
            if (!toolSettings)
                return;
            toolSettings.show();
        });
    }, [enabled]);
}
function IModelProvider({ children }) {
    const imodel = useActiveIModelConnection();
    return (React.createElement(IModelConnectionProvider, { iModelConnection: imodel }, children));
}
//# sourceMappingURL=ConfigurableUiContent.js.map