// Copyright (c) 2013, 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.

library curly_block_element;

import 'dart:async';
import 'dart:html';
import 'package:observatory_2/src/elements/helpers/custom_element.dart';
import 'package:observatory_2/src/elements/helpers/rendering_scheduler.dart';

class CurlyBlockToggleEvent {
  final CurlyBlockElement control;

  CurlyBlockToggleEvent(this.control);
}

class CurlyBlockElement extends CustomElement implements Renderable {
  RenderingScheduler<CurlyBlockElement> _r;

  final StreamController<CurlyBlockToggleEvent> _onToggle =
      new StreamController<CurlyBlockToggleEvent>.broadcast();
  Stream<CurlyBlockToggleEvent> get onToggle => _onToggle.stream;
  Stream<RenderedEvent<CurlyBlockElement>> get onRendered => _r.onRendered;

  bool _expanded;
  bool _disabled;
  Iterable<Element> _content = const [];

  bool get expanded => _expanded;
  bool get disabled => _disabled;
  Iterable<Element> get content => _content;

  set expanded(bool value) {
    if (_expanded != value) _onToggle.add(new CurlyBlockToggleEvent(this));
    _expanded = _r.checkAndReact(_expanded, value);
  }

  set disabled(bool value) => _disabled = _r.checkAndReact(_disabled, value);
  set content(Iterable<Element> value) {
    _content = value.toList();
    _r.dirty();
  }

  factory CurlyBlockElement(
      {bool expanded: false, bool disabled: false, RenderingQueue queue}) {
    assert(expanded != null);
    assert(disabled != null);
    CurlyBlockElement e = new CurlyBlockElement.created();
    e._r = new RenderingScheduler<CurlyBlockElement>(e, queue: queue);
    e._expanded = expanded;
    e._disabled = disabled;
    return e;
  }

  CurlyBlockElement.created() : super.created('curly-block');

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

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

  void toggle() {
    if (disabled) {
      _r.scheduleNotification();
      return;
    }
    expanded = !expanded;
  }

  void render() {
    List<Element> content = <Element>[new SpanElement()..text = '{'];
    SpanElement label = new SpanElement()
      ..classes = disabled ? ['curly-block', 'disabled'] : ['curly-block']
      ..innerHtml = expanded
          ? '&nbsp;&nbsp;&#8863;&nbsp;&nbsp;'
          : '&nbsp;&nbsp;&#8862;&nbsp;&nbsp;';
    if (disabled) {
      content.add(label);
    } else {
      content.add(new AnchorElement()
        ..onClick.listen((_) {
          toggle();
        })
        ..children = <Element>[label]);
    }
    if (expanded) {
      content.add(new BRElement());
      content.addAll(_content);
    }
    content.add(new SpanElement()..text = '}');
    children = content;
  }
}
