import { InputSnapshot } from "./InputSnapshot.js";
export class ActionMap {
    actions = new Map();
    axes = new Map();
    snapshot = new InputSnapshot();
    bind(name, bindings) {
        this.actions.set(name, [...bindings]);
    }
    bindAxis(name, bindings) {
        this.axes.set(name, [...bindings]);
    }
    useSnapshot(snapshot) {
        this.snapshot = snapshot;
    }
    down(name, snapshot = this.snapshot) {
        return this.evaluate(name, snapshot, "down");
    }
    pressed(name, snapshot = this.snapshot) {
        return this.evaluate(name, snapshot, "pressed");
    }
    released(name, snapshot = this.snapshot) {
        return this.evaluate(name, snapshot, "released");
    }
    axis(name, snapshot = this.snapshot) {
        let value = 0;
        for (const binding of this.axes.get(name) ?? []) {
            const scale = binding.scale ?? 1;
            if (binding.type === "keyboard-axis") {
                value += (snapshot.key(binding.positive).down ? 1 : 0) * scale;
                value -= (snapshot.key(binding.negative).down ? 1 : 0) * scale;
            }
            else if (binding.type === "pointer-axis") {
                const pointerValue = binding.axis === "x"
                    ? snapshot.pointer.deltaX
                    : binding.axis === "y"
                        ? snapshot.pointer.deltaY
                        : snapshot.pointer[binding.axis];
                value += pointerValue * scale;
            }
            else {
                const gamepad = snapshot.gamepads.find((pad) => pad.index === (binding.gamepad ?? 0));
                value += (gamepad?.axes[binding.axis] ?? 0) * scale;
            }
        }
        return value;
    }
    evaluate(name, snapshot, field) {
        return (this.actions.get(name) ?? []).some((binding) => {
            if (binding.type === "keyboard") {
                return snapshot.key(binding.code)[field];
            }
            if (binding.type === "keyboard-chord") {
                return evaluateChord(binding.codes, snapshot, field);
            }
            if (binding.type === "pointer") {
                return snapshot.button(binding.button)[field];
            }
            return snapshot.gamepadButton(binding.gamepad ?? 0, binding.button)[field];
        });
    }
}
function evaluateChord(codes, snapshot, field) {
    if (codes.length === 0)
        return false;
    const states = codes.map((code) => snapshot.key(code));
    if (field === "down") {
        return states.every((state) => state.down);
    }
    if (field === "pressed") {
        return states.every((state) => state.down) && states.some((state) => state.pressed);
    }
    return states.some((state) => state.released);
}
//# sourceMappingURL=ActionMap.js.map