// 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 = [];
  }

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

  @override
  Element render() => 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, int viewLength);

  /// Returns an interval specifying what views are currently visible given a
  /// particular [:offset:].
  Interval<int> 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;
  final List<D> _data;
  final ObservableValue<D?>? _selectedItem;
  final Map<int, View> _itemViews;
  late Element _containerElem;
  final bool _vertical;

  /// Length of the scrollable dimension of the view in px. */
  int _viewLength = 0;
  Interval<int> _activeInterval;
  final bool _paginate;
  final bool _removeClippedViews;
  final ListViewLayout<D> _layout;
  D? _lastSelectedItem;
  final 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 = Interval(0, 0),
        _itemViews = <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;
  }

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

  void _onClick(MouseEvent e) {
    int? index = _findAssociatedIndex(e.target as Node?);
    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 as Element);
      }
      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.isNotEmpty) {
      return int.parse(index);
    }
    return null;
  }

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

    if (_scrollable) {
      scroller = Scroller(
          _containerElem,
          _vertical /* verticalScrollEnabled */,
          !_vertical /* horizontalScrollEnabled */,
          true /* momentumEnabled */, () {
        num? width = _layout.getWidth(_viewLength);
        num? height = _layout.getHeight(_viewLength);
        width = width ?? 0;
        height = height ?? 0;
        return 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 = Scrollbar(scroller!, true);
      }
    } else {
      _reserveArea();
      renderVisibleItems(true);
    }

    return node;
  }

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

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

    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) as int;
      if (_viewLength != lastViewLength) {
        if (_scrollbar != null) {
          _scrollbar!.refresh();
        }
        renderVisibleItems(true);
      }
    });
  }

  @override
  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() {
    final scroll = scroller!;
    num currentTarget = scroll.verticalEnabled
        ? scroll.currentTarget.y
        : scroll.currentTarget.x;
    num current = scroll.verticalEnabled
        ? scroll.contentOffset.y
        : scroll.contentOffset.x;
    int 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 (scroll.verticalEnabled) {
        scroll.throwTo(scroll.contentOffset.x, targetPosition);
      } else {
        scroll.throwTo(targetPosition, scroll.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 = 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<int> getVisibleInterval() {
    return _layout.computeVisibleInterval(_offset, _viewLength, 0);
  }

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

    if (_pages != null) {
      _pages!.current.value =
          _layout.getPage(targetInterval.start, _viewLength);
    }
    if (_pages != null) {
      _pages!.length.value = _data.isNotEmpty
          ? _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.
    final nodeView = _itemViews[index]!;
    if (nodeView is! _PlaceholderView) {
      // Remove from the active DOM but don't destroy.
      nodeView.node.remove();
      childViewRemoved(nodeView);
    }
  }

  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 = _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.
    late Coordinate 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;
  final List<D> _data;
  final bool _paginate;

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

  @override
  void onDataChange() {}

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

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

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

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

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

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

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

  @override
  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.isNotEmpty) {
        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);
    }
  }

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

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

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

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

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

  @override
  Interval<int> 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 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])
      : super(
            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> {
  final List<D> _data;
  List<int> _itemOffsets;
  List<int> _lengths;
  int _lastOffset = 0;
  final bool _vertical;
  final bool _paginate;
  VariableSizeViewFactory<D> itemViewFactory;
  Interval<int> _lastVisibleInterval;

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

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

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

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

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

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

  @override
  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.
  @override
  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.isNotEmpty) {
      // 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;
      }
    }
  }

  @override
  int getLength(int viewLength) {
    if (_data.isEmpty) {
      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);
    }
  }

  @override
  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];
  }

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

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

  @override
  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;
  }

  @override
  Interval<int> computeVisibleInterval(
      num offset, num viewLength, num bufferLength) {
    final offsetInt = offset.toInt();
    int start = _findFirstItemBefore(-offsetInt - bufferLength,
        _lastVisibleInterval != null ? _lastVisibleInterval.start : 0);
    int end = _findFirstItemAfter(-offsetInt + viewLength + bufferLength,
        _lastVisibleInterval != null ? _lastVisibleInterval.end : 0);
    _lastVisibleInterval = Interval(start, Math.max(start, end));
    _lastOffset = offsetInt;
    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])
      : super(
            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();

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

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

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

  @override
  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;
  late Element container;
  late PushButtonView _done;

  DialogView(this._title, this._cssName, this._content);

  @override
  Element render() {
    final node = 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 =
        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() {}
}
