import { ActionMap } from "./ActionMap.js";
import { GamepadDevice } from "./GamepadDevice.js";
import { InputSnapshot } from "./InputSnapshot.js";
import { KeyboardDevice } from "./KeyboardDevice.js";
import { PointerDevice } from "./PointerDevice.js";
export class InputSystem {
    keyboard = new KeyboardDevice();
    pointer = new PointerDevice();
    gamepads = new GamepadDevice();
    actions = new ActionMap();
    attachedTargets = new Map();
    snapshotRef = new InputSnapshot();
    constructor(target) {
        if (target) {
            this.attach(target);
        }
    }
    get snapshot() {
        return this.snapshotRef;
    }
    attach(target) {
        if (this.attachedTargets.has(target)) {
            return;
        }
        const onKeyDown = ((event) => this.keyboard.keyDown(event));
        const onKeyUp = ((event) => this.keyboard.keyUp(event));
        const onPointerMove = ((event) => this.pointer.move(event));
        const onPointerDown = ((event) => this.pointer.down(event));
        const onPointerUp = ((event) => this.pointer.up(event));
        const onWheel = ((event) => this.pointer.wheel(event));
        const onBlur = (() => {
            this.keyboard.blur();
            this.pointer.blur();
        });
        const listeners = [
            ["keydown", onKeyDown],
            ["keyup", onKeyUp],
            ["pointermove", onPointerMove],
            ["pointerdown", onPointerDown],
            ["pointerup", onPointerUp],
            ["wheel", onWheel],
            ["blur", onBlur]
        ];
        const disposers = [];
        for (const [type, listener] of listeners) {
            target.addEventListener(type, listener);
            disposers.push(() => target.removeEventListener(type, listener));
        }
        this.attachedTargets.set(target, disposers);
    }
    update(gamepads = []) {
        const keyboard = this.keyboard.snapshotSets();
        const pointer = this.pointer.snapshotData();
        this.snapshotRef = new InputSnapshot({
            ...keyboard,
            ...pointer,
            gamepads: this.gamepads.poll(gamepads)
        });
        this.actions.useSnapshot(this.snapshotRef);
        return this.snapshotRef;
    }
    endFrame() {
        this.keyboard.endFrame();
        this.pointer.endFrame();
    }
    dispose() {
        for (const disposers of this.attachedTargets.values()) {
            while (disposers.length > 0) {
                disposers.pop()?.();
            }
        }
        this.attachedTargets.clear();
        this.keyboard.blur();
        this.pointer.blur();
    }
}
//# sourceMappingURL=InputSystem.js.map