// Copyright (c) 2012, 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 view;

import 'dart:async';
import 'dart:html';
import 'dart:math' as Math;

import '../base/base.dart';
import '../observable/observable.dart';
import '../touch/touch.dart';
import '../layout/layout.dart';

part 'CompositeView.dart';
part 'ConveyorView.dart';
part 'MeasureText.dart';
part 'PagedViews.dart';
part 'SliderMenu.dart';


// TODO(rnystrom): Note! This class is undergoing heavy construction. It will
// temporary support both some old and some new ways of doing things until all
// subclasses are refactored to use the new way. There will be some scaffolding
// and construction cones laying around. Try not to freak out.

/** A generic view. */
class View implements Positionable {
  Element _node;
  ViewLayout _layout;

  // TODO(jmesserly): instead of tracking this on every View, we could have the
  // App track the views that want to be notified of resize()
  StreamSubscription _resizeSubscription;

  /**
   * Style properties configured for this view.
   */
  // TODO(jmesserly): We should be getting these from our CSS preprocessor.
  // I'm not sure if this will stay as a Map, or just be a get method.
  // TODO(jacobr): Consider returning a somewhat typed base.Style wrapper
  // object instead, and integrating with built in CSS properties.
  final Map<String, String> customStyle;

  View()
    : customStyle = new Map<String, String>();

  View.fromNode(Element this._node)
    : customStyle = new Map<String, String>();

  View.html(String html)
    : customStyle = new Map<String, String>(),
      _node = new Element.html(html);

  // TODO(rnystrom): Get rid of this when all views are refactored to not use
  // it.
  Element get node {
    // Lazy render.
    if (_node == null) {
      _render();
    }

    return _node;
  }

  /**
   * A subclass that contains child views should override this to return those
   * views. View uses this to ensure that child views are properly rendered
   * and initialized when their parent view is without the parent having to
   * manually handle that traversal.
   */
  Iterable<View> get childViews {
    return const [];
  }

  /**
   * View presumes the collection of views returned by childViews is more or
   * less static after the view is first created. Subclasses should call this
   * when that invariant doesn't hold to let View know that a new childView has
   * appeared.
   */
  void childViewAdded(View child) {
    if (isInDocument) {
      child._enterDocument();

      // TODO(jmesserly): is this too expensive?
      doLayout();
    }
  }

  /**
   * View presumes the collection of views returned by childViews is more or
   * less static after the view is first created. Subclasses should call this
   * when that invariant doesn't hold to let View know that a childView has
   * been removed.
   */
  void childViewRemoved(View child) {
    if (isInDocument) {
      child._exitDocument();
    }
  }

  /** Gets whether this View has already been rendered or not. */
  bool get isRendered {
    return _node != null;
  }

  /**
   * Gets whether this View (or one of its parents) has been added to the
   * document or not.
   */
  bool get isInDocument {
    return _node != null
        && node.ownerDocument is HtmlDocument
        && (node.ownerDocument as HtmlDocument).body.contains(node);
  }

  /**
   * Adds this view to the document as a child of the given node. This should
   * generally only be called once for the top-level view.
   */
  void addToDocument(Element parentNode) {
    assert(!isInDocument);

    _render();
    parentNode.nodes.add(_node);
    _hookGlobalLayoutEvents();
    _enterDocument();
  }

  void removeFromDocument() {
    assert(isInDocument);

    // Remove runs in reverse order of how we entered.
    _exitDocument();
    _unhookGlobalLayoutEvents();
    _node.remove();
  }

  /**
   * Override this to generate the DOM structure for the view.
   */
  // TODO(rnystrom): make this method abstract, see b/5015671
  Element render() { throw 'abstract'; }

  /**
   * Override this to perform initialization behavior that requires access to
   * the DOM associated with the View, such as event wiring.
   */
  void afterRender(Element node) {
    // Do nothing by default.
  }

  /**
   * Override this to perform behavior after this View has been added to the
   * document. This is appropriate if you need access to state (such as the
   * calculated size of an element) that's only available when the View is in
   * the document.
   *
   * This will be called each time the View is added to the document, if it is
   * added and removed multiple times.
   */
  void enterDocument() {}

  /**
   * Override this to perform behavior after this View has been removed from the
   * document. This can be a convenient time to unregister event handlers bound
   * in enterDocument().
   *
   * This will be called each time the View is removed from the document, if it
   * is added and removed multiple times.
   */
  void exitDocument() {}

  /** Override this to perform behavior after the window is resized. */
  // TODO(jmesserly): this isn't really the event we want. Ideally we want to
  // fire the event only if this particular View changed size. Also we should
  // give a view the ability to measure itself when added to the document.
  void windowResized() {}

  /**
   * Registers the given listener callback to the given observable. Also
   * immedially invokes the callback once as if a change has just come in. This
   * lets you define a render() method that renders the skeleton of a view, then
   * register a bunch of listeners which all fire to populate the view with
   * model data.
   */
  void watch(Observable observable, void watcher(EventSummary summary)) {
    // Make a fake summary for the initial watch.
    final summary = new EventSummary(observable);
    watcher(summary);

    attachWatch(observable, watcher);
  }

  /** Registers the given listener callback to the given observable. */
  void attachWatch(Observable observable, void watcher(EventSummary summary)) {
    observable.addChangeListener(watcher);

    // TODO(rnystrom): Should keep track of this and unregister when the view
    // is discarded.
  }

  void addOnClick(EventListener handler) {
    _node.onClick.listen(handler);
  }

  /**
   * Gets whether the view is hidden.
   */
  bool get hidden => _node.style.display == 'none';

  /**
   * Sets whether the view is hidden.
   */
  void set hidden(bool hidden) {
    if (hidden) {
      node.style.display = 'none';
    } else {
      node.style.display = '';
    }
  }

  void addClass(String className) {
    node.classes.add(className);
  }

  void removeClass(String className) {
    node.classes.remove(className);
  }

  /** Sets the CSS3 transform applied to the view. */
  set transform(String transform) {
    node.style.transform = transform;
  }

  // TODO(rnystrom): Get rid of this, or move into a separate class?
  /** Creates a View whose node is a <div> with the given class(es). */
  static View div(String cssClass, [String body = null]) {
    if (body == null) {
      body = '';
    }
    return new View.html('<div class="$cssClass">$body</div>');
  }

  /**
   * Internal render method that deals with traversing child views. Should not
   * be overridden.
   */
  void _render() {
    // TODO(rnystrom): Should render child views here. Not implemented yet.
    // Instead, we rely on the parent accessing .node to implicitly cause the
    // child to be rendered.

    // Render this view.
    if (_node == null) {
      _node = render();
    }

    // Pass the node back to the derived view so it can register event
    // handlers on it.
    afterRender(_node);
  }

  /**
   * Internal method that deals with traversing child views. Should not be
   * overridden.
   */
  void _enterDocument() {
    // Notify the children first.
    for (final child in childViews) {
      child._enterDocument();
    }

    enterDocument();
  }

  // Layout related methods

  ViewLayout get layout {
    if (_layout == null) {
      _layout = new ViewLayout.fromView(this);
    }
    return _layout;
  }

  /**
   * Internal method that deals with traversing child views. Should not be
   * overridden.
   */
  void _exitDocument() {
    // Notify this View first so that it's children are still valid.
    exitDocument();

    // Notify the children.
    for (final child in childViews) {
      child._exitDocument();
    }
  }

  /**
   * If needed, starts a layout computation from the top level.
   * Also hooks the relevant events like window resize, so we can layout on too
   * demand.
   */
  void _hookGlobalLayoutEvents() {
    if (_resizeSubscription == null) {
      var handler = EventBatch.wrap((e) => doLayout());
      _resizeSubscription = window.onResize.listen(handler);
    }


    // Trigger the initial layout.
    doLayout();
  }

  void _unhookGlobalLayoutEvents() {
    if (_resizeSubscription != null) {
      _resizeSubscription.cancel();
      _resizeSubscription = null;
    }
  }

  void doLayout() {
    _measureLayout().then((changed) {
      if (changed) {
        _applyLayoutToChildren();
      }
    });
  }

  Future<bool> _measureLayout() {
    // TODO(10459): code should not use Completer.sync.
    final changed = new Completer<bool>.sync();
    _measureLayoutHelper(changed);

    var changedComplete = false;
    changed.future.then((_) {
      changedComplete = true;
    });

    scheduleMicrotask(() {
      if (!changedComplete) {
        changed.complete(false);
      }
    });
    return changed.future;
  }

  void _measureLayoutHelper(Completer<bool> changed) {
    windowResized();

    // TODO(jmesserly): this logic is more complex than it needs to be because
    // we're taking pains to not initialize _layout if it's not needed. Is that
    // a good tradeoff?
    if (ViewLayout.hasCustomLayout(this)) {
      // TODO(10459): code should not use Completer.sync.
      Completer sizeCompleter = new Completer<Size>.sync();
      scheduleMicrotask(() {
        sizeCompleter.complete(
            new Size(_node.client.width, _node.client.height));
      });
      layout.measureLayout(sizeCompleter.future, changed);
    } else {
      for (final child in childViews) {
        child._measureLayoutHelper(changed);
      }
    }
  }

  void _applyLayoutToChildren() {
    for (final child in childViews) {
      child._applyLayout();
    }
  }

  void _applyLayout() {
    if (_layout != null) {
      _layout.applyLayout();
    }
    _applyLayoutToChildren();
  }
}
