"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const _1 = require("../../../../../Class/$");
const Holder_1 = require("../../../../../Class/Holder");
const gamepad_1 = require("../../../../../client/event/gamepad");
const callAll_1 = require("../../../../../util/call/callAll");
const _ids_1 = require("../../../../_ids");
class _Gamepad extends Holder_1.Holder {
    constructor(system) {
        super({
            fi: ['i'],
            fo: [],
            o: ['state'],
        }, {
            output: {
                state: {
                    ref: true,
                },
            },
        }, system, _ids_1.ID_GAMEPAD);
    }
    async f({ i }, done, fail) {
        const { api: { input: { gamepad: { getGamepad, addEventListener }, }, }, } = this.__system;
        try {
            const gamepad = getGamepad(i);
            this._gamepad = new gamepad_1.Gamepad_(this.__system, gamepad);
        }
        catch (err) {
            fail(err.message);
            return;
        }
        const onConnect = (event) => {
            const { gamepad } = event;
            const { index } = gamepad;
            if (index === i) {
                this._gamepad = new gamepad_1.Gamepad_(this.__system, gamepad);
                pushPad(this._gamepad);
            }
        };
        const onDisconnect = (event) => {
            const { gamepad } = event;
            const { index } = gamepad;
            if (index === i) {
                this._gamepad = null;
                pullPad();
            }
        };
        this._unlisten = (0, callAll_1.callAll)([
            addEventListener('gamepadconnected', onConnect),
            addEventListener('gamepaddisconnected', onDisconnect),
            () => {
                if (this._gamepad) {
                    pullPad();
                }
            },
        ]);
        const pushPad = (gamepad_) => {
            const pad = new (class Pad extends _1.$ {
                read(callback) {
                    callback(gamepad_.state);
                }
                write(data, callback) {
                    callback(undefined, 'cannot write to gamepad state');
                }
            })(this.__system);
            this._output.state.push(pad);
        };
        const pullPad = () => {
            this._output.state.pull();
        };
        if (this._gamepad) {
            pushPad(this._gamepad);
        }
    }
    d() {
        if (this._unlisten) {
            this._unlisten();
            this._unlisten = undefined;
        }
    }
}
exports.default = _Gamepad;
//# sourceMappingURL=index.js.map