"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Gamepad_ = exports.GAMEPAD_DEFAULT_TRESHOLD = exports.GAMEPAD_AXIS_COUNT = exports.GAMEPAD_BUTTON_COUNT = void 0;
const EventEmitter_1 = require("../../../EventEmitter");
exports.GAMEPAD_BUTTON_COUNT = 16;
exports.GAMEPAD_AXIS_COUNT = 4;
exports.GAMEPAD_DEFAULT_TRESHOLD = 0.001;
class Gamepad_ extends EventEmitter_1.EventEmitter_ {
    constructor(system, gamepad) {
        super();
        this.state = {
            buttons: new Array(exports.GAMEPAD_BUTTON_COUNT).fill(false, 0, exports.GAMEPAD_BUTTON_COUNT),
            axes: new Array(exports.GAMEPAD_AXIS_COUNT).fill(0, 0, exports.GAMEPAD_AXIS_COUNT),
        };
        this._frame = null;
        this._event_capture_tick = () => {
            const { api: { input: { gamepad: { getGamepad }, }, animation: { requestAnimationFrame }, }, } = this.system;
            this.gamepad = getGamepad(this.gamepad.index);
            const prevButtonsPressed = [...this.state.buttons];
            const buttonsPressed = this.gamepad.buttons.map((b) => b.pressed);
            this.state.buttons = buttonsPressed;
            for (let i = 0; i < exports.GAMEPAD_BUTTON_COUNT; i++) {
                if (buttonsPressed[i] && !prevButtonsPressed[i]) {
                    this.emit('buttondown', i);
                }
                else if (!buttonsPressed[i] && prevButtonsPressed[i]) {
                    this.emit('buttonup', i);
                }
            }
            const prevAxes = this.state.axes;
            const axes = this.gamepad.axes.map((a) => a);
            this.state.axes = axes;
            for (let i = 0; i < exports.GAMEPAD_AXIS_COUNT; i++) {
                if (Math.abs(axes[i] - prevAxes[i]) >= exports.GAMEPAD_DEFAULT_TRESHOLD) {
                    this.emit('axischange', [i, axes[i]]);
                }
            }
            this._frame = requestAnimationFrame(this._event_capture_tick);
        };
        this._start_event_capture = () => {
            // console.log('Gamepad_', '_start_event_capture')
            this._event_capture_tick();
        };
        this._stop_event_capture = () => {
            // console.log('Gamepad_', '_stop_event_capture')
            const { api: { animation: { cancelAnimationFrame }, }, } = this.system;
            if (this._frame !== undefined) {
                cancelAnimationFrame(this._frame);
                this._frame = undefined;
            }
        };
        this._listenerCount = 0;
        this.system = system;
        this.gamepad = gamepad;
    }
    read() {
        return __awaiter(this, void 0, void 0, function* () {
            return this.state;
        });
    }
    write(data) {
        return __awaiter(this, void 0, void 0, function* () {
            throw new Error('cannot write to gamepad state');
        });
    }
    addListener(event, listener) {
        // console.log('Gamepad_', 'addListener', event)
        const unlisten = super.addListener(event, listener);
        this._listenerCount++;
        if (this._listenerCount >= 1) {
            this._start_event_capture();
        }
        return () => {
            this._listenerCount--;
            if (this._listenerCount === 0) {
                this._stop_event_capture();
            }
            unlisten();
        };
    }
    disconnect() {
        this._stop_event_capture();
    }
}
exports.Gamepad_ = Gamepad_;
//# sourceMappingURL=index.js.map