Sky Event Model
===============

```dart
import 'dart:collection';
import 'dart:async';

class ExceptionAndStackTrace<T> {
  const ExceptionAndStackTrace(this.exception, this.stackTrace);
  final T exception;
  final StackTrace stackTrace;
}

class ExceptionListException<T> extends IterableMixin<ExceptionAndStackTrace<T>> implements Exception {
  List<ExceptionAndStackTrace<T>> _exceptions;
  void add(T exception, [StackTrace stackTrace = null]) {
    if (_exceptions == null)
      _exceptions = new List<ExceptionAndStackTrace<T>>();
    _exceptions.add(new ExceptionAndStackTrace<T>(exception, stackTrace));
  }
  int get length => _exceptions == null ? 0 : _exceptions.length;
  Iterator<ExceptionAndStackTrace<T>> get iterator => _exceptions.iterator;
}

typedef bool Filter<T>(T t);
typedef void Handler<T>(T t);

class DispatcherController<T> {
  DispatcherController() : dispatcher = new Dispatcher<T>();
  final Dispatcher<T> dispatcher;
  void add(T data) => dispatcher._add(data);
}

class Pair<A, B> {
  const Pair(this.a, this.b);
  final A a;
  final B b;
}

class Dispatcher<T> {
  List<Pair<Handler, ZoneUnaryCallback>> _listeners;
  void listen(Handler<T> handler) {
    // you should not throw out of this handler
    if (_listeners == null)
      _listeners = new List<Pair<Handler, ZoneUnaryCallback>>();
    _listeners.add(new Pair<Handler, ZoneUnaryCallback>(handler, Zone.current.bindUnaryCallback(handler)));
  }
  bool unlisten(Handler<T> handler) {
    if (_listeners == null)
      return false;
    var target = _listeners.lastWhere((v) => v.a == handler, orElse: () => null);
    if (target == null)
      return false;
    _listeners.removeAt(_listeners.lastIndexOf(target));
    return true;
  }
  void _add(T data) {
    if (_listeners == null)
      return;
    ExceptionListException exceptions = new ExceptionListException();
    // we make a copy of the list here so that the listeners can
    // mutate our list without worry
    _listeners.toList().forEach((Pair<Handler, ZoneUnaryCallback> item) {
      try {
        item.b(data);
      } catch (exception, stackTrace) {
        exceptions.add(exception, stackTrace);
      }
    });
    if (exceptions.length > 0)
      throw exceptions;
  }

  Dispatcher<T> where(Filter<T> filter) => new WhereDispatcher<T>(this, filter);

  Dispatcher<T> until(Filter<T> filter) {
    var subdispatcher = new Dispatcher<T>();
    Handler handler;
    handler = (T data) {
      if (filter(data))
        unlisten(handler);
      else
        subdispatcher._add(data);
    };
    listen(handler);
    return subdispatcher;
  }

  Future<T> firstWhere(Filter<T> filter) {
    Completer completer = new Completer();
    Handler handler;
    handler = (T data) {
      if (filter(data)) {
        completer.complete(data);
        unlisten(handler);
      }
    };
    listen(handler);
    return completer.future;
  }
}

class WhereDispatcher<T> extends Dispatcher {
  WhereDispatcher(this.parent, this.filter) : super();
  Dispatcher parent;
  Filter filter;

  void listen(Handler<T> handler) {
    if (_listeners == null || _listeners.length == 0)
      parent.listen(_handler);
    super.listen(handler);
  }
  bool unlisten(Handler<T> handler) {
    var result = super.unlisten(handler);
    if (result && _listeners.length == 0)
      parent.unlisten(_handler);
    return result;
  }
  void _handler(T data) {
    if (filter(data))
      _add(data);
  }
}

abstract class Event<ReturnType> {
  Event() { init(); }
  void init() { }

  bool get bubbles;

  EventTarget _target;
  EventTarget get target => _target;

  EventTarget _currentTarget;
  EventTarget get currentTarget => _currentTarget;

  bool handled; // precise semantics depend on the event type, but in general, set this when you set result
  ReturnType result;

  bool resultIsCompatible(dynamic candidate) => candidate is ReturnType;

  // TODO(ianh): abstract API for doing things at shadow tree boundaries 
  // TODO(ianh): do events get blocked at scope boundaries, e.g. focus events when both sides are in the scope?
  // TODO(ianh): do events get retargetted, e.g. focus when leaving a custom element?
  // e.g. sent from inside a shadow tree, when exiting the shadow tree, focus event should:
  //  - disappear if we're moving from one to another element
  //  - be targetted if it's going to another node in a different scope
}

class EventTarget {
  EventTarget() : _eventsController = new DispatcherController<Event>();

  Dispatcher get events => _eventsController.dispatcher;
  EventTarget parentNode;

  List<EventTarget> getEventDispatchChain() {
    if (this.parentNode == null) {
      return [this];
    } else {
      var result = this.parentNode.getEventDispatchChain();
      result.insert(0, this);
      return result;
    }
  }

  final DispatcherController _eventsController;

  dynamic dispatchEvent(Event event, { dynamic defaultResult: null }) { // O(N*M) where N is the length of the chain and M is the average number of listeners per link in the chain
    // note: this will throw an ExceptionListException<ExceptionListException> if any of the listeners threw
    assert(event != null); // event must be non-null
    event.handled = false;
    assert(event.resultIsCompatible(defaultResult));
    event.result = defaultResult;
    event._target = this;
    var chain;
    if (event.bubbles)
      chain = this.getEventDispatchChain();
    else
      chain = [this];
    var exceptions = new ExceptionListException<ExceptionListException>();
    for (var link in chain) {
      try {
        link._dispatchEventLocally(event);
      } on ExceptionListException catch (e) {
        exceptions.add(e);
      }
    }
    if (exceptions.length > 0)
      throw exceptions;
    return event.result;
  }

  void _dispatchEventLocally(Event event) {
    event._currentTarget = this;
    _eventsController.add(event);
  }
}
```
