// 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 "third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h"

#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/shadow/shadow_element_utils.h"
#include "third_party/blink/renderer/core/input_type_names.h"
#include "third_party/blink/renderer/core/layout/geometry/logical_size.h"
#include "third_party/blink/renderer/core/layout/intrinsic_sizing_info.h"
#include "third_party/blink/renderer/core/layout/layout_replaced.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/layout/min_max_sizes.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h"
#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column.h"
#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"

namespace blink {
namespace {

#if DCHECK_IS_ON()
void AppendNodeToString(NGLayoutInputNode node,
                        StringBuilder* string_builder,
                        unsigned indent = 2) {
  if (!node)
    return;
  DCHECK(string_builder);

  string_builder->Append(node.ToString());
  string_builder->Append("\n");

  StringBuilder indent_builder;
  for (unsigned i = 0; i < indent; i++)
    indent_builder.Append(" ");

  if (auto* block_node = DynamicTo<NGBlockNode>(node)) {
    NGLayoutInputNode first_child = block_node->FirstChild();
    for (NGLayoutInputNode node_runner = first_child; node_runner;
         node_runner = node_runner.NextSibling()) {
      string_builder->Append(indent_builder.ToString());
      AppendNodeToString(node_runner, string_builder, indent + 2);
    }
  }

  if (auto* inline_node = DynamicTo<NGInlineNode>(node)) {
    const auto& items = inline_node->ItemsData(false).items;
    for (const NGInlineItem& inline_item : items) {
      string_builder->Append(indent_builder.ToString());
      string_builder->Append(inline_item.ToString());
      string_builder->Append("\n");
    }
    NGLayoutInputNode next_sibling = inline_node->NextSibling();
    for (NGLayoutInputNode node_runner = next_sibling; node_runner;
         node_runner = node_runner.NextSibling()) {
      string_builder->Append(indent_builder.ToString());
      AppendNodeToString(node_runner, string_builder, indent + 2);
    }
  }
}
#endif

}  // namespace

bool NGLayoutInputNode::IsSlider() const {
  if (const auto* input = DynamicTo<HTMLInputElement>(box_->GetNode()))
    return input->type() == input_type_names::kRange;
  return false;
}

bool NGLayoutInputNode::IsSliderThumb() const {
  return IsBlock() && blink::IsSliderThumb(GetDOMNode());
}

bool NGLayoutInputNode::IsEmptyTableSection() const {
  return box_->IsTableSection() && To<LayoutNGTableSection>(box_)->IsEmpty();
}

wtf_size_t NGLayoutInputNode::TableColumnSpan() const {
  DCHECK(IsTableCol() || IsTableColgroup());
  return To<LayoutNGTableColumn>(box_)->Span();
}

wtf_size_t NGLayoutInputNode::TableCellColspan() const {
  DCHECK(box_->IsTableCell());
  return To<LayoutNGTableCell>(box_)->ColSpan();
}

wtf_size_t NGLayoutInputNode::TableCellRowspan() const {
  DCHECK(box_->IsTableCell());
  return To<LayoutNGTableCell>(box_)->ComputedRowSpan();
}

bool NGLayoutInputNode::IsTextControlPlaceholder() const {
  return IsBlock() && blink::IsTextControlPlaceholder(GetDOMNode());
}

MinMaxSizesResult NGLayoutInputNode::ComputeMinMaxSizes(
    WritingMode writing_mode,
    const MinMaxSizesInput& input,
    const NGConstraintSpace* space) const {
  if (auto* inline_node = DynamicTo<NGInlineNode>(this))
    return inline_node->ComputeMinMaxSizes(writing_mode, input, space);
  return To<NGBlockNode>(*this).ComputeMinMaxSizes(writing_mode, input, space);
}

void NGLayoutInputNode::IntrinsicSize(
    base::Optional<LayoutUnit>* computed_inline_size,
    base::Optional<LayoutUnit>* computed_block_size) const {
  DCHECK(IsReplaced());

  GetOverrideIntrinsicSize(computed_inline_size, computed_block_size);
  if (*computed_inline_size && *computed_block_size)
    return;

  IntrinsicSizingInfo legacy_sizing_info;

  To<LayoutReplaced>(box_)->ComputeIntrinsicSizingInfo(legacy_sizing_info);
  if (!*computed_inline_size && legacy_sizing_info.has_width)
    *computed_inline_size = LayoutUnit(legacy_sizing_info.size.Width());
  if (!*computed_block_size && legacy_sizing_info.has_height)
    *computed_block_size = LayoutUnit(legacy_sizing_info.size.Height());
}

NGLayoutInputNode NGLayoutInputNode::NextSibling() const {
  auto* inline_node = DynamicTo<NGInlineNode>(this);
  return inline_node ? inline_node->NextSibling()
                     : To<NGBlockNode>(*this).NextSibling();
}

PhysicalSize NGLayoutInputNode::InitialContainingBlockSize() const {
  IntSize icb_size =
      GetDocument().GetLayoutView()->GetLayoutSize(kIncludeScrollbars);
  return PhysicalSize(icb_size);
}

String NGLayoutInputNode::ToString() const {
  auto* inline_node = DynamicTo<NGInlineNode>(this);
  return inline_node ? inline_node->ToString()
                     : To<NGBlockNode>(*this).ToString();
}

#if DCHECK_IS_ON()
void NGLayoutInputNode::ShowNodeTree() const {
  StringBuilder string_builder;
  string_builder.Append(".:: LayoutNG Node Tree ::.\n");
  AppendNodeToString(*this, &string_builder);
  DLOG(INFO) << "\n" << string_builder.ToString().Utf8();
}
#endif

void NGLayoutInputNode::GetOverrideIntrinsicSize(
    base::Optional<LayoutUnit>* computed_inline_size,
    base::Optional<LayoutUnit>* computed_block_size) const {
  DCHECK(IsReplaced());

  LayoutUnit override_inline_size = OverrideIntrinsicContentInlineSize();
  if (override_inline_size != kIndefiniteSize) {
    *computed_inline_size = override_inline_size;
  } else {
    LayoutUnit default_inline_size = DefaultIntrinsicContentInlineSize();
    if (default_inline_size != kIndefiniteSize)
      *computed_inline_size = default_inline_size;
  }

  LayoutUnit override_block_size = OverrideIntrinsicContentBlockSize();
  if (override_block_size != kIndefiniteSize) {
    *computed_block_size = override_block_size;
  } else {
    LayoutUnit default_block_size = DefaultIntrinsicContentBlockSize();
    if (default_block_size != kIndefiniteSize)
      *computed_block_size = default_block_size;
  }

  // TODO(mstensho): Update for contain:inline-size / contain:block-size.
  if (ShouldApplySizeContainment()) {
    if (!*computed_inline_size)
      *computed_inline_size = LayoutUnit();
    if (!*computed_block_size)
      *computed_block_size = LayoutUnit();
  }
}

}  // namespace blink
