// The core of this is using a single broker for event handling across the app in RiotControl._broker.
// Then all events are handled by riot.control.on and triggered by riot.control.trigger.
// Special handling is required in riot tags to ensure that events get mounted/unmounted along with the tag, 
// else you end up with fns firing in the background

// =====================================
// event_helper.js

class RiotControl {
  constructor() {
    this._broker = riot.observable();
  }

  on(evt, handler) {
    this._broker.on(evt, handler);
  }

  off(evt, handler) {
    this._broker.off(evt, handler);
  }

  one(evt, handler) {
    this._broker.one(evt, handler);
  }

  trigger() {
    var args = [].slice.call(arguments);
    try {
      this._broker.trigger.apply(this._broker, args);
    } catch(ex) {
      console.error("Error in riotcontrol.trigger(" + args[0] + ", ...) ", ex.stack);
      throw ex;
    }
  }
}

riot.control = new RiotControl();

// need to use this in tag pages to turn on and off event handlers during mount and unmount respectively
// In the example we use ES6 [] to compute the keys, which just uses the riot.EVT string as a key
// Example:
// riot.registerEventHandlers(this, {
//     [riot.EVT.resetPasswordSuccess]: resetPasswordSuccessHandler,
//     [riot.EVT.resetPasswordFailed]: resetPasswordFailedHandler,
//     [riot.EVT.authenticationFailed]: authenticationFailedHandler
//   });
// _ = lodash
riot.registerEventHandlers = (tag, handlers) => {
  tag.on('before-mount', () => {
    _.forEach(handlers, (value, key) => {
      riot.control.on(key, value);
    });
  });

  tag.on('before-unmount', () => {
    _.forEach(handlers, (value, key) => {
      riot.control.off(key, value);
    });
  });
};

// event names

riot.EVT = {
  // results
  changeResults: 'changeResults',
  changeResultsSuccess: 'changeResultsSuccess',
  changeResultsFailed: 'changeResultsFailed',

};

// =====================================
// In stores instantiated once per app
riot.control.on(riot.EVT.changeResults, fn);
riot.control.trigger(riot.EVT.changeResultsSuccess, {...payload...});

// =====================================
// In page.tags that get mounted/unmounted

let userClickEvent = e => {
    riot.control.trigger(riot.EVT.changeResults);
}

let changeResultsHandler = () => {
  ...
  this.update();
}

let changeResultsSuccessHandler = () => {
  ...
  this.update();
}

let changeResultsFailedHandler = e => {
  ...
  this.update();
}

riot.registerEventHandlers(this, {
  [riot.EVT.changeResults]: changeResultsHandler,
  [riot.EVT.changeResultsSuccess]: changeResultsSuccessHandler,
  [riot.EVT.changeResultsFailed]: changeResultsFailedHandler,
});