import { GamepadConnectEvent, GamepadDisconnectEvent, GamepadButtonEvent, GamepadAxisEvent } from '../Events';
import { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter';
export type GamepadEvents = {
    connect: GamepadConnectEvent;
    disconnect: GamepadDisconnectEvent;
    button: GamepadButtonEvent;
    axis: GamepadAxisEvent;
};
export declare const GamepadEvents: {
    GamepadConnect: string;
    GamepadDisconnect: string;
    GamepadButton: string;
    GamepadAxis: string;
};
/**
 * Excalibur leverages the HTML5 Gamepad API [where it is supported](http://caniuse.com/#feat=gamepad)
 * to provide controller support for your games.
 */
export declare class Gamepads {
    events: EventEmitter<GamepadEvents>;
    /**
     * Whether or not to poll for Gamepad input (default: `false`)
     */
    enabled: boolean;
    /**
     * Whether or not Gamepad API is supported
     */
    supported: boolean;
    /**
     * The minimum value an axis has to move before considering it a change
     */
    static MinAxisMoveThreshold: number;
    private _gamePadTimeStamps;
    private _oldPads;
    private _pads;
    private _initSuccess;
    private _navigator;
    private _minimumConfiguration;
    private _enabled;
    init(): void;
    toggleEnabled(enabled: boolean): void;
    /**
     * Sets the minimum gamepad configuration, for example {axis: 4, buttons: 4} means
     * this game requires at minimum 4 axis inputs and 4 buttons, this is not restrictive
     * all other controllers with more axis or buttons are valid as well. If no minimum
     * configuration is set all pads are valid.
     */
    setMinimumGamepadConfiguration(config: GamepadConfiguration): void;
    /**
     * When implicitly enabled, set the enabled flag and run an update so information is updated
     */
    private _enableAndUpdate;
    /**
     * Checks a navigator gamepad against the minimum configuration if present.
     */
    private _isGamepadValid;
    emit<TEventName extends EventKey<GamepadEvents>>(eventName: TEventName, event: GamepadEvents[TEventName]): void;
    emit(eventName: string, event?: any): void;
    on<TEventName extends EventKey<GamepadEvents>>(eventName: TEventName, handler: Handler<GamepadEvents[TEventName]>): Subscription;
    on(eventName: string, handler: Handler<unknown>): Subscription;
    once<TEventName extends EventKey<GamepadEvents>>(eventName: TEventName, handler: Handler<GamepadEvents[TEventName]>): Subscription;
    once(eventName: string, handler: Handler<unknown>): Subscription;
    off<TEventName extends EventKey<GamepadEvents>>(eventName: TEventName, handler: Handler<GamepadEvents[TEventName]>): void;
    off(eventName: string, handler: Handler<unknown>): void;
    off(eventName: string): void;
    /**
     * Updates Gamepad state and publishes Gamepad events
     */
    update(): void;
    /**
     * Safely retrieves a Gamepad at a specific index and creates one if it doesn't yet exist
     */
    at(index: number): Gamepad;
    /**
     * Returns a list of all valid gamepads that meet the minimum configuration requirement.
     */
    getValidGamepads(): Gamepad[];
    /**
     * Gets the number of connected gamepads
     */
    count(): number;
    private _clonePads;
    /**
     * Fastest way to clone a known object is to do it yourself
     */
    private _clonePad;
}
/**
 * Gamepad holds state information for a connected controller. See {@apilink Gamepads}
 * for more information on handling controller input.
 */
export declare class Gamepad {
    events: EventEmitter<GamepadEvents>;
    connected: boolean;
    navigatorGamepad: NavigatorGamepad;
    private _axes;
    private _buttons;
    private _buttonsUp;
    private _buttonsDown;
    constructor();
    update(): void;
    /**
     * Whether or not the given button is pressed
     * @deprecated will be removed in v0.28.0. Use isButtonHeld instead
     * @param button     The button to query
     * @param threshold  The threshold over which the button is considered to be pressed
     */
    isButtonPressed(button: Buttons | number, threshold?: number): boolean;
    /**
     * Tests if a certain button is held down. This is persisted between frames.
     * @param button     The button to query
     * @param threshold  The threshold over which the button is considered to be pressed
     */
    isButtonHeld(button: Buttons | number, threshold?: number): boolean;
    /**
     * Tests if a certain button was just pressed this frame. This is cleared at the end of the update frame.
     * @param button Test whether a button was just pressed
     * @param threshold  The threshold over which the button is considered to be pressed
     */
    wasButtonPressed(button: Buttons | number, threshold?: number): boolean;
    /**
     * Tests if a certain button was just released this frame. This is cleared at the end of the update frame.
     * @param button  Test whether a button was just released
     */
    wasButtonReleased(button: Buttons | number): boolean;
    /**
     * Gets the given button value between 0 and 1
     */
    getButton(button: Buttons | number): number;
    /**
     * Gets the given axis value between -1 and 1. Values below
     * {@apilink MinAxisMoveThreshold} are considered 0.
     */
    getAxes(axes: Axes | number): number;
    updateButton(buttonIndex: number, value: number): void;
    updateAxes(axesIndex: number, value: number): void;
    emit<TEventName extends EventKey<GamepadEvents>>(eventName: TEventName, event: GamepadEvents[TEventName]): void;
    emit(eventName: string, event?: any): void;
    on<TEventName extends EventKey<GamepadEvents>>(eventName: TEventName, handler: Handler<GamepadEvents[TEventName]>): Subscription;
    on(eventName: string, handler: Handler<unknown>): Subscription;
    once<TEventName extends EventKey<GamepadEvents>>(eventName: TEventName, handler: Handler<GamepadEvents[TEventName]>): Subscription;
    once(eventName: string, handler: Handler<unknown>): Subscription;
    off<TEventName extends EventKey<GamepadEvents>>(eventName: TEventName, handler: Handler<GamepadEvents[TEventName]>): void;
    off(eventName: string, handler: Handler<unknown>): void;
    off(eventName: string): void;
}
/**
 * Gamepad Buttons enumeration
 */
export declare enum Buttons {
    /**
     * Any button that isn't explicity known by excalibur
     */
    Unknown = -1,
    /**
     * Face 1 button (e.g. A)
     */
    Face1 = 0,
    /**
     * Face 2 button (e.g. B)
     */
    Face2 = 1,
    /**
     * Face 3 button (e.g. X)
     */
    Face3 = 2,
    /**
     * Face 4 button (e.g. Y)
     */
    Face4 = 3,
    /**
     * Left bumper button
     */
    LeftBumper = 4,
    /**
     * Right bumper button
     */
    RightBumper = 5,
    /**
     * Left trigger button
     */
    LeftTrigger = 6,
    /**
     * Right trigger button
     */
    RightTrigger = 7,
    /**
     * Select button
     */
    Select = 8,
    /**
     * Start button
     */
    Start = 9,
    /**
     * Left analog stick press (e.g. L3)
     */
    LeftStick = 10,
    /**
     * Right analog stick press (e.g. R3)
     */
    RightStick = 11,
    /**
     * D-pad up
     */
    DpadUp = 12,
    /**
     * D-pad down
     */
    DpadDown = 13,
    /**
     * D-pad left
     */
    DpadLeft = 14,
    /**
     * D-pad right
     */
    DpadRight = 15,
    /**
     * Center button (e.g. the Nintendo Home Button)
     */
    CenterButton = 16,
    /**
     * Misc button 1 (e.g. Xbox Series X share button, PS5 microphone button, Nintendo Switch Pro capture button, Amazon Luna microphone button)
     * defacto standard not listed on the w3c spec for a standard gamepad https://w3c.github.io/gamepad/#dfn-standard-gamepad
     */
    MiscButton1 = 17
}
/**
 * Gamepad Axes enumeration
 */
export declare enum Axes {
    /**
     * Left analogue stick X direction
     */
    LeftStickX = 0,
    /**
     * Left analogue stick Y direction
     */
    LeftStickY = 1,
    /**
     * Right analogue stick X direction
     */
    RightStickX = 2,
    /**
     * Right analogue stick Y direction
     */
    RightStickY = 3
}
/**
 * @internal
 */
export interface NavigatorGamepads {
    getGamepads(): (NavigatorGamepad | undefined)[];
}
/**
 * @internal
 */
export interface NavigatorGamepad {
    axes: number[];
    buttons: NavigatorGamepadButton[];
    connected: boolean;
    id: string;
    index: number;
    mapping: string;
    timestamp: number;
}
/**
 * @internal
 */
export interface NavigatorGamepadButton {
    pressed: boolean;
    value: number;
}
/**
 * @internal
 */
export interface NavigatorGamepadEvent {
    gamepad: NavigatorGamepad;
}
/**
 * @internal
 */
export interface GamepadConfiguration {
    axis: number;
    buttons: number;
}
