/** @packageDocumentation
 * @module QuantityFormatting
 */
import { BeUiEvent } from "@itwin/core-bentley";
import { AlternateUnitLabelsProvider, FormatProps, FormatterSpec, ParserSpec, QuantityParseResult, UnitConversionProps, UnitProps, UnitsProvider, UnitSystemKey } from "@itwin/core-quantity";
import { IModelConnection } from "../IModelConnection";
import { CustomFormatPropEditorSpec } from "./QuantityTypesEditorSpecs";
/**
 * Defines standard format types for tools that need to display measurements to user.
 * @public
 */
export declare enum QuantityType {
    /** Length which is stored in meters. Typically formatted to display in meters or feet-inches based on active unit system. */
    Length = 1,
    /** Angular value which is stored in radians. Typically formatted to display degrees or Degrees-Minute-Seconds based on active unit system. */
    Angle = 2,
    /** Area value store in meters squared. Typically formatted to display in meters squared or feet squared based on active unit system. */
    Area = 3,
    /** Volume value which is stored in meters cubed. Typically formatted to display in meters cubed or feet cubed based on active unit system. */
    Volume = 4,
    /** LatLong is an angular value which is stored in radians. Typically formatted to display degrees or Degrees-Minute-Seconds based on active unit system. */
    LatLong = 5,
    /** Coordinate/Location value which is stored in meters. Typically formatted to display in meters or feet based on active unit system. */
    Coordinate = 6,
    /** Stationing is a distance value stored in meters. Typically formatted to display `xxx+xx` or `xx+xxx` based on active unit system. */
    Stationing = 7,
    /** LengthSurvey is a distance value stored in meters. Typically formatted to display in meters or US Survey Feet based on active unit system.. */
    LengthSurvey = 8,
    /** LengthEngineering is a distance value stored in meters. Typically formatted to display either meters or feet based on active unit system. */
    LengthEngineering = 9
}
/**
 * Used to uniquely identify the type or quantity. [[QuantityType]] are built-in types and `string` are used for custom quantity types.
 * @public
 */
export type QuantityTypeArg = QuantityType | string;
/** String used to uniquely identify a QuantityType in the quantity registry. See function [[QuantityType.getQuantityTypeKey]].
 * @public
 */
export type QuantityTypeKey = string;
/** String used to uniquely identify a UnitProp.
 * @public
 */
export type UnitNameKey = string;
/**
 * Class that contains alternate Unit Labels. These labels are used when parsing strings to quantities.
 * One use case is to allow a "^", which is easily input, to be used to specify "°".
 * @internal
 */
export declare class AlternateUnitLabelsRegistry implements AlternateUnitLabelsProvider {
    private _alternateLabelRegistry;
    addAlternateLabels(key: UnitNameKey, ...labels: string[]): void;
    constructor(defaultAlternates?: Map<UnitNameKey, Set<string>>);
    getAlternateUnitLabels(unit: UnitProps): string[] | undefined;
}
/**
 * Function to return a QuantityTypeKey given either a QuantityType enum value or a string. This allows caching and
 * retrieving standard and custom quantity types.
 * @public
 */
export declare function getQuantityTypeKey(type: QuantityTypeArg): QuantityTypeKey;
/**
 * This interface supplies the definition of a `standard` quantity type that is registered with the QuantityFormatter.
 * A `standard` quantity type could be one of the nine delivered QuantityTypes or a CustomQuantityTypeDefinition.
 * @public
 */
export interface QuantityTypeDefinition {
    /** String used as a key to look up the quantity type. If defining a [[CustomQuantityTypeDefinition]] the QuantityTypeKey
     * should match the QuantityTypeArg. */
    readonly key: QuantityTypeKey;
    /** The type value which can be one of the standard QuantityType enum values or a unique string if defining a custom type. */
    readonly type: QuantityTypeArg;
    /** The unit that the magnitude of the quantity is stored ie. (Meter for Length and Radian for Angle). The persistence unit is
     * also used during formatting if the FormatProps does not define one or more composite units.  */
    readonly persistenceUnit: UnitProps;
    /** Localized label to display in UI */
    label: string;
    /** Localized description that may be used to provide detailed description for the Quantity type. */
    description: string;
    getDefaultFormatPropsBySystem: (requestedSystem: UnitSystemKey) => FormatProps;
    /** Async function to generate a [FormatterSpec]$(core-quantity) that will be called to format values.*/
    generateFormatterSpec: (formatProps: FormatProps, unitsProvider: UnitsProvider) => Promise<FormatterSpec>;
    /** Async function to generate a [ParserSpec]$(core-quantity) that will be called to parse a string into a quantity value.*/
    generateParserSpec: (formatProps: FormatProps, unitsProvider: UnitsProvider, alternateUnitLabelsProvider?: AlternateUnitLabelsProvider) => Promise<ParserSpec>;
}
/** CustomQuantityTypeDefinition interface is used to define a Custom quantity type that can be registered with the [[QuantityFormatter]].
 * A custom quantity formatter must be able to generate a FormatterSpec and ParserSpec that will be called to format and parse values.
 * Optionally it can provide specification of custom properties that it will use to define any formatting options. CustomQuantityTypeDefinitions
 * must be registered with the [[QuantityFormatter]] using the method `IModelApp.quantityFormatter.registerQuantityType`.
 * @public
 */
export interface CustomQuantityTypeDefinition extends QuantityTypeDefinition {
    /** Return true if the FormatProps have the necessary `custom` property definition */
    isCompatibleFormatProps: (formatProps: FormatProps) => boolean;
    /** An array of specifications that are used to generate a label and editor in the UI used to display and edit the FormatProps.
     * UI items defined as primary will be shown higher in the list of UI components. */
    primaryPropEditorSpecs?: CustomFormatPropEditorSpec[];
    /** An array of specifications that are used to generate a label and editor in the UI used to display and edit the FormatProps.
     * UI items defined as secondary will be shown below other UI components that edit FormatProps. */
    secondaryPropEditorSpecs?: CustomFormatPropEditorSpec[];
}
/** CustomQuantityTypeDefinition type guard.
 * @public
*/
export declare function isCustomQuantityTypeDefinition(item: QuantityTypeDefinition): item is CustomQuantityTypeDefinition;
/** Override format entries can define formats for any of the different unit systems.
 * @public
 */
export interface OverrideFormatEntry {
    /** Override format for "imperial" unit system */
    imperial?: FormatProps;
    /** Override format for "metric" unit system */
    metric?: FormatProps;
    /** Override format for "usCustomary" unit system */
    usCustomary?: FormatProps;
    /** Override format for "usSurvey" unit system */
    usSurvey?: FormatProps;
}
/** Interface that defines the functions required to be implemented to provide custom formatting and parsing of a custom quantity type.
 * @public
 */
export interface FormatterParserSpecsProvider {
    /** Custom quantity id */
    quantityType: QuantityTypeArg;
    /** Async function to return FormatterSpec for a custom quantity type */
    createFormatterSpec: (unitSystem: UnitSystemKey) => Promise<FormatterSpec>;
    /** Async function to return ParserSpec for a custom quantity type */
    createParserSpec: (unitSystem: UnitSystemKey) => Promise<ParserSpec>;
}
/** Arguments sent to FormattingUnitSystemChanged event listeners.
 * @public
 */
export interface FormattingUnitSystemChangedArgs {
    /** string that defines unit system activated. */
    readonly system: UnitSystemKey;
}
/** Arguments sent to QuantityFormatsChanged event listeners.
 * @public
 */
export interface QuantityFormatsChangedArgs {
    /** string that represents the QuantityType that has been overriden or the overrides cleared. */
    readonly quantityType: string;
}
/** Arguments sent to [[UnitFormattingSettingsProvider]] when overrides are changed.
 * @public
 */
export interface QuantityFormatOverridesChangedArgs {
    /** string that represents the QuantityType that has been overriden or the overrides cleared. */
    readonly typeKey: QuantityTypeKey;
    /** overrideEntry will be undefined when clearing overrides */
    readonly overrideEntry?: OverrideFormatEntry;
    /** used only when change applies to a single unit system */
    readonly unitSystem?: UnitSystemKey;
}
/**
 * The UnitFormattingSettingsProvider interface is used to store and retrieve override FormatProps and Presentation Unit System
 * for use by the QuantityFormatter. If no UnitFormattingSettingsProvider is supplied to the QuantityFormatter then any overrides
 * set are lost when the session is closed. The `ui-test-app` has and example implementation that uses browser local storage via the
 * class [[LocalUnitFormatProvider]] [here](https://github.com/iTwin/itwinjs-core/blob/d341e030d4c1427effd80ea54b3d57fec8ad1bc1/test-apps/ui-test-app/src/frontend/index.tsx#L315).
 *  @public
 */
export interface UnitFormattingSettingsProvider {
    /** serializes JSON object containing format overrides for a specific quantity type. */
    store(quantityTypeKey: QuantityTypeKey, overrideProps: OverrideFormatEntry): Promise<boolean>;
    /** retrieves serialized JSON object containing format overrides for a specific quantity type. */
    retrieve(quantityTypeKey: QuantityTypeKey): Promise<OverrideFormatEntry | undefined>;
    /** removes the override formats for a specific quantity type. */
    remove(quantityTypeKey: QuantityTypeKey): Promise<boolean>;
    /** retrieves the active unit system typically based on the "active" iModelConnection */
    retrieveUnitSystem(defaultKey: UnitSystemKey): Promise<UnitSystemKey>;
    /** store the active unit system typically for the "active" iModelConnection */
    storeUnitSystemKey(unitSystemKey: UnitSystemKey): Promise<boolean>;
    /** Function to load overrides for a specific IModelConnection. Typically this is not called often since typical
     * implementations monitor for IModelConnection changes and call this method internally. */
    loadOverrides(imodel: IModelConnection | undefined): Promise<void>;
    /** function called to save changes to Presentation Unit System */
    storeUnitSystemSetting(args: FormattingUnitSystemChangedArgs): Promise<void>;
    /** function called to save format overrides */
    storeFormatOverrides(args: QuantityFormatOverridesChangedArgs): Promise<void>;
    /** property that is set by the implementation to inform the BaseUnitFormattingSettingsProvider if the provider
     *  should trigger reloading of the overrides when the "active" imodel changes. */
    readonly maintainOverridesPerIModel: boolean;
}
/** Class that supports formatting quantity values into strings and parsing strings into quantity values. This class also maintains
 * the "active" unit system and caches FormatterSpecs and ParserSpecs for the "active" unit system to allow synchronous access to
 * parsing and formatting values. The support unit systems are defined by [[UnitSystemKey]] and is kept in synch with the unit systems
 * provided by the Presentation Manager on the backend. The QuantityFormatter contains a registry of quantity type definitions. These definitions implement
 * the [[QuantityTypeDefinition]] interface, which among other things, provide default [FormatProps]$(core-quantity), and provide methods
 * to generate both a [FormatterSpec]$(core-quantity) and a [ParserSpec]$(core-quantity). There are built-in quantity types that are
 * identified by the [[QuantityType]] enum. [[CustomQuantityTypeDefinition]] can be registered to extend the available quantity types available
 * by frontend tools. The QuantityFormatter also allows the default formats to be overriden.
 *
 * @public
 */
export declare class QuantityFormatter implements UnitsProvider {
    private _unitsProvider;
    private _alternateUnitLabelsRegistry;
    /** Registry containing available quantity type definitions. */
    protected _quantityTypeRegistry: Map<QuantityTypeKey, QuantityTypeDefinition>;
    /** Active UnitSystem key - must be one of "imperial", "metric", "usCustomary", or "usSurvey". */
    protected _activeUnitSystem: UnitSystemKey;
    /** Map of FormatSpecs for all available QuantityTypes and the active Unit System */
    protected _activeFormatSpecsByType: Map<string, FormatterSpec>;
    /** Map of ParserSpecs for all available QuantityTypes and the active Unit System */
    protected _activeParserSpecsByType: Map<string, ParserSpec>;
    /** Map of FormatSpecs that have been overriden from the default. */
    protected _overrideFormatPropsByUnitSystem: Map<UnitSystemKey, Map<string, FormatProps>>;
    /** Optional object that gets called to store and retrieve format overrides. */
    protected _unitFormattingSettingsProvider: UnitFormattingSettingsProvider | undefined;
    /** Set the settings provider and if not iModel specific initialize setting for user. */
    setUnitFormattingSettingsProvider(provider: UnitFormattingSettingsProvider): Promise<void>;
    /** Called after the active unit system is changed.
    * The system will report the UnitSystemKey/name of the the system that was activated.
    */
    readonly onActiveFormattingUnitSystemChanged: BeUiEvent<FormattingUnitSystemChangedArgs>;
    /** Called when the format of a QuantityType is overriden or the override is cleared. The string returned will
     * be a QuantityTypeKey generated by method `getQuantityTypeKey`.
     */
    readonly onQuantityFormatsChanged: BeUiEvent<QuantityFormatsChangedArgs>;
    /** Fired when the active UnitsProvider is updated. This will allow cached Formatter and Parser specs to be updated if necessary. */
    readonly onUnitsProviderChanged: BeUiEvent<void>;
    /**
     * constructor
     * @param showMetricOrUnitSystem - Pass in `true` to show Metric formatted quantity values. Defaults to Imperial. To explicitly
     * set it to a specific unit system pass a UnitSystemKey.
     */
    constructor(showMetricOrUnitSystem?: boolean | UnitSystemKey);
    private getOverrideFormatPropsByQuantityType;
    /** Method used to register all QuantityTypes defined in QuantityType enum. */
    protected initializeQuantityTypesRegistry(): Promise<void>;
    /** Asynchronous call to load Formatting and ParsingSpecs for a unit system. This method ends up caching FormatterSpecs and ParserSpecs
     *  so they can be quickly accessed.
     * @internal public for unit test usage
     */
    protected loadFormatAndParsingMapsForSystem(systemType?: UnitSystemKey): Promise<void>;
    private getFormatPropsByQuantityTypeEntryAndSystem;
    private loadFormatAndParserSpec;
    private loadDefaultFormatAndParserSpecForQuantity;
    private setOverrideFormatsByQuantityTypeKey;
    /** Method called to clear override and restore defaults formatter and parser spec */
    private clearOverrideFormatsByQuantityTypeKey;
    /** This method is called during IModelApp initialization to load the standard quantity types into the registry and to initialize the cache.
     * @internal
     */
    onInitialized(): Promise<void>;
    /** Return a map that serves as a registry of all standard and custom quantity types. */
    get quantityTypesRegistry(): Map<string, QuantityTypeDefinition>;
    /** Return the class the contain map of all alternate labels for units. These alternate labels are used when parsing strings in quantity values. */
    get alternateUnitLabelsProvider(): AlternateUnitLabelsProvider;
    /**
     * Add one or more alternate labels for a unit - these labels are used during string parsing.
     * @param key UnitNameKey which comes from `UnitProps.name`
     * @param labels one or more unit labels
     */
    addAlternateLabels(key: UnitNameKey, ...labels: string[]): void;
    /** Get/Set the active UnitsProvider class. */
    get unitsProvider(): UnitsProvider;
    set unitsProvider(unitsProvider: UnitsProvider);
    /** async method to set a units provider and reload caches */
    setUnitsProvider(unitsProvider: UnitsProvider): Promise<void>;
    /** Async call typically used after IModel is closed to reset UnitsProvider to default one that does not require an Units schema. */
    resetToUseInternalUnitsProvider(): Promise<void>;
    /** Async call to register a CustomQuantityType and load the FormatSpec and ParserSpec for the new type. */
    registerQuantityType(entry: CustomQuantityTypeDefinition, replace?: boolean): Promise<boolean>;
    /** Reinitialize caches. Typically called by active UnitFormattingSettingsProvider.
     * startDefaultTool - set to true to start the Default to instead of leaving any active tool pointing to cached unit data that is no longer valid
     * @public
     */
    reinitializeFormatAndParsingsMaps(overrideFormatPropsByUnitSystem: Map<UnitSystemKey, Map<QuantityTypeKey, FormatProps>>, unitSystemKey?: UnitSystemKey, fireUnitSystemChanged?: boolean, startDefaultTool?: boolean): Promise<void>;
    /** Set the Active unit system to one of the supported types. This will asynchronously load the formatter and parser specs for the activated system. */
    setActiveUnitSystem(isImperialOrUnitSystem: UnitSystemKey | boolean, restartActiveTool?: boolean): Promise<void>;
    /** Retrieve the active [[UnitSystemKey]] which is used to determine what formats are to be used to display quantities */
    get activeUnitSystem(): UnitSystemKey;
    /** Clear any formatting override for specified quantity type, but only for the "active" Unit System. */
    clearOverrideFormats(type: QuantityTypeArg): Promise<void>;
    /** Set formatting override for specified quantity type, but only for the "active" Unit System. */
    setOverrideFormats(type: QuantityTypeArg, overrideEntry: OverrideFormatEntry): Promise<void>;
    /** Set Override Format for a quantity type, but only in the "active" Unit System. */
    setOverrideFormat(type: QuantityTypeArg, overrideFormat: FormatProps): Promise<void>;
    /** Clear formatting override for all quantity types, but only for the "active" Unit System. */
    clearAllOverrideFormats(): Promise<void>;
    /** Converts a QuantityTypeArg into a QuantityTypeKey/string value that can be used to lookup custom and standard quantity types. */
    getQuantityTypeKey(type: QuantityTypeArg): string;
    /** Return [[QuantityTypeDefinition]] if type has been registered. Standard QuantityTypes are automatically registered. */
    getQuantityDefinition(type: QuantityTypeArg): QuantityTypeDefinition | undefined;
    /** Synchronous call to get a FormatterSpec of a QuantityType. If the FormatterSpec is not yet cached an undefined object is returned. The
     * cache is populated by the async call loadFormatAndParsingMapsForSystem.
     */
    findFormatterSpecByQuantityType(type: QuantityTypeArg, _unused?: boolean): FormatterSpec | undefined;
    /** Asynchronous Call to get a FormatterSpec for a QuantityType. This formatter spec can be used to synchronously format quantities. */
    generateFormatterSpecByType(type: QuantityTypeArg, formatProps: FormatProps): Promise<FormatterSpec>;
    /** Asynchronous Call to get a FormatterSpec for a QuantityType and a Unit System. This formatter spec can be used to synchronously format quantities.
     * @param type        One of the built-in quantity types supported.
     * @param system      Requested unit system key. Note it is more efficient to use setActiveUnitSystem to set up formatters for all
     * quantity types of a unit system.
     * @return A FormatterSpec Promise.
     */
    getFormatterSpecByQuantityTypeAndSystem(type: QuantityTypeArg, system?: UnitSystemKey): Promise<FormatterSpec | undefined>;
    /** Asynchronous Call to get a FormatterSpec for a QuantityType.
     * @param type        One of the built-in quantity types supported.
     * @param isImperial  Argument to specify use of imperial or metric unit system. If left undefined the active unit system is used.
     * @return A FormatterSpec Promise.
     */
    getFormatterSpecByQuantityType(type: QuantityTypeArg, isImperial?: boolean): Promise<FormatterSpec | undefined>;
    /** Synchronous call to get a ParserSpec for a QuantityType. If the ParserSpec is not yet cached an undefined object is returned. The
     * cache is populated when the active units system is set.
     */
    findParserSpecByQuantityType(type: QuantityTypeArg): ParserSpec | undefined;
    /** Asynchronous Call to get a ParserSpec for a QuantityType. If the UnitSystemKey is not specified the active Unit System is used. **/
    getParserSpecByQuantityTypeAndSystem(type: QuantityTypeArg, system?: UnitSystemKey): Promise<ParserSpec | undefined>;
    /** Asynchronous Call to get a ParserSpec for a QuantityType.
     * @param type        One of the built-in quantity types supported.
     * @param isImperial  Argument to specify use of imperial or metric unit system. If left undefined the active unit system is used.
     * @return A FormatterSpec Promise.
     */
    getParserSpecByQuantityType(type: QuantityTypeArg, isImperial?: boolean): Promise<ParserSpec | undefined>;
    /** Generates a formatted string for a quantity given its format spec.
     * @param magnitude       The magnitude of the quantity.
     * @param formatSpec      The format specification. See methods getFormatterSpecByQuantityType and findFormatterSpecByQuantityType.
     * @return the formatted string.
     */
    formatQuantity(magnitude: number, formatSpec: FormatterSpec | undefined): string;
    /** Parse input string into quantity given the ParserSpec
     * @param inString       The magnitude of the quantity.
     * @param parserSpec     The parse specification the defines the expected format of the string and the conversion to the output unit.
     * @return QuantityParseResult object containing either the parsed value or an error value if unsuccessful.
     */
    parseToQuantityValue(inString: string, parserSpec: ParserSpec | undefined): QuantityParseResult;
    /**
     * Get a UnitSystemKey from a string that may have been entered via a key-in. Supports different variation of
     * unit system names that have been used in the past.
     */
    getUnitSystemFromString(inputSystem: string, fallback?: UnitSystemKey): UnitSystemKey;
    /** Return true if the QuantityType is using an override format. */
    hasActiveOverride(type: QuantityTypeArg, checkOnlyActiveUnitSystem?: boolean): boolean;
    /** Get the cached FormatProps give a quantity type. If ignoreOverrides is false then if the format has been overridden
     * the overridden format is returned, else the standard format is returned.
     */
    getFormatPropsByQuantityType(quantityType: QuantityTypeArg, requestedSystem?: UnitSystemKey, ignoreOverrides?: boolean): FormatProps | undefined;
    /** Find [UnitProp] for a specific unit label. */
    findUnit(unitLabel: string, schemaName?: string, phenomenon?: string, unitSystem?: string): Promise<UnitProps>;
    /** Returns all defined units for the specified Unit Family/Phenomenon. */
    getUnitsByFamily(phenomenon: string): Promise<UnitProps[]>;
    /** Find [UnitProp] for a specific unit name. */
    findUnitByName(unitName: string): Promise<UnitProps>;
    /** Returns data needed to convert from one Unit to another in the same Unit Family/Phenomenon. */
    getConversion(fromUnit: UnitProps, toUnit: UnitProps): Promise<UnitConversionProps>;
}
//# sourceMappingURL=QuantityFormatter.d.ts.map