// 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:html';
import 'dart:async';
import 'package:observatory/src/elements/helpers/tag.dart';
import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';

class RefreshEvent {
  final NavRefreshElement element;
  RefreshEvent(this.element);
}

class NavRefreshElement extends HtmlElement implements Renderable {
  static const tag = const Tag<NavRefreshElement>('nav-refresh-wrapped');

  RenderingScheduler _r;

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

  final StreamController<RefreshEvent> _onRefresh =
                                new StreamController<RefreshEvent>.broadcast();
  Stream<RefreshEvent> get onRefresh => _onRefresh.stream;

  bool _disabled;
  String _label;
  bool get disabled => _disabled;
  String get label => _label;
  set disabled(bool value) => _disabled = _r.checkAndReact(_disabled, value);
  set label(String value) => _label = _r.checkAndReact(_label, value);

  factory NavRefreshElement({String label: 'Refresh', bool disabled: false,
                             RenderingQueue queue}) {
    assert(label != null);
    assert(disabled != null);
    NavRefreshElement e = document.createElement(tag.name);
    e._r = new RenderingScheduler(e, queue: queue);
    e._label = label;
    e._disabled = disabled;
    return e;
  }

  NavRefreshElement.created() : super.created();

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

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

  void render() {
    children = [
      new LIElement()
        ..children = [
          new ButtonElement()
            ..text = label
            ..disabled = disabled
            ..onClick.map(_toEvent).listen(_refresh)
        ]
    ];
  }

  RefreshEvent _toEvent(_) {
    return new RefreshEvent(this);
  }

  void _refresh(RefreshEvent e) {
    if (_disabled) return;
    _onRefresh.add(e);
  }

  void refresh() {
    if (_disabled) return;
    _refresh(new RefreshEvent(this));
  }
}
