// 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 layout;

/**
 * Implements a grid-based layout system based on:
 * [http://dev.w3.org/csswg/css3-grid-align/]
 *
 * This layout is designed to support animations and work on browsers that
 * don't support grid natively. As such, we implement it on top of absolute
 * positioning.
 */
// TODO(jmesserly): the DOM integration still needs work:
//  - The grid assumes it is absolutely positioned in its container.
//    Because of that, the grid doesn't work right unless it has at least one
//    fractional size in each dimension. In other words, only "top down" grids
//    work at the moment, because the grid can't determine its own size.
//    The core algorithm supports computing min breadth; the issue is about how
//    to integrate it into our View layer.
//  - Unless a child element is "display: inline-block" we can't get its
//    horizontal content size.
//  - Once we set an element's size to "position: absolute", we lose the
//    ability to get its original content size. If the width or height gets
//    set to something other than the content size, we can't recover the
//    original content size.
//  - There's some rounding to ints when we want to set the positions of our
//    tracks. I don't think we necessarily need to do that.
//
// TODO(jmesserly): Some features of the spec are unimplemented:
//  - grid-flow & items that have row and column set to 'auto'.
//  - Grid writing modes (right to left languages, etc)
//  - We don't do a second calculation pass if min content size of a grid-item
//    changes due to column width.
//  - The CSS parsing is not 100% complete, see the parser TODOs.
//  - We don't implement error recovery for invalid combinations of CSS
//    properties, or invalid CSS property values. Instead we throw an error.
//
// TODO(jmesserly): high level performance optimizations we could do:
//  - Optimize for the common case of spanCount = 1
//  - Optimize for the vbox/hbox case (1 row or 1 column)
//  - Optimize for the case of no content sized tracks
//  - Optimize for the "incremental update" cases
class GridLayout extends ViewLayout {
  /** Configuration parameters defined in CSS. */
  final GridTrackList rows;
  final GridTrackList columns;
  final GridTemplate template;

  /** The default sizing for new rows. */
  final TrackSizing rowSizing;

  /** The default sizing for new columns. */
  final TrackSizing columnSizing;

  /**
   * This stores the grid's size during a layout.
   * Used for rows/columns with % or fr units.
   */
  int _gridWidth, _gridHeight;

  /**
   * During a layout, this stores all row/column size information.
   * Because grid-items can implicitly specify their own rows/columns, we can't
   * compute this until we know the set of items.
   */
  List<GridTrack> _rowTracks, _columnTracks;

  /** During a layout, tracks which dimension we're processing. */
  Dimension _dimension;

  GridLayout(Positionable view)
      : rows = _GridTrackParser.parse(view.customStyle['grid-rows']),
        columns = _GridTrackParser.parse(view.customStyle['grid-columns']),
        template = _GridTemplateParser.parse(view.customStyle['grid-template']),
        rowSizing = _GridTrackParser
            .parseTrackSizing(view.customStyle['grid-row-sizing']),
        columnSizing = _GridTrackParser
            .parseTrackSizing(view.customStyle['grid-column-sizing']),
        super(view) {
    _rowTracks = rows != null ? rows.tracks : new List<GridTrack>();
    _columnTracks = columns != null ? columns.tracks : new List<GridTrack>();
  }

  int get currentWidth => _gridWidth;
  int get currentHeight => _gridHeight;

  void cacheExistingBrowserLayout() {
    // We don't need to do anything as we don't rely on the _cachedViewRect
    // when the grid layout is used.
  }

  // TODO(jacobr): cleanup this method so that it returns a Future
  // rather than taking a Completer as an argument.
  /** The main entry point for layout computation. */
  void measureLayout(Future<Size> size, Completer<bool> changed) {
    _ensureAllTracks();
    size.then((value) {
      _gridWidth = value.width;
      _gridHeight = value.height;

      if (_rowTracks.length > 0 && _columnTracks.length > 0) {
        _measureTracks();
        _setBoundsOfChildren();
        if (changed != null) {
          changed.complete(true);
        }
      }
    });
  }

  /**
   * The top level measurement function.
   * [http://dev.w3.org/csswg/css3-grid-align/#calculating-size-of-grid-tracks]
   */
  void _measureTracks() {
    // Resolve logical width, then height. Width comes first so we can use
    // the width when determining the content-sized height.
    try {
      _dimension = Dimension.WIDTH;
      _computeUsedBreadthOfTracks(_columnTracks);
      _dimension = Dimension.HEIGHT;
      _computeUsedBreadthOfTracks(_rowTracks);
    } finally {
      _dimension = null;
    }

    // TODO(jmesserly): we're supposed to detect a min-content size change
    // due to our computed width and trigger a new layout.
    // How do we implement that?
  }

  num _getRemainingSpace(List<GridTrack> tracks) {
    num remaining = _getGridContentSize();
    remaining -= CollectionUtils.sum(tracks, (t) => t.usedBreadth);
    return Math.max(0, remaining);
  }

  /**
   * This is the core Grid Track sizing algorithm. It is run for Grid columns
   * and Grid rows. The goal of the function is to ensure:
   *   1. That each Grid Track satisfies its minSizing
   *   2. That each Grid Track grows from the breadth which satisfied its
   *      minSizing to a breadth which satifies its
   *      maxSizing, subject to RemainingSpace.
   */
  // Note: spec does not correctly doc all the parameters to this function.
  void _computeUsedBreadthOfTracks(List<GridTrack> tracks) {
    // TODO(jmesserly): as a performance optimization we could cache this
    final items = view.childViews.map((view_) => view_.layout).toList();
    CollectionUtils.sortBy(items, (item) => _getSpanCount(item));

    // 1. Initialize per Grid Track variables
    for (final t in tracks) {
      // percentage or length sizing functions will return a value
      // min-content, max-content, or a fraction will be set to 0
      t.usedBreadth = t.minSizing.resolveLength(_getGridContentSize());
      t.maxBreadth = t.maxSizing.resolveLength(_getGridContentSize());
      t.updatedBreadth = 0;
    }

    // 2. Resolve content-based MinTrackSizingFunctions
    final USED_BREADTH = const _UsedBreadthAccumulator();
    final MAX_BREADTH = const _MaxBreadthAccumulator();

    _distributeSpaceBySpanCount(items, ContentSizeMode.MIN, USED_BREADTH);

    _distributeSpaceBySpanCount(items, ContentSizeMode.MAX, USED_BREADTH);

    // 3. Ensure that maxBreadth is as big as usedBreadth for each track
    for (final t in tracks) {
      if (t.maxBreadth < t.usedBreadth) {
        t.maxBreadth = t.usedBreadth;
      }
    }

    // 4. Resolve content-based MaxTrackSizingFunctions
    _distributeSpaceBySpanCount(items, ContentSizeMode.MIN, MAX_BREADTH);

    _distributeSpaceBySpanCount(items, ContentSizeMode.MAX, MAX_BREADTH);

    // 5. Grow all Grid Tracks in GridTracks from their usedBreadth up to their
    //    maxBreadth value until RemainingSpace is exhausted.
    // Note: it's not spec'd what to pass as the accumulator, but usedBreadth
    // seems right.
    _distributeSpaceToTracks(
        tracks, _getRemainingSpace(tracks), USED_BREADTH, false);

    // Spec wording is confusing about which direction this assignment happens,
    // but this is the way that makes sense.
    for (final t in tracks) {
      t.usedBreadth = t.updatedBreadth;
    }

    // 6. Grow all Grid Tracks having a fraction as their maxSizing
    final tempBreadth = _calcNormalizedFractionBreadth(tracks);
    for (final t in tracks) {
      t.usedBreadth =
          Math.max(t.usedBreadth, tempBreadth * t.maxSizing.fractionValue);
    }

    _computeTrackPositions(tracks);
  }

  /**
   * Final steps to finish positioning tracks. Takes the track size and uses
   * it to get start and end positions. Also rounds the positions to integers.
   */
  void _computeTrackPositions(List<GridTrack> tracks) {
    // Compute start positions of tracks, as well as the final position

    num position = 0;
    for (final t in tracks) {
      t.start = position;
      position += t.usedBreadth;
    }

    // Now, go through and round each position to an integer. Then
    // compute the sizes based on those integers.
    num finalPosition = position;

    for (int i = 0; i < tracks.length; i++) {
      int startEdge = tracks[i].start;
      int endEdge;
      if (i < tracks.length - 1) {
        endEdge = tracks[i + 1].start.round();
        tracks[i + 1].start = endEdge;
      } else {
        endEdge = finalPosition.round();
      }
      int breadth = endEdge - startEdge;

      // check that we're not off by >= 1px.
      assert((endEdge - startEdge - tracks[i].usedBreadth).abs() < 1);

      tracks[i].usedBreadth = breadth;
    }
  }

  /**
   * This method computes a '1fr' value, referred to as the
   * tempBreadth, for a set of Grid Tracks. The value computed
   * will ensure that when the tempBreadth is multiplied by the
   * fractions associated with tracks, that the UsedBreadths of tracks
   * will increase by an amount equal to the maximum of zero and the specified
   * freeSpace less the sum of the current UsedBreadths.
   */
  num _calcNormalizedFractionBreadth(List<GridTrack> tracks) {
    final fractionTracks = tracks.where((t) => t.maxSizing.isFraction).toList();

    // Note: the spec has various bugs in this function, such as mismatched
    // identifiers and names that aren't defined. For the most part it's
    // possible to figure out the meaning. It's also a bit confused about
    // how to compute spaceNeededFromFractionTracks, but that should just be the
    // set to the remaining free space after usedBreadth is accounted for.

    // We use the tempBreadth field to store the normalized fraction breadth
    for (final t in fractionTracks) {
      t.tempBreadth = t.usedBreadth / t.maxSizing.fractionValue;
    }

    CollectionUtils.sortBy(fractionTracks, (t) => t.tempBreadth);

    num spaceNeededFromFractionTracks = _getRemainingSpace(tracks);
    num currentBandFractionBreadth = 0;
    num accumulatedFractions = 0;
    for (final t in fractionTracks) {
      if (t.tempBreadth != currentBandFractionBreadth) {
        if (t.tempBreadth * accumulatedFractions >
            spaceNeededFromFractionTracks) {
          break;
        }
        currentBandFractionBreadth = t.tempBreadth;
      }
      accumulatedFractions += t.maxSizing.fractionValue;
      spaceNeededFromFractionTracks += t.usedBreadth;
    }
    return spaceNeededFromFractionTracks / accumulatedFractions;
  }

  /**
   * Ensures that for each Grid Track in tracks, a value will be
   * computed, updatedBreadth, that represents the Grid Track's share of
   * freeSpace.
   */
  void _distributeSpaceToTracks(List<GridTrack> tracks, num freeSpace,
      _BreadthAccumulator breadth, bool ignoreMaxBreadth) {
    // TODO(jmesserly): in some cases it would be safe to sort the passed in
    // list in place. Not always though.
    tracks = CollectionUtils.orderBy(
        tracks, (t) => t.maxBreadth - breadth.getSize(t));

    // Give each Grid Track an equal share of the space, but without exceeding
    // their maxBreadth values. Because there are different MaxBreadths
    // assigned to the different Grid Tracks, this can result in uneven growth.
    for (int i = 0; i < tracks.length; i++) {
      num share = freeSpace / (tracks.length - i);
      share = Math.min(share, tracks[i].maxBreadth);
      tracks[i].tempBreadth = share;
      freeSpace -= share;
    }

    // If the first loop completed having grown every Grid Track to its
    // maxBreadth, and there is still freeSpace, then divide that space
    // evenly and assign it to each Grid Track without regard for its
    // maxBreadth. This phase of growth will always be even, but only occurs
    // when the ignoreMaxBreadth flag is true.
    if (freeSpace > 0 && ignoreMaxBreadth) {
      for (int i = 0; i < tracks.length; i++) {
        final share = freeSpace / (tracks.length - i);
        tracks[i].tempBreadth += share;
        freeSpace -= share;
      }
    }

    // Note: the spec has us updating all grid tracks, not just the passed in
    // tracks, but I think that's a spec bug.
    for (final t in tracks) {
      t.updatedBreadth = Math.max(t.updatedBreadth, t.tempBreadth);
    }
  }

  /**
   * This function prioritizes the distribution of space driven by Grid Items
   * in content-sized Grid Tracks by the Grid Item's spanCount. That is, Grid
   * Items having a lower spanCount have an opportunity to increase the size of
   * the Grid Tracks they cover before those with larger SpanCounts.
   *
   * Note: items are assumed to be already sorted in increasing span count
   */
  void _distributeSpaceBySpanCount(List<ViewLayout> items,
      ContentSizeMode sizeMode, _BreadthAccumulator breadth) {
    items = items
        .where((item) =>
            _hasContentSizedTracks(_getTracks(item), sizeMode, breadth))
        .toList();

    var tracks = [];

    for (int i = 0; i < items.length; i++) {
      final item = items[i];

      final itemTargetSize = item.measureContent(this, _dimension, sizeMode);

      final spannedTracks = _getTracks(item);
      _distributeSpaceToTracks(spannedTracks, itemTargetSize, breadth, true);

      // Remember that we need to update the sizes on these tracks
      tracks.addAll(spannedTracks);

      // Each time we transition to a new spanCount, update any modified tracks
      bool spanCountFinished = false;
      if (i + 1 == items.length) {
        spanCountFinished = true;
      } else if (_getSpanCount(item) != _getSpanCount(items[i + 1])) {
        spanCountFinished = true;
      }

      if (spanCountFinished) {
        for (final t in tracks) {
          breadth.setSize(t, Math.max(breadth.getSize(t), t.updatedBreadth));
        }
        tracks = [];
      }
    }
  }

  /**
   * Returns true if we have an appropriate content sized dimension, and don't
   * cross a fractional track.
   */
  static bool _hasContentSizedTracks(Iterable<GridTrack> tracks,
      ContentSizeMode sizeMode, _BreadthAccumulator breadth) {
    for (final t in tracks) {
      final fn = breadth.getSizingFunction(t);
      if (sizeMode == ContentSizeMode.MAX && fn.isMaxContentSized ||
          sizeMode == ContentSizeMode.MIN && fn.isContentSized) {
        // Make sure we don't cross a fractional track
        return tracks.length == 1 || !tracks.any((t_) => t_.isFractional);
      }
    }
    return false;
  }

  /** Ensures that the numbered track exists. */
  void _ensureTrack(
      List<GridTrack> tracks, TrackSizing sizing, int start, int span) {
    // Start is 1-based. Make it 0-based.
    start -= 1;

    // Grow the list if needed
    int length = start + span;
    int first = Math.min(start, tracks.length);
    tracks.length = Math.max(tracks.length, length);

    // Fill in tracks
    for (int i = first; i < length; i++) {
      if (tracks[i] == null) {
        tracks[i] = new GridTrack(sizing);
      }
    }
  }

  /**
   * Scans children creating GridLayoutParams as needed, and creates all of the
   * rows and columns that we will need.
   *
   * Note: this can potentially create new rows/columns, so this needs to be
   * run before the track sizing algorithm.
   */
  void _ensureAllTracks() {
    final items = view.childViews.map((view_) => view_.layout);

    for (final child in items) {
      if (child.layoutParams == null) {
        final p = new GridLayoutParams(child.view, this);
        _ensureTrack(_rowTracks, rowSizing, p.row, p.rowSpan);
        _ensureTrack(_columnTracks, columnSizing, p.column, p.columnSpan);
        child.layoutParams = p;
      }
      child.cacheExistingBrowserLayout();
    }
  }

  /**
   * Given the track sizes that were computed, position children in the grid.
   */
  void _setBoundsOfChildren() {
    final items = view.childViews.map((view_) => view_.layout);

    for (final item in items) {
      GridLayoutParams childLayout = item.layoutParams;
      var xPos = _getTrackLocationX(childLayout);
      var yPos = _getTrackLocationY(childLayout);

      int left = xPos.start, width = xPos.length;
      int top = yPos.start, height = yPos.length;

      // Somewhat counterintuitively (at least to me):
      //   grid-col-align is the horizontal alignment
      //   grid-row-align is the vertical alignment
      xPos = childLayout.columnAlign.align(xPos, item.currentWidth);
      yPos = childLayout.rowAlign.align(yPos, item.currentHeight);

      item.setBounds(xPos.start, yPos.start, xPos.length, yPos.length);
    }
  }

  num _getGridContentSize() {
    if (_dimension == Dimension.WIDTH) {
      return _gridWidth;
    } else if (_dimension == Dimension.HEIGHT) {
      return _gridHeight;
    }
  }

  _GridLocation _getTrackLocationX(GridLayoutParams childLayout) {
    int start = childLayout.column - 1;
    int end = start + childLayout.columnSpan - 1;

    start = _columnTracks[start].start;
    end = _columnTracks[end].end;

    return new _GridLocation(start, end - start);
  }

  _GridLocation _getTrackLocationY(GridLayoutParams childLayout) {
    int start = childLayout.row - 1;
    int end = start + childLayout.rowSpan - 1;

    start = _rowTracks[start].start;
    end = _rowTracks[end].end;

    return new _GridLocation(start, end - start);
  }

  /** Gets the tracks that this item crosses. */
  // TODO(jmesserly): might be better to return an iterable
  List<GridTrack> _getTracks(ViewLayout item) {
    GridLayoutParams childLayout = item.layoutParams;

    int start, span;
    List<GridTrack> tracks;
    if (_dimension == Dimension.WIDTH) {
      start = childLayout.column - 1;
      span = childLayout.columnSpan;
      tracks = _columnTracks;
    } else if (_dimension == Dimension.HEIGHT) {
      start = childLayout.row - 1;
      span = childLayout.rowSpan;
      tracks = _rowTracks;
    }

    assert(start >= 0 && span >= 1);

    final result = new List<GridTrack>(span);
    for (int i = 0; i < span; i++) {
      result[i] = tracks[start + i];
    }
    return result;
  }

  int _getSpanCount(ViewLayout item) {
    GridLayoutParams childLayout = item.layoutParams;
    return (_dimension == Dimension.WIDTH
        ? childLayout.columnSpan
        : childLayout.rowSpan);
  }
}
