// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';
import 'dart:html';
import 'package:observatory/models.dart' as M show Target;
import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
import 'package:observatory/src/elements/helpers/tag.dart';
import 'package:observatory/src/elements/helpers/uris.dart';

class TargetEvent {
  final M.Target target;

  TargetEvent(this.target);
}

class VMConnectTargetElement extends HtmlElement implements Renderable{

  static const tag =
    const Tag<VMConnectTargetElement>('vm-connect-target-wrapped');

  RenderingScheduler<VMConnectTargetElement> _r;

  Stream<RenderedEvent<VMConnectTargetElement>> get onRendered => _r.onRendered;

  final StreamController<TargetEvent> _onConnect =
      new StreamController<TargetEvent>.broadcast();
  Stream<TargetEvent> get onConnect => _onConnect.stream;
  final StreamController<TargetEvent> _onDelete =
      new StreamController<TargetEvent>.broadcast();
  Stream<TargetEvent> get onDelete => _onDelete.stream;

  M.Target _target;
  bool _current;

  M.Target get target => _target;
  bool get current => _current;

  factory VMConnectTargetElement(M.Target target, {bool current: false,
      RenderingQueue queue}) {
    assert(target != null);
    assert(current != null);
    VMConnectTargetElement e = document.createElement(tag.name);
    e._r = new RenderingScheduler(e, queue: queue);
    e._target = target;
    e._current = current;
    return e;
  }

  VMConnectTargetElement.created() : super.created();

  @override
  void attached() {
    super.attached();
    _r.enable();
  }

  @override
  void detached() {
    super.detached();
    children = [];
    _r.disable(notify: true);
  }

  void connect() {
    _connect(new TargetEvent(target));
  }

  void delete() {
    _delete(new TargetEvent(target));
  }

  void render() {
    children = [
      new AnchorElement(href: Uris.vm())
        ..text = current ? '${target.name} (Connected)' : '${target.name}'
        ..onClick.where(_filter).map(_toEvent).listen(_connect),
      new ButtonElement()
        ..text = '✖ Remove' ..classes = ['delete-button']
        ..onClick.map(_toEvent).listen(_delete)
    ];
  }

  void _connect(TargetEvent e) {
    _onConnect.add(e);
  }

  void _delete(TargetEvent e) {
    _onDelete.add(e);
  }

  TargetEvent _toEvent(_) {
    return new TargetEvent(target);
  }

  static bool _filter(MouseEvent event) {
    return !(event.button > 0 || event.metaKey || event.ctrlKey ||
        event.shiftKey || event.altKey);
  }
}
