import type { Event } from '@difizen/mana-common';
import { Deferred, Emitter } from '@difizen/mana-common';
import { LocalStorageService } from '../common';
import { KeyboardLayoutProvider, KeyboardLayoutChangeNotifier } from './keyboard-protocol';
import type { KeyValidationInput, KeyValidator, NativeKeyboardLayout } from './keyboard-protocol';
export type KeyboardLayoutSource = 'navigator.keyboard' | 'user-choice' | 'pressed-keys';
export declare class BrowserKeyboardLayoutProvider implements KeyboardLayoutProvider, KeyboardLayoutChangeNotifier, KeyValidator {
    layoutDatas: KeyboardLayoutData[];
    pendingLayoutMap: Map<string, Promise<KeyboardLayoutData>>;
    protected tester: KeyboardTester;
    protected readonly storageService: LocalStorageService;
    constructor();
    protected readonly initialized: Deferred<void>;
    protected readonly nativeLayoutChanged: Emitter<NativeKeyboardLayout>;
    get onDidChangeNativeLayout(): Event<NativeKeyboardLayout>;
    protected source: KeyboardLayoutSource;
    protected currentLayout: KeyboardLayoutData;
    protected updateTester(): void;
    /**
     * Keyboard layout files are expected to have the following name scheme:
     *     `language-name-hardware.json`
     *
     * - `language`: A language subtag according to IETF BCP 47
     * - `name`:     Display name of the keyboard layout (without dashes)
     * - `hardware`: `pc` or `mac`
     */
    protected getLayoutData(layoutId: string, raw: NativeKeyboardLayout): KeyboardLayoutData;
    protected loadLayout(layoutId: string): Promise<KeyboardLayoutData>;
    addLayout(layoutId: string): Promise<void>;
    get allLayoutData(): KeyboardLayoutData[];
    get currentLayoutData(): KeyboardLayoutData;
    get currentLayoutSource(): KeyboardLayoutSource;
    protected initialize(): Promise<void>;
    getNativeLayout(): Promise<NativeKeyboardLayout>;
    /**
     * Set user-chosen keyboard layout data.
     */
    setLayoutData(layout: KeyboardLayoutData | 'autodetect'): Promise<KeyboardLayoutData>;
    /**
     * Test all known keyboard layouts with the given combination of pressed key and
     * produced character. Matching layouts have their score increased (see class
     * KeyboardTester). If this leads to a change of the top-scoring layout, a layout
     * change event is fired.
     */
    validateKey(keyCode: KeyValidationInput): void;
    protected setCurrent(layout: KeyboardLayoutData, source: KeyboardLayoutSource): void;
    protected autodetect(): Promise<[KeyboardLayoutData, KeyboardLayoutSource]>;
    /**
     * @param layoutMap a keyboard layout map according to https://wicg.github.io/keyboard-map/
     */
    protected testLayoutMap(layoutMap: KeyboardLayoutMap): void;
    /**
     * Select a layout based on the current tester state and the operating system
     * and language detected from the browser.
     */
    protected selectLayout(): KeyboardLayoutData;
    protected saveState(): Promise<void>;
    protected loadState(): Promise<void>;
}
export interface KeyboardLayoutData {
    name: string;
    hardware: 'pc' | 'mac';
    language: string;
    raw: NativeKeyboardLayout;
}
/**
 * This is the fallback keyboard layout selected when nothing else matches.
 * It has an empty mapping, so user inputs are handled like with a standard US keyboard.
 */
export declare const DEFAULT_LAYOUT_DATA: KeyboardLayoutData;
export interface LayoutProviderState {
    tester?: KeyboardTesterState;
    source?: KeyboardLayoutSource;
    currentLayout?: string | undefined;
}
export interface KeyboardTesterState {
    scores?: Record<string, number>;
    topScore?: number;
    testedInputs?: Record<string, string>;
}
/**
 * Holds score values for all known keyboard layouts. Scores are updated
 * by comparing key codes with the corresponding character produced by
 * the user's keyboard.
 */
export declare class KeyboardTester {
    readonly scores: number[];
    topScore: number;
    private readonly testedInputs;
    readonly candidates: KeyboardLayoutData[];
    get inputCount(): number;
    constructor(candidates: KeyboardLayoutData[]);
    reset(): void;
    updateScores(input: KeyValidationInput): boolean;
    protected testCandidate(candidate: KeyboardLayoutData, input: KeyValidationInput, property: 'value' | 'withShift' | 'withAltGr' | 'withShiftAltGr'): number;
    getState(): KeyboardTesterState;
    setState(state: KeyboardTesterState): void;
}
type KeyboardLayoutMap = Map<string, string>;
export {};
//# sourceMappingURL=browser-keyboard-layout-provider.d.ts.map