// Copyright 2017 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_floats_utils.h"

#include "core/layout/ng/ng_box_fragment.h"
#include "core/layout/ng/ng_constraint_space_builder.h"
#include "core/layout/ng/ng_layout_opportunity_iterator.h"
#include "core/layout/ng/ng_layout_result.h"
#include "core/layout/ng/ng_length_utils.h"
#include "core/layout/ng/ng_min_max_content_size.h"

namespace blink {
namespace {

// Adjusts the provided offset to the top edge alignment rule.
// Top edge alignment rule: the outer top of a floating box may not be higher
// than the outer top of any block or floated box generated by an element
// earlier in the source document.
NGLogicalOffset AdjustToTopEdgeAlignmentRule(const NGConstraintSpace& space,
                                             const NGLogicalOffset& offset) {
  NGLogicalOffset adjusted_offset = offset;
  LayoutUnit& adjusted_block_offset = adjusted_offset.block_offset;
  if (space.Exclusions()->last_left_float)
    adjusted_block_offset =
        std::max(adjusted_block_offset,
                 space.Exclusions()->last_left_float->rect.BlockStartOffset());
  if (space.Exclusions()->last_right_float)
    adjusted_block_offset =
        std::max(adjusted_block_offset,
                 space.Exclusions()->last_right_float->rect.BlockStartOffset());
  return adjusted_offset;
}

NGLayoutOpportunity FindLayoutOpportunityForFloat(
    const NGConstraintSpace& space,
    const NGUnpositionedFloat& unpositioned_float,
    LayoutUnit inline_size) {
  NGLogicalOffset adjusted_origin_point =
      AdjustToTopEdgeAlignmentRule(space, unpositioned_float.origin_offset);
  return FindLayoutOpportunityForFragment(
      space.Exclusions().get(), unpositioned_float.available_size,
      adjusted_origin_point, unpositioned_float.margins,
      {inline_size, LayoutUnit()});
}

// Calculates the logical offset for opportunity.
NGLogicalOffset CalculateLogicalOffsetForOpportunity(
    const NGLayoutOpportunity& opportunity,
    const LayoutUnit float_offset,
    const NGUnpositionedFloat* unpositioned_float) {
  DCHECK(unpositioned_float);
  auto margins = unpositioned_float->margins;
  // Adjust to child's margin.
  NGLogicalOffset result = margins.InlineBlockStartOffset();

  // Offset from the opportunity's block/inline start.
  result += opportunity.offset;

  // Adjust to float: right offset if needed.
  result.inline_offset += float_offset;

  result -= unpositioned_float->from_offset;
  return result;
}

// Creates an exclusion from the fragment that will be placed in the provided
// layout opportunity.
NGExclusion CreateExclusion(const NGFragment& fragment,
                            const NGLayoutOpportunity& opportunity,
                            const LayoutUnit float_offset,
                            const NGBoxStrut& margins,
                            NGExclusion::Type exclusion_type) {
  NGExclusion exclusion;
  exclusion.type = exclusion_type;
  NGLogicalRect& rect = exclusion.rect;
  rect.offset = opportunity.offset;
  rect.offset.inline_offset += float_offset;

  rect.size.inline_size = fragment.InlineSize() + margins.InlineSum();
  rect.size.block_size = fragment.BlockSize() + margins.BlockSum();
  return exclusion;
}

// Updates the Floating Object's left and top offsets.
NGPhysicalOffset CalculateFloatingObjectPaintOffset(
    const NGConstraintSpace& new_parent_space,
    const NGLogicalOffset& float_logical_offset,
    const NGUnpositionedFloat& unpositioned_float) {
  // TODO(glebl): We should use physical offset here.
  LayoutUnit left_offset = unpositioned_float.from_offset.inline_offset -
                           new_parent_space.BfcOffset().inline_offset +
                           float_logical_offset.inline_offset;
  DCHECK(unpositioned_float.parent_bfc_block_offset);
  LayoutUnit top_offset = unpositioned_float.from_offset.block_offset -
                          unpositioned_float.parent_bfc_block_offset.value() +
                          float_logical_offset.block_offset;
  return {left_offset, top_offset};
}

WTF::Optional<LayoutUnit> CalculateFragmentationOffset(
    const NGUnpositionedFloat& unpositioned_float,
    const NGConstraintSpace& parent_space) {
  const ComputedStyle& style = unpositioned_float.node->Style();
  DCHECK(FromPlatformWritingMode(style.GetWritingMode()) ==
         parent_space.WritingMode());

  if (parent_space.HasBlockFragmentation()) {
    return parent_space.FragmentainerSpaceAvailable() -
           unpositioned_float.origin_offset.block_offset;
  }

  return WTF::nullopt;
}

// Creates a constraint space for an unpositioned float.
RefPtr<NGConstraintSpace> CreateConstraintSpaceForFloat(
    const NGUnpositionedFloat& unpositioned_float,
    NGConstraintSpace* parent_space,
    WTF::Optional<LayoutUnit> fragmentation_offset = WTF::nullopt) {
  const ComputedStyle& style = unpositioned_float.node->Style();

  NGConstraintSpaceBuilder builder(parent_space);

  if (fragmentation_offset) {
    builder.SetFragmentainerSpaceAvailable(fragmentation_offset.value())
        .SetFragmentationType(parent_space->BlockFragmentationType());
  } else {
    builder.SetFragmentationType(NGFragmentationType::kFragmentNone);
  }

  return builder.SetPercentageResolutionSize(unpositioned_float.percentage_size)
      .SetAvailableSize(unpositioned_float.available_size)
      .SetIsNewFormattingContext(true)
      .SetIsShrinkToFit(true)
      .SetTextDirection(style.Direction())
      .ToConstraintSpace(FromPlatformWritingMode(style.GetWritingMode()));
}

}  // namespace

LayoutUnit ComputeInlineSizeForUnpositionedFloat(
    NGConstraintSpace* parent_space,
    NGUnpositionedFloat* unpositioned_float) {
  DCHECK(unpositioned_float);

  const ComputedStyle& style = unpositioned_float->node->Style();

  bool is_same_writing_mode = FromPlatformWritingMode(style.GetWritingMode()) ==
                              parent_space->WritingMode();

  // If we've already performed layout on the unpositioned float, just return
  // the cached value.
  if (unpositioned_float->fragment) {
    DCHECK(!is_same_writing_mode);
    return NGBoxFragment(parent_space->WritingMode(),
                         unpositioned_float->fragment.value().Get())
        .InlineSize();
  }

  const RefPtr<NGConstraintSpace> space =
      CreateConstraintSpaceForFloat(*unpositioned_float, parent_space);

  // If the float has the same writing mode as the block formatting context we
  // shouldn't perform a full layout just yet. Our position may determine where
  // we fragment.
  if (is_same_writing_mode) {
    WTF::Optional<MinMaxContentSize> min_max_size;
    if (NeedMinMaxContentSize(*space.Get(), style))
      min_max_size = unpositioned_float->node->ComputeMinMaxContentSize();
    return ComputeInlineSizeForFragment(*space.Get(), style, min_max_size);
  }

  // If we are performing layout on a float to determine its inline size it
  // should never have fragmented.
  DCHECK(!unpositioned_float->token);

  // A float which has a different writing mode can't fragment, and we
  // (probably) need to perform a full layout in order to correctly determine
  // its inline size. We are able to cache this result on the
  // unpositioned_float at this stage.
  RefPtr<NGLayoutResult> layout_result =
      unpositioned_float->node->Layout(space.Get());

  RefPtr<NGPhysicalBoxFragment> fragment =
      ToNGPhysicalBoxFragment(layout_result->PhysicalFragment().Get());
  unpositioned_float->fragment = fragment;

  DCHECK(fragment->BreakToken()->IsFinished());

  return NGBoxFragment(parent_space->WritingMode(), fragment.Get())
      .InlineSize();
}

NGPositionedFloat PositionFloat(NGUnpositionedFloat* unpositioned_float,
                                NGConstraintSpace* new_parent_space) {
  DCHECK(unpositioned_float);
  LayoutUnit inline_size = ComputeInlineSizeForUnpositionedFloat(
      new_parent_space, unpositioned_float);

  // Find a layout opportunity that will fit our float.
  NGLayoutOpportunity opportunity = FindLayoutOpportunityForFloat(
      *new_parent_space, *unpositioned_float, inline_size);

#if DCHECK_IS_ON()
  bool is_same_writing_mode =
      FromPlatformWritingMode(
          unpositioned_float->node->Style().GetWritingMode()) ==
      new_parent_space->WritingMode();
#endif

  RefPtr<NGPhysicalBoxFragment> physical_fragment;
  // We should only have a fragment if its writing mode is different, i.e. it
  // can't fragment.
  if (unpositioned_float->fragment) {
#if DCHECK_IS_ON()
    DCHECK(!is_same_writing_mode);
#endif
    physical_fragment = unpositioned_float->fragment.value();
  } else {
#if DCHECK_IS_ON()
    DCHECK(is_same_writing_mode);
#endif
    WTF::Optional<LayoutUnit> fragmentation_offset =
        CalculateFragmentationOffset(*unpositioned_float, *new_parent_space);

    RefPtr<NGConstraintSpace> space = CreateConstraintSpaceForFloat(
        *unpositioned_float, new_parent_space, fragmentation_offset);
    RefPtr<NGLayoutResult> layout_result = unpositioned_float->node->Layout(
        space.Get(), unpositioned_float->token.Get());
    physical_fragment =
        ToNGPhysicalBoxFragment(layout_result->PhysicalFragment().Get());
  }

  NGBoxFragment float_fragment(new_parent_space->WritingMode(),
                               physical_fragment.Get());

  // TODO(glebl): This should check for infinite opportunity instead.
  if (opportunity.IsEmpty()) {
    // Because of the implementation specific of the layout opportunity iterator
    // an empty opportunity can mean 2 things:
    // - search for layout opportunities is exhausted.
    // - opportunity has an infinite size. That's because CS is infinite.
    opportunity = NGLayoutOpportunity(
        NGLogicalOffset(),
        NGLogicalSize(float_fragment.InlineSize(), float_fragment.BlockSize()));
  }

  // Calculate the float offset if needed.
  LayoutUnit float_offset;
  if (unpositioned_float->IsRight()) {
    LayoutUnit float_margin_box_inline_size =
        float_fragment.InlineSize() + unpositioned_float->margins.InlineSum();
    float_offset = opportunity.size.inline_size - float_margin_box_inline_size;
  }

  // Add the float as an exclusion.
  const NGExclusion exclusion = CreateExclusion(
      float_fragment, opportunity, float_offset, unpositioned_float->margins,
      unpositioned_float->IsRight() ? NGExclusion::Type::kFloatRight
                                    : NGExclusion::Type::kFloatLeft);
  new_parent_space->AddExclusion(exclusion);

  NGLogicalOffset logical_offset = CalculateLogicalOffsetForOpportunity(
      opportunity, float_offset, unpositioned_float);
  NGPhysicalOffset paint_offset = CalculateFloatingObjectPaintOffset(
      *new_parent_space, logical_offset, *unpositioned_float);

  return NGPositionedFloat(std::move(physical_fragment), logical_offset,
                           paint_offset);
}

const Vector<NGPositionedFloat> PositionFloats(
    LayoutUnit origin_block_offset,
    LayoutUnit from_block_offset,
    LayoutUnit parent_bfc_offset,
    const Vector<RefPtr<NGUnpositionedFloat>>& unpositioned_floats,
    NGConstraintSpace* space) {
  Vector<NGPositionedFloat> positioned_floats;
  positioned_floats.ReserveCapacity(unpositioned_floats.size());

  for (auto& unpositioned_float : unpositioned_floats) {
    unpositioned_float->origin_offset.block_offset = origin_block_offset;
    unpositioned_float->from_offset.block_offset = from_block_offset;
    unpositioned_float->parent_bfc_block_offset = parent_bfc_offset;
    positioned_floats.push_back(PositionFloat(unpositioned_float.Get(), space));
  }

  return positioned_floats;
}

}  // namespace blink
