// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/layout/inline_formatting_context.h"

#include <algorithm>
#include <memory>

#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "cobalt/cssom/keyword_value.h"
#include "cobalt/layout/line_box.h"
#include "cobalt/layout/used_style.h"

namespace cobalt {
namespace layout {

InlineFormattingContext::InlineFormattingContext(
    const scoped_refptr<cssom::PropertyValue>& line_height,
    const render_tree::FontMetrics& font_metrics,
    const LayoutParams& layout_params, BaseDirection base_direction,
    const scoped_refptr<cssom::PropertyValue>& text_align,
    const scoped_refptr<cssom::PropertyValue>& font_size,
    LayoutUnit text_indent_offset, LayoutUnit ellipsis_width)
    : line_height_(line_height),
      font_metrics_(font_metrics),
      layout_params_(layout_params),
      base_direction_(base_direction),
      text_align_(text_align),
      font_size_(font_size),
      text_indent_offset_(text_indent_offset),
      ellipsis_width_(ellipsis_width),
      line_count_(0) {
  CreateLineBox();
}

InlineFormattingContext::~InlineFormattingContext() {}

Box* InlineFormattingContext::TryAddChildAndMaybeWrap(Box* child_box) {
  // When an inline box exceeds the width of a line box, it is split into
  // several boxes and these boxes are distributed across several line boxes.
  //   https://www.w3.org/TR/CSS21/visuren.html#inline-formatting
  //
  // We tackle this problem one line at a time.

  Box* child_box_before_wrap = line_box_->TryAddChildAndMaybeWrap(child_box);
  // If |child_box_before_wrap| is non-NULL, then a line wrap has occurred and a
  // new line box must be created.
  if (child_box_before_wrap) {
    CreateLineBox();
  }
  return child_box_before_wrap;
}

void InlineFormattingContext::EndUpdates() {
  // Treat the end of child boxes almost as an explicit line break,
  // but don't create the new line box.
  DestroyLineBox();

  // The shrink-to-fit width is:
  // min(max(preferred minimum width, available width), preferred width).
  //   https://www.w3.org/TR/CSS21/visudet.html#float-width
  //
  // Naive solution of the above expression would require two layout passes:
  // one to calculate the "preferred minimum width" and another one to
  // calculate the "preferred width". It is possible to save one layout pass
  // taking into account that:
  //   - an exact value of "preferred width" does not matter if "available
  //     width" cannot acommodate it;
  //   - the inline formatting context has more than one line if and only if
  //     the "preferred width" is greater than the "available width";
  //   - "preferred minimum" and "preferred" widths are equal when an inline
  //     formatting context has only one line.
  set_shrink_to_fit_width(std::max(
      preferred_min_width_, line_count_ > 1
                                ? layout_params_.containing_block_size.width()
                                : LayoutUnit()));
}

const std::vector<math::Vector2dF>&
InlineFormattingContext::GetEllipsesCoordinates() const {
  return ellipses_coordinates_;
}

void InlineFormattingContext::CreateLineBox() {
  if (line_box_) {
    DestroyLineBox();
  }

  // "'Text-indent' only affects a line if it is the first formatted line of an
  // element."
  //   https://www.w3.org/TR/CSS21/text.html#propdef-text-indent
  LayoutUnit line_indent_offset =
      line_count_ == 0 ? text_indent_offset_ : LayoutUnit();

  // Line boxes are stacked with no vertical separation and they never
  // overlap.
  //   https://www.w3.org/TR/CSS21/visuren.html#inline-formatting
  line_box_ = base::WrapUnique(
      new LineBox(auto_height(), false, line_height_, font_metrics_, true, true,
                  layout_params_, base_direction_, text_align_, font_size_,
                  line_indent_offset, ellipsis_width_));
}

void InlineFormattingContext::DestroyLineBox() {
  line_box_->EndUpdates();

  // The baseline of an "inline-block" is the baseline of its last line box
  // in the normal flow, unless it has no in-flow line boxes.
  //   https://www.w3.org/TR/CSS21/visudet.html#line-height
  if (line_box_->LineExists()) {
    ++line_count_;

    preferred_min_width_ =
        std::max(preferred_min_width_, line_box_->shrink_to_fit_width());

    // If "height" is "auto", the used value is the distance from box's top
    // content edge to the bottom edge of the last line box, if the box
    // establishes an inline formatting context with one or more lines.
    //   https://www.w3.org/TR/CSS21/visudet.html#normal-block
    set_auto_height(line_box_->top() + line_box_->height());

    set_baseline_offset_from_top_content_edge(
        line_box_->top() + line_box_->baseline_offset_from_top());

    if (line_box_->IsEllipsisPlaced()) {
      ellipses_coordinates_.push_back(line_box_->GetEllipsisCoordinates());
    }
  }

  line_box_.reset();
}

}  // namespace layout
}  // namespace cobalt
