// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_NG_GRID_LAYOUT_ALGORITHM_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_NG_GRID_LAYOUT_ALGORITHM_H_

#include "third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_algorithm.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"

namespace blink {

class NGGridPlacement;

class CORE_EXPORT NGGridLayoutAlgorithm
    : public NGLayoutAlgorithm<NGBlockNode,
                               NGBoxFragmentBuilder,
                               NGBlockBreakToken> {
 public:
  enum class AutoPlacementType { kNotNeeded, kMajor, kMinor, kBoth };
  enum class AxisEdge { kStart, kCenter, kEnd, kBaseline };
  enum class ItemType { kInGridFlow, kOutOfFlow };

  // This enum corresponds to each step used to accommodate grid items across
  // intrinsic tracks according to their min and max track sizing functions, as
  // defined in https://drafts.csswg.org/css-grid-2/#algo-spanning-items.
  enum class GridItemContributionType {
    kForIntrinsicMinimums,
    kForContentBasedMinimums,
    kForMaxContentMinimums,
    kForIntrinsicMaximums,
    kForMaxContentMaximums,
    kForFreeSpace
  };

  struct ItemSetIndices {
    wtf_size_t begin = kNotFound;
    wtf_size_t end = kNotFound;
  };

  struct CORE_EXPORT GridItemData {
    explicit GridItemData(const NGBlockNode node) : node(node) {}

    AutoPlacementType AutoPlacement(
        GridTrackSizingDirection flow_direction) const;
    const GridSpan& Span(GridTrackSizingDirection track_direction) const;
    void SetSpan(const GridSpan& span,
                 GridTrackSizingDirection track_direction);

    wtf_size_t StartLine(GridTrackSizingDirection track_direction) const;
    wtf_size_t EndLine(GridTrackSizingDirection track_direction) const;
    wtf_size_t SpanSize(GridTrackSizingDirection track_direction) const;

    const TrackSpanProperties& GetTrackSpanProperties(
        GridTrackSizingDirection track_direction) const;
    void SetTrackSpanProperty(TrackSpanProperties::PropertyId property,
                              GridTrackSizingDirection track_direction);

    bool IsSpanningFlexibleTrack(
        GridTrackSizingDirection track_direction) const;
    bool IsSpanningIntrinsicTrack(
        GridTrackSizingDirection track_direction) const;

    // For this item and track direction, computes and stores the pair of
    // indices "begin" and "end" such that the item spans every set from the
    // respective collection's |sets_| with an index in the range [begin, end).
    // |grid_placement| is used to resolve the grid lines of out of flow items
    // and it has a default nullptr value for grid items.
    ItemSetIndices SetIndices(
        const NGGridLayoutAlgorithmTrackCollection& track_collection,
        const NGGridPlacement* grid_placement = nullptr);

    const NGBlockNode node;
    GridArea resolved_position;

    NGBoxStrut margins;

    AxisEdge inline_axis_alignment;
    AxisEdge block_axis_alignment;

    ItemType item_type;

    bool is_inline_axis_stretched;
    bool is_block_axis_stretched;

    TrackSpanProperties column_span_properties;
    TrackSpanProperties row_span_properties;

    // These fields are used to determine the sets this item spans in the
    // respective track collection; see |SetIndices|. We use optional since some
    // scenarios don't require to compute the indices at all.
    base::Optional<ItemSetIndices> column_set_indices;
    base::Optional<ItemSetIndices> row_set_indices;
  };

  struct CORE_EXPORT GridItems {
    class Iterator
        : public std::iterator<std::input_iterator_tag, GridItemData> {
     public:
      Iterator(Vector<GridItemData>* item_data,
               Vector<wtf_size_t>::const_iterator current_index)
          : item_data_(item_data), current_index_(current_index) {
        DCHECK(item_data_);
      }

      bool operator!=(const Iterator& other) const {
        return current_index_ != other.current_index_ ||
               item_data_ != other.item_data_;
      }

      Iterator& operator++() {
        ++current_index_;
        return *this;
      }

      GridItemData* operator->() {
        DCHECK(current_index_ && *current_index_ < item_data_->size());
        return &(item_data_->at(*current_index_));
      }

      GridItemData& operator*() {
        DCHECK(current_index_ && *current_index_ < item_data_->size());
        return item_data_->at(*current_index_);
      }

     private:
      Vector<GridItemData>* item_data_;
      Vector<wtf_size_t>::const_iterator current_index_;
    };

    Iterator begin();
    Iterator end();

    void Append(const GridItemData& new_item_data);

    bool IsEmpty() const;

    // Grid items are appended to |item_data_| in the same order provided by
    // |NGGridChildIterator|, which iterates over its children in order-modified
    // document order; we want to keep such order since auto-placement and
    // painting order rely on it later in the algorithm.
    Vector<GridItemData> item_data;
    Vector<wtf_size_t> reordered_item_indices;
  };

  // See |SetGeometry|.
  struct SetOffsetData {
    SetOffsetData(LayoutUnit offset, wtf_size_t last_indefinite_index)
        : offset(offset), last_indefinite_index(last_indefinite_index) {}
    LayoutUnit offset;
    wtf_size_t last_indefinite_index;
  };

  // Represents the offsets for the sets, and the gutter-size.
  //
  // Initially we only know some of the set sizes - others will be indefinite.
  // To represent this we store both the offset for the set, and the last index
  // where there was an indefinite set (or kNotFound if everything so far has
  // been definite). This allows us to get the appropriate size if a grid item
  // spans only fixed tracks, but will allow us to return an indefinite size if
  // it spans any indefinite set.
  //
  // As an example:
  //   grid-template-rows: auto auto 100px 100px auto 100px;
  //
  // Results in:
  //                  |  auto |  auto |   100   |   100   |   auto  |   100   |
  //   [{0, kNotFound}, {0, 0}, {0, 1}, {100, 1}, {200, 1}, {200, 4}, {300, 4}]
  //
  // Various queries (start/end refer to the grid lines):
  //  start: 0, end: 1 -> indefinite as:
  //    "start <= sets[end].last_indefinite_index"
  //  start: 1, end: 3 -> indefinite as:
  //    "start <= sets[end].last_indefinite_index"
  //  start: 2, end: 4 -> 200px
  //  start: 5, end: 6 -> 100px
  //  start: 3, end: 5 -> indefinite as:
  //    "start <= sets[end].last_indefinite_index"
  struct SetGeometry {
    Vector<SetOffsetData> sets;
    LayoutUnit gutter_size;
  };

  // Typically we pass around both the column, and row geometry together.
  struct GridGeometry {
    SetGeometry column_geometry;
    SetGeometry row_geometry;
  };

  explicit NGGridLayoutAlgorithm(const NGLayoutAlgorithmParams& params);

  scoped_refptr<const NGLayoutResult> Layout() override;
  MinMaxSizesResult ComputeMinMaxSizes(const MinMaxSizesInput&) const override;

 private:
  friend class NGGridLayoutAlgorithmTest;

  enum class SizingConstraint { kLayout, kMinContent, kMaxContent };

  // Returns the size that a grid item will distribute across the tracks with an
  // intrinsic sizing function it spans in the relevant track direction.
  LayoutUnit ContributionSizeForGridItem(
      const GridGeometry& grid_geometry,
      const GridItemData& grid_item,
      GridTrackSizingDirection track_direction,
      GridItemContributionType contribution_type) const;

  wtf_size_t ComputeAutomaticRepetitions(
      GridTrackSizingDirection track_direction) const;

  void ConstructAndAppendGridItems(
      GridItems* grid_items,
      Vector<GridItemData>* out_of_flow_items = nullptr) const;
  GridItemData MeasureGridItem(const NGBlockNode node) const;

  void BuildBlockTrackCollections(
      GridItems* grid_items,
      NGGridBlockTrackCollection* column_track_collection,
      NGGridBlockTrackCollection* row_track_collection,
      NGGridPlacement* grid_placement) const;

  void BuildAlgorithmTrackCollections(
      GridItems* grid_items,
      NGGridLayoutAlgorithmTrackCollection* column_track_collection,
      NGGridLayoutAlgorithmTrackCollection* row_track_collection,
      NGGridPlacement* grid_placement) const;

  // Ensure coverage in block collection after grid items have been placed.
  void EnsureTrackCoverageForGridItems(
      const GridItems& grid_items,
      NGGridBlockTrackCollection* track_collection) const;

  // For every grid item, caches properties of the track sizing functions it
  // spans (i.e. whether an item spans intrinsic or flexible tracks).
  void CacheGridItemsTrackSpanProperties(
      const NGGridLayoutAlgorithmTrackCollection& track_collection,
      GridItems* grid_items) const;

  // Initializes the given track collection, and returns the base set geometry.
  SetGeometry InitializeTrackSizes(
      NGGridLayoutAlgorithmTrackCollection* track_collection) const;

  // Calculates from the min and max track sizing functions the used track size.
  void ComputeUsedTrackSizes(
      SizingConstraint sizing_constraint,
      const GridGeometry& grid_geometry,
      NGGridLayoutAlgorithmTrackCollection* track_collection,
      GridItems* grid_items) const;

  // These methods implement the steps of the algorithm for intrinsic track size
  // resolution defined in https://drafts.csswg.org/css-grid-2/#algo-content.
  void ResolveIntrinsicTrackSizes(
      const GridGeometry& grid_geometry,
      NGGridLayoutAlgorithmTrackCollection* track_collection,
      GridItems* grid_items) const;

  void IncreaseTrackSizesToAccommodateGridItems(
      const GridGeometry& grid_geometry,
      GridItems::Iterator group_begin,
      GridItems::Iterator group_end,
      const bool is_group_spanning_flex_track,
      GridItemContributionType contribution_type,
      NGGridLayoutAlgorithmTrackCollection* track_collection) const;

  void MaximizeTracks(
      SizingConstraint sizing_constraint,
      NGGridLayoutAlgorithmTrackCollection* track_collection) const;

  void StretchAutoTracks(
      SizingConstraint sizing_constraint,
      NGGridLayoutAlgorithmTrackCollection* track_collection) const;

  SetGeometry ComputeSetGeometry(
      const NGGridLayoutAlgorithmTrackCollection& track_collection,
      const LayoutUnit available_size) const;

  // Gets the row or column gap of the grid.
  LayoutUnit GridGap(GridTrackSizingDirection track_direction,
                     LayoutUnit available_size = kIndefiniteSize) const;

  LayoutUnit DetermineFreeSpace(
      SizingConstraint sizing_constraint,
      const NGGridLayoutAlgorithmTrackCollection& track_collection) const;

  const NGConstraintSpace CreateConstraintSpace(
      const GridGeometry& grid_geometry,
      const GridItemData& grid_item,
      NGCacheSlot cache_slot,
      LogicalRect* rect) const;

  // Layout the |grid_items| based on the offsets provided.
  void PlaceGridItems(const GridItems& grid_items,
                      const GridGeometry& grid_geometry,
                      LayoutUnit block_size);

  // Computes the static position, grid area and its offset of out of flow
  // elements in the grid.
  void PlaceOutOfFlowItems(const Vector<GridItemData>& out_of_flow_items,
                           const GridGeometry& grid_geometry,
                           LayoutUnit block_size);

  // Gets the out of flow descendants from the container builder and computes
  // their containing block rect.
  void PlaceOutOfFlowDescendants(
      const NGGridLayoutAlgorithmTrackCollection& column_track_collection,
      const NGGridLayoutAlgorithmTrackCollection& row_track_collection,
      const GridGeometry& grid_geometry,
      const NGGridPlacement& grid_placement,
      LayoutUnit block_size);

  // Helper method to compute the containing grid area for grid items or the
  // containing block rect for out of flow elements.
  LogicalRect ComputeContainingGridAreaRect(const GridGeometry& grid_geometry,
                                            const GridItemData& item,
                                            LayoutUnit block_size);

  // Helper method that computes the offset and size of an item.
  void ComputeOffsetAndSize(const GridItemData& item,
                            const SetGeometry& set_geometry,
                            const GridTrackSizingDirection track_direction,
                            LayoutUnit block_size,
                            LayoutUnit* start_offset,
                            LayoutUnit* size) const;

  // Determines the position of the out of flow item's container.
  void DeterminePositionOfOutOfFlowContainer(
      Vector<GridItemData>* out_of_flow_items,
      const GridTrackSizingDirection track_direction) const;

  GridTrackSizingDirection AutoFlowDirection() const;

  LogicalSize border_box_size_;

  LogicalSize grid_available_size_;
  LogicalSize grid_min_available_size_;
  LogicalSize grid_max_available_size_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GRID_NG_GRID_LAYOUT_ALGORITHM_H_
