"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 Utilities
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.UiFramework = exports.UiVisibilityChangedEvent = void 0;
const core_bentley_1 = require("@itwin/core-bentley");
const core_frontend_1 = require("@itwin/core-frontend");
const core_frontend_2 = require("@itwin/core-frontend");
const appui_abstract_1 = require("@itwin/appui-abstract");
const core_react_1 = require("@itwin/core-react");
const imodel_components_react_1 = require("@itwin/imodel-components-react");
const BackstageManager_1 = require("./backstage/BackstageManager");
const InternalChildWindowManager_1 = require("./childwindow/InternalChildWindowManager");
const InternalConfigurableUiManager_1 = require("./configurableui/InternalConfigurableUiManager");
const SessionState_1 = require("./redux/SessionState");
const StateManager_1 = require("./redux/StateManager");
const HideIsolateEmphasizeManager_1 = require("./selection/HideIsolateEmphasizeManager");
const keyinPaletteTools = require("./tools/KeyinPaletteTools");
const openSettingTools = require("./tools/OpenSettingsTool");
const restoreLayoutTools = require("./tools/RestoreLayoutTool");
const toolSettingTools = require("./tools/ToolSettingsTools");
const InternalUiShowHideManager_1 = require("./utils/InternalUiShowHideManager");
const WidgetManager_1 = require("./widgets/WidgetManager");
const InternalFrontstageManager_1 = require("./frontstage/InternalFrontstageManager");
const InternalContentViewManager_1 = require("./content/InternalContentViewManager");
const InternalModalDialogManager_1 = require("./dialog/InternalModalDialogManager");
const InternalModelessDialogManager_1 = require("./dialog/InternalModelessDialogManager");
const InternalKeyboardShortcut_1 = require("./keyboardshortcut/InternalKeyboardShortcut");
const InternalToolSettingsManager_1 = require("./toolsettings/InternalToolSettingsManager");
const SyncUiEventDispatcher_1 = require("./syncui/SyncUiEventDispatcher");
const PopupManager_1 = require("./popup/PopupManager");
const AccuDrawPopupManager_1 = require("./accudraw/AccuDrawPopupManager");
const UiDataProvidedDialog_1 = require("./dialog/UiDataProvidedDialog");
const react_1 = require("react");
const Placement_1 = require("./utils/Placement");
const ThemeId_1 = require("./theme/ThemeId");
const ConfigurableUiState_1 = require("./redux/ConfigurableUiState");
const useGlobalStore_1 = require("./uistate/useGlobalStore");
const LocalStateStorage_1 = require("./uistate/LocalStateStorage");
const SettingsManager_1 = require("./settings/SettingsManager");
/** UiVisibility Event class.
 * @public
 * @deprecated in 4.13.0. This class should not be used by applications to instantiate objects.
 */
// eslint-disable-next-line deprecation/deprecation
class UiVisibilityChangedEvent extends appui_abstract_1.UiEvent {
}
exports.UiVisibilityChangedEvent = UiVisibilityChangedEvent;
/** Main entry point to configure and interact with the features provided by the AppUi-react package.
 * @public
 */
class UiFramework {
    /** Operation on the backstage component. */
    static get backstage() {
        if (!UiFramework._backstageManager)
            // eslint-disable-next-line deprecation/deprecation
            throw new appui_abstract_1.UiError(UiFramework.loggerCategory(this), UiFramework._complaint);
        return UiFramework._backstageManager;
    }
    /** Manage access to the child windows. */
    static get childWindows() {
        return this._childWindowManager;
    }
    /** Manage registered controls.
     * @deprecated in 4.16.0. Uses a deprecated interface {@link FrameworkControls}.
     */
    // eslint-disable-next-line deprecation/deprecation
    static get controls() {
        return InternalConfigurableUiManager_1.InternalConfigurableUiManager;
    }
    /** Manage access to frontstages and related helper methods. */
    static get frontstages() {
        return InternalFrontstageManager_1.InternalFrontstageManager;
    }
    /** Manage access and behavior of the tool settings. */
    static get toolSettings() {
        return InternalToolSettingsManager_1.InternalToolSettingsManager;
    }
    /** Manage content presented by the frontstages. */
    static get content() {
        return InternalContentViewManager_1.InternalContentViewManager;
    }
    /** Manage displayed dialogs. */
    static get dialogs() {
        return {
            modal: InternalModalDialogManager_1.InternalModalDialogManager,
            modeless: InternalModelessDialogManager_1.InternalModelessDialogManager,
        };
    }
    /** Manages global keyboard shortcuts
     *
     * Note: This only manages the list of available shortcuts registered with it. It does not listens to the actual
     * keyboard events. In order for these shortcuts to be called upon a keyboard event, the application can
     * override the `IModelApp.toolAdmin` and assign it [[FrameworkToolAdmin]] or create an event listener
     * and call `UiFramework.keyboardShortcuts.processKey`.
     */
    static get keyboardShortcuts() {
        return InternalKeyboardShortcut_1.InternalKeyboardShortcutManager;
    }
    /** Manages UI visibility (Show/Hide). */
    static get visibility() {
        return InternalUiShowHideManager_1.InternalUiShowHideManager;
    }
    /** Registers class that will be informed when the UserSettingsStorage location has been set or changed. This allows
     * classes to load any previously saved settings from the new storage location. Common storage locations are the browser's
     * local storage, or the iTwin Product Settings cloud storage available via the SettingsAdmin see `IModelApp.settingsAdmin`.
     */
    static registerUserSettingsProvider(entry) {
        if (this._uiSettingsProviderRegistry.has(entry.providerId))
            return false;
        this._uiSettingsProviderRegistry.set(entry.providerId, entry);
        return true;
    }
    static async initialize(store, frameworkStateKey) {
        // TODO: check `arguments` to determine between redux & no-redux initializers.
        if (UiFramework._initialized) {
            core_bentley_1.Logger.logInfo(UiFramework.loggerCategory(UiFramework), `UiFramework.initialize already called`);
            return;
        }
        /* if store is undefined then the StateManager class should have been initialized by parent app and the apps default set of reducers registered with it.
          If the app has no reducers to add and does not initialize a StateManager then just initialize the StateManager with the default framework reducer now */
        // eslint-disable-next-line deprecation/deprecation
        if (undefined === store && !StateManager_1.StateManager.isInitialized(true))
            // eslint-disable-next-line deprecation/deprecation
            new StateManager_1.StateManager();
        UiFramework._store = store;
        // ignore setting _frameworkStateKeyInStore if not using store
        if (frameworkStateKey && store)
            UiFramework._frameworkStateKeyInStore = frameworkStateKey;
        // set up namespace and register all tools from package
        const frameworkNamespace = core_frontend_2.IModelApp.localization?.registerNamespace(UiFramework.localizationNamespace);
        [
            restoreLayoutTools,
            keyinPaletteTools,
            openSettingTools,
            toolSettingTools,
        ].forEach((tool) => core_frontend_2.IModelApp.tools.registerModule(tool, this.localizationNamespace));
        // eslint-disable-next-line deprecation/deprecation
        UiFramework._backstageManager = new BackstageManager_1.BackstageManager();
        UiFramework._hideIsolateEmphasizeActionHandler =
            new HideIsolateEmphasizeManager_1.HideIsolateEmphasizeManager(); // this allows user to override the default HideIsolateEmphasizeManager implementation.
        UiFramework._widgetManager = new WidgetManager_1.WidgetManager();
        // Initialize ui-imodel-components, ui-components, ui-core & ui-abstract
        await imodel_components_react_1.UiIModelComponents.initialize();
        UiFramework.settingsManager.onSettingsProvidersChanged.addListener(() => {
            dispatchSyncUiEvent(SyncUiEventDispatcher_1.SyncUiEventId.SettingsProvidersChanged);
        });
        // Initialize the MessagePresenter interface in UiAdmin for Editor notifications
        appui_abstract_1.UiAdmin.messagePresenter = core_frontend_2.IModelApp.notifications;
        UiFramework._initialized = true;
        // initialize any standalone settings providers that don't need to have defaults set by iModelApp
        InternalUiShowHideManager_1.UiShowHideSettingsProvider.initialize();
        InternalConfigurableUiManager_1.InternalConfigurableUiManager.initialize();
        return frameworkNamespace;
    }
    /** Un-registers the UiFramework internationalization service namespace. */
    static terminate() {
        InternalKeyboardShortcut_1.InternalKeyboardShortcutManager.shortcutContainer.emptyData();
        UiFramework._store = undefined;
        UiFramework._frameworkStateKeyInStore = "frameworkState";
        // eslint-disable-next-line deprecation/deprecation
        if (StateManager_1.StateManager.isInitialized(true))
            StateManager_1.StateManager.clearStore();
        core_frontend_2.IModelApp.localization?.unregisterNamespace(UiFramework.localizationNamespace);
        UiFramework._backstageManager = undefined;
        UiFramework._widgetManager = undefined;
        UiFramework._hideIsolateEmphasizeActionHandler = undefined;
        UiFramework._settingsManager = undefined;
        imodel_components_react_1.UiIModelComponents.terminate();
        InternalUiShowHideManager_1.InternalUiShowHideManager.terminate();
        UiFramework._initialized = false;
    }
    /** Determines if UiFramework has been initialized */
    static get initialized() {
        return UiFramework._initialized;
    }
    /** Property that returns the SettingManager used by AppUI-based applications. */
    static get settingsManager() {
        if (undefined === UiFramework._settingsManager)
            UiFramework._settingsManager = new SettingsManager_1.SettingsManager();
        return UiFramework._settingsManager;
    }
    /** The internationalization service namespace. */
    static get localizationNamespace() {
        return "UiFramework";
    }
    static get hideIsolateEmphasizeActionHandler() {
        if (!UiFramework._hideIsolateEmphasizeActionHandler)
            // eslint-disable-next-line deprecation/deprecation
            throw new appui_abstract_1.UiError(UiFramework.loggerCategory(this), UiFramework._complaint);
        return UiFramework._hideIsolateEmphasizeActionHandler;
    }
    static setHideIsolateEmphasizeActionHandler(handler) {
        if (handler)
            UiFramework._hideIsolateEmphasizeActionHandler = handler;
        else
            UiFramework._hideIsolateEmphasizeActionHandler =
                new HideIsolateEmphasizeManager_1.HideIsolateEmphasizeManager();
    }
    /** @alpha */
    static get widgetManager() {
        if (!UiFramework._widgetManager)
            // eslint-disable-next-line deprecation/deprecation
            throw new appui_abstract_1.UiError(UiFramework.loggerCategory(this), UiFramework._complaint);
        return UiFramework._widgetManager;
    }
    /** Calls localization.getLocalizedString with the "UiFramework" namespace. Do NOT include the namespace in the key.
     * @internal
     */
    static translate(key, options) {
        return core_frontend_2.IModelApp.localization.getLocalizedString(`${UiFramework.localizationNamespace}:${key}`, options);
    }
    /** @internal */
    static get packageName() {
        return "appui-react";
    }
    /** @internal */
    static loggerCategory(obj) {
        const className = (0, core_react_1.getObjectClassName)(obj);
        const category = UiFramework.packageName + (className ? `.${className}` : "");
        return category;
    }
    /** Show a context menu at a particular location.
     * @param items Properties of the menu items to display.
     * @param location Location of the context menu, relative to the origin of anchorElement or the overall window.
     * @param anchorElement The HTMLElement that anchors the context menu. If undefined, the location is relative to the overall window.
     * @return true if the menu was displayed, false if the menu could not be displayed.
     */
    static openContextMenu(items, location, anchorElement) {
        let position = location;
        let childWindowId;
        if (anchorElement) {
            const anchorOffset = anchorElement.getBoundingClientRect();
            position = {
                x: anchorOffset.left + location.x,
                y: anchorOffset.top + location.y,
            };
            childWindowId = UiFramework.childWindows.findId(anchorElement.ownerDocument.defaultView);
        }
        position = {
            x: position.x + UiFramework.CONTEXT_MENU_OFFSET,
            y: position.y + UiFramework.CONTEXT_MENU_OFFSET,
        };
        const cursorMenuData = {
            position,
            items,
            childWindowId,
        };
        UiFramework.openCursorMenu(cursorMenuData);
        return true;
    }
    static openCursorMenu(
    // eslint-disable-next-line deprecation/deprecation
    menuData) {
        // eslint-disable-next-line deprecation/deprecation
        if (this.frameworkState) {
            // eslint-disable-next-line deprecation/deprecation
            UiFramework.dispatchActionToStore(
            // eslint-disable-next-line deprecation/deprecation
            SessionState_1.SessionStateActionId.UpdateCursorMenu, menuData);
            return;
        }
        useGlobalStore_1.useGlobalStore.setState({ cursorMenuPayload: menuData });
        // eslint-disable-next-line deprecation/deprecation
        dispatchSyncUiEvent(SessionState_1.SessionStateActionId.UpdateCursorMenu);
    }
    static closeCursorMenu() {
        // eslint-disable-next-line deprecation/deprecation
        if (UiFramework.frameworkState) {
            // eslint-disable-next-line deprecation/deprecation
            UiFramework.dispatchActionToStore(
            // eslint-disable-next-line deprecation/deprecation
            SessionState_1.SessionStateActionId.UpdateCursorMenu, undefined);
            return;
        }
        useGlobalStore_1.useGlobalStore.setState({ cursorMenuPayload: undefined });
        // eslint-disable-next-line deprecation/deprecation
        dispatchSyncUiEvent(SessionState_1.SessionStateActionId.UpdateCursorMenu);
    }
    /** @note Returned value is immutable.  */
    static getCursorMenuData() {
        // eslint-disable-next-line deprecation/deprecation
        const state = this.frameworkState;
        if (state) {
            return (
            // eslint-disable-next-line deprecation/deprecation
            state.sessionState.cursorMenuPayload ??
                // eslint-disable-next-line deprecation/deprecation
                state.sessionState.cursorMenuData);
        }
        return useGlobalStore_1.useGlobalStore.getState().cursorMenuPayload;
    }
    static setIModelConnection(iModelConnection, immediateSync = false) {
        const oldConnection = UiFramework.getIModelConnection();
        if (oldConnection === iModelConnection)
            return;
        InternalFrontstageManager_1.InternalFrontstageManager.clearFrontstageDefsForIModelId(oldConnection?.iModelId);
        oldConnection && SyncUiEventDispatcher_1.SyncUiEventDispatcher.clearConnectionEvents(oldConnection);
        iModelConnection &&
            SyncUiEventDispatcher_1.SyncUiEventDispatcher.initializeConnectionEvents(iModelConnection);
        // eslint-disable-next-line deprecation/deprecation
        if (UiFramework.frameworkState) {
            // eslint-disable-next-line deprecation/deprecation
            UiFramework.dispatchActionToStore(
            // eslint-disable-next-line deprecation/deprecation
            SessionState_1.SessionStateActionId.SetIModelConnection, iModelConnection, immediateSync);
        }
        else {
            useGlobalStore_1.useGlobalStore.setState({ iModelConnection });
            // eslint-disable-next-line deprecation/deprecation
            dispatchSyncUiEvent(SessionState_1.SessionStateActionId.SetIModelConnection);
        }
        const itemsSelected = iModelConnection
            ? iModelConnection.selectionSet.elements.size
            : 0;
        UiFramework.setNumItemsSelected(itemsSelected);
        // eslint-disable-next-line deprecation/deprecation
        UiFramework.setActiveIModelId(iModelConnection?.iModelId ?? "");
    }
    static getIModelConnection() {
        // eslint-disable-next-line deprecation/deprecation
        const frameworkState = UiFramework.frameworkState;
        if (frameworkState) {
            // eslint-disable-next-line deprecation/deprecation
            return frameworkState.sessionState.iModelConnection;
        }
        return useGlobalStore_1.useGlobalStore.getState().iModelConnection;
    }
    static setNumItemsSelected(numSelected) {
        // eslint-disable-next-line deprecation/deprecation
        if (UiFramework.frameworkState) {
            // eslint-disable-next-line deprecation/deprecation
            UiFramework.dispatchActionToStore(
            // eslint-disable-next-line deprecation/deprecation
            SessionState_1.SessionStateActionId.SetNumItemsSelected, numSelected);
            return;
        }
        useGlobalStore_1.useGlobalStore.setState({ numItemsSelected: numSelected });
        // eslint-disable-next-line deprecation/deprecation
        dispatchSyncUiEvent(SessionState_1.SessionStateActionId.SetNumItemsSelected);
    }
    static getNumItemsSelected() {
        // eslint-disable-next-line deprecation/deprecation
        const state = this.frameworkState;
        if (state) {
            // eslint-disable-next-line deprecation/deprecation
            return state.sessionState.numItemsSelected;
        }
        return useGlobalStore_1.useGlobalStore.getState().numItemsSelected;
    }
    /** Called by iModelApp to initialize saved UI state from registered UseSettingsProviders. */
    static async initializeStateFromUserSettingsProviders(immediateSync = false) {
        // let any registered providers to load values from the new storage location
        const providerKeys = [...this._uiSettingsProviderRegistry.keys()];
        for await (const key of providerKeys) {
            await this._uiSettingsProviderRegistry
                .get(key)
                .loadUserSettings(UiFramework._uiStateStorage);
        }
        dispatchSyncUiEvent(SyncUiEventDispatcher_1.SyncUiEventId.UiStateStorageChanged, immediateSync);
    }
    static async setUiStateStorage(storage, immediateSync = false) {
        if (UiFramework._uiStateStorage === storage)
            return;
        UiFramework._uiStateStorage = storage;
        await this.initializeStateFromUserSettingsProviders(immediateSync);
    }
    /** The UI Settings Storage is a convenient wrapper around Local Storage to assist in caching state information across user sessions.
     * It was previously used to conflate both the state information across session and the information driven directly from user explicit action,
     * which are now handled with user preferences.
     */
    static getUiStateStorage() {
        return UiFramework._uiStateStorage;
    }
    static setDefaultViewState(viewState, immediateSync = false) {
        // eslint-disable-next-line deprecation/deprecation
        if (UiFramework.frameworkState) {
            // eslint-disable-next-line deprecation/deprecation
            UiFramework.dispatchActionToStore(
            // eslint-disable-next-line deprecation/deprecation
            SessionState_1.SessionStateActionId.SetDefaultViewState, viewState, immediateSync);
            return;
        }
        useGlobalStore_1.useGlobalStore.setState({ viewState });
        dispatchSyncUiEvent(
        // eslint-disable-next-line deprecation/deprecation
        SessionState_1.SessionStateActionId.SetDefaultViewState, immediateSync);
    }
    static getDefaultViewState() {
        // eslint-disable-next-line deprecation/deprecation
        const frameworkState = UiFramework.frameworkState;
        if (frameworkState) {
            // eslint-disable-next-line deprecation/deprecation
            return frameworkState.sessionState.defaultViewState;
        }
        return useGlobalStore_1.useGlobalStore.getState().viewState;
    }
    static getIsUiVisible() {
        return UiFramework.visibility.isUiVisible;
    }
    static setIsUiVisible(visible) {
        UiFramework.visibility.isUiVisible = visible;
    }
    /** @deprecated in 4.13.0. Use {@link @itwin/core-bentley#ProcessDetector.isMobileBrowser} instead. */
    // eslint-disable-next-line @itwin/prefer-get
    static isMobile() {
        return core_bentley_1.ProcessDetector.isMobileBrowser;
    }
    /** Determines whether a ContextMenu is open
     * @alpha
     */
    static get isContextMenuOpen() {
        const contextMenu = document.querySelector("div.core-context-menu-opened");
        return contextMenu !== null && contextMenu !== undefined;
    }
    /** Show a Card containing content, a title and a toolbar at a particular location.
     * @param content The React component of the content to display
     * @param title Title to display at the top of the card.
     * @param toolbarProps Properties of the Toolbar to display.
     * @param location Location of the Card, relative to the origin of anchorElement or the window.
     * @param offset Offset of the Card from the location.
     * @param onItemExecuted Function invoked after a Toolbar item is executed
     * @param onCancel Function invoked when the Escape key is pressed or a click occurs outside the Card
     * @param placement {@link Placement} relative to the given location. Defaults to top-end.
     * @param anchorElement The HTMLElement that anchors the Card. If undefined, the location is relative to the overall window.
     * @return true if the Card was displayed, false if the Card could not be displayed.
     * @internal
     */
    static showCard(content, title, toolbarProps, location, offset, onItemExecuted, onCancel, placement = "top-end", anchorElement) {
        const anchor = this.resolveHtmlElement(anchorElement);
        return PopupManager_1.PopupManager.displayCard(content, {
            title,
            toolbarProps,
            location,
            offset,
            onItemExecuted,
            onCancel,
            placement,
            anchor,
        });
    }
    /**
     * Hides a Card displayed with {@link UiFramework.showCard}
     * @internal
     */
    static hideCard() {
        return PopupManager_1.PopupManager.hideCard();
    }
    /** Opens a Tool Settings Ui popup at a particular location.
     * @param dataProvider The DialogLayoutDataProvider for the tool settings popup dialog.
     * @param location Location of the tool settings, relative to the origin of anchorElement or the window
     * @param offset Offset of the tool settings from the location
     * @param onCancel Function invoked when the Escape key is pressed or a click occurs outside the tool settings
     * @param placement {@link Placement} relative to the given location. Defaults to top-end.
     * @param anchorElement The HTMLElement that anchors the tool settings. If undefined, the location is relative to the overall window.
     * @return true if the tool settings were displayed, false if the tool settings could not be displayed.
     * @internal
     */
    static openToolSettingsPopup(dataProvider, location, offset, onCancel, placement = "top-end", anchorElement) {
        const el = this.resolveHtmlElement(anchorElement);
        const relativePosition = (0, Placement_1.mapToRelativePosition)(placement);
        return PopupManager_1.PopupManager.openToolSettings(dataProvider, el, location, offset, onCancel, relativePosition);
    }
    /**
     * Closes the Tool Settings Ui popup.
     * @internal
     */
    static closeToolSettingsPopup() {
        return PopupManager_1.PopupManager.closeToolSettings();
    }
    /** Show a Toolbar at a particular location.
     * @param toolbarProps Properties of the Toolbar to display.
     * @param location Location of the Toolbar, relative to the origin of anchorElement or the overall window.
     * @param offset Offset of the Toolbar from the location.
     * @param onItemExecuted Function invoked after a Toolbar item is executed
     * @param onCancel Function invoked when the Escape key is pressed or a click occurs outside the Toolbar
     * @param placement {@link Placement} relative to the given location. Defaults to top-end.
     * @param anchorElement The HTMLElement that anchors the Toolbar. If undefined, the location is relative to the overall window.
     * @return true if the Toolbar was displayed, false if the Toolbar could not be displayed.
     */
    static showToolbar(toolbarProps, location, offset, onItemExecuted, onCancel, placement = "top-end", anchorElement) {
        const anchor = UiFramework.resolveHtmlElement(anchorElement);
        return PopupManager_1.PopupManager.displayToolbar(toolbarProps.items, {
            anchor,
            location,
            offset,
            onItemExecuted,
            onCancel,
            placement,
        });
    }
    /** Hides a toolbar displayed via {@link UiFramework.showToolbar} */
    static hideToolbar() {
        return PopupManager_1.PopupManager.hideToolbar();
    }
    /** Show a menu button at a particular location. A menu button opens a context menu.
     * @param id Id of the menu button. Multiple menu buttons may be displayed.
     * @param menuItemsProps Properties of the menu items to display.
     * @param location Location of the context menu, relative to the origin of anchorElement or the window.
     * @param anchorElement The HTMLElement that anchors the context menu. If undefined, the location is relative to the overall window.
     * @return true if the menu was displayed, false if the menu could not be displayed.
     */
    static showMenuButton(id, menuItemsProps, location, anchorElement) {
        const el = this.resolveHtmlElement(anchorElement);
        return AccuDrawPopupManager_1.AccuDrawPopupManager.showMenuButton(id, el, location, menuItemsProps);
    }
    /** Hides a menu button.
     * @param id Id of the menu button. Multiple menu buttons may be displayed.
     * @return true if the menu was hidden, false if the menu could not be hidden.
     */
    static hideMenuButton(id) {
        return AccuDrawPopupManager_1.AccuDrawPopupManager.hideMenuButton(id);
    }
    /** Show a calculator at a particular location.
     * @param initialValue Value initially displayed in the calculator.
     * @param resultIcon Icon displayed to the left of the value.
     * @param location Location of the calculator, relative to the origin of anchorElement or the window.
     * @param onOk Function called when the OK button or the Enter key is pressed.
     * @param onCancel Function called when the Cancel button or the Escape key  is pressed.
     * @param anchorElement The HTMLElement that anchors the context menu. If undefined, the location is relative to the overall window.
     * @return true if the menu was displayed, false if the menu could not be displayed.
     */
    static showCalculator(initialValue, resultIcon, location, onOk, onCancel, anchorElement) {
        const el = this.resolveHtmlElement(anchorElement);
        return AccuDrawPopupManager_1.AccuDrawPopupManager.showCalculator(el, location, initialValue, resultIcon, onOk, onCancel);
    }
    /** Hides the calculator. */
    static hideCalculator() {
        return AccuDrawPopupManager_1.AccuDrawPopupManager.hideCalculator();
    }
    /** Show a React Element at a particular location.
     * @param component The ReactElement to display
     * @param options - Optional {@link: ShowComponentParams}
     */
    static showComponent(...params) {
        const options = params[1] || {};
        const component = params[0];
        const { anchorRef, id } = options;
        let { location, offset, onCancel, placement } = options;
        if (!location)
            location = { x: 0, y: 0 };
        if (!offset)
            offset = { x: 0, y: 0 };
        if (!placement)
            placement = "top-end";
        if (!onCancel)
            onCancel = () => UiFramework.hideComponent(id);
        return PopupManager_1.PopupManager.showComponent(component, {
            location,
            offset,
            onCancel,
            placement,
            anchor: anchorRef?.current ?? undefined,
            id,
        });
    }
    /**
     * Hides the Component previously shown with {@link UiFramework.showComponent}
     */
    static hideComponent(id) {
        return PopupManager_1.PopupManager.hideComponent(id);
    }
    /** Show an input editor for an angle value at a particular location.
     * @param initialValue Value initially displayed in the editor.
     * @param location Location of the editor, relative to the origin of anchorElement or the window.
     * @param onCommit Function called when the OK button or the Enter key is pressed.
     * @param onCancel Function called when the Cancel button or the Escape key  is pressed.
     * @param anchorElement The HTMLElement that anchors the context menu. If undefined, the location is relative to the overall window.
     * @return true if the editor was displayed, false if the editor could not be displayed.
     */
    static showAngleEditor(initialValue, location, onCommit, onCancel, anchorElement) {
        const el = this.resolveHtmlElement(anchorElement);
        return AccuDrawPopupManager_1.AccuDrawPopupManager.showAngleEditor(el, location, initialValue, onCommit, onCancel);
    }
    /** Show an input editor for a length value at a particular location.
     * @param ShowInputEditorOptions Options detailed below for the input editor
     * @param ShowInputEditorOptions.anchorElement The HTMLElement that anchors the context menu. If undefined, the location is relative to the overall window.
     * @param ShowInputEditorOptions.propertyDescription Description of the primitive value property
     * @param ShowInputEditorOptions.initialValue Value initially displayed in the editor.
     * @param ShowInputEditorOptions.location Location of the editor, relative to the origin of anchorElement or the window.
     * @param ShowInputEditorOptions.onCommit Function called when the OK button or the Enter key is pressed.
     * @param ShowInputEditorOptions.onCancel Function called when the Cancel button or the Escape key is pressed.
     * @return true if the editor was displayed, false if the editor could not be displayed.
     * @internal
     */
    static showInputEditor({ anchorElement, initialValue, location, onCancel, onCommit, propertyDescription, }) {
        const el = this.resolveHtmlElement(anchorElement);
        PopupManager_1.PopupManager.showInputEditor(el, location, initialValue, propertyDescription, onCommit, onCancel);
        return true;
    }
    /** Show an input editor for a length value at a particular location.
     * @param dimension Dimension determining which editor to display.
     * @param initialValue Value initially displayed in the editor.
     * @param location Location of the editor, relative to the origin of anchorElement or the window.
     * @param onCommit Function called when the OK button or the Enter key is pressed.
     * @param onCancel Function called when the Cancel button or the Escape key  is pressed.
     * @param anchorElement The HTMLElement that anchors the context menu. If undefined, the location is relative to the overall window.
     * @return true if the editor was displayed, false if the editor could not be displayed.
     */
    static showDimensionEditor(dimension, initialValue, location, onCommit, onCancel, anchorElement) {
        const el = this.resolveHtmlElement(anchorElement);
        return AccuDrawPopupManager_1.AccuDrawPopupManager.showDimensionEditor(dimension, el, location, initialValue, onCommit, onCancel);
    }
    /** Hides the input editor.
     * @internal
     */
    static hideInputEditor() {
        return PopupManager_1.PopupManager.hideInputEditor();
    }
    /** Opens a Dialog and automatically populates it using the properties defined by the UiDataProvider.
     * @param uiDataProvider The UiDataProvider for the tool settings
     * @param title Specify title for dialog.
     * @param isModal Specify if the dialog is opened as a modal or modeless.
     * @param id Id of the dialog that is used to close it.
     * @param optionalProps Optional props for Dialog construction.
     * @return true if the tool settings were displayed, false if the tool settings could not be displayed.
     * @internal
     */
    static openDialog(uiDataProvider, title, isModal, id, optionalProps) {
        // eslint-disable-next-line deprecation/deprecation
        const dialog = (0, react_1.createElement)(UiDataProvidedDialog_1.UiDataProvidedDialog, {
            uiDataProvider,
            title,
            isModal,
            id,
            ...optionalProps,
        });
        const modalType = isModal ? "modal" : "modeless";
        UiFramework.dialogs[modalType].open(dialog, id);
        return true;
    }
    /** Closes the Dialog with the specified dialogId.
     * @param dialogId Id of the dialog to close.
     * @internal
     */
    static closeDialog(dialogId) {
        const findFn = (info) => info.id === dialogId;
        if (UiFramework.dialogs.modeless.dialogs.findIndex(findFn) !== -1) {
            UiFramework.dialogs.modeless.close(dialogId);
            return true;
        }
        if (UiFramework.dialogs.modal.dialogs.findIndex(findFn) !== -1) {
            UiFramework.dialogs.modal.close();
            return true;
        }
        return false;
    }
    /** Show the Key-in Palette to display key-in from all registered Tools.
     * @param keyinEntries A list of KeyinEntry to display in the palette. These can be gathered and filtered from iModelApp.tools.getToolList()
     * @param htmlElement The HTMLElement that anchors the Popup. If undefined, the location is relative to the overall window.
     * @return true if the Command Palette was displayed, false if it could not be displayed.
     */
    static showKeyinPalette(keyinEntries, htmlElement) {
        return PopupManager_1.PopupManager.showKeyinPalette(keyinEntries, UiFramework.resolveHtmlElement(htmlElement));
    }
    /** Hides the Key-in Palette. */
    static hideKeyinPalette() {
        return PopupManager_1.PopupManager.hideKeyinPalette();
    }
    static resolveHtmlElement(htmlElement) {
        // eslint-disable-next-line deprecation/deprecation
        const el = htmlElement ?? UiFramework.controls.getWrapperElement();
        return el;
    }
    /* eslint-disable deprecation/deprecation */
    /** @deprecated in 4.15.0. Use your preferred state management library instead and {@link SyncUiEventDispatcher} to dispatch sync UI events. */
    static dispatchActionToStore(type, payload, immediateSync = false) {
        const reduxStore = UiFramework.reduxStore;
        const reduxState = reduxStore?.getState();
        const frameworkState = reduxState?.[UiFramework.frameworkStateKey];
        if (!frameworkState)
            return;
        reduxStore.dispatch({ type, payload });
        dispatchSyncUiEvent(type, immediateSync);
    }
    /** Key used to access framework state from redux store.
     * @deprecated in 4.15.0. Use your preferred state management library instead.
     */
    static get frameworkStateKey() {
        return UiFramework._frameworkStateKeyInStore;
    }
    /** The Redux store.
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Use your preferred state management library instead.
     */
    static get store() {
        const reduxStore = this.reduxStore;
        if (!reduxStore) {
            throw new appui_abstract_1.UiError(UiFramework.loggerCategory(this), `Error trying to access redux store before either store or StateManager has been initialized.`);
        }
        return reduxStore;
    }
    /** @internal */
    static get reduxStore() {
        if (UiFramework._store) {
            return UiFramework._store;
        }
        if (StateManager_1.StateManager.isInitialized(true)) {
            return StateManager_1.StateManager.store;
        }
        return undefined;
    }
    /** The UiFramework state maintained by Redux.
     * @note Returned fields should not be modified. Use the appropriate action dispatchers to modify the state.
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Use your preferred state management library instead.
     */
    static get frameworkState() {
        const store = UiFramework.reduxStore;
        const state = store?.getState();
        const frameworkState = state?.[UiFramework.frameworkStateKey];
        return frameworkState;
    }
    /** Set the theme value used by the [[ThemeManager]] component.
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Components should take `theme` as a prop.
     */
    static getColorTheme() {
        return (UiFramework.frameworkState?.configurableUiState.theme ??
            ThemeId_1.SYSTEM_PREFERRED_COLOR_THEME);
    }
    /** Set the theme value used by the [[ThemeManager]] component.
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Use `theme` prop of {@link ThemeManager}.
     */
    static setColorTheme(theme) {
        if (UiFramework.getColorTheme() === theme)
            return;
        UiFramework.dispatchActionToStore(ConfigurableUiState_1.ConfigurableUiActionId.SetTheme, theme, true);
    }
    /** Returns the variable controlling whether the overlay is displayed in a Viewport.
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Components should take `viewOverlay` as a prop.
     */
    static get viewOverlayDisplay() {
        return (UiFramework.frameworkState?.configurableUiState.viewOverlayDisplay ?? true);
    }
    /** Set the variable that controls display of the view overlay. Applies to all viewports in the app.
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Use {@link ConfigurableUiContentProps.viewOverlay} prop of {@link ConfigurableUiContent}.
     */
    static setViewOverlayDisplay(display) {
        if (UiFramework.viewOverlayDisplay === display)
            return;
        UiFramework.dispatchActionToStore(ConfigurableUiState_1.ConfigurableUiActionId.SetViewOverlayDisplay, display);
    }
    /**
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Components should take `widgetOpacity` as a prop.
     */
    static getWidgetOpacity() {
        return (UiFramework.frameworkState?.configurableUiState.widgetOpacity ??
            ThemeId_1.WIDGET_OPACITY_DEFAULT);
    }
    /**
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Use {@link ConfigurableUiContentProps.widgetOpacity} prop of {@link ConfigurableUiContent}.
     */
    static setWidgetOpacity(opacity) {
        if (UiFramework.getWidgetOpacity() === opacity)
            return;
        UiFramework.dispatchActionToStore(ConfigurableUiState_1.ConfigurableUiActionId.SetWidgetOpacity, opacity, true);
    }
    /**
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Components should take `snapMode` as a prop.
     */
    static getAccudrawSnapMode() {
        return (UiFramework.frameworkState?.configurableUiState.snapMode ??
            core_frontend_1.SnapMode.NearestKeypoint);
    }
    /**
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Use `snapMode` prop of {@link SnapModeField}.
     */
    static setAccudrawSnapMode(snapMode) {
        UiFramework.dispatchActionToStore(ConfigurableUiState_1.ConfigurableUiActionId.SetSnapMode, snapMode, true);
    }
    /**
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Components should take `useDragInteraction` as a prop.
     */
    static get useDragInteraction() {
        return (UiFramework.frameworkState?.configurableUiState.useDragInteraction ??
            false);
    }
    /**
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Use `useDragInteraction` prop of {@link Toolbar}.
     */
    static setUseDragInteraction(useDragInteraction) {
        UiFramework.dispatchActionToStore(ConfigurableUiState_1.ConfigurableUiActionId.SetDragInteraction, useDragInteraction, true);
    }
    /**
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Components should take `widgetIcon` as a prop.
     */
    static get showWidgetIcon() {
        return (UiFramework.frameworkState?.configurableUiState.showWidgetIcon ?? false);
    }
    /**
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Use {@link ConfigurableUiContentProps.widgetIcon} prop of {@link ConfigurableUiContent}.
     */
    static setShowWidgetIcon(value) {
        if (UiFramework.showWidgetIcon === value)
            return;
        UiFramework.dispatchActionToStore(ConfigurableUiState_1.ConfigurableUiActionId.SetShowWidgetIcon, value, true);
    }
    /** When `true`, panels will close as soon as the mouse leave the panel.
     * When `false` (default), panels will close on next click outside the panel.
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Components should take `collapsePanels` as a prop.
     */
    static get autoCollapseUnpinnedPanels() {
        return (UiFramework.frameworkState?.configurableUiState
            .autoCollapseUnpinnedPanels ?? false);
    }
    /** Method used to enable the automatic closing of an unpinned widget panel as soon as the
     * mouse leaves the widget panel. The default behavior is to require a mouse click outside
     * the panel before it is closed.
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Use {@link ConfigurableUiContentProps.collapsePanels} prop of {@link ConfigurableUiContent}.
     */
    static setAutoCollapseUnpinnedPanels(value) {
        if (UiFramework.autoCollapseUnpinnedPanels === value)
            return;
        UiFramework.dispatchActionToStore(ConfigurableUiState_1.ConfigurableUiActionId.AutoCollapseUnpinnedPanels, value, true);
    }
    /** Animate Tool Settings on appear.
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Components should take `animateToolSettings` as a prop.
     */
    static get animateToolSettings() {
        return (UiFramework.frameworkState?.configurableUiState.animateToolSettings ??
            false);
    }
    /**
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Use {@link ConfigurableUiContentProps.animateToolSettings} prop of {@link ConfigurableUiContent}.
     */
    static setAnimateToolSettings(value) {
        if (UiFramework.animateToolSettings === value)
            return;
        UiFramework.dispatchActionToStore(ConfigurableUiState_1.ConfigurableUiActionId.AnimateToolSettings, value, true);
    }
    /** Use Tool Name As Tool Settings Widget Tab Label.
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Components should take `toolAsToolSettingsLabel` as a prop.
     */
    static get useToolAsToolSettingsLabel() {
        return (UiFramework.frameworkState?.configurableUiState
            .useToolAsToolSettingsLabel ?? false);
    }
    /**
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Use {@link ConfigurableUiContentProps.toolAsToolSettingsLabel} prop of {@link ConfigurableUiContent}.
     */
    static setUseToolAsToolSettingsLabel(value) {
        if (UiFramework.useToolAsToolSettingsLabel === value)
            return;
        UiFramework.dispatchActionToStore(ConfigurableUiState_1.ConfigurableUiActionId.UseToolAsToolSettingsLabel, value, true);
    }
    /** UiFramework.getToolbarOpacity() returns a number between 0 and 1 that is the non-hovered opacity for toolbars.
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Components should take `opacity` as a prop.
     */
    static getToolbarOpacity() {
        return (UiFramework.frameworkState?.configurableUiState.toolbarOpacity ??
            ThemeId_1.TOOLBAR_OPACITY_DEFAULT);
    }
    /** UiFramework.setToolbarOpacity() sets the non-hovered opacity to the value specified.
     * @param opacity a value between 0 and 1. The default value is 0.5. IT IS NOT ADVISED TO USE A VALUE BELOW 0.2
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Use {@link ConfigurableUiContentProps.toolbarOpacity} prop of {@link ConfigurableUiContent}.
     */
    static setToolbarOpacity(opacity) {
        if (UiFramework.getToolbarOpacity() === opacity)
            return;
        UiFramework.dispatchActionToStore(ConfigurableUiState_1.ConfigurableUiActionId.SetToolbarOpacity, opacity, true);
    }
    /**
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Get id from iModel connection.
     */
    static getActiveIModelId() {
        return UiFramework.frameworkState?.sessionState.iModelId ?? "";
    }
    /**
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Not used by AppUI components.
     */
    static setActiveIModelId(iModelId) {
        UiFramework.dispatchActionToStore(SessionState_1.SessionStateActionId.SetActiveIModelId, iModelId);
    }
    /** Returns the stored active selection scope id.
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Components should take `activeScope` as a prop.
     */
    static getActiveSelectionScope() {
        return (UiFramework.frameworkState?.sessionState.activeSelectionScope ?? "element");
    }
    /** This method stores the active selection scope to the supplied scope id, and triggers
     * a `SessionStateActionId.SetSelectionScope` event in the `SyncUiEventDispatcher`.
     * Note: As of 4.0, this method *does not change* the active selection scope in the `Presentation.selection.scopes.activeScope` property.
     * This event should be listened to and the change should typically be applied to
     * `Presentation.selection.scopes.activeScope` property from the `@itwin/presentation-frontend` package.
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Use `activeScope` prop of {@link SelectionScopeField}.
     */
    static setActiveSelectionScope(selectionScopeId) {
        if (!UiFramework.frameworkState)
            return;
        const foundIndex = UiFramework.frameworkState.sessionState.availableSelectionScopes.findIndex((selectionScope) => selectionScope.id === selectionScopeId);
        if (foundIndex < 0)
            return;
        UiFramework.dispatchActionToStore(SessionState_1.SessionStateActionId.SetSelectionScope, selectionScopeId);
    }
    /** Returns the stored list of available selection scopes. This list should be set by the application
     * by dispatching the `setAvailableSelectionScopes` action.
     * The value for this action typically come from `Presentation.selection.scopes.getSelectionScopes()`
     * method found in the `@itwin/presentation-frontend` package.
     * @note Returned value is immutable.
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Components should take `selectionScopes` as a prop.
     */
    static getAvailableSelectionScopes() {
        return (UiFramework.frameworkState?.sessionState.availableSelectionScopes ?? [
            { id: "element", label: "Element" },
        ]);
    }
    /**
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Not used by AppUI components.
     */
    static getDefaultIModelViewportControlId() {
        return (UiFramework.frameworkState?.sessionState.defaultIModelViewportControlId ??
            undefined);
    }
    /**
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Not used by AppUI components.
     */
    static setDefaultIModelViewportControlId(iModelViewportControlId, immediateSync = false) {
        UiFramework.dispatchActionToStore(SessionState_1.SessionStateActionId.SetDefaultIModelViewportControlId, iModelViewportControlId, immediateSync);
    }
    /**
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Not used by AppUI components.
     */
    static getDefaultViewId() {
        return UiFramework.frameworkState?.sessionState.defaultViewId ?? undefined;
    }
    /**
     * @note Requires redux provider.
     * @deprecated in 4.15.0. Not used by AppUI components.
     */
    static setDefaultViewId(viewId, immediateSync = false) {
        UiFramework.dispatchActionToStore(SessionState_1.SessionStateActionId.SetDefaultViewId, viewId, immediateSync);
    }
}
exports.UiFramework = UiFramework;
UiFramework._initialized = false;
UiFramework._complaint = "UiFramework not initialized";
UiFramework._frameworkStateKeyInStore = "frameworkState"; // default name
/** this provides a default state storage handler */
UiFramework._uiStateStorage = new LocalStateStorage_1.LocalStateStorage();
UiFramework._uiSettingsProviderRegistry = new Map();
UiFramework._childWindowManager = new InternalChildWindowManager_1.InternalChildWindowManager();
UiFramework.useDefaultPopoutUrl = false;
UiFramework.CONTEXT_MENU_OFFSET = -8;
/** Get Show Ui event. */
// eslint-disable-next-line deprecation/deprecation
UiFramework.onUiVisibilityChanged = new UiVisibilityChangedEvent();
function dispatchSyncUiEvent(eventId, immediateSync = false) {
    if (immediateSync) {
        SyncUiEventDispatcher_1.SyncUiEventDispatcher.dispatchImmediateSyncUiEvent(eventId);
        return;
    }
    SyncUiEventDispatcher_1.SyncUiEventDispatcher.dispatchSyncUiEvent(eventId);
}
//# sourceMappingURL=UiFramework.js.map