import { Dualsense } from "./dualsense";
import { Input, InputParams } from "./input";
/** The state exposed by a DualsenseManager via the Input system */
export interface DualsenseManagerState {
    /** Number of currently connected controllers */
    active: number;
    /** All managed controllers, keyed by slot index (player number) */
    players: ReadonlyMap<number, Dualsense>;
}
/** Settings for the DualsenseManager */
export interface DualsenseManagerParams extends InputParams {
    /** Polling interval (ms) for discovering new devices in Node.js. Default: 2000 */
    discoveryInterval?: number;
    /** Whether to automatically assign player LED patterns. Default: true */
    autoAssignPlayerLeds?: boolean;
}
/**
 * Manages multiple Dualsense controllers. Automatically discovers devices,
 * assigns player LEDs, and provides indexed access to each controller.
 *
 * Extends Input so that events from all managed controllers bubble up:
 * - `change` fires when the controller count changes or any controller input changes
 * - `press` / `release` bubble from any managed controller (including connection state)
 */
export declare class DualsenseManager extends Input<DualsenseManagerState> {
    /** Current manager state: active count and player map */
    state: DualsenseManagerState;
    /** Whether to auto-assign player LED patterns on connection */
    autoAssignPlayerLeds: boolean;
    /** Player LED bitmask patterns indexed by slot number (0–30) */
    private readonly playerPatterns;
    /** All controller slots, indexed by slot number */
    private readonly slots;
    /** Map from node-hid serial to slot index — best-effort, used as a fallback */
    private readonly serialToSlot;
    /** Map from canonical hardware identity to slot index — preferred when available */
    private readonly identityToSlot;
    /** Discovery polling timer (Node.js only) */
    private discoveryTimer?;
    /** Whether we're running in a browser environment */
    private readonly isBrowser;
    constructor(params?: DualsenseManagerParams);
    get active(): boolean;
    /**
     * All managed controller instances (including disconnected ones awaiting
     * reconnection). Excludes provisional slots whose identity is still being
     * resolved — those become visible only after firmware info loads, to
     * avoid surfacing controllers that may be merged into an existing slot.
     */
    get controllers(): readonly Dualsense[];
    /** Number of managed controllers (including disconnected ones awaiting reconnection) */
    get count(): number;
    /** Get a controller by slot index */
    get(index: number): Dualsense | undefined;
    /** Iterate over all managed controllers */
    [Symbol.iterator](): IterableIterator<Dualsense>;
    /** Slots that are visible to the consumer (i.e. identity has been resolved) */
    private publicSlots;
    /**
     * True while at least one controller has been discovered but is still
     * waiting for firmware info to load. Useful for showing a "connecting"
     * state in the UI without surfacing the unresolved slot itself.
     */
    get pending(): boolean;
    /**
     * Override the player LED pattern for a given slot index.
     * @param index Slot index (0-based)
     * @param bitmask 5-bit LED bitmask (0x00–0x1f)
     */
    setPlayerPattern(index: number, bitmask: number): void;
    /** Get the player LED pattern for a given slot index */
    getPlayerPattern(index: number): number;
    /**
     * Release a controller slot, freeing it for reuse.
     * If the controller is still connected, it will be disconnected.
     * @param index Slot index to release
     */
    release(index: number): void;
    /**
     * Release all disconnected controller slots.
     * Connected controllers are not affected.
     */
    releaseDisconnected(): void;
    /**
     * Stop discovery and disconnect all controllers.
     */
    dispose(): void;
    /**
     * For WebHID: returns a click handler that opens the device picker,
     * allowing the user to select multiple controllers at once.
     */
    getRequest(): () => Promise<void>;
    /** Previous state snapshot, for deduplication */
    private lastActive;
    private lastPlayerCount;
    /** Fingerprint of the last published player set (slot indices + connected flags) */
    private lastPlayerKey;
    /** Build a new state snapshot and push it through InputSet */
    private updateState;
    /**
     * Create a Dualsense instance and register it in a (provisional) slot.
     * The caller is responsible for opening the device on the provider — the
     * manager treats this as the *only* path that opens new devices, so
     * identity matching can run before the slot becomes visible.
     *
     * Note: identity is the sole reconnection key. We do NOT key on node-hid's
     * serialNumber because it can be missing or wrong. Path is tracked only
     * so we can re-target the same device on transplant.
     */
    private createSlot;
    /**
     * Called when a slot's HID layer has finished reading firmware/factory info.
     * If the resolved identity matches a *different* (disconnected) slot, the
     * underlying device is transplanted into that slot's existing provider so
     * the consumer's Dualsense reference is preserved across reconnect.
     */
    private handleSlotReady;
    /** Mark a slot as visible to consumers and publish state */
    private promoteSlot;
    /**
     * Move the device handle from `from` into `into`'s existing provider so
     * the existing Dualsense instance reconnects in place. Then remove `from`.
     */
    private transplant;
    /** Remove a slot without firing the player-LED reshuffle */
    private dropSlot;
    private startNodeDiscovery;
    /**
     * Handle a newly discovered device from enumeration. Opens the device on
     * a fresh provider, which adds it to `claimedDevices` so subsequent polls
     * skip it. Identity matching (and any merge into a disconnected slot)
     * happens later, once firmware info has been read.
     */
    private processDiscoveredDevice;
    private startWebDiscovery;
    /** HIDDevice objects we've already handed to a provider */
    private readonly knownWebDevices;
    private addWebDevice;
}
//# sourceMappingURL=manager.d.ts.map