// 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_out_of_flow_layout_part.h"

#include "core/layout/ng/ng_absolute_utils.h"
#include "core/layout/ng/ng_block_node.h"
#include "core/layout/ng/ng_box_fragment.h"
#include "core/layout/ng/ng_constraint_space_builder.h"
#include "core/layout/ng/ng_fragment.h"
#include "core/layout/ng/ng_fragment_builder.h"
#include "core/layout/ng/ng_length_utils.h"
#include "core/layout/ng/ng_physical_fragment.h"
#include "core/style/ComputedStyle.h"

namespace blink {

namespace {

// True if the container will contain an absolute descendant.
bool IsContainingBlockForAbsoluteDescendant(
    const ComputedStyle& container_style,
    const ComputedStyle& descendant_style) {
  EPosition position = descendant_style.position();
  bool contains_fixed = container_style.canContainFixedPositionObjects();
  bool contains_absolute =
      container_style.canContainAbsolutePositionObjects() || contains_fixed;

  return (contains_absolute && position == AbsolutePosition) ||
         (contains_fixed && position == FixedPosition);
}

}  // namespace

NGOutOfFlowLayoutPart::NGOutOfFlowLayoutPart(
    const ComputedStyle& container_style,
    NGFragmentBuilder* container_builder)
    : container_style_(container_style), container_builder_(container_builder) {
  NGWritingMode writing_mode(
      FromPlatformWritingMode(container_style_.getWritingMode()));

  NGBoxStrut borders = ComputeBorders(container_style_);
  container_border_offset_ =
      NGLogicalOffset{borders.inline_start, borders.block_start};
  container_border_physical_offset_ =
      container_border_offset_.ConvertToPhysical(
          writing_mode, container_style_.direction(),
          container_builder_->Size().ConvertToPhysical(writing_mode),
          NGPhysicalSize());

  NGLogicalSize space_size = container_builder_->Size();
  space_size.block_size -= borders.BlockSum();
  space_size.inline_size -= borders.InlineSum();

  // Initialize ConstraintSpace
  NGConstraintSpaceBuilder space_builder(writing_mode);
  space_builder.SetAvailableSize(space_size);
  space_builder.SetPercentageResolutionSize(space_size);
  space_builder.SetIsNewFormattingContext(true);
  space_builder.SetTextDirection(container_style_.direction());
  container_space_ = space_builder.ToConstraintSpace();
}

void NGOutOfFlowLayoutPart::Run() {
  HeapLinkedHashSet<WeakMember<NGBlockNode>> out_of_flow_candidates;
  Vector<NGStaticPosition> out_of_flow_candidate_positions;
  container_builder_->GetAndClearOutOfFlowDescendantCandidates(
      &out_of_flow_candidates, &out_of_flow_candidate_positions);

  size_t position_index = 0;

  for (auto& descendant : out_of_flow_candidates) {
    NGStaticPosition static_position =
        out_of_flow_candidate_positions[position_index++];

    if (IsContainingBlockForAbsoluteDescendant(container_style_,
                                               *descendant->Style())) {
      NGLogicalOffset offset;
      NGFragment* fragment =
          LayoutDescendant(*descendant, static_position, &offset);
      // TODO(atotic) Need to adjust size of overflow rect per spec.
      container_builder_->AddChild(fragment, offset);
    } else {
      container_builder_->AddOutOfFlowDescendant(descendant, static_position);
    }
  }
}

NGFragment* NGOutOfFlowLayoutPart::LayoutDescendant(
    NGBlockNode& descendant,
    NGStaticPosition static_position,
    NGLogicalOffset* offset) {
  // Adjust the static_position origin. The static_position coordinate origin is
  // relative to the container's border box, ng_absolute_utils expects it to be
  // relative to the container's padding box.
  static_position.offset -= container_border_physical_offset_;

  NGFragment* fragment = nullptr;
  Optional<MinAndMaxContentSizes> inline_estimate;
  Optional<LayoutUnit> block_estimate;

  if (AbsoluteNeedsChildInlineSize(*descendant.Style())) {
    inline_estimate = descendant.ComputeMinAndMaxContentSizesSync();
  }

  NGAbsolutePhysicalPosition node_position =
      ComputePartialAbsoluteWithChildInlineSize(
          *container_space_, *descendant.Style(), static_position,
          inline_estimate);

  if (AbsoluteNeedsChildBlockSize(*descendant.Style())) {
    fragment = GenerateFragment(descendant, block_estimate, node_position);
    block_estimate = fragment->BlockSize();
  }

  ComputeFullAbsoluteWithChildBlockSize(*container_space_, *descendant.Style(),
                                        static_position, block_estimate,
                                        &node_position);

  // Skip this step if we produced a fragment when estimating the block size.
  if (!fragment) {
    block_estimate =
        node_position.size.ConvertToLogical(container_space_->WritingMode())
            .block_size;
    fragment = GenerateFragment(descendant, block_estimate, node_position);
  }

  // Compute logical offset, NGAbsolutePhysicalPosition is calculated relative
  // to the padding box so add back the container's borders.
  NGBoxStrut inset = node_position.inset.ConvertToLogical(
      container_space_->WritingMode(), container_space_->Direction());
  offset->inline_offset =
      inset.inline_start + container_border_offset_.inline_offset;
  offset->block_offset =
      inset.block_start + container_border_offset_.block_offset;

  return fragment;
}

NGFragment* NGOutOfFlowLayoutPart::GenerateFragment(
    NGBlockNode& descendant,
    const Optional<LayoutUnit>& block_estimate,
    const NGAbsolutePhysicalPosition node_position) {
  // The fragment is generated in one of these two scenarios:
  // 1. To estimate descendant's block size, in this case block_size is
  //    container's available size.
  // 2. To compute final fragment, when block size is known from the absolute
  //    position calculation.
  LayoutUnit inline_size =
      node_position.size.ConvertToLogical(container_space_->WritingMode())
          .inline_size;
  LayoutUnit block_size = block_estimate
                              ? *block_estimate
                              : container_space_->AvailableSize().block_size;

  NGLogicalSize available_size{inline_size, block_size};

  NGConstraintSpaceBuilder builder(container_space_->WritingMode());
  builder.SetAvailableSize(available_size);
  builder.SetPercentageResolutionSize(container_space_->AvailableSize());
  if (block_estimate)
    builder.SetIsFixedSizeBlock(true);
  builder.SetIsFixedSizeInline(true);
  builder.SetIsNewFormattingContext(true);
  NGConstraintSpace* space = builder.ToConstraintSpace();

  NGPhysicalFragment* fragment = descendant.Layout(space);

  // TODO(ikilpatrick): the writing mode switching here looks wrong.
  return new NGBoxFragment(container_space_->WritingMode(),
                           container_space_->Direction(),
                           toNGPhysicalBoxFragment(fragment));
}

}  // namespace blink
