/*!
 * Custom elements for Nanopore-Digital Web applications
 */
export function EvEmitter() { }
const proto = EvEmitter.prototype;
proto.on = function (eventName, listener) {
    if (!eventName || !listener) {
        return;
    }
    // set events hash
    const events = (this._events = this._events || {});
    // set listeners array
    const listeners = (events[eventName] = events[eventName] || []);
    // only add once
    if (listeners.indexOf(listener) == -1) {
        listeners.push(listener);
    }
    return this;
};
proto.once = function (eventName, listener) {
    if (!eventName || !listener) {
        return;
    }
    // add event
    this.on(eventName, listener);
    // set once flag
    // set onceEvents hash
    const onceEvents = (this._onceEvents = this._onceEvents || {});
    // set onceListeners object
    const onceListeners = (onceEvents[eventName] = onceEvents[eventName] || {});
    // set flag
    onceListeners[listener] = true;
    return this;
};
proto.off = function (eventName, listener) {
    const listeners = this._events && this._events[eventName];
    if (!listeners || !listeners.length) {
        return;
    }
    const index = listeners.indexOf(listener);
    if (index != -1) {
        listeners.splice(index, 1);
    }
    return this;
};
proto.emitEvent = function (eventName, args) {
    let listeners = this._events && this._events[eventName];
    if (!listeners || !listeners.length) {
        return;
    }
    // copy over to avoid interference if .off() in listener
    listeners = listeners.slice(0);
    args = args || [];
    // once stuff
    const onceListeners = this._onceEvents && this._onceEvents[eventName];
    for (let i = 0; i < listeners.length; i++) {
        const listener = listeners[i];
        const isOnce = onceListeners && onceListeners[listener];
        if (isOnce) {
            // remove listener
            // remove before trigger to prevent recursion
            this.off(eventName, listener);
            // unset once flag
            delete onceListeners[listener];
        }
        // trigger listener
        listener.apply(this, args);
    }
    return this;
};
proto.allOff = function () {
    delete this._events;
    delete this._onceEvents;
};
