// Copyright (c) 2014, 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 isolate_reconnect_element;

import 'dart:html';
import 'dart:async';
import 'package:observatory/models.dart' as M;
import 'package:observatory/src/elements/helpers/nav_bar.dart';
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';
import 'package:observatory/src/elements/nav/notify.dart';
import 'package:observatory/src/elements/nav/top_menu.dart';
import 'package:observatory/src/elements/view_footer.dart';

class IsolateReconnectElement extends CustomElement implements Renderable {
  static const tag = const Tag<IsolateReconnectElement>('isolate-reconnect',
      dependencies: const [
        NavTopMenuElement.tag,
        NavNotifyElement.tag,
        ViewFooterElement.tag
      ]);

  RenderingScheduler _r;

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

  M.VM _vm;
  String _missing;
  Uri _uri;
  M.EventRepository _events;
  StreamSubscription _subscription;

  M.VM get vm => _vm;
  String get missing => _missing;
  Uri get uri => _uri;

  M.NotificationRepository _notifications;
  factory IsolateReconnectElement(M.VM vm, M.EventRepository events,
      M.NotificationRepository notifications, String missing, Uri uri,
      {RenderingQueue queue}) {
    assert(vm != null);
    assert(events != null);
    assert(missing != null);
    assert(uri != null);
    assert(notifications != null);
    IsolateReconnectElement e = new IsolateReconnectElement.created();
    e._r = new RenderingScheduler<IsolateReconnectElement>(e, queue: queue);
    e._vm = vm;
    e._events = events;
    e._missing = missing;
    e._uri = uri;
    e._notifications = notifications;
    return e;
  }

  IsolateReconnectElement.created() : super.created(tag);

  @override
  void attached() {
    super.attached();
    _subscription = _events.onVMUpdate.listen((e) {
      _vm = e.vm;
      _r.dirty();
    });
    _r.enable();
  }

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

  void render() {
    children = <Element>[
      navBar(<Element>[
        new NavTopMenuElement(queue: _r.queue).element,
        new NavNotifyElement(_notifications, queue: _r.queue).element
      ]),
      new DivElement()
        ..classes = ['content-centered']
        ..children = <Element>[
          new HeadingElement.h1()..text = 'Isolate $_missing no longer exists',
          new HRElement(),
          new BRElement(),
          new DivElement()
            ..classes = ['memberList']
            ..children = (_vm.isolates.map<Element>((isolate) {
              final query = new Map<String, dynamic>.from(_uri.queryParameters);
              query['isolateId'] = isolate.id;
              final href = new Uri(path: _uri.path, queryParameters: query);
              return new DivElement()
                ..classes = ['memberItem', 'doubleSpaced']
                ..children = <Element>[
                  new SpanElement()..text = 'Continue in ',
                  new AnchorElement(href: '#$href')
                    ..classes = ['isolate-link']
                    ..text = '${isolate.id} (${isolate.name})'
                ];
            }).toList()
              ..add(new DivElement()
                ..classes = ['memberItem', 'doubleSpaced']
                ..children = <Element>[
                  new SpanElement()..text = 'Go to ',
                  new AnchorElement(href: Uris.vm())..text = 'isolates summary',
                ]))
        ],
      new ViewFooterElement(queue: _r.queue).element
    ];
  }
}
