import { EVENT_ALL } from "../api.js";
import { mixin } from "../mixin.js";
const inotify_dispatch = (listeners, e) => {
  if (!listeners) return false;
  for (let i = 0, n = listeners.length, l; i < n; i++) {
    l = listeners[i];
    l[0].call(l[1], e);
    if (e.canceled) {
      return false;
    }
  }
  return true;
};
const INotifyMixin = mixin({
  addListener(id, fn, scope) {
    let l = (this._listeners = this._listeners || {})[id];
    !l && (l = this._listeners[id] = []);
    if (this.__listener(l, fn, scope) === -1) {
      l.push([fn, scope]);
      return true;
    }
    return false;
  },
  removeListener(id, fn, scope) {
    let listeners;
    if (!(listeners = this._listeners)) return false;
    const l = listeners[id];
    if (l) {
      const idx = this.__listener(l, fn, scope);
      if (idx !== -1) {
        l.splice(idx, 1);
        !l.length && delete listeners[id];
        return true;
      }
    }
    return false;
  },
  notify(e) {
    let listeners;
    if (!(listeners = this._listeners)) return false;
    e.target === void 0 && (e.target = this);
    const res = inotify_dispatch(listeners[e.id], e);
    return inotify_dispatch(listeners[EVENT_ALL], e) || res;
  },
  __listener(listeners, f, scope) {
    let i = listeners.length;
    while (i-- > 0) {
      const l = listeners[i];
      if (l[0] === f && l[1] === scope) {
        break;
      }
    }
    return i;
  }
});
export {
  INotifyMixin,
  inotify_dispatch
};
