// 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"

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;
}

// Finds a layout opportunity for the fragment.
// It iterates over all layout opportunities in the constraint space and returns
// the first layout opportunity that is wider than the fragment or returns the
// last one which is always the widest.
//
// @param space Constraint space that is used to find layout opportunity for
//              the fragment.
// @param fragment Fragment that needs to be placed.
// @param origin_point {@code space}'s offset relative to the space that
//                     establishes a new formatting context that we're currently
//                     in and where all our exclusions reside.
// @param margins Margins of the fragment.
// @return Layout opportunity for the fragment.
const NGLayoutOpportunity FindLayoutOpportunityForFragment(
    const NGConstraintSpace* space,
    const NGFragment& fragment,
    const NGLogicalOffset& origin_point,
    const NGBoxStrut& margins) {
  NGLogicalOffset adjusted_origin_point =
      AdjustToTopEdgeAlignmentRule(*space, origin_point);

  NGLayoutOpportunityIterator opportunity_iter(space, adjusted_origin_point);
  NGLayoutOpportunity opportunity;
  NGLayoutOpportunity opportunity_candidate = opportunity_iter.Next();

  while (!opportunity_candidate.IsEmpty()) {
    opportunity = opportunity_candidate;
    // Checking opportunity's block size is not necessary as a float cannot be
    // positioned on top of another float inside of the same constraint space.
    auto fragment_inline_size = fragment.InlineSize() + margins.InlineSum();
    if (opportunity.size.inline_size >= fragment_inline_size)
      break;

    opportunity_candidate = opportunity_iter.Next();
  }
  return opportunity;
}

// Calculates the logical offset for opportunity.
NGLogicalOffset CalculateLogicalOffsetForOpportunity(
    const NGLayoutOpportunity& opportunity,
    const LayoutUnit float_offset,
    const NGLogicalOffset& from_offset,
    NGFloatingObject* floating_object) {
  DCHECK(floating_object);
  auto margins = floating_object->margins;
  // Adjust to child's margin.
  LayoutUnit inline_offset = margins.inline_start;
  LayoutUnit block_offset = margins.block_start;

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

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

  block_offset -= from_offset.block_offset;
  inline_offset -= from_offset.inline_offset;

  return NGLogicalOffset(inline_offset, block_offset);
}

// 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 offset from the provided parent_space
// and {@code floating_object}'s space and margins.
void UpdateFloatingObjectLeftOffset(const NGConstraintSpace& new_parent_space,
                                    const NGLogicalOffset& float_logical_offset,
                                    NGFloatingObject* floating_object) {
  DCHECK(floating_object);
  // TODO(glebl): We should use physical offset here.
  floating_object->left_offset =
      floating_object->original_parent_space->BfcOffset().inline_offset -
      new_parent_space.BfcOffset().inline_offset +
      float_logical_offset.inline_offset;
}
}  // namespace

// Calculates the relative position from {@code from_offset} of the
// floating object that is requested to be positioned from {@code origin_point}.
NGLogicalOffset PositionFloat(const NGLogicalOffset& origin_point,
                              const NGLogicalOffset& from_offset,
                              NGFloatingObject* floating_object,
                              NGConstraintSpace* new_parent_space) {
  DCHECK(floating_object);
  const auto* float_space = floating_object->space.get();
  DCHECK(floating_object->fragment) << "Fragment cannot be null here";

  // TODO(ikilpatrick): The writing mode switching here looks wrong.
  NGBoxFragment float_fragment(
      float_space->WritingMode(),
      toNGPhysicalBoxFragment(floating_object->fragment.get()));

  // Find a layout opportunity that will fit our float.
  const NGLayoutOpportunity opportunity = FindLayoutOpportunityForFragment(
      float_space, float_fragment, origin_point, floating_object->margins);
  DCHECK(!opportunity.IsEmpty()) << "Opportunity is empty but it shouldn't be";

  // Calculate the float offset if needed.
  LayoutUnit float_offset;
  if (floating_object->exclusion_type == NGExclusion::kFloatRight) {
    LayoutUnit float_margin_box_inline_size =
        float_fragment.InlineSize() + floating_object->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, floating_object->margins,
      floating_object->exclusion_type);
  new_parent_space->AddExclusion(exclusion);

  NGLogicalOffset logical_offset = CalculateLogicalOffsetForOpportunity(
      opportunity, float_offset, from_offset, floating_object);
  UpdateFloatingObjectLeftOffset(*new_parent_space, logical_offset,
                                 floating_object);
  return logical_offset;
}
}  // namespace blink
