// 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.

// @dart = 2.9

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();

  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)
      : _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();

  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);

  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);

  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() {}
}
