// Copyright 2018 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 "third_party/blink/renderer/core/layout/ng/exclusions/ng_layout_opportunity.h"

#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
#include "third_party/blink/renderer/core/layout/shapes/shape_outside_info.h"

namespace blink {

namespace {

// Returns how far a line can "fit" into a given exclusion based on its shape
// area. If the exclusion does not obstruct the line, then the returned
// LineSegment will be "invalid".
LineSegment ExcludedSegment(const NGExclusion& exclusion,
                            LayoutUnit bfc_block_offset,
                            LayoutUnit line_block_size) {
  DCHECK(exclusion.shape_data);
  const NGExclusionShapeData& shape_data = *exclusion.shape_data;
  const Shape& shape =
      shape_data.layout_box->GetShapeOutsideInfo()->ComputedShape();

  // Determine the block offset (relative to the shape) at which we need to
  // test for.
  LayoutUnit shape_relative_block_offset =
      bfc_block_offset -
      (exclusion.rect.BlockStartOffset() + shape_data.margins.block_start +
       shape_data.shape_insets.block_start);

  // At the block-start/end of shapes it is possible for a line to just touch,
  // and GetExcludedInterval will return a valid segment.
  // This check skips the shape when this happens.
  if (!shape.LineOverlapsShapeMarginBounds(shape_relative_block_offset,
                                           line_block_size))
    return LineSegment();

  // Clamp the line size to the size of the shape.
  LayoutUnit clamped_line_block_size =
      std::min(line_block_size, exclusion.rect.BlockSize() -
                                    shape_data.shape_insets.BlockSum() -
                                    shape_data.margins.BlockSum());

  LineSegment segment = shape.GetExcludedInterval(shape_relative_block_offset,
                                                  clamped_line_block_size);

  // Adjust the segment offsets to be relative to the line-left margin edge.
  LayoutUnit margin_delta =
      shape_data.margins.LineLeft(TextDirection::kLtr) +
      shape_data.shape_insets.LineLeft(TextDirection::kLtr);
  segment.logical_left += margin_delta;
  segment.logical_right += margin_delta;

  // Clamp the segment offsets to the size of the exclusion.
  segment.logical_left = clampTo<LayoutUnit>(segment.logical_left, LayoutUnit(),
                                             exclusion.rect.InlineSize());
  segment.logical_right = clampTo<LayoutUnit>(
      segment.logical_right, LayoutUnit(), exclusion.rect.InlineSize());

  // Make the segment offsets relative to the BFC coordinate space.
  segment.logical_left += exclusion.rect.LineStartOffset();
  segment.logical_right += exclusion.rect.LineStartOffset();

  return segment;
}

// Returns if the given line block-size and offset intersects with the given
// exclusion.
bool IntersectsExclusion(const NGExclusion& exclusion,
                         LayoutUnit bfc_block_offset,
                         LayoutUnit line_block_size) {
  return bfc_block_offset < exclusion.rect.BlockEndOffset() &&
         bfc_block_offset + line_block_size > exclusion.rect.BlockStartOffset();
}

}  // namespace

bool NGLayoutOpportunity::IsBlockDeltaBelowShapes(
    LayoutUnit block_delta) const {
  DCHECK(shape_exclusions);

  for (const auto& exclusion : shape_exclusions->line_left_shapes) {
    if (rect.BlockStartOffset() + block_delta <
        exclusion->rect.BlockEndOffset())
      return false;
  }

  for (const auto& exclusion : shape_exclusions->line_right_shapes) {
    if (rect.BlockStartOffset() + block_delta <
        exclusion->rect.BlockEndOffset())
      return false;
  }

  return true;
}

NGLineLayoutOpportunity NGLayoutOpportunity::ComputeLineLayoutOpportunity(
    const NGConstraintSpace& space,
    LayoutUnit line_block_size,
    LayoutUnit block_delta) const {
  return NGLineLayoutOpportunity(
      ComputeLineLeftOffset(space, line_block_size, block_delta),
      ComputeLineRightOffset(space, line_block_size, block_delta),
      rect.LineStartOffset(), rect.LineEndOffset(),
      rect.BlockStartOffset() + block_delta, line_block_size);
}

LayoutUnit NGLayoutOpportunity::ComputeLineLeftOffset(
    const NGConstraintSpace& space,
    LayoutUnit line_block_size,
    LayoutUnit block_delta) const {
  if (!shape_exclusions || shape_exclusions->line_left_shapes.IsEmpty())
    return rect.LineStartOffset();

  LayoutUnit bfc_block_offset = rect.BlockStartOffset() + block_delta;

  // Step through each exclusion and re-build the line_left_offset. Without
  // shapes this would be the same as the opportunity offset.
  //
  // We rebuild this offset from the line-left end, checking each exclusion and
  // increasing the line_left when an exclusion intersects.
  LayoutUnit line_left = space.BfcOffset().line_offset;
  for (auto& exclusion : shape_exclusions->line_left_shapes) {
    if (exclusion->shape_data) {
      LineSegment segment =
          ExcludedSegment(*exclusion, bfc_block_offset, line_block_size);
      if (segment.is_valid)
        line_left = std::max(line_left, segment.logical_right);
    } else {
      if (IntersectsExclusion(*exclusion, bfc_block_offset, line_block_size))
        line_left = std::max(line_left, exclusion->rect.LineEndOffset());
    }
  }

  return std::min(line_left, rect.LineEndOffset());
}

LayoutUnit NGLayoutOpportunity::ComputeLineRightOffset(
    const NGConstraintSpace& space,
    LayoutUnit line_block_size,
    LayoutUnit block_delta) const {
  if (!shape_exclusions || shape_exclusions->line_right_shapes.IsEmpty())
    return rect.LineEndOffset();

  LayoutUnit bfc_block_offset = rect.BlockStartOffset() + block_delta;

  LayoutUnit line_right =
      space.BfcOffset().line_offset + space.AvailableSize().inline_size;

  // Step through each exclusion and re-build the line_right_offset. Without
  // shapes this would be the same as the opportunity offset.
  //
  // We rebuild this offset from the line-right end, checking each exclusion and
  // reducing the line_right when an exclusion intersects.
  for (auto& exclusion : shape_exclusions->line_right_shapes) {
    if (exclusion->shape_data) {
      LineSegment segment =
          ExcludedSegment(*exclusion, bfc_block_offset, line_block_size);
      if (segment.is_valid)
        line_right = std::min(line_right, segment.logical_left);
    } else {
      if (IntersectsExclusion(*exclusion, bfc_block_offset, line_block_size))
        line_right = std::min(line_right, exclusion->rect.LineStartOffset());
    }
  }

  return std::max(line_right, rect.LineStartOffset());
}

}  // namespace blink
