"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 AccuDraw
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.FrameworkAccuDraw = exports.AccuDrawUiSettingsChangedEvent = exports.AccuDrawGrabInputFocusEvent = exports.AccuDrawSetCompassModeEvent = exports.AccuDrawSetFieldLockEvent = exports.AccuDrawSetFieldValueFromUiEvent = exports.AccuDrawSetFieldValueToUiEvent = exports.AccuDrawSetFieldFocusEvent = void 0;
const core_bentley_1 = require("@itwin/core-bentley");
const core_frontend_1 = require("@itwin/core-frontend");
const appui_abstract_1 = require("@itwin/appui-abstract");
const core_react_1 = require("@itwin/core-react");
const UiFramework_1 = require("../UiFramework");
const SyncUiEventDispatcher_1 = require("../syncui/SyncUiEventDispatcher");
// cspell:ignore dont
const compassModeToKeyMap = new Map([
    [core_frontend_1.CompassMode.Polar, "polar"],
    [core_frontend_1.CompassMode.Rectangular, "rectangular"],
]);
const rotationModeToKeyMap = new Map([
    [core_frontend_1.RotationMode.Top, "top"],
    [core_frontend_1.RotationMode.Front, "front"],
    [core_frontend_1.RotationMode.Side, "side"],
    [core_frontend_1.RotationMode.View, "view"],
    [core_frontend_1.RotationMode.ACS, "ACS"],
    [core_frontend_1.RotationMode.Context, "context"],
]);
/** AccuDraw Set Field Focus event
 * @beta */
class AccuDrawSetFieldFocusEvent extends core_bentley_1.BeUiEvent {
}
exports.AccuDrawSetFieldFocusEvent = AccuDrawSetFieldFocusEvent;
/** AccuDraw Set Field Value to Ui event
 * @beta */
class AccuDrawSetFieldValueToUiEvent extends core_bentley_1.BeUiEvent {
}
exports.AccuDrawSetFieldValueToUiEvent = AccuDrawSetFieldValueToUiEvent;
/** AccuDraw Set Field Value from Ui event
 * @beta */
class AccuDrawSetFieldValueFromUiEvent extends core_bentley_1.BeUiEvent {
}
exports.AccuDrawSetFieldValueFromUiEvent = AccuDrawSetFieldValueFromUiEvent;
/** AccuDraw Set Field Lock event
 * @beta */
class AccuDrawSetFieldLockEvent extends core_bentley_1.BeUiEvent {
}
exports.AccuDrawSetFieldLockEvent = AccuDrawSetFieldLockEvent;
/** AccuDraw Set Compass Mode event
 * @beta */
class AccuDrawSetCompassModeEvent extends core_bentley_1.BeUiEvent {
}
exports.AccuDrawSetCompassModeEvent = AccuDrawSetCompassModeEvent;
/** AccuDraw Grab Input Focus event
 * @beta */
class AccuDrawGrabInputFocusEvent extends core_bentley_1.BeUiEvent {
}
exports.AccuDrawGrabInputFocusEvent = AccuDrawGrabInputFocusEvent;
/** AccuDraw Ui Settings Changed event
 * @beta */
class AccuDrawUiSettingsChangedEvent extends core_bentley_1.BeUiEvent {
}
exports.AccuDrawUiSettingsChangedEvent = AccuDrawUiSettingsChangedEvent;
/** Implementation of AccuDraw that sends events for UI and status changes
 * @beta
 */
class FrameworkAccuDraw extends core_frontend_1.AccuDraw {
    /** Determines if notifications should be displayed for AccuDraw changes */
    static get displayNotifications() {
        return FrameworkAccuDraw._displayNotifications;
    }
    static set displayNotifications(v) {
        FrameworkAccuDraw._displayNotifications = v;
        void UiFramework_1.UiFramework.getUiStateStorage().saveSetting(this._settingsNamespace, this._notificationsKey, v);
    }
    /* @internal */
    async loadUserSettings(storage) {
        const result = await storage.getSetting(FrameworkAccuDraw._settingsNamespace, FrameworkAccuDraw._notificationsKey);
        if (result.status === core_react_1.UiStateStorageStatus.Success)
            FrameworkAccuDraw._displayNotifications = result.setting;
    }
    /** AccuDraw User Interface settings */
    static get uiStateStorage() {
        return FrameworkAccuDraw._uiSettings;
    }
    static set uiStateStorage(v) {
        FrameworkAccuDraw._uiSettings = v;
        FrameworkAccuDraw.onAccuDrawUiSettingsChangedEvent.emit({});
    }
    constructor() {
        super();
        this.providerId = "FrameworkAccuDraw";
        this.handleSetFieldValueFromUiEvent = async (args) => {
            return this.processFieldInput(args.field, args.stringValue, false);
        };
        FrameworkAccuDraw.onAccuDrawSetFieldValueFromUiEvent.addListener(this.handleSetFieldValueFromUiEvent);
        UiFramework_1.UiFramework.registerUserSettingsProvider(this);
    }
    /** @internal */
    onCompassModeChange() {
        FrameworkAccuDraw.onAccuDrawSetCompassModeEvent.emit({
            mode: this.compassMode,
        });
        SyncUiEventDispatcher_1.SyncUiEventDispatcher.dispatchSyncUiEvent(SyncUiEventDispatcher_1.SyncUiEventId.AccuDrawCompassModeChanged);
        this.outputCompassModeMessage();
    }
    /** @internal */
    onRotationModeChange() {
        SyncUiEventDispatcher_1.SyncUiEventDispatcher.dispatchSyncUiEvent(SyncUiEventDispatcher_1.SyncUiEventId.AccuDrawRotationChanged);
        this.outputRotationMessage();
    }
    /** @internal */
    onFieldLockChange(index) {
        FrameworkAccuDraw.onAccuDrawSetFieldLockEvent.emit({
            field: index,
            lock: this.getFieldLock(index),
        });
    }
    /** @internal */
    onFieldValueChange(index) {
        const value = this.getValueByIndex(index);
        const formattedValue = FrameworkAccuDraw.getFieldDisplayValue(index);
        FrameworkAccuDraw.onAccuDrawSetFieldValueToUiEvent.emit({
            field: index,
            value,
            formattedValue,
        });
    }
    fieldValuesChanged() {
        this.onFieldValueChange(core_frontend_1.ItemField.X_Item);
        this.onFieldValueChange(core_frontend_1.ItemField.Y_Item);
        this.onFieldValueChange(core_frontend_1.ItemField.Z_Item);
        this.onFieldValueChange(core_frontend_1.ItemField.ANGLE_Item);
        this.onFieldValueChange(core_frontend_1.ItemField.DIST_Item);
    }
    /** @internal */
    setFocusItem(index) {
        FrameworkAccuDraw.onAccuDrawSetFieldFocusEvent.emit({ field: index });
    }
    /** Implemented by sub-classes to update ui fields to show current deltas or coordinates when inactive.
     * Should also choose active x or y input field in rectangular mode based on cursor position when
     * axis isn't locked to support "smart lock".
     * @internal
     */
    onMotion(_ev) {
        if (!this.isEnabled || this.isDeactivated || UiFramework_1.UiFramework.isContextMenuOpen)
            return;
        this.fieldValuesChanged();
        if (!this.dontMoveFocus)
            this.setFocusItem(this.newFocus);
    }
    /** Determine if the AccuDraw UI has focus
     * @internal
     */
    get hasInputFocus() {
        let hasFocus = false;
        const el = document.querySelector("div.uifw-accudraw-field-container");
        if (el)
            hasFocus = el.contains(document.activeElement);
        return hasFocus;
    }
    /** Implement this method to set focus to the AccuDraw UI.
     * @internal
     */
    grabInputFocus() {
        FrameworkAccuDraw.onAccuDrawGrabInputFocusEvent.emit({});
    }
    /** Gets the display value for an AccuDraw field */
    static getFieldDisplayValue(index) {
        const value = core_frontend_1.IModelApp.accuDraw.getValueByIndex(index);
        let formattedValue = value.toString();
        const formatterSpec = core_frontend_1.IModelApp.quantityFormatter.findFormatterSpecByQuantityType(core_frontend_1.ItemField.ANGLE_Item === index
            ? core_frontend_1.QuantityType.Angle
            : core_frontend_1.QuantityType.Length);
        // istanbul ignore else
        if (formatterSpec)
            formattedValue = core_frontend_1.IModelApp.quantityFormatter.formatQuantity(value, formatterSpec);
        return formattedValue;
    }
    /** AccuDraw Set Field Value from Ui. */
    static setFieldValueFromUi(field, stringValue) {
        FrameworkAccuDraw.onAccuDrawSetFieldValueFromUiEvent.emit({
            field,
            stringValue,
        });
    }
    outputInfoMessage(message) {
        // istanbul ignore else
        if (FrameworkAccuDraw.displayNotifications)
            core_frontend_1.IModelApp.notifications.outputMessage(new core_frontend_1.NotifyMessageDetails(core_frontend_1.OutputMessagePriority.Info, message));
    }
    outputCompassModeMessage() {
        if (FrameworkAccuDraw.displayNotifications) {
            let modeKey = compassModeToKeyMap.get(this.compassMode);
            // istanbul ignore if
            if (modeKey === undefined)
                modeKey = "polar";
            const modeString = UiFramework_1.UiFramework.translate(`accuDraw.compassMode.${modeKey}`);
            const modeMessage = UiFramework_1.UiFramework.localization.getLocalizedString("accuDraw.compassModeSet", { modeString, ns: UiFramework_1.UiFramework.localizationNamespace });
            this.outputInfoMessage(modeMessage);
        }
    }
    outputRotationMessage() {
        if (FrameworkAccuDraw.displayNotifications) {
            let rotationKey = rotationModeToKeyMap.get(this.rotationMode);
            // istanbul ignore if
            if (rotationKey === undefined)
                rotationKey = "top";
            const rotationString = UiFramework_1.UiFramework.translate(`accuDraw.rotation.${rotationKey}`);
            const rotationMessage = UiFramework_1.UiFramework.localization.getLocalizedString("accuDraw.rotationSet", { rotationString, ns: UiFramework_1.UiFramework.localizationNamespace });
            this.outputInfoMessage(rotationMessage);
        }
    }
}
FrameworkAccuDraw._displayNotifications = false;
FrameworkAccuDraw._settingsNamespace = "AppUiSettings";
FrameworkAccuDraw._notificationsKey = "AccuDrawNotifications";
/** AccuDraw Set Field Focus event. */
FrameworkAccuDraw.onAccuDrawSetFieldFocusEvent = new AccuDrawSetFieldFocusEvent();
/** AccuDraw Set Field Value to Ui event. */
FrameworkAccuDraw.onAccuDrawSetFieldValueToUiEvent = new AccuDrawSetFieldValueToUiEvent();
/** AccuDraw Set Field Value from Ui event. */
FrameworkAccuDraw.onAccuDrawSetFieldValueFromUiEvent = new AccuDrawSetFieldValueFromUiEvent();
/** AccuDraw Set Field Lock event. */
FrameworkAccuDraw.onAccuDrawSetFieldLockEvent = new AccuDrawSetFieldLockEvent();
/** AccuDraw Set Mode event. */
FrameworkAccuDraw.onAccuDrawSetCompassModeEvent = new AccuDrawSetCompassModeEvent();
/** AccuDraw Grab Input Focus event. */
FrameworkAccuDraw.onAccuDrawGrabInputFocusEvent = new AccuDrawGrabInputFocusEvent();
/** Determines if AccuDraw.rotationMode === RotationMode.Top */
FrameworkAccuDraw.isTopRotationConditional = new appui_abstract_1.ConditionalBooleanValue(() => core_frontend_1.IModelApp.accuDraw.rotationMode === core_frontend_1.RotationMode.Top, [SyncUiEventDispatcher_1.SyncUiEventId.AccuDrawRotationChanged]);
/** Determines if AccuDraw.rotationMode === RotationMode.Front */
FrameworkAccuDraw.isFrontRotationConditional = new appui_abstract_1.ConditionalBooleanValue(() => core_frontend_1.IModelApp.accuDraw.rotationMode === core_frontend_1.RotationMode.Front, [SyncUiEventDispatcher_1.SyncUiEventId.AccuDrawRotationChanged]);
/** Determines if AccuDraw.rotationMode === RotationMode.Side */
FrameworkAccuDraw.isSideRotationConditional = new appui_abstract_1.ConditionalBooleanValue(() => core_frontend_1.IModelApp.accuDraw.rotationMode === core_frontend_1.RotationMode.Side, [SyncUiEventDispatcher_1.SyncUiEventId.AccuDrawRotationChanged]);
/** Determines if AccuDraw.rotationMode === RotationMode.View */
FrameworkAccuDraw.isViewRotationConditional = new appui_abstract_1.ConditionalBooleanValue(() => core_frontend_1.IModelApp.accuDraw.rotationMode === core_frontend_1.RotationMode.View, [SyncUiEventDispatcher_1.SyncUiEventId.AccuDrawRotationChanged]);
/** Determines if AccuDraw.rotationMode === RotationMode.ACS */
FrameworkAccuDraw.isACSRotationConditional = new appui_abstract_1.ConditionalBooleanValue(() => core_frontend_1.IModelApp.accuDraw.rotationMode === core_frontend_1.RotationMode.ACS, [SyncUiEventDispatcher_1.SyncUiEventId.AccuDrawRotationChanged]);
/** Determines if AccuDraw.rotationMode === RotationMode.Context */
FrameworkAccuDraw.isContextRotationConditional = new appui_abstract_1.ConditionalBooleanValue(() => core_frontend_1.IModelApp.accuDraw.rotationMode === core_frontend_1.RotationMode.Context, [SyncUiEventDispatcher_1.SyncUiEventId.AccuDrawRotationChanged]);
/** Determines if AccuDraw.compassMode === CompassMode.Polar */
FrameworkAccuDraw.isPolarModeConditional = new appui_abstract_1.ConditionalBooleanValue(() => core_frontend_1.IModelApp.accuDraw.compassMode === core_frontend_1.CompassMode.Polar, [SyncUiEventDispatcher_1.SyncUiEventId.AccuDrawCompassModeChanged]);
/** Determines if AccuDraw.compassMode === CompassMode.Rectangular */
FrameworkAccuDraw.isRectangularModeConditional = new appui_abstract_1.ConditionalBooleanValue(() => core_frontend_1.IModelApp.accuDraw.compassMode === core_frontend_1.CompassMode.Rectangular, [SyncUiEventDispatcher_1.SyncUiEventId.AccuDrawCompassModeChanged]);
/** AccuDraw Grab Input Focus event. */
FrameworkAccuDraw.onAccuDrawUiSettingsChangedEvent = new AccuDrawUiSettingsChangedEvent();
exports.FrameworkAccuDraw = FrameworkAccuDraw;
//# sourceMappingURL=FrameworkAccuDraw.js.map