'use strict';

exports.__esModule = true;

var _types = require('wp-element-ui/lib/utils/types');

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function toArray(list, start) {
  start = start || 0;
  var i = list.length - start;
  var ret = new Array(i);
  while (i--) {
    ret[i] = list[i + start];
  }
  return ret;
}
function invokeWithErrorHandling(handler, context, args, info) {
  var res = void 0;
  try {
    res = args ? handler.apply(context, args) : handler.call(context);
    if (res && (0, _types.isPromise)(res) && !res._handled) {
      res.catch(function (e) {
        console.error(info + ' (Promise/async)');
        console.error(e);
      });
      res._handled = true;
    }
  } catch (e) {
    console.error(info);
    console.error(e);
  }
  return res;
}

var EventEmitter = function () {
  function EventEmitter() {
    _classCallCheck(this, EventEmitter);

    this._events = Object.create(null);
  }

  EventEmitter.prototype.$on = function $on(event, fn) {
    if (Array.isArray(event)) {
      for (var i = 0, l = event.length; i < l; i++) {
        this.$on(event[i], fn);
      }
    } else {
      (this._events[event] || (this._events[event] = [])).push(fn);
    }
  };

  EventEmitter.prototype.$once = function $once(event, fn) {
    var instance = this;

    function on() {
      instance.$off(event, on);
      fn.apply(instance, arguments);
    }
    on.fn = fn;
    this.$on(event, on);
  };

  EventEmitter.prototype.$off = function $off(event, fn) {
    var instance = this;
    // 不传任何清除所有监听事件
    if (!arguments.length) {
      instance._events = Object.create(null);
      return;
    }
    // array of events
    if (Array.isArray(event)) {
      for (var _i = 0, l = event.length; _i < l; _i++) {
        instance.$off(event[_i], fn);
      }
      return;
    }
    // specific event
    var cbs = instance._events[event];
    if (!cbs) {
      return;
    }
    if (!fn) {
      instance._events[event] = null;
      return;
    }
    // specific handler
    var cb = void 0;
    var i = cbs.length;
    while (i--) {
      cb = cbs[i];
      if (cb === fn || cb.fn === fn) {
        cbs.splice(i, 1);
        break;
      }
    }
  };

  EventEmitter.prototype.$emit = function $emit(event) {
    var instance = this;
    if (process.env.NODE_ENV !== 'production') {
      var lowerCaseEvent = event.toLowerCase();
      if (lowerCaseEvent !== event && instance._events[lowerCaseEvent]) {
        console.error(event + ' has been emitted');
      }
    }
    var cbs = instance._events[event];
    if (cbs) {
      cbs = cbs.length > 1 ? toArray(cbs) : cbs;
      var args = toArray(arguments, 1);
      var info = 'event handler for "' + event + '"';
      for (var i = 0, l = cbs.length; i < l; i++) {
        invokeWithErrorHandling(cbs[i], instance, args, info);
      }
    }
  };

  return EventEmitter;
}();

exports.default = EventEmitter;