/*
 * Copyright (C) 2019 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "TableFormattingGeometry.h"

#if ENABLE(LAYOUT_FORMATTING_CONTEXT)

#include "InlineFormattingState.h"
#include "LayoutBoxGeometry.h"
#include "LayoutContext.h"
#include "LayoutDescendantIterator.h"
#include "LayoutInitialContainingBlock.h"
#include "TableFormattingContext.h"
#include "TableFormattingQuirks.h"

namespace WebCore {
namespace Layout {

TableFormattingGeometry::TableFormattingGeometry(const TableFormattingContext& tableFormattingContext)
    : FormattingGeometry(tableFormattingContext)
{
}

LayoutUnit TableFormattingGeometry::cellBoxContentHeight(const ContainerBox& cellBox) const
{
    ASSERT(cellBox.isInFlow());
    if (layoutState().inQuirksMode() && TableFormattingQuirks::shouldIgnoreChildContentVerticalMargin(cellBox)) {
        ASSERT(cellBox.firstInFlowChild());
        auto formattingContext = this->formattingContext();
        auto& firstInFlowChild = *cellBox.firstInFlowChild();
        auto& lastInFlowChild = *cellBox.lastInFlowChild();
        auto& firstInFlowChildGeometry = formattingContext.geometryForBox(firstInFlowChild, FormattingContext::EscapeReason::TableQuirkNeedsGeometryFromEstablishedFormattingContext);
        auto& lastInFlowChildGeometry = formattingContext.geometryForBox(lastInFlowChild, FormattingContext::EscapeReason::TableQuirkNeedsGeometryFromEstablishedFormattingContext);

        auto top = firstInFlowChild.style().hasMarginBeforeQuirk() ? BoxGeometry::borderBoxRect(firstInFlowChildGeometry).top() : BoxGeometry::marginBoxRect(firstInFlowChildGeometry).top();
        auto bottom = lastInFlowChild.style().hasMarginAfterQuirk() ? BoxGeometry::borderBoxRect(lastInFlowChildGeometry).bottom() : BoxGeometry::marginBoxRect(lastInFlowChildGeometry).bottom();
        return bottom - top;
    }
    return contentHeightForFormattingContextRoot(cellBox);
}

Edges TableFormattingGeometry::computedCellBorder(const TableGrid::Cell& cell) const
{
    auto& grid = formattingContext().formattingState().tableGrid();
    auto& cellBox = cell.box();
    auto border = computedBorder(cellBox);
    auto collapsedBorder = grid.collapsedBorder();
    if (!collapsedBorder)
        return border;

    // We might want to cache these collapsed borders on the grid.
    auto cellPosition = cell.position();
    // Collapsed border left from table and adjacent cells.
    if (!cellPosition.column)
        border.horizontal.left = collapsedBorder->horizontal.left / 2;
    else {
        auto adjacentBorderRight = computedBorder(grid.slot({ cellPosition.column - 1, cellPosition.row })->cell().box()).horizontal.right;
        border.horizontal.left = std::max(border.horizontal.left, adjacentBorderRight) / 2;
    }
    // Collapsed border right from table and adjacent cells.
    if (cellPosition.column == grid.columns().size() - 1)
        border.horizontal.right = collapsedBorder->horizontal.right / 2;
    else {
        auto adjacentBorderLeft = computedBorder(grid.slot({ cellPosition.column + 1, cellPosition.row })->cell().box()).horizontal.left;
        border.horizontal.right = std::max(border.horizontal.right, adjacentBorderLeft) / 2;
    }
    // Collapsed border top from table, row and adjacent cells.
    auto& rows = grid.rows().list();
    if (!cellPosition.row)
        border.vertical.top = collapsedBorder->vertical.top / 2;
    else {
        auto adjacentBorderBottom = computedBorder(grid.slot({ cellPosition.column, cellPosition.row - 1 })->cell().box()).vertical.bottom;
        auto adjacentRowBottom = computedBorder(rows[cellPosition.row - 1].box()).vertical.bottom;
        auto adjacentCollapsedBorder = std::max(adjacentBorderBottom, adjacentRowBottom);
        border.vertical.top = std::max(border.vertical.top, adjacentCollapsedBorder) / 2;
    }
    // Collapsed border bottom from table, row and adjacent cells.
    if (cellPosition.row == grid.rows().size() - 1)
        border.vertical.bottom = collapsedBorder->vertical.bottom / 2;
    else {
        auto adjacentBorderTop = computedBorder(grid.slot({ cellPosition.column, cellPosition.row + 1 })->cell().box()).vertical.top;
        auto adjacentRowTop = computedBorder(rows[cellPosition.row + 1].box()).vertical.top;
        auto adjacentCollapsedBorder = std::max(adjacentBorderTop, adjacentRowTop);
        border.vertical.bottom = std::max(border.vertical.bottom, adjacentCollapsedBorder) / 2;
    }
    return border;
}

std::optional<LayoutUnit> TableFormattingGeometry::computedColumnWidth(const ContainerBox& columnBox) const
{
    // Check both style and <col>'s width attribute.
    // FIXME: Figure out what to do with calculated values, like <col style="width: 10%">.
    if (auto computedWidthValue = computedWidth(columnBox, { }))
        return computedWidthValue;
    return columnBox.columnWidth();
}

IntrinsicWidthConstraints TableFormattingGeometry::intrinsicWidthConstraintsForCellContent(const TableGrid::Cell& cell) const
{
    auto& cellBox = cell.box();
    if (!cellBox.hasInFlowOrFloatingChild())
        return { };
    auto& layoutState = this->layoutState();
    return LayoutContext::createFormattingContext(cellBox, const_cast<LayoutState&>(layoutState))->computedIntrinsicWidthConstraints();
}

InlineLayoutUnit TableFormattingGeometry::usedBaselineForCell(const ContainerBox& cellBox) const
{
    // The baseline of a cell is defined as the baseline of the first in-flow line box in the cell,
    // or the first in-flow table-row in the cell, whichever comes first.
    // If there is no such line box, the baseline is the bottom of content edge of the cell box.
    if (cellBox.establishesInlineFormattingContext())
        return layoutState().formattingStateForInlineFormattingContext(cellBox).lines()[0].baseline();
    for (auto& cellDescendant : descendantsOfType<ContainerBox>(cellBox)) {
        if (cellDescendant.establishesInlineFormattingContext()) {
            auto& inlineFormattingStateForCell = layoutState().formattingStateForInlineFormattingContext(cellDescendant);
            if (!inlineFormattingStateForCell.lines().isEmpty())
                return inlineFormattingStateForCell.lines()[0].baseline();
        }
        if (cellDescendant.establishesTableFormattingContext())
            return layoutState().formattingStateForTableFormattingContext(cellDescendant).tableGrid().rows().list()[0].baseline();
    }
    return formattingContext().geometryForBox(cellBox).contentBoxBottom();
}

LayoutUnit TableFormattingGeometry::horizontalSpaceForCellContent(const TableGrid::Cell& cell) const
{
    auto& grid = formattingContext().formattingState().tableGrid();
    auto& columnList = grid.columns().list();
    auto logicalWidth = LayoutUnit { };
    for (auto columnIndex = cell.startColumn(); columnIndex < cell.endColumn(); ++columnIndex)
        logicalWidth += columnList.at(columnIndex).usedLogicalWidth();
    // No column spacing when spanning.
    logicalWidth += (cell.columnSpan() - 1) * grid.horizontalSpacing();
    auto& cellBoxGeometry = formattingContext().geometryForBox(cell.box());
    logicalWidth -= (cellBoxGeometry.horizontalBorder() + cellBoxGeometry.horizontalPadding().value_or(0));
    return logicalWidth;
}

LayoutUnit TableFormattingGeometry::verticalSpaceForCellContent(const TableGrid::Cell& cell, std::optional<LayoutUnit> availableVerticalSpace) const
{
    auto& cellBox = cell.box();
    auto contentHeight = cellBoxContentHeight(cellBox);
    auto computedHeight = this->computedHeight(cellBox, availableVerticalSpace);
    if (!computedHeight)
        return contentHeight;
    auto heightUsesBorderBox = layoutState().inQuirksMode() || cellBox.style().boxSizing() == BoxSizing::BorderBox;
    if (heightUsesBorderBox) {
        auto& cellBoxGeometry = formattingContext().geometryForBox(cell.box());
        *computedHeight -= (cellBoxGeometry.verticalBorder() + cellBoxGeometry.verticalPadding().value_or(0));
    }
    return std::max(contentHeight, *computedHeight);
}

}
}

#endif
