"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EventEmitter_ = void 0;
const ListenerNotFoundError_1 = require("./exception/ListenerNotFoundError");
const f_1 = require("./system/f/object/Keys/f");
class EventEmitter_ {
    constructor() {
        this.__listeners = {};
        this._removeListener = (event, listener) => {
            const listeners = this.__listeners[event];
            if (!listeners) {
                throw new ListenerNotFoundError_1.ListenerNotFoundError();
            }
            const i = listeners.indexOf(listener);
            if (i < 0) {
                throw new ListenerNotFoundError_1.ListenerNotFoundError();
            }
            listeners.splice(i, 1);
            if (listeners.length === 0) {
                delete this.__listeners[event];
                this.emit('unlisten', { event });
            }
        };
    }
    prependListener(event, listener) {
        this.__listeners[event] = this.__listeners[event] || [];
        this.__listeners[event].unshift(listener);
        this.emit('listen', { event });
        return () => {
            this._removeListener(event, listener);
        };
    }
    removeListener(event, listener) {
        this._removeListener(event, listener);
    }
    addListener(event, listener) {
        this.__listeners[event] = this.__listeners[event] || [];
        this.__listeners[event].push(listener);
        this.emit('listen', { event });
        return () => {
            this._removeListener(event, listener);
        };
    }
    eventNames() {
        return (0, f_1.keys)(this.__listeners);
    }
    listenerCount(name) {
        return (this.__listeners[name] || []).length;
    }
    emit(event, ...args) {
        const listeners = this.__listeners[event];
        if (!listeners) {
            return;
        }
        for (const listener of listeners) {
            listener.call(this, ...args);
        }
    }
}
exports.EventEmitter_ = EventEmitter_;
//# sourceMappingURL=EventEmitter.js.map