"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 QuantityFormatting
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseUnitFormattingSettingsProvider = void 0;
const IModelApp_1 = require("../IModelApp");
const IModelConnection_1 = require("../IModelConnection");
/** This abstract class reacts to changes in the "active" iModel and updates the [[QuantityFormatter]] overrides and active
 * presentation unit system based on stored preferences.  In addition, monitors the [[QuantityFormatter]] for changes to format overrides and the active
 * unit system and stores these changes. The "active" iModel is determined by listening to the `IModelApp.viewManager.onSelectedViewportChanged` event
 * and gets the iModel from the selected viewport.
 * @beta
 */
class BaseUnitFormattingSettingsProvider {
    /**
     * @param maintainOverridesPerIModel If maintainOverridesPerIModel is true the base class will set up listeners
     * to monitor "active" iModel changes so the overrides for the QuantityFormatter properly match the overrides set
     * up by the user. If false then the overrides are maintained only per user.
     * @beta
     */
    constructor(_quantityFormatter, _maintainOverridesPerIModel) {
        this._quantityFormatter = _quantityFormatter;
        this._maintainOverridesPerIModel = _maintainOverridesPerIModel;
        this.storeFormatOverrides = async ({ typeKey, overrideEntry, unitSystem }) => {
            if (undefined === overrideEntry) {
                // remove all overrides for quantity type
                if (undefined === unitSystem) {
                    await this.remove(typeKey);
                    return;
                }
                else {
                    // remove only system specific overrides for quantity type
                    const storedJson = await this.retrieve(typeKey);
                    if (storedJson) {
                        delete storedJson[unitSystem];
                        if (Object.keys(storedJson).length) {
                            await this.store(typeKey, storedJson);
                        }
                        else {
                            await this.remove(typeKey);
                        }
                    }
                }
            }
            else {
                // setting a new override or set of overrides
                const storedJson = await this.retrieve(typeKey);
                const updatedFormat = { ...storedJson, ...overrideEntry };
                await this.store(typeKey, updatedFormat);
            }
        };
        /** save UnitSystem for active iModel */
        this.storeUnitSystemSetting = async ({ system }) => {
            await this.storeUnitSystemKey(system);
        };
        this.applyQuantityFormattingSettingsForIModel = async (imodel) => {
            if (this._maintainOverridesPerIModel)
                this._imodelConnection = imodel;
            const overrideFormatProps = await this.buildQuantityFormatOverridesMap();
            const unitSystemKey = await this.retrieveUnitSystem(this._quantityFormatter.activeUnitSystem);
            await this._quantityFormatter.reinitializeFormatAndParsingsMaps(overrideFormatProps, unitSystemKey, true, true);
        };
        this.handleIModelOpen = async (imodel) => {
            await this.applyQuantityFormattingSettingsForIModel(imodel);
        };
        this.handleViewportChanged = async (args) => {
            if (args.current?.iModel && (args.current?.iModel?.iModelId !== this.imodelConnection?.iModelId)) {
                await this.applyQuantityFormattingSettingsForIModel(args.current?.iModel);
            }
        };
        this.handleIModelClose = async () => {
            this._imodelConnection = undefined;
        };
        if (this._maintainOverridesPerIModel) {
            IModelApp_1.IModelApp.viewManager.onSelectedViewportChanged.addListener(this.handleViewportChanged);
            IModelConnection_1.IModelConnection.onOpen.addListener(this.handleIModelOpen);
            IModelConnection_1.IModelConnection.onClose.addListener(this.handleIModelClose);
        }
    }
    get maintainOverridesPerIModel() {
        return !!this._maintainOverridesPerIModel;
    }
    async loadOverrides(imodel) {
        await this.applyQuantityFormattingSettingsForIModel(imodel);
    }
    get imodelConnection() {
        return this._imodelConnection;
    }
    /** function to convert from serialized JSON format for Quantity Type overrides to build a map compatible with QuantityManager */
    async buildQuantityFormatOverridesMap() {
        const overrideFormatProps = new Map();
        // use map and await all returned promises - overrides are stored by QuantityType
        for (const quantityTypeKey of [...this._quantityFormatter.quantityTypesRegistry.keys()]) {
            const quantityTypeDef = this._quantityFormatter.quantityTypesRegistry.get(quantityTypeKey);
            if (quantityTypeDef) {
                const typeKey = quantityTypeDef.key;
                const overrideEntry = await this.retrieve(typeKey);
                if (overrideEntry) {
                    // extract overrides and insert into appropriate override map entry
                    Object.keys(overrideEntry).forEach((systemKey) => {
                        const unitSystemKey = systemKey;
                        const props = overrideEntry[unitSystemKey];
                        if (props) {
                            if (overrideFormatProps.has(unitSystemKey)) {
                                overrideFormatProps.get(unitSystemKey).set(typeKey, props);
                            }
                            else {
                                const newMap = new Map();
                                newMap.set(typeKey, props);
                                overrideFormatProps.set(unitSystemKey, newMap);
                            }
                        }
                    });
                }
            }
        }
        return overrideFormatProps;
    }
}
exports.BaseUnitFormattingSettingsProvider = BaseUnitFormattingSettingsProvider;
//# sourceMappingURL=BaseUnitFormattingSettingsProvider.js.map