/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Admin
 */
import * as React from "react";
import { IModelApp } from "@itwin/core-frontend";
import { RelativePosition, UiAdmin, } from "@itwin/appui-abstract";
import { AccuDrawPopupManager } from "../accudraw/AccuDrawPopupManager";
import { CursorInformation } from "../cursor/CursorInformation";
import { PopupManager } from "../popup/PopupManager";
import { UiFramework } from "../UiFramework";
import { UiDataProvidedDialog } from "../dialog/UiDataProvidedDialog";
/** Controls whether localized and/or non-localized key-in strings appear in a KeyinField's auto-completion list.
 * @public
 */
export var KeyinFieldLocalization;
(function (KeyinFieldLocalization) {
    /** Include only non-localized key-in strings. */
    KeyinFieldLocalization[KeyinFieldLocalization["NonLocalized"] = 0] = "NonLocalized";
    /** Include only localized key-in strings. */
    KeyinFieldLocalization[KeyinFieldLocalization["Localized"] = 1] = "Localized";
    /** Include localized and non-localized strings for each key-in. */
    KeyinFieldLocalization[KeyinFieldLocalization["Both"] = 2] = "Both";
})(KeyinFieldLocalization || (KeyinFieldLocalization = {}));
/** The UiAdmin controls various UI components and is callable from IModelApp.uiAdmin in the core-frontend package.
 * @public
 */
export class FrameworkUiAdmin extends UiAdmin {
    constructor() {
        super(...arguments);
        this._localizedKeyinPreference = KeyinFieldLocalization.NonLocalized;
    }
    get localizedKeyinPreference() { return this._localizedKeyinPreference; }
    set localizedKeyinPreference(preference) { this._localizedKeyinPreference = preference; }
    /** @internal */
    onInitialized() { }
    /** Gets the cursor X and Y position, which is mouseEvent.pageX and mouseEvent.pageY. */
    get cursorPosition() { return CursorInformation.cursorPosition; }
    /** Determines if focus is set to Home */
    get isFocusOnHome() { return UiFramework.keyboardShortcuts.isFocusOnHome; }
    /** Sets focus to Home */
    setFocusToHome() { UiFramework.keyboardShortcuts.setFocusToHome(); }
    /** 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 htmlElement or the overall window.
     * @param htmlElement 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.
     */
    showContextMenu(items, location, htmlElement) {
        let position = location;
        let childWindowId;
        if (htmlElement) {
            const anchorOffset = htmlElement.getBoundingClientRect();
            position = { x: anchorOffset.left + location.x, y: anchorOffset.top + location.y };
            childWindowId = UiFramework.childWindows.findId(htmlElement.ownerDocument.defaultView);
        }
        const offset = -8;
        position = { x: position.x + offset, y: position.y + offset };
        const cursorMenu = { position, items, childWindowId };
        UiFramework.openCursorMenu(cursorMenu);
        return true;
    }
    /** Resolve location and parent element */
    resolveHtmlElement(location, htmlElement) {
        const position = location;
        const el = htmlElement !== null && htmlElement !== void 0 ? htmlElement : UiFramework.controls.getWrapperElement();
        return { position, el };
    }
    getKeyins() {
        const toolKeyins = [];
        const tools = IModelApp.tools.getToolList();
        for (const tool of tools) {
            switch (this.localizedKeyinPreference) {
                case KeyinFieldLocalization.Localized:
                    toolKeyins.push({ value: tool.keyin });
                    break;
                case KeyinFieldLocalization.Both:
                    toolKeyins.push({ value: tool.keyin });
                    // istanbul ignore else
                    if (tool.keyin === tool.englishKeyin)
                        break;
                // istanbul ignore next
                default: // eslint-disable-line no-fallthrough
                case KeyinFieldLocalization.NonLocalized:
                    // istanbul ignore next
                    if (KeyinFieldLocalization.NonLocalized === this.localizedKeyinPreference || (KeyinFieldLocalization.Both === this.localizedKeyinPreference && tool.englishKeyin !== tool.keyin))
                        toolKeyins.push({ value: tool.englishKeyin });
                    break;
            }
        }
        return toolKeyins;
    }
    /** Show the Key-in Palette to display key-in from all registered Tools.
     * @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.
     */
    showKeyinPalette(htmlElement) {
        if (!this.featureFlags.allowKeyinPalette)
            return false;
        // istanbul ignore next
        const el = htmlElement ? htmlElement : UiFramework.controls.getWrapperElement();
        // istanbul ignore next
        const hidePopup = () => {
            IModelApp.uiAdmin.hideKeyinPalette();
        };
        return PopupManager.showKeyinPalette(this.getKeyins(), el, hidePopup, hidePopup);
    }
    /** Hides the Key-in Palette. */
    hideKeyinPalette() {
        if (!this.featureFlags.allowKeyinPalette)
            return false;
        return PopupManager.hideKeyinPalette();
    }
    /** 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 htmlElement 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 relativePosition Position relative to the given location. Defaults to TopRight.
     * @param htmlElement 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.
     */
    showToolbar(toolbarProps, location, offset, onItemExecuted, onCancel, relativePosition, htmlElement) {
        const { position, el } = this.resolveHtmlElement(location, htmlElement);
        if (relativePosition === undefined)
            relativePosition = RelativePosition.TopRight;
        return PopupManager.showToolbar(toolbarProps, el, position, offset, onItemExecuted, onCancel, relativePosition);
    }
    /** Hides the toolbar. */
    hideToolbar() {
        return 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 htmlElement or the window.
     * @param htmlElement 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.
     */
    showMenuButton(id, menuItemsProps, location, htmlElement) {
        const { position, el } = this.resolveHtmlElement(location, htmlElement);
        return AccuDrawPopupManager.showMenuButton(id, el, position, 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.
     */
    hideMenuButton(id) {
        return 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 htmlElement 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 htmlElement 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.
     */
    showCalculator(initialValue, resultIcon, location, onOk, onCancel, htmlElement) {
        const { position, el } = this.resolveHtmlElement(location, htmlElement);
        return AccuDrawPopupManager.showCalculator(el, position, initialValue, resultIcon, onOk, onCancel);
    }
    /** Hides the calculator. */
    hideCalculator() {
        return AccuDrawPopupManager.hideCalculator();
    }
    /** 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 htmlElement 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 htmlElement 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.
     */
    showAngleEditor(initialValue, location, onCommit, onCancel, htmlElement) {
        const { position, el } = this.resolveHtmlElement(location, htmlElement);
        return AccuDrawPopupManager.showAngleEditor(el, position, initialValue, onCommit, onCancel);
    }
    /** Show an input editor for a length value at a particular location.
     * @param initialValue Value initially displayed in the editor.
     * @param location Location of the editor, relative to the origin of htmlElement 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 htmlElement 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.
     */
    showLengthEditor(initialValue, location, onCommit, onCancel, htmlElement) {
        const { position, el } = this.resolveHtmlElement(location, htmlElement);
        return AccuDrawPopupManager.showLengthEditor(el, position, initialValue, onCommit, onCancel);
    }
    /** Show an input editor for a height value at a particular location.
     * @param initialValue Value initially displayed in the editor.
     * @param location Location of the editor, relative to the origin of htmlElement 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 htmlElement 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.
     */
    showHeightEditor(initialValue, location, onCommit, onCancel, htmlElement) {
        const { position, el } = this.resolveHtmlElement(location, htmlElement);
        return AccuDrawPopupManager.showHeightEditor(el, position, initialValue, onCommit, onCancel);
    }
    /** Show an input editor for a primitive value at a particular location.
     * @param initialValue Value initially displayed in the editor.
     * @param propertyDescription Description of the primitive value property
     * @param location Location of the editor, relative to the origin of htmlElement 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 htmlElement 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.
     */
    showInputEditor(initialValue, propertyDescription, location, onCommit, onCancel, htmlElement) {
        const { position, el } = this.resolveHtmlElement(location, htmlElement);
        return PopupManager.showInputEditor(el, position, initialValue, propertyDescription, onCommit, onCancel);
    }
    /** Hides the input editor. */
    hideInputEditor() {
        return PopupManager.hideInputEditor();
    }
    /** Show an HTML element at a particular location.
     * @param displayElement The HTMLElement to display
     * @param location Location of the display element, relative to the origin of htmlElement or the window
     * @param offset Offset of the display element from the location
     * @param onCancel Function invoked when the Escape key is pressed or a click occurs outside the display element
     * @param relativePosition Position relative to the given location. Defaults to TopRight.
     * @param anchorElement The HTMLElement that anchors the display element. If undefined, the location is relative to the overall window.
     * @return true if the display element was displayed, false if the display element could not be displayed.
     */
    showHTMLElement(displayElement, location, offset, onCancel, relativePosition, anchorElement) {
        const { position, el } = this.resolveHtmlElement(location, anchorElement);
        // istanbul ignore if
        if (relativePosition === undefined)
            relativePosition = RelativePosition.TopRight;
        return PopupManager.showHTMLElement(displayElement, el, position, offset, onCancel, relativePosition);
    }
    /** Hides the HTML Element. */
    hideHTMLElement() {
        return PopupManager.hideHTMLElement();
    }
    /** Show a Card containing content, a title and a toolbar at a particular location.
     * @param content The HTMLElement 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 htmlElement 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 relativePosition Position relative to the given location. Defaults to TopRight.
     * @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.
     */
    showCard(content, title, toolbarProps, location, offset, onItemExecuted, onCancel, relativePosition, anchorElement) {
        const { position, el } = this.resolveHtmlElement(location, anchorElement);
        // istanbul ignore if
        if (relativePosition === undefined)
            relativePosition = RelativePosition.TopRight;
        return PopupManager.showCard(content, title, toolbarProps, el, position, offset, onItemExecuted, onCancel, relativePosition);
    }
    /** Show a Card containing React-based content, a title and a toolbar at a particular location.
     * @param content The React node 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 htmlElement 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 relativePosition Position relative to the given location. Defaults to TopRight.
     * @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.
     */
    showReactCard(content, title, toolbarProps, location, offset, onItemExecuted, onCancel, relativePosition, anchorElement) {
        const { position, el } = this.resolveHtmlElement(location, anchorElement);
        const reactContent = { reactNode: content };
        // istanbul ignore if
        if (relativePosition === undefined)
            relativePosition = RelativePosition.TopRight;
        return PopupManager.showCard(reactContent, title, toolbarProps, el, position, offset, onItemExecuted, onCancel, relativePosition);
    }
    /** Hides the Card. */
    hideCard() {
        return 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 relativePosition Position relative to the given location. Defaults to TopRight.
     * @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.
     */
    openToolSettingsPopup(dataProvider, location, offset, onCancel, relativePosition, anchorElement) {
        const { position, el } = this.resolveHtmlElement(location, anchorElement);
        if (relativePosition === undefined)
            relativePosition = RelativePosition.TopRight;
        return PopupManager.openToolSettings(dataProvider, el, position, offset, onCancel, relativePosition);
    }
    /** Closes the Tool Settings Ui popup. */
    closeToolSettingsPopup() {
        return PopupManager.closeToolSettings();
    }
    /** 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.
    */
    openDialog(uiDataProvider, title, isModal, id, optionalProps) {
        if (isModal) {
            UiFramework.dialogs.modal.open(React.createElement(UiDataProvidedDialog, { uiDataProvider: uiDataProvider, title: title, isModal: isModal, id: id, ...optionalProps }), id);
            return true;
        }
        else {
            UiFramework.dialogs.modeless.open(React.createElement(UiDataProvidedDialog, { uiDataProvider: uiDataProvider, title: title, isModal: isModal, id: id, ...optionalProps }), id);
            return true;
        }
    }
    /** Closes the Tool Settings Ui popup. */
    closeDialog(dialogId) {
        // istanbul ignore else
        if (UiFramework.dialogs.modeless.dialogs.findIndex((info) => info.id === dialogId)) {
            UiFramework.dialogs.modeless.close(dialogId);
            return true;
        }
        // istanbul ignore else
        if (UiFramework.dialogs.modal.dialogs.findIndex((info) => info.id === dialogId)) {
            UiFramework.dialogs.modal.close();
            return true;
        }
        // istanbul ignore next
        return false;
    }
}
//# sourceMappingURL=FrameworkUiAdmin.js.map