/*
 * Copyright (C) 1997 Martin Jones (mjones@kde.org)
 *           (C) 1997 Torben Weis (weis@kde.org)
 *           (C) 1998 Waldo Bastian (bastian@kde.org)
 *           (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 * Copyright (C) 2003, 2004, 2005, 2006, 2009, 2013 Apple Inc. All rights
 * reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifndef LayoutTableSection_h
#define LayoutTableSection_h

#include "base/macros.h"
#include "core/CoreExport.h"
#include "core/layout/LayoutTable.h"
#include "core/layout/LayoutTableBoxComponent.h"
#include "core/layout/TableGridCell.h"
#include "platform/wtf/Vector.h"

namespace blink {

// Helper class for paintObject.
class CellSpan {
  STACK_ALLOCATED();

 public:
  CellSpan() : start_(0), end_(0) {}
  CellSpan(unsigned start, unsigned end) : start_(start), end_(end) {}

  unsigned Start() const { return start_; }
  unsigned End() const { return end_; }

  void DecreaseStart() { --start_; }
  void IncreaseEnd() { ++end_; }

  void EnsureConsistency(const unsigned);

 private:
  unsigned start_;
  unsigned end_;
};

inline bool operator==(const CellSpan& s1, const CellSpan& s2) {
  return s1.Start() == s2.Start() && s1.End() == s2.End();
}
inline bool operator!=(const CellSpan& s1, const CellSpan& s2) {
  return !(s1 == s2);
}

class LayoutTableCell;
class LayoutTableRow;

// LayoutTableSection is used to represent table row group (display:
// table-row-group), header group (display: table-header-group) and footer group
// (display: table-footer-group).
//
// The object holds the internal representation of the rows (m_grid). See
// recalcCells() below for some extra explanation.
//
// A lot of the complexity in this class is related to handling rowspan, colspan
// or just non-regular tables.
//
// Example of rowspan / colspan leading to overlapping cells (rowspan and
// colspan are overlapping):
// <table>
//   <tr>
//       <td>first row</td>
//       <td rowspan="2">rowspan</td>
//     </tr>
//    <tr>
//        <td colspan="2">colspan</td>
//     </tr>
// </table>
//
// Example of non-regular table (missing one cell in the first row):
// <!DOCTYPE html>
// <table>
//   <tr><td>First row only child.</td></tr>
//   <tr>
//     <td>Second row first child</td>
//     <td>Second row second child</td>
//   </tr>
// </table>
//
// LayoutTableSection is responsible for laying out LayoutTableRows and
// LayoutTableCells (see layoutRows()). However it is not their containing
// block, the enclosing LayoutTable (this object's parent()) is. This is why
// this class inherits from LayoutTableBoxComponent and not LayoutBlock.
class CORE_EXPORT LayoutTableSection final : public LayoutTableBoxComponent {
 public:
  explicit LayoutTableSection(Element*);
  ~LayoutTableSection() override;

  LayoutTableRow* FirstRow() const;
  LayoutTableRow* LastRow() const;

  void AddChild(LayoutObject* child,
                LayoutObject* before_child = nullptr) override;

  LayoutUnit FirstLineBoxBaseline() const override;

  void AddCell(LayoutTableCell*, LayoutTableRow*);

  int VBorderSpacingBeforeFirstRow() const;
  int CalcRowLogicalHeight();
  void LayoutRows();
  void ComputeOverflowFromDescendants();
  bool RecalcOverflowAfterStyleChange() override;

  void MarkAllCellsWidthsDirtyAndOrNeedsLayout(LayoutTable::WhatToMarkAllCells);

  LayoutTable* Table() const final { return ToLayoutTable(Parent()); }

  typedef Vector<LayoutTableCell*, 2> SpanningLayoutTableCells;

  struct SpanningRowsHeight {
    STACK_ALLOCATED();

   public:
    SpanningRowsHeight()
        : total_rows_height(0),
          spanning_cell_height_ignoring_border_spacing(0),
          is_any_row_with_only_spanning_cells(false) {}

    Vector<int> row_height;
    int total_rows_height;
    int spanning_cell_height_ignoring_border_spacing;
    bool is_any_row_with_only_spanning_cells;
    DISALLOW_COPY_AND_ASSIGN(SpanningRowsHeight);
  };

  TableGridCell& GridCellAt(unsigned row, unsigned effective_column) {
    return grid_[row].grid_cells[effective_column];
  }
  const TableGridCell& GridCellAt(unsigned row,
                                  unsigned effective_column) const {
    return grid_[row].grid_cells[effective_column];
  }
  LayoutTableCell* PrimaryCellAt(unsigned row, unsigned effective_column) {
    auto& grid_cells = grid_[row].grid_cells;
    if (effective_column >= grid_cells.size())
      return nullptr;
    return grid_cells[effective_column].PrimaryCell();
  }
  const LayoutTableCell* PrimaryCellAt(unsigned row,
                                       unsigned effective_column) const {
    return const_cast<LayoutTableSection*>(this)->PrimaryCellAt(
        row, effective_column);
  }

  // Returns the primary cell at (row, effectiveColumn) if the cell exists and
  // originates from (instead of spanning into) the grid slot, or nullptr.
  LayoutTableCell* OriginatingCellAt(unsigned row, unsigned effective_column);
  const LayoutTableCell* OriginatingCellAt(unsigned row,
                                           unsigned effective_column) const {
    return const_cast<LayoutTableSection*>(this)->OriginatingCellAt(
        row, effective_column);
  }

  unsigned NumCols(unsigned row) const { return grid_[row].grid_cells.size(); }

  // Returns null for cells with a rowspan that exceed the last row. Possibly
  // others.
  LayoutTableRow* RowLayoutObjectAt(unsigned row) { return grid_[row].row; }
  const LayoutTableRow* RowLayoutObjectAt(unsigned row) const {
    return grid_[row].row;
  }

  void AppendEffectiveColumn(unsigned pos);
  void SplitEffectiveColumn(unsigned pos, unsigned first);

  unsigned NumRows() const {
    DCHECK(!NeedsCellRecalc());
    return grid_.size();
  }
  unsigned NumEffectiveColumns() const;

  // recalcCells() is used when we are not sure about the section's structure
  // and want to do an expensive (but safe) reconstruction of m_grid from
  // scratch.
  // An example of this is inserting a new cell in the middle of an existing
  // row or removing a row.
  //
  // Accessing m_grid when m_needsCellRecalc is set is UNSAFE as pointers can
  // be left dangling. Thus care should be taken in the code to check
  // m_needsCellRecalc before accessing m_grid.
  void RecalcCells();
  void RecalcCellsIfNeeded() {
    if (needs_cell_recalc_)
      RecalcCells();
  }

  bool NeedsCellRecalc() const { return needs_cell_recalc_; }
  void SetNeedsCellRecalc();

  LayoutUnit RowBaseline(unsigned row) { return grid_[row].baseline; }

  void RowLogicalHeightChanged(LayoutTableRow*);

  // distributeExtraLogicalHeightToRows methods return the *consumed* extra
  // logical height.
  // FIXME: We may want to introduce a structure holding the in-flux layout
  // information.
  int DistributeExtraLogicalHeightToRows(int extra_logical_height);

  static LayoutTableSection* CreateAnonymousWithParent(const LayoutObject*);
  LayoutBox* CreateAnonymousBoxWithSameTypeAs(
      const LayoutObject* parent) const override {
    return CreateAnonymousWithParent(parent);
  }

  void Paint(const PaintInfo&, const LayoutPoint&) const override;

  // Flip the rect so it aligns with the coordinates used by the rowPos and
  // columnPos vectors.
  LayoutRect LogicalRectForWritingModeAndDirection(const LayoutRect&) const;

  // Sets |rows| and |columns| to cover all cells needing repaint in
  // |damage_rect|.
  void DirtiedRowsAndEffectiveColumns(const LayoutRect& damage_rect,
                                      CellSpan& rows,
                                      CellSpan& columns) const;

  const HashSet<const LayoutTableCell*>& OverflowingCells() const {
    return overflowing_cells_;
  }
  bool HasOverflowingCell() const {
    return overflowing_cells_.size() || force_full_paint_;
  }
  bool HasMultipleCellLevels() const { return has_multiple_cell_levels_; }

  const char* GetName() const override { return "LayoutTableSection"; }

  // Whether a section has opaque background depends on many factors, e.g.
  // border spacing, border collapsing, missing cells, etc. For simplicity,
  // just conservatively assume all table sections are not opaque.
  bool ForegroundIsKnownToBeOpaqueInRect(const LayoutRect&,
                                         unsigned) const override {
    return false;
  }
  bool BackgroundIsKnownToBeOpaqueInRect(const LayoutRect&) const override {
    return false;
  }

  int PaginationStrutForRow(LayoutTableRow*, LayoutUnit logical_offset) const;

  bool MapToVisualRectInAncestorSpaceInternal(
      const LayoutBoxModelObject* ancestor,
      TransformState&,
      VisualRectFlags = kDefaultVisualRectFlags) const override;

  bool IsRepeatingHeaderGroup() const { return is_repeating_header_group_; };
  bool IsRepeatingFooterGroup() const { return is_repeating_footer_group_; };

  void UpdateLayout() override;

  CellSpan FullSectionRowSpan() const { return CellSpan(0, grid_.size()); }
  CellSpan FullTableEffectiveColumnSpan() const {
    return CellSpan(0, Table()->NumEffectiveColumns());
  }

  void DetermineIfHeaderGroupShouldRepeat() {
    is_repeating_header_group_ = HeaderGroupShouldRepeat();
  }

  // Check whether row or row group has visibility:collapse.
  bool RowHasVisibilityCollapse(unsigned row) const;

  void DetermineIfFooterGroupShouldRepeat() {
    is_repeating_footer_group_ = FooterGroupShouldRepeat();
  }

  // Update widths of cells affected by collapsed columns and sets whether cells
  // are spanning any collapsed columns.
  void UpdateLogicalWidthForCollapsedCells(
      const Vector<int>& col_collapsed_width);

 protected:
  void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
  bool NodeAtPoint(HitTestResult&,
                   const HitTestLocation& location_in_container,
                   const LayoutPoint& accumulated_offset,
                   HitTestAction) override;

 private:
  bool IsOfType(LayoutObjectType type) const override {
    return type == kLayoutObjectTableSection || LayoutBox::IsOfType(type);
  }

  void WillBeRemovedFromTree() override;

  int BorderSpacingForRow(unsigned row) const {
    return grid_[row].row ? Table()->VBorderSpacing() : 0;
  }

  void EnsureRows(unsigned num_rows) {
    if (num_rows > grid_.size())
      grid_.Grow(num_rows);
  }

  void EnsureCols(unsigned row_index, unsigned num_cols) {
    if (num_cols > NumCols(row_index))
      grid_[row_index].grid_cells.Grow(num_cols);
  }

  bool RowHasOnlySpanningCells(unsigned);
  unsigned CalcRowHeightHavingOnlySpanningCells(unsigned,
                                                int&,
                                                unsigned,
                                                unsigned&,
                                                Vector<int>&);
  void UpdateRowsHeightHavingOnlySpanningCells(LayoutTableCell*,
                                               struct SpanningRowsHeight&,
                                               unsigned&,
                                               Vector<int>&);

  void PopulateSpanningRowsHeightFromCell(LayoutTableCell*,
                                          struct SpanningRowsHeight&);
  void DistributeExtraRowSpanHeightToPercentRows(LayoutTableCell*,
                                                 float,
                                                 int&,
                                                 Vector<int>&);
  void DistributeWholeExtraRowSpanHeightToPercentRows(LayoutTableCell*,
                                                      float,
                                                      int&,
                                                      Vector<int>&);
  void DistributeExtraRowSpanHeightToAutoRows(LayoutTableCell*,
                                              int,
                                              int&,
                                              Vector<int>&);
  void DistributeExtraRowSpanHeightToRemainingRows(LayoutTableCell*,
                                                   int,
                                                   int&,
                                                   Vector<int>&);
  void DistributeRowSpanHeightToRows(SpanningLayoutTableCells& row_span_cells);

  void DistributeExtraLogicalHeightToPercentRows(int& extra_logical_height,
                                                 int total_percent);
  void DistributeExtraLogicalHeightToAutoRows(int& extra_logical_height,
                                              unsigned auto_rows_count);
  void DistributeRemainingExtraLogicalHeight(int& extra_logical_height);

  void UpdateBaselineForCell(LayoutTableCell*,
                             unsigned row,
                             LayoutUnit& baseline_descent);

  // These two functions take a rectangle as input that has been flipped by
  // logicalRectForWritingModeAndDirection.
  // The returned span of rows or columns is end-exclusive, and empty if
  // start==end.
  CellSpan SpannedRows(const LayoutRect& flipped_rect) const;
  CellSpan SpannedEffectiveColumns(const LayoutRect& flipped_rect) const;

  void SetLogicalPositionForCell(LayoutTableCell*,
                                 unsigned effective_column) const;

  void RelayoutCellIfFlexed(LayoutTableCell&, int row_index, int row_height);

  int LogicalHeightForRow(const LayoutTableRow&) const;

  // Honor breaking restrictions inside the table row, and adjust position and
  // size accordingly.
  void AdjustRowForPagination(LayoutTableRow&, SubtreeLayoutScope&);

  // The offset at which the first row in the section will get positioned to
  // avoid any repeating headers in its table or ancestor tables.
  int OffsetForRepeatedHeader() const;

  bool PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const override;

  bool HeaderGroupShouldRepeat() const {
    return Table()->Header() == this && GroupShouldRepeat();
  }

  bool FooterGroupShouldRepeat() const {
    return Table()->Footer() == this && GroupShouldRepeat();
  }

  bool GroupShouldRepeat() const;

  struct TableGridRow {
    DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();

   public:
    inline void SetRowLogicalHeightToRowStyleLogicalHeight();
    inline void UpdateLogicalHeightForCell(const LayoutTableCell*);

    // The index is effective column index.
    Vector<TableGridCell> grid_cells;
    LayoutTableRow* row = nullptr;
    LayoutUnit baseline = LayoutUnit(-1);
    Length logical_height;
  };

  // The representation of the rows and their grid cells.
  Vector<TableGridRow> grid_;

  // The logical offset of each row from the top of the section.
  //
  // Note that this Vector has one more entry than the number of rows so that
  // we can keep track of the final size of the section. That is,
  // m_rowPos[m_grid.size()] is a valid entry.
  //
  // To know a row's height at |rowIndex|, use the formula:
  // m_rowPos[rowIndex + 1] - m_rowPos[rowIndex]
  Vector<int> row_pos_;

  // The amount of height collapsed in each row.
  //
  // This is used to adjust the padding of row-spanning cells. The padding
  // should stay the same as if the row were not collapsed.
  Vector<int> row_collapsed_height_;

  // Whether any row in the table section is or has been collapsed.
  bool is_any_row_collapsed_;

  // The current insertion position in the grid.
  // The position is used when inserting a new cell into the section to
  // know where it should be inserted and expand our internal structure.
  //
  // The reason for them is that we process cells as we discover them
  // during parsing or during recalcCells (ie in DOM order). This means
  // that we can discover changes in the structure later (e.g. due to
  // colspans, extra cells, ...).
  //
  // Do not use outside of recalcCells and addChild.
  unsigned c_col_;
  unsigned c_row_;

  bool needs_cell_recalc_;

  // This HashSet holds the overflowing cells for the partial paint path. If we
  // have too many overflowing cells, it will be empty and force_full_paint_
  // will be set to save memory. See ComputeOverflowFromDescendants().
  HashSet<const LayoutTableCell*> overflowing_cells_;
  bool force_full_paint_;

  // This boolean tracks if we have cells overlapping due to rowspan / colspan
  // (see class comment above about when it could appear).
  //
  // The use is to disable a painting optimization where we just paint the
  // invalidated cells.
  bool has_multiple_cell_levels_;

  // Whether any cell spans multiple rows or cols.
  bool has_spanning_cells_;

  // Header group should be painted on every page.
  bool is_repeating_header_group_;

  // Footer group should be painted on every page.
  bool is_repeating_footer_group_;
};

DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutTableSection, IsTableSection());

}  // namespace blink

#endif  // LayoutTableSection_h
