// Copyright 2015 Google Inc. 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/line_box.h"

#include <algorithm>
#include <limits>

#include "cobalt/cssom/keyword_value.h"
#include "cobalt/layout/box.h"
#include "cobalt/layout/used_style.h"

namespace cobalt {
namespace layout {

// The left edge of a line box touches the left edge of its containing block.
//   https://www.w3.org/TR/CSS21/visuren.html#inline-formatting
LineBox::LineBox(LayoutUnit top, bool position_children_relative_to_baseline,
                 const scoped_refptr<cssom::PropertyValue>& line_height,
                 const render_tree::FontMetrics& font_metrics,
                 bool should_collapse_leading_white_space,
                 bool should_collapse_trailing_white_space,
                 const LayoutParams& layout_params,
                 BaseDirection base_direction,
                 const scoped_refptr<cssom::PropertyValue>& text_align,
                 const scoped_refptr<cssom::PropertyValue>& font_size,
                 LayoutUnit indent_offset, LayoutUnit ellipsis_width)
    : top_(top),
      position_children_relative_to_baseline_(
          position_children_relative_to_baseline),
      line_height_(line_height),
      font_metrics_(font_metrics),
      should_collapse_leading_white_space_(should_collapse_leading_white_space),
      should_collapse_trailing_white_space_(
          should_collapse_trailing_white_space),
      layout_params_(layout_params),
      base_direction_(base_direction),
      text_align_(text_align),
      font_size_(font_size),
      indent_offset_(indent_offset),
      ellipsis_width_(ellipsis_width),
      has_overflowed_(false),
      at_end_(false),
      num_absolutely_positioned_boxes_before_first_box_justifying_line_(0),
      shrink_to_fit_width_(indent_offset_),
      height_(0),
      baseline_offset_from_top_(0),
      is_ellipsis_placed_(false),
      placed_ellipsis_offset_(0) {}

Box* LineBox::TryAddChildAndMaybeWrap(Box* child_box) {
  DCHECK(!at_end_);

  if (child_box->IsAbsolutelyPositioned()) {
    BeginEstimateStaticPositionForAbsolutelyPositionedChild(child_box);
    return NULL;
  }

  UpdateSizePreservingTrailingWhiteSpace(child_box);

  // If the line box hasn't already overflowed the line, then attempt to add it
  // within the available width.
  if (!has_overflowed_ && !TryAddChildWithinAvailableWidth(child_box)) {
    // If the attempt failed, then adding the full box would overflow the line.
    // Attempt to find a wrap location within the available width, which will
    // prevent overflow from occurring. The priority is as follows:
    // 1. Attempt to find the last normal wrap opportunity in the current child
    //    within the available width.
    // 2. Attempt to find the last normal wrap opportunity within the previously
    //    added children.
    // 3. Attempt to find the last break-word wrap opportunity position in the
    //    current child within the available width. This will only be attempted
    //    when the overflow-wrap style of the box is break-word.
    // 4. Attempt to find the last break-word wrap opportunity within the
    //    previously added children. This will only be attempted when the
    //    overflow-wrap style of the box is break-word.
    // https://www.w3.org/TR/css-text-3/#line-breaking
    // https://www.w3.org/TR/css-text-3/#overflow-wrap
    if (TryWrapOverflowingBoxAndMaybeAddSplitChild(
            kWrapAtPolicyLastOpportunityWithinWidth,
            kWrapOpportunityPolicyNormal, child_box) ||
        TryWrapChildrenAtLastOpportunity(kWrapOpportunityPolicyNormal) ||
        TryWrapOverflowingBoxAndMaybeAddSplitChild(
            kWrapAtPolicyLastOpportunityWithinWidth,
            kWrapOpportunityPolicyBreakWord, child_box) ||
        TryWrapChildrenAtLastOpportunity(kWrapOpportunityPolicyBreakWord)) {
      // A wrap position was successfully found within the width. The line is
      // wrapping and at its end.
      at_end_ = true;
    } else {
      // If an inline box cannot be split (e.g., if the inline box contains
      // a single character, or language specific word breaking rules disallow
      // a break within the inline box), then the inline box overflows the line
      // box.
      //   https://www.w3.org/TR/CSS21/visuren.html#inline-formatting
      has_overflowed_ = true;
    }
  }

  if (has_overflowed_) {
    // If the line has overflowed, then the first wrap opportunity within the
    // child box is preferred, thereby minimizing the size of the overflow. This
    // can be either a break-word or normal wrap, depending on the overflow-wrap
    // style of the box.
    // https://www.w3.org/TR/css-text-3/#overflow-wrap
    if (TryWrapOverflowingBoxAndMaybeAddSplitChild(
            kWrapAtPolicyFirstOpportunity,
            kWrapOpportunityPolicyBreakWordOrNormal, child_box)) {
      // A wrap position was successfully found. The line is wrapping and at its
      // end.
      at_end_ = true;
    } else {
      // No wrap position was found within the child box. The box is allowed to
      // overflow the line and additional boxes can be added until a wrappable
      // box is found.
      BeginAddChildInternal(child_box);
    }
  }

  DCHECK(!child_boxes_.empty());
  return at_end_ ? child_boxes_[child_boxes_.size() - 1] : NULL;
}

void LineBox::BeginAddChildAndMaybeOverflow(Box* child_box) {
  if (child_box->IsAbsolutelyPositioned()) {
    BeginEstimateStaticPositionForAbsolutelyPositionedChild(child_box);
    return;
  }

  UpdateSizePreservingTrailingWhiteSpace(child_box);
  BeginAddChildInternal(child_box);
}

void LineBox::EndUpdates() {
  at_end_ = true;

  // A sequence of collapsible spaces at the end of a line is removed.
  //   https://www.w3.org/TR/css3-text/#white-space-phase-2
  if (should_collapse_trailing_white_space_) {
    CollapseTrailingWhiteSpace();
  }

  // Set the leading and trailing white space flags now. This ensures that the
  // values returned by HasLeadingWhiteSpace() and HasTrailingWhiteSpace()
  // remain valid even after bidi reversals.
  has_leading_white_space_ = HasLeadingWhiteSpace();
  has_trailing_white_space_ = HasTrailingWhiteSpace();

  ReverseChildBoxesByBidiLevels();
  UpdateChildBoxLeftPositions();
  SetLineBoxHeightFromChildBoxes();
  UpdateChildBoxTopPositions();
  MaybePlaceEllipsis();
}

bool LineBox::HasLeadingWhiteSpace() const {
  // |has_leading_white_space_| should only ever be set by EndUpdates() after
  // |at_end_| has been set to true;
  DCHECK(at_end_ || !has_leading_white_space_);

  // If |has_leading_white_space_| has been set, then use it. Otherwise, grab
  // the leading white space state from the first non-collapsed child box.
  return has_leading_white_space_
             ? *has_leading_white_space_
             : first_non_collapsed_child_box_index_ &&
                   child_boxes_[*first_non_collapsed_child_box_index_]
                       ->HasLeadingWhiteSpace();
}

bool LineBox::HasTrailingWhiteSpace() const {
  // |has_trailing_white_space_| should only ever be set by EndUpdates() after
  // |at_end_| has been set to true;
  DCHECK(at_end_ || !has_trailing_white_space_);

  // If |has_trailing_white_space_| has been set, then use it. Otherwise, grab
  // the trailing white space state from the last non-collapsed child box.
  return has_trailing_white_space_
             ? *has_trailing_white_space_
             : last_non_collapsed_child_box_index_ &&
                   child_boxes_[*last_non_collapsed_child_box_index_]
                       ->HasTrailingWhiteSpace();
}

bool LineBox::IsCollapsed() const {
  return !first_non_collapsed_child_box_index_;
}

bool LineBox::LineExists() const {
  return !!first_box_justifying_line_existence_index_;
}

size_t LineBox::GetFirstBoxJustifyingLineExistenceIndex() const {
  return first_box_justifying_line_existence_index_.value_or(
             child_boxes_.size()) +
         num_absolutely_positioned_boxes_before_first_box_justifying_line_;
}

bool LineBox::IsEllipsisPlaced() const { return is_ellipsis_placed_; }

math::Vector2dF LineBox::GetEllipsisCoordinates() const {
  return math::Vector2dF(placed_ellipsis_offset_.toFloat(),
                         (top_ + baseline_offset_from_top_).toFloat());
}

LayoutUnit LineBox::GetAvailableWidth() const {
  return layout_params_.containing_block_size.width() - shrink_to_fit_width_;
}

void LineBox::UpdateSizePreservingTrailingWhiteSpace(Box* child_box) {
  child_box->SetShouldCollapseLeadingWhiteSpace(
      ShouldCollapseLeadingWhiteSpaceInNextChildBox());
  child_box->SetShouldCollapseTrailingWhiteSpace(false);
  child_box->UpdateSize(layout_params_);
}

bool LineBox::ShouldCollapseLeadingWhiteSpaceInNextChildBox() const {
  return last_non_collapsed_child_box_index_
             // Any space immediately following another collapsible space - even
             // one outside the boundary of the inline containing that space,
             // provided they are both within the same inline formatting context
             // - is collapsed.
             //   https://www.w3.org/TR/css3-text/#white-space-phase-1
             ? child_boxes_[*last_non_collapsed_child_box_index_]
                   ->HasTrailingWhiteSpace()
             // A sequence of collapsible spaces at the beginning of a line is
             // removed.
             //   https://www.w3.org/TR/css3-text/#white-space-phase-2
             : should_collapse_leading_white_space_;
}

void LineBox::CollapseTrailingWhiteSpace() {
  if (!HasTrailingWhiteSpace()) {
    return;
  }

  // A white space between child boxes is already collapsed as a result
  // of calling |UpdateSizePreservingTrailingWhiteSpace|. Collapse the
  // trailing white space in the last non-collapsed child box (all fully
  // collapsed child boxes at the end of the line are treated as
  // non-existent for the purposes of collapsing).
  Box* last_non_collapsed_child_box =
      child_boxes_[*last_non_collapsed_child_box_index_];
  LayoutUnit child_box_pre_collapse_width =
      last_non_collapsed_child_box->width();
  last_non_collapsed_child_box->SetShouldCollapseTrailingWhiteSpace(true);
  last_non_collapsed_child_box->UpdateSize(layout_params_);
  LayoutUnit collapsed_white_space_width =
      child_box_pre_collapse_width - last_non_collapsed_child_box->width();

  shrink_to_fit_width_ -= collapsed_white_space_width;
}

void LineBox::RestoreTrailingWhiteSpace() {
  Box* last_non_collapsed_child_box =
      child_boxes_[*last_non_collapsed_child_box_index_];
  LayoutUnit child_box_pre_restore_width =
      last_non_collapsed_child_box->width();
  last_non_collapsed_child_box->SetShouldCollapseTrailingWhiteSpace(false);
  last_non_collapsed_child_box->UpdateSize(layout_params_);
  LayoutUnit restored_white_space_width =
      last_non_collapsed_child_box->width() - child_box_pre_restore_width;

  shrink_to_fit_width_ += restored_white_space_width;
}

bool LineBox::TryAddChildWithinAvailableWidth(Box* child_box) {
  // Horizontal margins, borders, and padding are respected between boxes.
  //   https://www.w3.org/TR/CSS21/visuren.html#inline-formatting
  // If the box fits within the available width, simply add it. Nothing more
  // needs to be done.
  if (child_box->GetMarginBoxWidth() <= GetAvailableWidth()) {
    BeginAddChildInternal(child_box);
    return true;
  }

  // Otherwise, the box currently does not fit, but if there is trailing
  // whitespace that can be collapsed, then one more attempt must be made to fit
  // the box within the available width.
  if (should_collapse_trailing_white_space_ &&
      (child_box->HasTrailingWhiteSpace() ||
       (child_box->IsCollapsed() && HasTrailingWhiteSpace()))) {
    bool child_has_trailing_white_space = child_box->HasTrailingWhiteSpace();
    bool child_fits_after_collapsing_trailing_whitespace = false;

    // A sequence of collapsible spaces at the end of a line is removed.
    //   https://www.w3.org/TR/css3-text/#white-space-phase-2
    if (child_has_trailing_white_space) {
      child_box->SetShouldCollapseTrailingWhiteSpace(true);
      child_box->UpdateSize(layout_params_);
    } else {
      CollapseTrailingWhiteSpace();
    }

    // Check to see if the box now fits, as the white space collapsing may have
    // freed up enough space for it.
    if (child_box->GetMarginBoxWidth() <= GetAvailableWidth()) {
      child_fits_after_collapsing_trailing_whitespace = true;
    }

    // Restore the collapsed trailing whitespace now that the space check is
    // complete.
    if (child_has_trailing_white_space) {
      child_box->SetShouldCollapseTrailingWhiteSpace(false);
      child_box->UpdateSize(layout_params_);
    } else {
      RestoreTrailingWhiteSpace();
    }

    // If there is enough space to add the child without overflowing the line,
    // add it now. This does not end the line, as more boxes may be able to fit
    // as well.
    if (child_fits_after_collapsing_trailing_whitespace) {
      BeginAddChildInternal(child_box);
      return true;
    }
  }

  // The child did not fit within the available width.
  return false;
}

bool LineBox::TryWrapOverflowingBoxAndMaybeAddSplitChild(
    WrapAtPolicy wrap_at_policy, WrapOpportunityPolicy wrap_opportunity_policy,
    Box* child_box) {
  // If none of the children justify the line's existence, then wrapping is
  // unavailable. The wrap can't happen before the first child justifying the
  // line.
  if (!first_box_justifying_line_existence_index_ &&
      !child_box->JustifiesLineExistence()) {
    return false;
  }

  // Attempt to wrap the child based upon the passed in wrap policy.
  WrapResult wrap_result = child_box->TryWrapAt(
      wrap_at_policy, wrap_opportunity_policy, LineExists(),
      GetAvailableWidth(), should_collapse_trailing_white_space_);
  // If the wrap is occurring before the box, then simply return that a wrap
  // occurred. This box is not being included within this line and does not need
  // to be added. The line ends with the box before this one.
  if (wrap_result == kWrapResultWrapBefore) {
    return true;
    // Otherwise, if a split wrap occurred, then the wrap location was found
    // within the box and the box was split. The first part of the box needs to
    // be added to the line. It is the last box included on this line. The
    // second part of the box will be the first box included on the next line.
  } else if (wrap_result == kWrapResultSplitWrap) {
    // The portion of the child box being added needs to be re-measured prior to
    // being added because the split invalidated its size.
    UpdateSizePreservingTrailingWhiteSpace(child_box);
    BeginAddChildInternal(child_box);

    // TODO: Enable this logic.
    // if (wrap_opportunity_policy == kWrapAtPolicyLastOpportunityWithinWidth) {
    // If trailing white space is being collapsed, then the child box can
    // exceed the available width prior to white space being collapsed. So the
    // DCHECK is only valid if the box's whitespace is collapsed prior to it.
    //   if (should_collapse_trailing_white_space_) {
    //     CollapseTrailingWhiteSpace();
    //   }
    //   DCHECK(child_box->GetMarginBoxWidth() <= available_width);
    // }

    return true;
    // Otherwise, no wrap location was found within the box.
  } else {
    return false;
  }
}

bool LineBox::TryWrapChildrenAtLastOpportunity(
    WrapOpportunityPolicy wrap_opportunity_policy) {
  // If none of the children justify the line's existence, then wrapping is
  // unavailable. The wrap can't happen before the first child justifying the
  // line.
  if (!first_box_justifying_line_existence_index_) {
    return false;
  }

  LayoutUnit total_wrap_width;

  // Walk the children in reverse order, since the last available wrap is
  // preferred over earlier ones. However, do not attempt any children preceding
  // the line justification index, as they are guaranteed to not be wrappable.
  size_t wrap_index = child_boxes_.size();
  size_t line_justification_index = *first_box_justifying_line_existence_index_;
  while (wrap_index > line_justification_index) {
    --wrap_index;
    Box* child_box = child_boxes_[wrap_index];

    total_wrap_width += child_box->GetMarginBoxWidth();

    // Check to see if the line existence is already justified prior to this
    // box. This will be the case if this isn't first box justifying the
    // line's existence. If this is the first box justifying the line's
    // existence, then justification occurs somewhere within this box.
    bool is_line_existence_already_justified =
        wrap_index != line_justification_index;

    // Attempt to wrap within the child. Width is not taken into account, as
    // the last wrappable location is always preferred, regardless of width.
    WrapResult wrap_result = child_box->TryWrapAt(
        kWrapAtPolicyLastOpportunity, wrap_opportunity_policy,
        is_line_existence_already_justified, LayoutUnit(), false);
    if (wrap_result != kWrapResultNoWrap) {
      // If a wrap was successfully found, then the line needs to be updated to
      // reflect that some of the previously added children are no longer being
      // fully included on the line.

      // Remove the wrap box and all subsequent boxes from the children, and
      // subtract their width from the line. In the case where this is a split
      // wrap, the portion of the split box being retained on the line will be
      // re-added after its width is recalculated below.
      child_boxes_.resize(wrap_index);
      shrink_to_fit_width_ -= total_wrap_width;

      // Update the non-collapsed indices to account for the boxes removed from
      // the line.
      if (first_non_collapsed_child_box_index_) {
        if (*first_non_collapsed_child_box_index_ >= wrap_index) {
          first_non_collapsed_child_box_index_ = base::nullopt;
          last_non_collapsed_child_box_index_ = base::nullopt;
        } else if (*last_non_collapsed_child_box_index_ >= wrap_index) {
          last_non_collapsed_child_box_index_ =
              first_non_collapsed_child_box_index_;
          size_t check_index = wrap_index;
          size_t last_check_index = *last_non_collapsed_child_box_index_ + 1;
          while (check_index > last_check_index) {
            --check_index;
            if (!child_boxes_[check_index]->IsCollapsed()) {
              last_non_collapsed_child_box_index_ = check_index;
              break;
            }
          }
        }
      }

      if (wrap_result == kWrapResultSplitWrap) {
        // If a split occurs, then the portion of the child box being added
        // needs to be re-measured prior to being added, as the split
        // invalidated the box's size.
        UpdateSizePreservingTrailingWhiteSpace(child_box);
        BeginAddChildInternal(child_box);
      }

      return true;
    }
  }

  return false;
}

void LineBox::BeginEstimateStaticPositionForAbsolutelyPositionedChild(
    Box* child_box) {
  if (!first_box_justifying_line_existence_index_) {
    ++num_absolutely_positioned_boxes_before_first_box_justifying_line_;
  }

  // The term "static position" (of an element) refers, roughly, to the position
  // an element would have had in the normal flow. More precisely:
  //
  // The static-position containing block is the containing block of a
  // hypothetical box that would have been the first box of the element if its
  // specified 'position' value had been 'static'.
  //
  // The static position for 'left' is the distance from the left edge of the
  // containing block to the left margin edge of a hypothetical box that would
  // have been the first box of the element if its 'position' property had been
  // 'static' and 'float' had been 'none'. The value is negative if the
  // hypothetical box is to the left of the containing block.
  //   https://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width

  // For the purposes of this section and the next, the term "static position"
  // (of an element) refers, roughly, to the position an element would have had
  // in the normal flow. More precisely, the static position for 'top' is the
  // distance from the top edge of the containing block to the top margin edge
  // of a hypothetical box that would have been the first box of the element if
  // its specified 'position' value had been 'static'.
  //   https://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-height

  switch (child_box->GetLevel()) {
    case Box::kInlineLevel:
      // NOTE: This case is never reached due to a bug.
      child_box->SetStaticPositionLeftFromParent(shrink_to_fit_width_);
      break;
    case Box::kBlockLevel:
      child_box->SetStaticPositionLeftFromParent(LayoutUnit());
      break;
    default:
      NOTREACHED();
      break;
  }
  child_box->SetStaticPositionTopFromParent(LayoutUnit());
}

void LineBox::BeginAddChildInternal(Box* child_box) {
  if (!first_box_justifying_line_existence_index_ &&
      child_box->JustifiesLineExistence()) {
    first_box_justifying_line_existence_index_ = child_boxes_.size();
  }

  if (!child_box->IsCollapsed()) {
    if (!first_non_collapsed_child_box_index_) {
      first_non_collapsed_child_box_index_ = child_boxes_.size();
    }
    last_non_collapsed_child_box_index_ = child_boxes_.size();
  }

  // If this child has a trailing line break, then we've reached the end of this
  // line. Nothing more can be added to it.
  if (child_box->HasTrailingLineBreak()) {
    at_end_ = true;
  }

  // Horizontal margins, borders, and padding are respected between boxes.
  //   https://www.w3.org/TR/CSS21/visuren.html#inline-formatting
  shrink_to_fit_width_ += child_box->GetMarginBoxWidth();

  child_boxes_.push_back(child_box);
}

void LineBox::ReverseChildBoxesByBidiLevels() {
  // From the highest level found in the text to the lowest odd level on each
  // line, including intermediate levels not actually present in the text,
  // reverse any contiguous sequence of characters that are at that level or
  // higher.
  //  http://unicode.org/reports/tr9/#L2
  const int kInvalidLevel = -1;
  int max_level = 0;
  int min_level = std::numeric_limits<int>::max();

  for (ChildBoxes::const_iterator child_box_iterator = child_boxes_.begin();
       child_box_iterator != child_boxes_.end(); ++child_box_iterator) {
    Box* child_box = *child_box_iterator;

    int child_level = child_box->GetBidiLevel().value_or(kInvalidLevel);
    if (child_level != kInvalidLevel) {
      if (child_level > max_level) {
        max_level = child_level;
      }
      if (child_level < min_level) {
        min_level = child_level;
      }
    }
  }

  // Reversals only occur down to the lowest odd level.
  if (min_level % 2 == 0) {
    min_level += 1;
  }

  for (int i = max_level; i >= min_level; --i) {
    ReverseChildBoxesMeetingBidiLevelThreshold(i);
  }
}

void LineBox::ReverseChildBoxesMeetingBidiLevelThreshold(int level) {
  // Walk all of the boxes in the line, looking for runs of boxes that have a
  // bidi level greater than or equal to the passed in level. Every run of two
  // or more boxes is reversed.
  int run_count = 0;
  ChildBoxes::iterator run_start;
  int child_level = 0;

  for (ChildBoxes::iterator child_box_iterator = child_boxes_.begin();
       child_box_iterator != child_boxes_.end();) {
    ChildBoxes::iterator current_iterator = child_box_iterator++;
    Box* child_box = *current_iterator;

    child_level = child_box->GetBidiLevel().value_or(child_level);

    // The child's level is greater than or equal to the required level, so it
    // qualifies for reversal.
    if (child_level >= level) {
      if (run_count == 0) {
        run_start = current_iterator;
      }
      ++run_count;
      // The child's level didn't qualify it for reversal. If there was an
      // active run, it has ended, so reverse it.
    } else {
      if (run_count > 1) {
        std::reverse(run_start, current_iterator);
      }
      run_count = 0;
    }
  }

  // A qualifying run was found that ran through the end of the children.
  // Reverse it.
  if (run_count > 1) {
    std::reverse(run_start, child_boxes_.end());
  }
}

void LineBox::UpdateChildBoxLeftPositions() {
  LayoutUnit horizontal_offset;

  // Determine the horizontal offset to apply to the child boxes from the
  // horizontal alignment.
  HorizontalAlignment horizontal_alignment = ComputeHorizontalAlignment();
  switch (horizontal_alignment) {
    case kLeftHorizontalAlignment:
      // The horizontal alignment is to the left, so no offset needs to be
      // applied based on the alignment. This places all of the available space
      // to the right of the boxes.
      break;
    case kCenterHorizontalAlignment:
      // The horizontal alignment is to the center, so offset by half of the
      // available width. This places half of the available width on each side
      // of the boxes.
      horizontal_offset = GetAvailableWidth() / 2;
      break;
    case kRightHorizontalAlignment:
      // The horizontal alignment is to the right, so offset by the full
      // available width. This places all of the available space to the left of
      // the boxes.
      horizontal_offset = GetAvailableWidth();
      break;
  }

  // Determine the horizontal offset to add to the child boxes from the indent
  // offset (https://www.w3.org/TR/CSS21/text.html#propdef-text-indent), which
  // is treated as a margin applied to the start edge of the line box. In the
  // case where the start edge is on the right, there is no offset to add, as
  // it was already included from the GetAvailableWidth() logic above.
  //
  // To add to this, the indent offset was added to |shrink_to_fit_width_| when
  // the line box was created. The above logic serves to subtract half of the
  // indent offset when the alignment is centered, and the full indent offset
  // when the alignment is to the right. Re-adding the indent offset in the case
  // where the base direction is LTR causes the indent to shift the boxes to the
  // right. Not adding it in the case where the base direction is RTL causes the
  // indent to shift the boxes to the left.
  //
  // Here are the 6 cases and the final indent offset they produce:
  // Left Align   + LTR => indent_offset
  // Center Align + LTR => indent_offset / 2
  // Right Align  + LTR => 0
  // Left Align   + RTL => 0
  // Center Align + RTL => -indent_offset / 2
  // Right Align  + RTL => -indent_offset
  if (base_direction_ != kRightToLeftBaseDirection) {
    horizontal_offset += indent_offset_;
  }

  // Set the first child box left position to the horizontal offset. This
  // results in all boxes being shifted by that offset.
  LayoutUnit child_box_left(horizontal_offset);
  for (ChildBoxes::const_iterator child_box_iterator = child_boxes_.begin();
       child_box_iterator != child_boxes_.end(); ++child_box_iterator) {
    Box* child_box = *child_box_iterator;
    child_box->set_left(child_box_left);
    child_box_left =
        child_box->GetMarginBoxRightEdgeOffsetFromContainingBlock();
  }
}

// Loops over the child boxes and sets the |baseline_offset_from_top_|
// and |height_| such that all child boxes fit.
void LineBox::SetLineBoxHeightFromChildBoxes() {
  // The minimum height consists of a minimum height above the baseline and
  // a minimum depth below it, exactly as if each line box starts with
  // a zero-width inline box with the element's font and line height properties.
  // We call that imaginary box a "strut."
  //   https://www.w3.org/TR/CSS21/visudet.html#strut
  UsedLineHeightProvider used_line_height_provider(font_metrics_, font_size_);
  line_height_->Accept(&used_line_height_provider);

  baseline_offset_from_top_ =
      used_line_height_provider.baseline_offset_from_top();
  LayoutUnit baseline_offset_from_bottom =
      used_line_height_provider.baseline_offset_from_bottom();

  LayoutUnit max_top_aligned_height;
  LayoutUnit max_bottom_aligned_height;

  // During this loop, the line box height above and below the baseline is
  // established.
  for (ChildBoxes::const_iterator child_box_iterator = child_boxes_.begin();
       child_box_iterator != child_boxes_.end(); ++child_box_iterator) {
    Box* child_box = *child_box_iterator;

    // The child box influence on the line box depends on the vertical-align
    // property.
    //   https://www.w3.org/TR/CSS21/visudet.html#propdef-vertical-align
    const scoped_refptr<cssom::PropertyValue>& vertical_align =
        child_box->computed_style()->vertical_align();
    LayoutUnit baseline_offset_from_child_top_margin_edge;
    bool update_height = false;
    if (vertical_align == cssom::KeywordValue::GetMiddle()) {
      // Align the vertical midpoint of the box with the baseline of the parent
      // box plus half the x-height (height of the 'x' glyph) of the parent.
      baseline_offset_from_child_top_margin_edge =
          GetHeightAboveMiddleAlignmentPoint(child_box);
      update_height = true;
    } else if (vertical_align == cssom::KeywordValue::GetTop()) {
      // Align the top of the aligned subtree with the top of the line box.
      // That means it will never affect the height above the baseline, but it
      // may affect the height below the baseline if this is the tallest child
      // box. We measure the tallest top-aligned box to implement that after
      // this loop.
      LayoutUnit child_height = child_box->GetInlineLevelBoxHeight();
      // If there previously was a taller bottom-aligned box, then this box does
      // not influence the line box height or baseline.
      if (child_height > max_bottom_aligned_height) {
        max_top_aligned_height = std::max(max_top_aligned_height, child_height);
      }
    } else if (vertical_align == cssom::KeywordValue::GetBottom()) {
      // Align the bottom of the aligned subtree with the bottom of the line
      // box.
      LayoutUnit child_height = child_box->GetInlineLevelBoxHeight();
      // If there previously was a taller top-aligned box, then this box does
      // not influence the line box height or baseline.
      if (child_height > max_top_aligned_height) {
        max_bottom_aligned_height =
            std::max(max_bottom_aligned_height, child_height);
      }
    } else if (vertical_align == cssom::KeywordValue::GetBaseline()) {
      // Align the baseline of the box with the baseline of the parent box.
      baseline_offset_from_child_top_margin_edge =
          child_box->GetBaselineOffsetFromTopMarginEdge();
      update_height = true;
    } else {
      NOTREACHED() << "Unknown value of \"vertical-align\".";
    }

    if (update_height) {
      baseline_offset_from_top_ =
          std::max(baseline_offset_from_top_,
                   baseline_offset_from_child_top_margin_edge);

      LayoutUnit baseline_offset_from_child_bottom_margin_edge =
          child_box->GetInlineLevelBoxHeight() -
          baseline_offset_from_child_top_margin_edge;
      baseline_offset_from_bottom =
          std::max(baseline_offset_from_bottom,
                   baseline_offset_from_child_bottom_margin_edge);
    }
  }
  // The line box height is the distance between the uppermost box top and the
  // lowermost box bottom.
  //   https://www.w3.org/TR/CSS21/visudet.html#line-height
  height_ = baseline_offset_from_top_ + baseline_offset_from_bottom;

  // In case they are aligned 'top' or 'bottom', they must be aligned so as to
  // minimize the line box height. If such boxes are tall enough, there are
  // multiple solutions and CSS 2.1 does not define the position of the line
  // box's baseline.
  //   https://www.w3.org/TR/CSS21/visudet.html#line-height
  // For the cases where CSS 2.1 does not specify the baseline position, the
  // code below matches the behavior or WebKit and Blink.
  if (max_top_aligned_height < max_bottom_aligned_height) {
    if (max_top_aligned_height > height_) {
      // The bottom aligned box is tallest, but there should also be enough
      // space below the baseline for the shorter top aligned box.
      baseline_offset_from_bottom =
          max_top_aligned_height - baseline_offset_from_top_;
    }
    if (max_bottom_aligned_height > height_) {
      // Increase the line box height above the baseline to make the largest
      // bottom-aligned child box fit.
      height_ = max_bottom_aligned_height;
      baseline_offset_from_top_ = height_ - baseline_offset_from_bottom;
    }
  } else {
    if (max_bottom_aligned_height > height_) {
      // The top aligned box is tallest, but there should also be enough
      // space above the baseline for the shorter bottom aligned box.
      baseline_offset_from_top_ =
          max_bottom_aligned_height - baseline_offset_from_bottom;
    }
    if (max_top_aligned_height > height_) {
      // Increase the line box height below the baseline to make the largest
      // top-aligned child box fit.
      height_ = max_top_aligned_height;
      baseline_offset_from_bottom = height_ - baseline_offset_from_top_;
    }
  }
}

void LineBox::UpdateChildBoxTopPositions() {
  LayoutUnit top_offset = top_;
  if (position_children_relative_to_baseline_) {
    // For InlineContainerBoxes, the children have to be aligned to the baseline
    // so that the vertical positioning can be consistent with the box position
    // with line-height and different font sizes.
    top_offset -= baseline_offset_from_top_;
  }
  // During this loop, the vertical positions of the child boxes are
  // established.
  for (ChildBoxes::const_iterator child_box_iterator = child_boxes_.begin();
       child_box_iterator != child_boxes_.end(); ++child_box_iterator) {
    Box* child_box = *child_box_iterator;

    // The child box top position depends on the vertical-align property.
    //   https://www.w3.org/TR/CSS21/visudet.html#propdef-vertical-align
    const scoped_refptr<cssom::PropertyValue>& vertical_align =
        child_box->computed_style()->vertical_align();
    LayoutUnit child_top;
    if (vertical_align == cssom::KeywordValue::GetMiddle()) {
      // Align the vertical midpoint of the box with the baseline of the parent
      //  box plus half the x-height (height of the 'x' glyph) of the parent.
      child_top = baseline_offset_from_top_ -
                  GetHeightAboveMiddleAlignmentPoint(child_box);
    } else if (vertical_align == cssom::KeywordValue::GetTop()) {
      // Align the top of the aligned subtree with the top of the line box.
      // Nothing to do child_top is already zero
    } else if (vertical_align == cssom::KeywordValue::GetBottom()) {
      // Align the bottom of the aligned subtree with the bottom of the line
      // box.
      child_top = height_ - child_box->GetInlineLevelBoxHeight();
    } else if (vertical_align == cssom::KeywordValue::GetBaseline()) {
      // Align the baseline of the box with the baseline of the parent box.
      child_top = baseline_offset_from_top_ -
                  child_box->GetBaselineOffsetFromTopMarginEdge();
    } else {
      NOTREACHED() << "Unsupported vertical_align property value";
    }
    child_box->set_top(top_offset + child_top +
                       child_box->GetInlineLevelTopMargin());
  }
}

void LineBox::MaybePlaceEllipsis() {
  // Check to see if an ellipsis should be placed, which only occurs when the
  // ellipsis has a positive width and the content has overflowed the line.
  if (ellipsis_width_ <= LayoutUnit() ||
      shrink_to_fit_width_ <= layout_params_.containing_block_size.width()) {
    return;
  }

  // Determine the preferred start edge offset for the ellipsis, which is the
  // offset at which the ellipsis begins clipping content on the line.
  // - If the ellipsis fully fits on the line, then the preferred end edge for
  //   the ellipsis is the line's end edge. Therefore the preferred ellipsis
  //   start edge is simply the end edge offset by the ellipsis's width.
  // - However, if there is insufficient space for the ellipsis to fully fit on
  //   the line, then the ellipsis should overflow the line's end edge, rather
  //   than its start edge. As a result, the preferred ellipsis start edge
  //   offset is simply the line's start edge.
  // https://www.w3.org/TR/css3-ui/#propdef-text-overflow
  LayoutUnit preferred_start_edge_offset;
  if (ellipsis_width_ <= layout_params_.containing_block_size.width()) {
    preferred_start_edge_offset =
        base_direction_ == kRightToLeftBaseDirection
            ? ellipsis_width_
            : layout_params_.containing_block_size.width() - ellipsis_width_;
  } else {
    preferred_start_edge_offset =
        base_direction_ == kRightToLeftBaseDirection
            ? layout_params_.containing_block_size.width()
            : LayoutUnit();
  }

  // Whether or not a character or atomic inline-level element has been
  // encountered within the boxes already checked on the line. The ellipsis
  // cannot be placed at an offset that precedes the first character or atomic
  // inline-level element on a line.
  // https://www.w3.org/TR/css3-ui/#propdef-text-overflow
  bool is_placement_requirement_met = false;

  // The start edge offset at which the ellipsis was eventually placed. This
  // will be set by TryPlaceEllipsisOrProcessPlacedEllipsis() within one of the
  // child boxes.
  // NOTE: While this is is guaranteed to be set later, initializing it here
  // keeps compilers from complaining about it being an uninitialized variable
  // below.
  LayoutUnit placed_start_edge_offset;

  // Walk each box within the line in base direction order attempting to place
  // the ellipsis and update the box's ellipsis state. Even after the ellipsis
  // is placed, subsequent boxes must still be processed, as their state may
  // change as a result of having an ellipsis preceding them on the line.
  if (base_direction_ == kRightToLeftBaseDirection) {
    for (ChildBoxes::reverse_iterator child_box_iterator =
             child_boxes_.rbegin();
         child_box_iterator != child_boxes_.rend(); ++child_box_iterator) {
      Box* child_box = *child_box_iterator;
      child_box->TryPlaceEllipsisOrProcessPlacedEllipsis(
          base_direction_, preferred_start_edge_offset,
          &is_placement_requirement_met, &is_ellipsis_placed_,
          &placed_start_edge_offset);
    }
  } else {
    for (ChildBoxes::iterator child_box_iterator = child_boxes_.begin();
         child_box_iterator != child_boxes_.end(); ++child_box_iterator) {
      Box* child_box = *child_box_iterator;
      child_box->TryPlaceEllipsisOrProcessPlacedEllipsis(
          base_direction_, preferred_start_edge_offset,
          &is_placement_requirement_met, &is_ellipsis_placed_,
          &placed_start_edge_offset);
    }
  }

  // Set |placed_ellipsis_offset_|. This is the offset at which an ellipsis will
  // be rendered and represents the left edge of the placed ellipsis.
  // In the case where the line's base direction is right-to-left and the start
  // edge is the right edge of the ellipsis, the width of the ellipsis must be
  // subtracted to produce the left edge of the ellipsis.
  placed_ellipsis_offset_ = base_direction_ == kRightToLeftBaseDirection
                                ? placed_start_edge_offset - ellipsis_width_
                                : placed_start_edge_offset;
}

// Returns the height of half the given box above the 'middle' of the line box.
LayoutUnit LineBox::GetHeightAboveMiddleAlignmentPoint(Box* child_box) {
  return (child_box->GetInlineLevelBoxHeight() +
          LayoutUnit(font_metrics_.x_height())) /
         2.0f;
}

LineBox::HorizontalAlignment LineBox::ComputeHorizontalAlignment() const {
  // When the total width of the inline-level boxes on a line is less than
  // the width of the line box containing them, their horizontal distribution
  // within the line box is determined by the "text-align" property.
  //   https://www.w3.org/TR/CSS21/visuren.html#inline-formatting.
  // text-align is vaguely specified by
  // https://www.w3.org/TR/css-text-3/#text-align.

  HorizontalAlignment horizontal_alignment;
  if (layout_params_.containing_block_size.width() < shrink_to_fit_width_) {
    // If the content has overflowed the line, then do not base horizontal
    // alignment on the value of text-align. Instead, simply rely upon the base
    // direction of the line, so that inline-level content begins at the
    // starting edge of the line.
    horizontal_alignment = base_direction_ == kRightToLeftBaseDirection
                               ? kRightHorizontalAlignment
                               : kLeftHorizontalAlignment;
  } else if (text_align_ == cssom::KeywordValue::GetStart()) {
    // If the value of text-align is start, then inline-level content is aligned
    // to the start edge of the line box.
    horizontal_alignment = base_direction_ == kRightToLeftBaseDirection
                               ? kRightHorizontalAlignment
                               : kLeftHorizontalAlignment;
  } else if (text_align_ == cssom::KeywordValue::GetEnd()) {
    // If the value of text-align is end, then inline-level content is aligned
    // to the end edge of the line box.
    horizontal_alignment = base_direction_ == kRightToLeftBaseDirection
                               ? kLeftHorizontalAlignment
                               : kRightHorizontalAlignment;
  } else if (text_align_ == cssom::KeywordValue::GetLeft()) {
    // If the value of text-align is left, then inline-level content is aligned
    // to the left line edge.
    horizontal_alignment = kLeftHorizontalAlignment;
  } else if (text_align_ == cssom::KeywordValue::GetRight()) {
    // If the value of text-align is right, then inline-level content is aligned
    // to the right line edge.
    horizontal_alignment = kRightHorizontalAlignment;
  } else if (text_align_ == cssom::KeywordValue::GetCenter()) {
    // If the value of text-align is center, then inline-content is centered
    // within the line box.
    horizontal_alignment = kCenterHorizontalAlignment;
  } else {
    NOTREACHED() << "Unknown value of \"text-align\".";
    horizontal_alignment = kLeftHorizontalAlignment;
  }
  return horizontal_alignment;
}

}  // namespace layout
}  // namespace cobalt
