/**
 * Excalibur's typed event emitter, this allows events to be sent with any string to Type mapping
 */
export class EventEmitter {
    constructor() {
        this._paused = false;
        this._listeners = {};
        this._listenersOnce = {};
        this._pipes = [];
    }
    clear() {
        this._listeners = {};
        this._listenersOnce = {};
        this._pipes.length = 0;
    }
    on(eventName, handler) {
        var _a;
        this._listeners[eventName] = (_a = this._listeners[eventName]) !== null && _a !== void 0 ? _a : [];
        this._listeners[eventName].push(handler);
        return {
            close: () => this.off(eventName, handler)
        };
    }
    once(eventName, handler) {
        var _a;
        this._listenersOnce[eventName] = (_a = this._listenersOnce[eventName]) !== null && _a !== void 0 ? _a : [];
        this._listenersOnce[eventName].push(handler);
        return {
            close: () => this.off(eventName, handler)
        };
    }
    off(eventName, handler) {
        var _a, _b;
        if (handler) {
            const newListeners = (_a = this._listeners[eventName]) === null || _a === void 0 ? void 0 : _a.filter((h) => h !== handler);
            this._listeners[eventName] = newListeners;
            const newOnceListeners = (_b = this._listenersOnce[eventName]) === null || _b === void 0 ? void 0 : _b.filter((h) => h !== handler);
            this._listenersOnce[eventName] = newOnceListeners;
        }
        else {
            delete this._listeners[eventName];
        }
    }
    emit(eventName, event) {
        var _a;
        if (this._paused) {
            return;
        }
        (_a = this._listeners[eventName]) === null || _a === void 0 ? void 0 : _a.forEach((fn) => fn(event));
        const onces = this._listenersOnce[eventName];
        this._listenersOnce[eventName] = [];
        if (onces) {
            onces.forEach((fn) => fn(event));
        }
        this._pipes.forEach((pipe) => {
            pipe.emit(eventName, event);
        });
    }
    pipe(emitter) {
        if (this === emitter) {
            throw Error('Cannot pipe to self');
        }
        this._pipes.push(emitter);
        return {
            close: () => {
                const i = this._pipes.indexOf(emitter);
                if (i > -1) {
                    this._pipes.splice(i, 1);
                }
            }
        };
    }
    unpipe(emitter) {
        const i = this._pipes.indexOf(emitter);
        if (i > -1) {
            this._pipes.splice(i, 1);
        }
    }
    pause() {
        this._paused = true;
    }
    unpause() {
        this._paused = false;
    }
}
//# sourceMappingURL=EventEmitter.js.map