"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 Settings
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.QuantityFormatSettingsPage = exports.getQuantityFormatsSettingsManagerEntry = void 0;
require("./QuantityFormat.scss");
const React = require("react");
const core_geometry_1 = require("@itwin/core-geometry");
const core_frontend_1 = require("@itwin/core-frontend");
const imodel_components_react_1 = require("@itwin/imodel-components-react");
const core_react_1 = require("@itwin/core-react");
const UiFramework_1 = require("../../UiFramework");
const UnitSystemSelector_1 = require("./UnitSystemSelector");
const itwinui_react_1 = require("@itwin/itwinui-react");
const itwinui_icons_react_1 = require("@itwin/itwinui-icons-react");
const useTranslation_1 = require("../../hooks/useTranslation");
function formatAreEqual(obj1, obj2) {
    const compare = new core_geometry_1.DeepCompare();
    return compare.compare(obj1, obj2);
}
/**
 * Return a SettingsTabEntry that can be used to define the available settings that can be set for an application.
 * @param itemPriority - Used to define the order of the entry in the Settings Stage
 * @param opts - Options to initialize the settings page that allows users to set Quantity formatting overrides.
 * @beta
 */
function getQuantityFormatsSettingsManagerEntry(itemPriority, opts) {
    const { availableUnitSystems, initialQuantityType } = { ...opts };
    return {
        itemPriority,
        tabId: "uifw:Quantity",
        label: UiFramework_1.UiFramework.translate("settings.quantity-formatting.label"),
        subLabel: UiFramework_1.UiFramework.translate("settings.quantity-formatting.subLabel"),
        page: (React.createElement(QuantityFormatSettingsPage, { initialQuantityType: initialQuantityType ?? core_frontend_1.QuantityType.Length, availableUnitSystems: availableUnitSystems ??
                new Set(["metric", "imperial", "usCustomary", "usSurvey"]) })),
        isDisabled: false,
        icon: React.createElement(itwinui_icons_react_1.SvgMeasure, null),
        tooltip: UiFramework_1.UiFramework.translate("settings.quantity-formatting.tooltip"),
        pageWillHandleCloseRequest: true,
    };
}
exports.getQuantityFormatsSettingsManagerEntry = getQuantityFormatsSettingsManagerEntry;
/** UI Component shown in settings page to set the active Presentation Unit System and to set format overrides.
 * @beta
 */
function QuantityFormatSettingsPage({ initialQuantityType, availableUnitSystems, }) {
    const { translate } = (0, useTranslation_1.useTranslation)();
    const [activeUnitSystemKey, setActiveUnitSystemKey] = React.useState(core_frontend_1.IModelApp.quantityFormatter.activeUnitSystem);
    const [activeQuantityType, setActiveQuantityType] = React.useState((0, core_frontend_1.getQuantityTypeKey)(initialQuantityType));
    const [activeFormatterSpec, setActiveFormatterSpec] = React.useState(core_frontend_1.IModelApp.quantityFormatter.findFormatterSpecByQuantityType((0, core_frontend_1.getQuantityTypeKey)(activeQuantityType)));
    const [saveEnabled, setSaveEnabled] = React.useState(false);
    const [clearEnabled, setClearEnabled] = React.useState(core_frontend_1.IModelApp.quantityFormatter.hasActiveOverride(initialQuantityType, true));
    const newQuantityTypeRef = React.useRef();
    React.useEffect(() => {
        return core_frontend_1.IModelApp.quantityFormatter.onActiveFormattingUnitSystemChanged.addListener(() => {
            if (activeUnitSystemKey !== core_frontend_1.IModelApp.quantityFormatter.activeUnitSystem) {
                setActiveUnitSystemKey(core_frontend_1.IModelApp.quantityFormatter.activeUnitSystem);
                setActiveFormatterSpec(core_frontend_1.IModelApp.quantityFormatter.findFormatterSpecByQuantityType(activeQuantityType));
                setSaveEnabled(false);
                setClearEnabled(core_frontend_1.IModelApp.quantityFormatter.hasActiveOverride(activeQuantityType, true));
            }
        });
    }, [activeQuantityType, activeUnitSystemKey]);
    React.useEffect(() => {
        return core_frontend_1.IModelApp.quantityFormatter.onQuantityFormatsChanged.addListener((args) => {
            if (!newQuantityTypeRef.current) {
                const quantityKey = core_frontend_1.IModelApp.quantityFormatter.getQuantityTypeKey(activeQuantityType);
                if (args.quantityType === quantityKey) {
                    setActiveFormatterSpec(core_frontend_1.IModelApp.quantityFormatter.findFormatterSpecByQuantityType(activeQuantityType));
                    setSaveEnabled(false);
                    setClearEnabled(core_frontend_1.IModelApp.quantityFormatter.hasActiveOverride(activeQuantityType, true));
                }
            }
            newQuantityTypeRef.current = undefined;
        });
    }, [activeQuantityType]);
    const saveChanges = React.useCallback((afterSaveFunction, args) => {
        if (activeFormatterSpec) {
            const formatProps = activeFormatterSpec.format.toJSON();
            const formatPropsInUse = core_frontend_1.IModelApp.quantityFormatter
                .findFormatterSpecByQuantityType(activeQuantityType)
                .format.toJSON();
            if (formatPropsInUse &&
                !formatAreEqual(formatProps, formatPropsInUse)) {
                UiFramework_1.UiFramework.dialogs.modal.open(React.createElement(SaveFormatModalDialog, { formatProps: formatProps, quantityType: activeQuantityType, onDialogCloseArgs: args, onDialogClose: afterSaveFunction }), "saveQuantityFormat");
                return;
            }
        }
        afterSaveFunction(args);
    }, [activeFormatterSpec, activeQuantityType]);
    // eslint-disable-next-line deprecation/deprecation
    (0, core_react_1.useSaveBeforeActivatingNewSettingsTab)(UiFramework_1.UiFramework.settingsManager, saveChanges);
    // eslint-disable-next-line deprecation/deprecation
    (0, core_react_1.useSaveBeforeClosingSettingsContainer)(UiFramework_1.UiFramework.settingsManager, saveChanges);
    const processListboxValueChange = React.useCallback((newQuantityType) => {
        const volumeFormatterSpec = core_frontend_1.IModelApp.quantityFormatter.findFormatterSpecByQuantityType(newQuantityType);
        setActiveFormatterSpec(volumeFormatterSpec);
        setActiveQuantityType(newQuantityType);
        setSaveEnabled(false);
        setClearEnabled(core_frontend_1.IModelApp.quantityFormatter.hasActiveOverride(newQuantityType, true));
    }, []);
    const onListboxValueChange = React.useCallback((newQuantityType) => {
        if (activeFormatterSpec) {
            const formatProps = activeFormatterSpec.format.toJSON();
            const formatPropsInUse = core_frontend_1.IModelApp.quantityFormatter
                .findFormatterSpecByQuantityType(activeQuantityType)
                .format.toJSON();
            if (formatPropsInUse &&
                !formatAreEqual(formatProps, formatPropsInUse)) {
                newQuantityTypeRef.current = newQuantityType;
                UiFramework_1.UiFramework.dialogs.modal.open(React.createElement(SaveFormatModalDialog, { formatProps: formatProps, quantityType: activeQuantityType, onDialogCloseArgs: newQuantityType, onDialogClose: processListboxValueChange }), "saveQuantityFormat");
                return;
            }
        }
        processListboxValueChange(newQuantityType);
    }, [activeFormatterSpec, activeQuantityType, processListboxValueChange]);
    const handleOnFormatChanged = React.useCallback(async (formatProps) => {
        if (activeFormatterSpec) {
            const newSpec = await core_frontend_1.IModelApp.quantityFormatter.generateFormatterSpecByType(activeQuantityType, formatProps);
            const formatPropsInUse = core_frontend_1.IModelApp.quantityFormatter.getFormatPropsByQuantityType(activeQuantityType);
            if (formatPropsInUse)
                setSaveEnabled(!formatAreEqual(formatProps, formatPropsInUse));
            setActiveFormatterSpec(newSpec);
        }
    }, [activeFormatterSpec, activeQuantityType]);
    const handleOnFormatSave = React.useCallback(async () => {
        if (activeFormatterSpec) {
            const format = activeFormatterSpec.format.toJSON();
            await core_frontend_1.IModelApp.quantityFormatter.setOverrideFormat(activeQuantityType, format);
            setClearEnabled(true);
        }
    }, [activeFormatterSpec, activeQuantityType]);
    const handleOnFormatReset = React.useCallback(async () => {
        await core_frontend_1.IModelApp.quantityFormatter.clearOverrideFormats(activeQuantityType);
        setClearEnabled(false);
    }, [activeQuantityType]);
    const processNewUnitSystem = React.useCallback(async (unitSystem) => {
        await core_frontend_1.IModelApp.quantityFormatter.setActiveUnitSystem(unitSystem);
    }, []);
    const handleUnitSystemSelected = React.useCallback(async (unitSystem) => {
        if (unitSystem === activeUnitSystemKey)
            return;
        saveChanges(processNewUnitSystem, unitSystem);
    }, [activeUnitSystemKey, processNewUnitSystem, saveChanges]);
    return (React.createElement("div", { className: "quantity-formatting-container" },
        React.createElement(UnitSystemSelector_1.UnitSystemSelector, { selectedUnitSystemKey: activeUnitSystemKey, availableUnitSystems: availableUnitSystems, onUnitSystemSelected: handleUnitSystemSelected }),
        React.createElement("span", { className: "uifw-quantity-format-section-label" }, translate("settings.quantity-formatting.formatSectionLabel")),
        React.createElement("div", { className: "uifw-quantity-types-container" },
            React.createElement("div", { className: "left-panel" },
                React.createElement(core_react_1.Listbox, { id: "uifw-quantity-types-list", className: "uifw-quantity-types", onListboxValueChange: onListboxValueChange, selectedValue: activeQuantityType }, [...core_frontend_1.IModelApp.quantityFormatter.quantityTypesRegistry.keys()].map((key) => {
                    const entry = core_frontend_1.IModelApp.quantityFormatter.quantityTypesRegistry.get(key);
                    const description = entry.description;
                    const label = entry.label;
                    return (
                    // eslint-disable-next-line deprecation/deprecation
                    React.createElement(core_react_1.ListboxItem, { key: entry.key, className: "quantity-type-list-entry", value: entry.key },
                        React.createElement("span", { className: "map-source-list-entry-name", title: description }, label)));
                }))),
            React.createElement("div", { className: "right-panel" }, activeFormatterSpec && (React.createElement(React.Fragment, null,
                React.createElement("div", { className: "uifw-quantity-types-right-top" },
                    React.createElement("div", { className: "uifw-quantity-types-right-top-sample" },
                        React.createElement(imodel_components_react_1.FormatSample, { formatSpec: activeFormatterSpec, initialMagnitude: 1234.56, hideLabels: true }))),
                React.createElement("div", { className: "uifw-quantity-types-formats" },
                    React.createElement(imodel_components_react_1.QuantityFormatPanel, { onFormatChange: handleOnFormatChanged, quantityType: activeQuantityType })),
                React.createElement("div", { className: "components-button-panel" },
                    React.createElement(itwinui_react_1.Button, { styleType: "cta", onClick: handleOnFormatSave, disabled: !saveEnabled }, translate("settings.quantity-formatting.setButtonLabel")),
                    React.createElement(itwinui_react_1.Button, { styleType: "default", onClick: handleOnFormatReset, disabled: !clearEnabled }, translate("settings.quantity-formatting.clearButtonLabel")))))))));
}
exports.QuantityFormatSettingsPage = QuantityFormatSettingsPage;
function SaveFormatModalDialog({ formatProps, quantityType, onDialogCloseArgs, onDialogClose, }) {
    const { translate } = (0, useTranslation_1.useTranslation)();
    const [isOpen, setIsOpen] = React.useState(true);
    const handleClose = React.useCallback(() => {
        setIsOpen(false);
        UiFramework_1.UiFramework.dialogs.modal.close();
        onDialogClose && onDialogClose(onDialogCloseArgs);
    }, [onDialogClose, onDialogCloseArgs]);
    const handleOK = React.useCallback(() => {
        void core_frontend_1.IModelApp.quantityFormatter.setOverrideFormat(quantityType, formatProps);
        handleClose();
    }, [formatProps, handleClose, quantityType]);
    const handleCancel = React.useCallback(() => {
        handleClose();
    }, [handleClose]);
    return (React.createElement(itwinui_react_1.Dialog, { isOpen: isOpen, onClose: handleCancel, className: "uifw-settings-quantityFormatting-saveFormatModalDialog", closeOnEsc: true, closeOnExternalClick: true, preventDocumentScroll: true },
        React.createElement(itwinui_react_1.Dialog.Backdrop, null),
        React.createElement(itwinui_react_1.Dialog.Main, { style: { minWidth: 200, maxWidth: 400, minHeight: 150, maxHeight: 400 } },
            React.createElement(itwinui_react_1.Dialog.TitleBar, { titleText: "Save Format Changes" }),
            React.createElement(itwinui_react_1.Dialog.Content, null, "Do you want to save changes to format before changing to another type?"),
            React.createElement(itwinui_react_1.Dialog.ButtonBar, null,
                React.createElement(itwinui_react_1.Button, { styleType: "high-visibility", onClick: handleOK }, translate("dialog.yes")),
                React.createElement(itwinui_react_1.Button, { onClick: handleCancel }, translate("dialog.no"))))));
}
//# sourceMappingURL=QuantityFormat.js.map