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

part of swarmlib;

// This file contains View framework classes.
// As it grows, it may need to be split into multiple files.

/** A factory that creates a view from a data model. */
abstract class ViewFactory<D> {
  View newView(D item);

  /** The width of the created view or null if the width is not fixed. */
  int get width;

  /** The height of the created view or null if the height is not fixed. */
  int get height;
}

abstract class VariableSizeViewFactory<D> {
  View newView(D item);

  /** The width of the created view for a specific data model. */
  int getWidth(D item);

  /** The height of the created view for a specific data model. */
  int getHeight(D item);
}

/** A collection of event listeners. */
class EventListeners {
  var listeners;
  EventListeners() {
    listeners = new List();
  }

  void addListener(listener) {
    listeners.add(listener);
  }

  void fire(var event) {
    for (final listener in listeners) {
      listener(event);
    }
  }
}

/**
 * Private view class used to store placeholder views for detached ListView
 * elements.
 */
class _PlaceholderView extends View {
  _PlaceholderView() : super() {}

  Element render() => new Element.tag('div');
}

/**
 * Class providing all metrics required to layout a data driven list view.
 */
abstract class ListViewLayout<D> {
  void onDataChange();

  // TODO(jacobr): placing the newView member function on this class seems like
  // the wrong design.
  View newView(int index);
  /** Get the height of the view. Possibly expensive to compute. */
  int getHeight(int viewLength);
  /** Get the width of the view. Possibly expensive to compute. */
  int getWidth(int viewLength);
  /** Get the length of the view. Possible expensive to compute. */
  int getLength(int viewLength);
  /** Estimated height of the view. Guaranteed to be fast to compute. */
  int getEstimatedHeight(int viewLength);
  /** Estimated with of the view. Guaranteed to be fast to compute. */
  int getEstimatedWidth(int viewLength);

  /**
   * Returns the offset in px that the ith item in the view should be placed
   * at.
   */
  int getOffset(int index);

  /**
   * The page the ith item in the view should be placed in.
   */
  int getPage(int index, int viewLength);
  int getPageStartIndex(int index, int viewLength);

  int getEstimatedLength(int viewLength);
  /**
   * Snap a specified index to the nearest visible view given the [viewLength].
   */
  int getSnapIndex(num offset, num viewLength);
  /**
   * Returns an interval specifying what views are currently visible given a
   * particular [:offset:].
   */
  Interval computeVisibleInterval(num offset, num viewLength, num bufferLength);
}

/**
 * Base class used for the simple fixed size item [:ListView:] classes and more
 * complex list view classes such as [:VariableSizeListView:] using a
 * [:ListViewLayout:] class to drive the actual layout.
 */
class GenericListView<D> extends View {
  /** Minimum throw distance in pixels to trigger snapping to the next item. */
  static const SNAP_TO_NEXT_THROW_THRESHOLD = 15;

  static const INDEX_DATA_ATTRIBUTE = 'data-index';

  final bool _scrollable;
  final bool _showScrollbar;
  final bool _snapToItems;
  Scroller scroller;
  Scrollbar _scrollbar;
  List<D> _data;
  ObservableValue<D> _selectedItem;
  Map<int, View> _itemViews;
  Element _containerElem;
  bool _vertical;
  /** Length of the scrollable dimension of the view in px. */
  int _viewLength = 0;
  Interval _activeInterval;
  bool _paginate;
  bool _removeClippedViews;
  ListViewLayout<D> _layout;
  D _lastSelectedItem;
  PageState _pages;

  /**
   * Creates a new GenericListView with the given layout and data. If [:_data:]
   * is an [:ObservableList<T>:] then it will listen to changes to the list
   * and update the view appropriately.
   */
  GenericListView(
      this._layout,
      this._data,
      this._scrollable,
      this._vertical,
      this._selectedItem,
      this._snapToItems,
      this._paginate,
      this._removeClippedViews,
      this._showScrollbar,
      this._pages)
      : super(),
        _activeInterval = new Interval(0, 0),
        _itemViews = new Map<int, View>() {
    // TODO(rnystrom): Move this into enterDocument once we have an exitDocument
    // that we can use to unregister it.
    if (_scrollable) {
      window.onResize.listen((Event event) {
        if (isInDocument) {
          onResize();
        }
      });
    }
  }

  void onSelectedItemChange() {
    // TODO(rnystrom): use Observable to track the last value of _selectedItem
    // rather than tracking it ourselves.
    _select(findIndex(_lastSelectedItem), false);
    _select(findIndex(_selectedItem.value), true);
    _lastSelectedItem = _selectedItem.value;
  }

  Iterable<View> get childViews {
    return _itemViews.values.toList();
  }

  void _onClick(MouseEvent e) {
    int index = _findAssociatedIndex(e.target);
    if (index != null) {
      _selectedItem.value = _data[index];
    }
  }

  int _findAssociatedIndex(Node leafNode) {
    Node node = leafNode;
    while (node != null && node != _containerElem) {
      if (node.parent == _containerElem) {
        return _nodeToIndex(node);
      }
      node = node.parent;
    }
    return null;
  }

  int _nodeToIndex(Element node) {
    // TODO(jacobr): use data attributes when available.
    String index = node.attributes[INDEX_DATA_ATTRIBUTE];
    if (index != null && index.length > 0) {
      return int.parse(index);
    }
    return null;
  }

  Element render() {
    final node = new Element.tag('div');
    if (_scrollable) {
      _containerElem = new Element.tag('div');
      _containerElem.tabIndex = -1;
      node.nodes.add(_containerElem);
    } else {
      _containerElem = node;
    }

    if (_scrollable) {
      scroller = new Scroller(
          _containerElem,
          _vertical /* verticalScrollEnabled */,
          !_vertical /* horizontalScrollEnabled */,
          true /* momentumEnabled */, () {
        num width = _layout.getWidth(_viewLength);
        num height = _layout.getHeight(_viewLength);
        width = width != null ? width : 0;
        height = height != null ? height : 0;
        return new Size(width, height);
      },
          _paginate && _snapToItems
              ? Scroller.FAST_SNAP_DECELERATION_FACTOR
              : 1);
      scroller.onContentMoved.listen((e) => renderVisibleItems(false));
      if (_pages != null) {
        watch(_pages.target, (s) => _onPageSelected());
      }

      if (_snapToItems) {
        scroller.onDecelStart.listen((e) => _decelStart());
        scroller.onScrollerDragEnd.listen((e) => _decelStart());
      }
      if (_showScrollbar) {
        _scrollbar = new Scrollbar(scroller, true);
      }
    } else {
      _reserveArea();
      renderVisibleItems(true);
    }

    return node;
  }

  void afterRender(Element node) {
    // If our data source is observable, observe it.
    if (_data is ObservableList<D>) {
      ObservableList<D> observable = _data;
      attachWatch(observable, (EventSummary e) {
        if (e.target == observable) {
          onDataChange();
        }
      });
    }

    if (_selectedItem != null) {
      addOnClick((Event e) {
        _onClick(e);
      });
    }

    if (_selectedItem != null) {
      watch(_selectedItem, (EventSummary summary) => onSelectedItemChange());
    }
  }

  void onDataChange() {
    _layout.onDataChange();
    _renderItems();
  }

  void _reserveArea() {
    final style = _containerElem.style;
    int width = _layout.getWidth(_viewLength);
    int height = _layout.getHeight(_viewLength);
    if (width != null) {
      style.width = '${width}px';
    }
    if (height != null) {
      style.height = '${height}px';
    }
    // TODO(jacobr): this should be specified by the default CSS for a
    // GenericListView.
    style.overflow = 'hidden';
  }

  void onResize() {
    int lastViewLength = _viewLength;
    scheduleMicrotask(() {
      _viewLength = _vertical ? node.offset.height : node.offset.width;
      if (_viewLength != lastViewLength) {
        if (_scrollbar != null) {
          _scrollbar.refresh();
        }
        renderVisibleItems(true);
      }
    });
  }

  void enterDocument() {
    if (scroller != null) {
      onResize();

      if (_scrollbar != null) {
        _scrollbar.initialize();
      }
    }
  }

  int getNextIndex(int index, bool forward) {
    int delta = forward ? 1 : -1;
    if (_paginate) {
      int newPage = Math.max(0, _layout.getPage(index, _viewLength) + delta);
      index = _layout.getPageStartIndex(newPage, _viewLength);
    } else {
      index += delta;
    }
    return GoogleMath.clamp(index, 0, _data.length - 1);
  }

  void _decelStart() {
    num currentTarget = scroller.verticalEnabled
        ? scroller.currentTarget.y
        : scroller.currentTarget.x;
    num current = scroller.verticalEnabled
        ? scroller.contentOffset.y
        : scroller.contentOffset.x;
    num targetIndex = _layout.getSnapIndex(currentTarget, _viewLength);
    if (current != currentTarget) {
      // The user is throwing rather than statically releasing.
      // For this case, we want to move them to the next snap interval
      // as long as they made at least a minimal throw gesture.
      num currentIndex = _layout.getSnapIndex(current, _viewLength);
      if (currentIndex == targetIndex &&
          (currentTarget - current).abs() > SNAP_TO_NEXT_THROW_THRESHOLD &&
          -_layout.getOffset(targetIndex) != currentTarget) {
        num snappedCurrentPosition = -_layout.getOffset(targetIndex);
        targetIndex = getNextIndex(targetIndex, currentTarget < current);
      }
    }
    num targetPosition = -_layout.getOffset(targetIndex);
    if (currentTarget != targetPosition) {
      if (scroller.verticalEnabled) {
        scroller.throwTo(scroller.contentOffset.x, targetPosition);
      } else {
        scroller.throwTo(targetPosition, scroller.contentOffset.y);
      }
    } else {
      // Update the target page only after we are all done animating.
      if (_pages != null) {
        _pages.target.value = _layout.getPage(targetIndex, _viewLength);
      }
    }
  }

  void _renderItems() {
    for (int i = _activeInterval.start; i < _activeInterval.end; i++) {
      _removeView(i);
    }
    _itemViews.clear();
    _activeInterval = new Interval(0, 0);
    if (scroller == null) {
      _reserveArea();
    }
    renderVisibleItems(false);
  }

  void _onPageSelected() {
    if (_pages.target != _layout.getPage(_activeInterval.start, _viewLength)) {
      _throwTo(_layout.getOffset(
          _layout.getPageStartIndex(_pages.target.value, _viewLength)));
    }
  }

  num get _offset {
    return scroller.verticalEnabled
        ? scroller.getVerticalOffset()
        : scroller.getHorizontalOffset();
  }

  /**
   * Calculates visible interval, based on the scroller position.
   */
  Interval getVisibleInterval() {
    return _layout.computeVisibleInterval(_offset, _viewLength, 0);
  }

  void renderVisibleItems(bool lengthChanged) {
    Interval targetInterval;
    if (scroller != null) {
      targetInterval = getVisibleInterval();
    } else {
      // If the view is not scrollable, render all elements.
      targetInterval = new Interval(0, _data.length);
    }

    if (_pages != null) {
      _pages.current.value = _layout.getPage(targetInterval.start, _viewLength);
    }
    if (_pages != null) {
      _pages.length.value = _data.length > 0
          ? _layout.getPage(_data.length - 1, _viewLength) + 1
          : 0;
    }

    if (!_removeClippedViews) {
      // Avoid removing clipped views by extending the target interval to
      // include the existing interval of rendered views.
      targetInterval = targetInterval.union(_activeInterval);
    }

    if (lengthChanged == false && targetInterval == _activeInterval) {
      return;
    }

    // TODO(jacobr): add unittests that this code behaves correctly.

    // Remove views that are not needed anymore
    for (int i = _activeInterval.start,
            end = Math.min(targetInterval.start, _activeInterval.end);
        i < end;
        i++) {
      _removeView(i);
    }
    for (int i = Math.max(targetInterval.end, _activeInterval.start);
        i < _activeInterval.end;
        i++) {
      _removeView(i);
    }

    // Add new views
    for (int i = targetInterval.start,
            end = Math.min(_activeInterval.start, targetInterval.end);
        i < end;
        i++) {
      _addView(i);
    }
    for (int i = Math.max(_activeInterval.end, targetInterval.start);
        i < targetInterval.end;
        i++) {
      _addView(i);
    }

    _activeInterval = targetInterval;
  }

  void _removeView(int index) {
    // Do not remove placeholder views as they need to stay present in case
    // they scroll out of view and then back into view.
    if (!(_itemViews[index] is _PlaceholderView)) {
      // Remove from the active DOM but don't destroy.
      _itemViews[index].node.remove();
      childViewRemoved(_itemViews[index]);
    }
  }

  View _newView(int index) {
    final view = _layout.newView(index);
    view.node.attributes[INDEX_DATA_ATTRIBUTE] = index.toString();
    return view;
  }

  View _addView(int index) {
    if (_itemViews.containsKey(index)) {
      final view = _itemViews[index];
      _addViewHelper(view, index);
      childViewAdded(view);
      return view;
    }

    final view = _newView(index);
    _itemViews[index] = view;
    // TODO(jacobr): its ugly to put this here... but its needed
    // as typical even-odd css queries won't work as we only display some
    // children at a time.
    if (index == 0) {
      view.addClass('first-child');
    }
    _selectHelper(view, _data[index] == _lastSelectedItem);
    // The order of the child elements doesn't matter as we use absolute
    // positioning.
    _addViewHelper(view, index);
    childViewAdded(view);
    return view;
  }

  void _addViewHelper(View view, int index) {
    _positionSubview(view.node, index);
    // The view might already be attached.
    if (view.node.parent != _containerElem) {
      _containerElem.nodes.add(view.node);
    }
  }

  /**
   * Detach a subview from the view replacing it with an empty placeholder view.
   * The detached subview can be safely reparented.
   */
  View detachSubview(D itemData) {
    int index = findIndex(itemData);
    View view = _itemViews[index];
    if (view == null) {
      // Edge case: add the view so we can detach as the view is currently
      // outside but might soon be inside the visible area.
      assert(!_activeInterval.contains(index));
      _addView(index);
      view = _itemViews[index];
    }
    final placeholder = new _PlaceholderView();
    view.node.replaceWith(placeholder.node);
    _itemViews[index] = placeholder;
    return view;
  }

  /**
   * Reattach a subview from the view that was detached from the view
   * by calling detachSubview. [callback] is called once the subview is
   * reattached and done animating into position.
   */
  void reattachSubview(D data, View view, bool animate) {
    int index = findIndex(data);
    // TODO(jacobr): perform some validation that the view is
    // really detached.
    var currentPosition;
    if (animate) {
      currentPosition =
          FxUtil.computeRelativePosition(view.node, _containerElem);
    }
    assert(_itemViews[index] is _PlaceholderView);
    view.enterDocument();
    _itemViews[index].node.replaceWith(view.node);
    _itemViews[index] = view;
    if (animate) {
      FxUtil.setTranslate(view.node, currentPosition.x, currentPosition.y, 0);
      // The view's position is unchanged except now re-parented to
      // the list view.
      Timer.run(() {
        _positionSubview(view.node, index);
      });
    } else {
      _positionSubview(view.node, index);
    }
  }

  int findIndex(D targetItem) {
    // TODO(jacobr): move this to a util library or modify this class so that
    // the data is an List not a Collection.
    int i = 0;
    for (D item in _data) {
      if (item == targetItem) {
        return i;
      }
      i++;
    }
    return null;
  }

  void _positionSubview(Element node, int index) {
    if (_vertical) {
      FxUtil.setTranslate(node, 0, _layout.getOffset(index), 0);
    } else {
      FxUtil.setTranslate(node, _layout.getOffset(index), 0, 0);
    }
    node.style.zIndex = index.toString();
  }

  void _select(int index, bool selected) {
    if (index != null) {
      final subview = getSubview(index);
      if (subview != null) {
        _selectHelper(subview, selected);
      }
    }
  }

  void _selectHelper(View view, bool selected) {
    if (selected) {
      view.addClass('sel');
    } else {
      view.removeClass('sel');
    }
  }

  View getSubview(int index) {
    return _itemViews[index];
  }

  void showView(D targetItem) {
    int index = findIndex(targetItem);
    if (index != null) {
      if (_layout.getOffset(index) < -_offset) {
        _throwTo(_layout.getOffset(index));
      } else if (_layout.getOffset(index + 1) > (-_offset + _viewLength)) {
        // TODO(jacobr): for completeness we should check whether
        // the current view is longer than _viewLength in which case
        // there are some nasty edge cases.
        _throwTo(_layout.getOffset(index + 1) - _viewLength);
      }
    }
  }

  void _throwTo(num offset) {
    if (_vertical) {
      scroller.throwTo(0, -offset);
    } else {
      scroller.throwTo(-offset, 0);
    }
  }
}

class FixedSizeListViewLayout<D> implements ListViewLayout<D> {
  final ViewFactory<D> itemViewFactory;
  final bool _vertical;
  List<D> _data;
  bool _paginate;

  FixedSizeListViewLayout(
      this.itemViewFactory, this._data, this._vertical, this._paginate);

  void onDataChange() {}

  View newView(int index) {
    return itemViewFactory.newView(_data[index]);
  }

  int get _itemLength {
    return _vertical ? itemViewFactory.height : itemViewFactory.width;
  }

  int getWidth(int viewLength) {
    return _vertical ? itemViewFactory.width : getLength(viewLength);
  }

  int getHeight(int viewLength) {
    return _vertical ? getLength(viewLength) : itemViewFactory.height;
  }

  int getEstimatedHeight(int viewLength) {
    // Returns the exact height as it is trivial to compute for this layout.
    return getHeight(viewLength);
  }

  int getEstimatedWidth(int viewLength) {
    // Returns the exact height as it is trivial to compute for this layout.
    return getWidth(viewLength);
  }

  int getEstimatedLength(int viewLength) {
    // Returns the exact length as it is trivial to compute for this layout.
    return getLength(viewLength);
  }

  int getLength(int viewLength) {
    int itemLength = _vertical ? itemViewFactory.height : itemViewFactory.width;
    if (viewLength == null || viewLength == 0) {
      return itemLength * _data.length;
    } else if (_paginate) {
      if (_data.length > 0) {
        final pageLength = getPageLength(viewLength);
        return getPage(_data.length - 1, viewLength) * pageLength +
            Math.max(viewLength, pageLength);
      } else {
        return 0;
      }
    } else {
      return itemLength * (_data.length - 1) + Math.max(viewLength, itemLength);
    }
  }

  int getOffset(int index) {
    return index * _itemLength;
  }

  int getPageLength(int viewLength) {
    final itemsPerPage = viewLength ~/ _itemLength;
    return Math.max(1, itemsPerPage) * _itemLength;
  }

  int getPage(int index, int viewLength) {
    return getOffset(index) ~/ getPageLength(viewLength);
  }

  int getPageStartIndex(int page, int viewLength) {
    return getPageLength(viewLength) ~/ _itemLength * page;
  }

  int getSnapIndex(num offset, num viewLength) {
    int index = (-offset / _itemLength).round();
    if (_paginate) {
      index = getPageStartIndex(getPage(index, viewLength), viewLength);
    }
    return GoogleMath.clamp(index, 0, _data.length - 1);
  }

  Interval computeVisibleInterval(
      num offset, num viewLength, num bufferLength) {
    int targetIntervalStart =
        Math.max(0, (-offset - bufferLength) ~/ _itemLength);
    num targetIntervalEnd = GoogleMath.clamp(
        ((-offset + viewLength + bufferLength) / _itemLength).ceil(),
        targetIntervalStart,
        _data.length);
    return new Interval(targetIntervalStart, targetIntervalEnd.toInt());
  }
}

/**
 * Simple list view class where each item has fixed width and height.
 */
class ListView<D> extends GenericListView<D> {
  /**
   * Creates a new ListView for the given data. If [:_data:] is an
   * [:ObservableList<T>:] then it will listen to changes to the list and
   * update the view appropriately.
   */
  ListView(List<D> data, ViewFactory<D> itemViewFactory, bool scrollable,
      bool vertical, ObservableValue<D> selectedItem,
      [bool snapToItems = false,
      bool paginate = false,
      bool removeClippedViews = false,
      bool showScrollbar = false,
      PageState pages = null])
      : super(
            new FixedSizeListViewLayout<D>(
                itemViewFactory, data, vertical, paginate),
            data,
            scrollable,
            vertical,
            selectedItem,
            snapToItems,
            paginate,
            removeClippedViews,
            showScrollbar,
            pages);
}

/**
 * Layout where each item may have variable size along the axis the list view
 * extends.
 */
class VariableSizeListViewLayout<D> implements ListViewLayout<D> {
  List<D> _data;
  List<int> _itemOffsets;
  List<int> _lengths;
  int _lastOffset = 0;
  bool _vertical;
  bool _paginate;
  VariableSizeViewFactory<D> itemViewFactory;
  Interval _lastVisibleInterval;

  VariableSizeListViewLayout(
      this.itemViewFactory, data, this._vertical, this._paginate)
      : _data = data,
        _lastVisibleInterval = new Interval(0, 0) {
    _itemOffsets = <int>[];
    _lengths = <int>[];
    _itemOffsets.add(0);
  }

  void onDataChange() {
    _itemOffsets.clear();
    _itemOffsets.add(0);
    _lengths.clear();
  }

  View newView(int index) => itemViewFactory.newView(_data[index]);

  int getWidth(int viewLength) {
    if (_vertical) {
      return itemViewFactory.getWidth(null);
    } else {
      return getLength(viewLength);
    }
  }

  int getHeight(int viewLength) {
    if (_vertical) {
      return getLength(viewLength);
    } else {
      return itemViewFactory.getHeight(null);
    }
  }

  int getEstimatedHeight(int viewLength) {
    if (_vertical) {
      return getEstimatedLength(viewLength);
    } else {
      return itemViewFactory.getHeight(null);
    }
  }

  int getEstimatedWidth(int viewLength) {
    if (_vertical) {
      return itemViewFactory.getWidth(null);
    } else {
      return getEstimatedLength(viewLength);
    }
  }

  // TODO(jacobr): this logic is overly complicated. Replace with something
  // simpler.
  int getEstimatedLength(int viewLength) {
    if (_lengths.length == _data.length) {
      // No need to estimate... we have all the data already.
      return getLength(viewLength);
    }
    if (_itemOffsets.length > 1 && _lengths.length > 0) {
      // Estimate length by taking the average of the lengths
      // of the known views.
      num lengthFromAllButLastElement = 0;
      if (_itemOffsets.length > 2) {
        lengthFromAllButLastElement =
            (getOffset(_itemOffsets.length - 2) - getOffset(0)) *
                (_data.length / (_itemOffsets.length - 2));
      }
      return (lengthFromAllButLastElement +
              Math.max(viewLength, _lengths[_lengths.length - 1]))
          .toInt();
    } else {
      if (_lengths.length == 1) {
        return Math.max(viewLength, _lengths[0]);
      } else {
        return viewLength;
      }
    }
  }

  int getLength(int viewLength) {
    if (_data.length == 0) {
      return viewLength;
    } else {
      // Hack so that _lengths[length - 1] is available.
      getOffset(_data.length);
      return (getOffset(_data.length - 1) - getOffset(0)) +
          Math.max(_lengths[_lengths.length - 1], viewLength);
    }
  }

  int getOffset(int index) {
    if (index >= _itemOffsets.length) {
      int offset = _itemOffsets[_itemOffsets.length - 1];
      for (int i = _itemOffsets.length; i <= index; i++) {
        int length = _vertical
            ? itemViewFactory.getHeight(_data[i - 1])
            : itemViewFactory.getWidth(_data[i - 1]);
        offset += length;
        _itemOffsets.add(offset);
        _lengths.add(length);
      }
    }
    return _itemOffsets[index];
  }

  int getPage(int index, int viewLength) {
    // TODO(jacobr): implement.
    throw 'Not implemented';
  }

  int getPageStartIndex(int page, int viewLength) {
    // TODO(jacobr): implement.
    throw 'Not implemented';
  }

  int getSnapIndex(num offset, num viewLength) {
    for (int i = 1; i < _data.length; i++) {
      if (getOffset(i) + getOffset(i - 1) > -offset * 2) {
        return i - 1;
      }
    }
    return _data.length - 1;
  }

  Interval computeVisibleInterval(
      num offset, num viewLength, num bufferLength) {
    offset = offset.toInt();
    int start = _findFirstItemBefore(-offset - bufferLength,
        _lastVisibleInterval != null ? _lastVisibleInterval.start : 0);
    int end = _findFirstItemAfter(-offset + viewLength + bufferLength,
        _lastVisibleInterval != null ? _lastVisibleInterval.end : 0);
    _lastVisibleInterval = new Interval(start, Math.max(start, end));
    _lastOffset = offset;
    return _lastVisibleInterval;
  }

  int _findFirstItemAfter(num target, int hint) {
    for (int i = 0; i < _data.length; i++) {
      if (getOffset(i) > target) {
        return i;
      }
    }
    return _data.length;
  }

  // TODO(jacobr): use hint.
  int _findFirstItemBefore(num target, int hint) {
    // We go search this direction delaying computing the actual view size
    // as long as possible.
    for (int i = 1; i < _data.length; i++) {
      if (getOffset(i) >= target) {
        return i - 1;
      }
    }
    return Math.max(_data.length - 1, 0);
  }
}

class VariableSizeListView<D> extends GenericListView<D> {
  VariableSizeListView(List<D> data, VariableSizeViewFactory<D> itemViewFactory,
      bool scrollable, bool vertical, ObservableValue<D> selectedItem,
      [bool snapToItems = false,
      bool paginate = false,
      bool removeClippedViews = false,
      bool showScrollbar = false,
      PageState pages = null])
      : super(
            new VariableSizeListViewLayout(
                itemViewFactory, data, vertical, paginate),
            data,
            scrollable,
            vertical,
            selectedItem,
            snapToItems,
            paginate,
            removeClippedViews,
            showScrollbar,
            pages);
}

/** A back button that is equivalent to clicking "back" in the browser. */
class BackButton extends View {
  BackButton() : super();

  Element render() => new Element.html('<div class="back-arrow button"></div>');

  void afterRender(Element node) {
    addOnClick((e) => window.history.back());
  }
}

// TODO(terry): Maybe should be part of ButtonView class in appstack/view?
/** OS button. */
class PushButtonView extends View {
  final String _text;
  final String _cssClass;
  final _clickHandler;

  PushButtonView(this._text, this._cssClass, this._clickHandler) : super();

  Element render() {
    return new Element.html('<button class="${_cssClass}">${_text}</button>');
  }

  void afterRender(Element node) {
    addOnClick(_clickHandler);
  }
}

// TODO(terry): Add a drop shadow around edge and corners need to be rounded.
//              Need to support conveyor for contents of dialog so it's not
//              larger than the parent window.
/** A generic dialog view supports title, done button and dialog content. */
class DialogView extends View {
  final String _title;
  final String _cssName;
  final View _content;
  Element container;
  PushButtonView _done;

  DialogView(this._title, this._cssName, this._content) : super() {}

  Element render() {
    final node = new Element.html('''
      <div class="dialog-modal">
        <div class="dialog $_cssName">
          <div class="dialog-title-area">
            <span class="dialog-title">$_title</span>
          </div>
          <div class="dialog-body"></div>
        </div>
      </div>''');

    _done = new PushButtonView(
        'Done', 'done-button', EventBatch.wrap((e) => onDone()));
    final titleArea = node.querySelector('.dialog-title-area');
    titleArea.nodes.add(_done.node);

    container = node.querySelector('.dialog-body');
    container.nodes.add(_content.node);

    return node;
  }

  /** Override to handle dialog done. */
  void onDone() {}
}
