// Copyright 2016 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.

#include "core/layout/ng/ng_length_utils.h"

#include "core/layout/ng/ng_constraint_space.h"
#include "core/style/ComputedStyle.h"
#include "platform/LayoutUnit.h"
#include "platform/Length.h"

namespace blink {
// TODO(layout-ng):
// - positioned and/or replaced calculations
// - Take scrollbars into account

namespace {

// Converts physical dimensions to logical ones per
// https://drafts.csswg.org/css-writing-modes-3/#logical-to-physical
// For now it's only used to calculate abstract values for margins.
NGBoxStrut ToLogicalDimensions(const NGPhysicalDimensions& physical_dim,
                               const NGWritingMode writing_mode,
                               const NGDirection direction) {
  bool is_ltr = direction == LeftToRight;
  NGBoxStrut logical_dim;
  switch (writing_mode) {
    case VerticalRightLeft:
    case SidewaysRightLeft:
      logical_dim = {is_ltr ? physical_dim.top : physical_dim.bottom,
                     is_ltr ? physical_dim.bottom : physical_dim.top,
                     physical_dim.right, physical_dim.left};
      break;
    case VerticalLeftRight:
      logical_dim = {is_ltr ? physical_dim.top : physical_dim.bottom,
                     is_ltr ? physical_dim.bottom : physical_dim.top,
                     physical_dim.left, physical_dim.right};
      break;
    case SidewaysLeftRight:
      logical_dim = {is_ltr ? physical_dim.bottom : physical_dim.top,
                     is_ltr ? physical_dim.top : physical_dim.bottom,
                     physical_dim.left, physical_dim.right};
      break;
    default:
      NOTREACHED();
    /* FALLTHROUGH */
    case HorizontalTopBottom:
      logical_dim = {is_ltr ? physical_dim.left : physical_dim.right,
                     is_ltr ? physical_dim.right : physical_dim.left,
                     physical_dim.top, physical_dim.bottom};
      break;
  }
  return logical_dim;
}

}  // namespace

LayoutUnit resolveInlineLength(const NGConstraintSpace& constraintSpace,
                               const ComputedStyle& style,
                               const Length& length,
                               LengthResolveType type) {
  // TODO(layout-ng): Handle min/max/fit-content
  DCHECK(!length.isMaxSizeNone());
  DCHECK_GE(constraintSpace.ContainerSize().inline_size, LayoutUnit());

  if (type == LengthResolveType::MinSize && length.isAuto())
    return LayoutUnit();

  if (type == LengthResolveType::MarginBorderPaddingSize && length.isAuto())
    return LayoutUnit();

  LayoutUnit container_size = constraintSpace.ContainerSize().inline_size;
  switch (length.type()) {
    case Auto:
    case FillAvailable: {
      NGBoxStrut margins =
          computeMargins(constraintSpace, style,
                         FromPlatformWritingMode(style.getWritingMode()),
                         FromPlatformDirection(style.direction()));
      return container_size - margins.InlineSum();
    }
    case Percent:
    case Fixed:
    case Calculated: {
      // TODO(layout-ng): adjust for border-box
      LayoutUnit value = valueForLength(length, container_size);
      if (style.boxSizing() == BoxSizingContentBox &&
          type != LengthResolveType::MarginBorderPaddingSize) {
        NGBoxStrut border_and_padding =
            computeBorders(style) + computePadding(constraintSpace, style);
        value += border_and_padding.InlineSum();
      }
      return value;
    }
    case MinContent:
    case MaxContent:
    case FitContent:
      // TODO(layout-ng): implement
      return LayoutUnit();
    case DeviceWidth:
    case DeviceHeight:
      // TODO(layout-ng): Do we need to handle this here or does the style
      // system already compute these?
      return LayoutUnit();
    case ExtendToZoom:
      NOTREACHED()
          << "ExtendToZoom should only be used for viewport definitions";
    case MaxSizeNone:
    default:
      NOTREACHED();
      return LayoutUnit();
  }
}

LayoutUnit resolveBlockLength(const NGConstraintSpace& constraintSpace,
                              const ComputedStyle& style,
                              const Length& length,
                              LayoutUnit contentSize,
                              LengthResolveType type) {
  DCHECK(!length.isMaxSizeNone());
  DCHECK(type != LengthResolveType::MarginBorderPaddingSize);

  if (type == LengthResolveType::MinSize && length.isAuto())
    return LayoutUnit();

  // Make sure that indefinite percentages resolve to NGSizeIndefinite, not to
  // a random negative number.
  if (length.isPercentOrCalc() &&
      constraintSpace.ContainerSize().block_size == NGSizeIndefinite)
    return contentSize;

  LayoutUnit container_size = constraintSpace.ContainerSize().block_size;
  switch (length.type()) {
    case FillAvailable: {
      NGBoxStrut margins =
          computeMargins(constraintSpace, style,
                         FromPlatformWritingMode(style.getWritingMode()),
                         FromPlatformDirection(style.direction()));
      return container_size - margins.BlockSum();
    }
    case Percent:
    case Fixed:
    case Calculated: {
      // TODO(layout-ng): adjust for border-box
      LayoutUnit value = valueForLength(length, container_size);
      if (style.boxSizing() == BoxSizingContentBox &&
          type != LengthResolveType::MarginBorderPaddingSize) {
        NGBoxStrut border_and_padding =
            computeBorders(style) + computePadding(constraintSpace, style);
        value += border_and_padding.BlockSum();
      }
      return value;
    }
    case Auto:
    case MinContent:
    case MaxContent:
    case FitContent:
      return contentSize;
    case DeviceWidth:
    case DeviceHeight:
      // TODO(layout-ng): Do we need to handle this here or does the style
      // system already compute these?
      return LayoutUnit();
    case ExtendToZoom:
      NOTREACHED()
          << "ExtendToZoom should only be used for viewport definitions";
    case MaxSizeNone:
    default:
      NOTREACHED();
      return LayoutUnit();
  }
}

LayoutUnit computeInlineSizeForFragment(
    const NGConstraintSpace& constraintSpace,
    const ComputedStyle& style) {
  if (constraintSpace.FixedInlineSize())
    return constraintSpace.ContainerSize().inline_size;

  LayoutUnit extent =
      resolveInlineLength(constraintSpace, style, style.logicalWidth(),
                          LengthResolveType::ContentSize);

  Length maxLength = style.logicalMaxWidth();
  if (!maxLength.isMaxSizeNone()) {
    LayoutUnit max = resolveInlineLength(constraintSpace, style, maxLength,
                                         LengthResolveType::MaxSize);
    extent = std::min(extent, max);
  }

  LayoutUnit min =
      resolveInlineLength(constraintSpace, style, style.logicalMinWidth(),
                          LengthResolveType::MinSize);
  extent = std::max(extent, min);
  return extent;
}

LayoutUnit computeBlockSizeForFragment(const NGConstraintSpace& constraintSpace,
                                       const ComputedStyle& style,
                                       LayoutUnit contentSize) {
  if (constraintSpace.FixedBlockSize())
    return constraintSpace.ContainerSize().block_size;

  LayoutUnit extent =
      resolveBlockLength(constraintSpace, style, style.logicalHeight(),
                         contentSize, LengthResolveType::ContentSize);
  if (extent == NGSizeIndefinite) {
    DCHECK_EQ(contentSize, NGSizeIndefinite);
    return extent;
  }

  Length maxLength = style.logicalMaxHeight();
  if (!maxLength.isMaxSizeNone()) {
    LayoutUnit max =
        resolveBlockLength(constraintSpace, style, maxLength, contentSize,
                           LengthResolveType::MaxSize);
    extent = std::min(extent, max);
  }

  LayoutUnit min =
      resolveBlockLength(constraintSpace, style, style.logicalMinHeight(),
                         contentSize, LengthResolveType::MinSize);
  extent = std::max(extent, min);
  return extent;
}

NGBoxStrut computeMargins(const NGConstraintSpace& constraintSpace,
                          const ComputedStyle& style,
                          const NGWritingMode writing_mode,
                          const NGDirection direction) {
  // Margins always get computed relative to the inline size:
  // https://www.w3.org/TR/CSS2/box.html#value-def-margin-width
  NGPhysicalDimensions physical_dim;
  physical_dim.left =
      resolveInlineLength(constraintSpace, style, style.marginLeft(),
                          LengthResolveType::MarginBorderPaddingSize);
  physical_dim.right =
      resolveInlineLength(constraintSpace, style, style.marginRight(),
                          LengthResolveType::MarginBorderPaddingSize);
  physical_dim.top =
      resolveInlineLength(constraintSpace, style, style.marginTop(),
                          LengthResolveType::MarginBorderPaddingSize);
  physical_dim.bottom =
      resolveInlineLength(constraintSpace, style, style.marginBottom(),
                          LengthResolveType::MarginBorderPaddingSize);
  return ToLogicalDimensions(physical_dim, writing_mode, direction);
}

NGBoxStrut computeBorders(const ComputedStyle& style) {
  NGBoxStrut borders;
  borders.inline_start = LayoutUnit(style.borderStartWidth());
  borders.inline_end = LayoutUnit(style.borderEndWidth());
  borders.block_start = LayoutUnit(style.borderBeforeWidth());
  borders.block_end = LayoutUnit(style.borderAfterWidth());
  return borders;
}

NGBoxStrut computePadding(const NGConstraintSpace& constraintSpace,
                          const ComputedStyle& style) {
  // Padding always gets computed relative to the inline size:
  // https://www.w3.org/TR/CSS2/box.html#value-def-padding-width
  NGBoxStrut padding;
  padding.inline_start =
      resolveInlineLength(constraintSpace, style, style.paddingStart(),
                          LengthResolveType::MarginBorderPaddingSize);
  padding.inline_end =
      resolveInlineLength(constraintSpace, style, style.paddingEnd(),
                          LengthResolveType::MarginBorderPaddingSize);
  padding.block_start =
      resolveInlineLength(constraintSpace, style, style.paddingBefore(),
                          LengthResolveType::MarginBorderPaddingSize);
  padding.block_end =
      resolveInlineLength(constraintSpace, style, style.paddingAfter(),
                          LengthResolveType::MarginBorderPaddingSize);
  return padding;
}

}  // namespace blink
