// Copyright 2019 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/flex_line.h"

#include <algorithm>
#include <list>
#include <utility>
#include <vector>

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

namespace cobalt {
namespace layout {

FlexLine::FlexLine(const LayoutParams& layout_params,
                   bool main_direction_is_horizontal,
                   bool direction_is_reversed, LayoutUnit main_size)
    : layout_params_(layout_params),
      main_direction_is_horizontal_(main_direction_is_horizontal),
      direction_is_reversed_(direction_is_reversed),
      main_size_(main_size) {
  items_outer_main_size_ = LayoutUnit(0);
}

bool FlexLine::CanAddItem(const FlexItem& item) const {
  LayoutUnit outer_main_size =
      item.hypothetical_main_size() + item.GetContentToMarginMainAxis();
  LayoutUnit next_main_size = items_outer_main_size_ + outer_main_size;
  if (!items_.empty() && next_main_size > main_size_) {
    return false;
  }
  return true;
}

void FlexLine::AddItem(std::unique_ptr<FlexItem>&& item) {
  LayoutUnit outer_main_size =
      item->hypothetical_main_size() + item->GetContentToMarginMainAxis();

  items_outer_main_size_ += outer_main_size;
  items_.emplace_back(std::move(item));
}

void FlexLine::ResolveFlexibleLengthsAndCrossSize() {
  // Algorithm for resolving flexible lengths:
  //   https://www.w3.org/TR/css-flexbox-1/#resolve-flexible-lengths

  // 1. Determine the used flex factor.
  // If the sum is less than the flex container's inner main size, use the flex
  // grow factor.
  flex_factor_grow_ = items_outer_main_size_ < main_size_;

  // 2. Size inflexible items.
  // 3. Calculate initial free space.
  LayoutUnit flex_space = LayoutUnit();
  LayoutUnit frozen_space = LayoutUnit();
  LayoutUnit scaled_flex_shrink_factor_sum = LayoutUnit();

  // Items are removed from this container in random order.
  std::list<FlexItem*> flexible_items;
  for (auto& item : items_) {
    item->DetermineFlexFactor(flex_factor_grow_);
    // 2. Size inflexible items:
    // - any item that has a flex factor of zero.
    // - if using the flex grow factor: any item that has a flex base size
    //   greater than its hypothetical main size.
    // - if using the flex shrink factor: any item that has a flex base size
    //   smaller than its hypothetical main size.
    LayoutUnit hypothetical_main_size = item->hypothetical_main_size();

    if (0 == item->flex_factor() ||
        (flex_factor_grow_ &&
         (item->flex_base_size() > hypothetical_main_size)) ||
        (!flex_factor_grow_ &&
         (item->flex_base_size() < hypothetical_main_size))) {
      // Freeze, setting its target main size to its hypothetical main size.
      base::Optional<LayoutUnit> content_based_minimum_size =
          item->GetContentBasedMinimumSize(
              layout_params_.containing_block_size);
      if (content_based_minimum_size.has_value()) {
        hypothetical_main_size =
            std::max(hypothetical_main_size, *content_based_minimum_size);
      }
      item->set_target_main_size(hypothetical_main_size);

      // 3. Calculate initial free space.
      // For frozen items, use their outer target main size;
      frozen_space +=
          item->GetContentToMarginMainAxis() + item->target_main_size();
    } else {
      flexible_items.push_back(item.get());

      // for other items, use their outer flex base size.
      item->set_flex_space(item->GetContentToMarginMainAxis() +
                           item->flex_base_size());
      item->set_target_main_size(item->hypothetical_main_size());
      flex_space += item->flex_space();

      // Precalculate the scaled flex shrink factor.
      // If using the flex shrink factor, for every unfrozen item on the line,
      if (!flex_factor_grow_) {
        // multiply its flex shrink factor by its inner flex base size.
        item->set_scaled_flex_shrink_factor(item->flex_base_size() *
                                            item->flex_factor());
        scaled_flex_shrink_factor_sum += item->scaled_flex_shrink_factor();
      }
    }
  }

  LayoutUnit initial_free_space = main_size_ - frozen_space - flex_space;

  // 4. Loop
  while (true) {
    // a. Check for flexible items.
    if (flexible_items.empty()) {
      // If all the flex items on the line are frozen, free space has been
      // distributed; exit this loop.
      break;
    }

    // b. Calculate the remaining free space.
    LayoutUnit remaining_free_space = main_size_ - frozen_space - flex_space;

    // If the sum of the unfrozen flex items' flex factors ...
    float unfrozen_flex_factor_sum = 0;
    for (auto& item : flexible_items) {
      unfrozen_flex_factor_sum += item->flex_factor();
    }

    // ... is less than one, multiply the initial free space by this sum.
    if (unfrozen_flex_factor_sum < 1.0f) {
      LayoutUnit free_space_magnitude =
          initial_free_space * unfrozen_flex_factor_sum;
      // If the magnitude of this value is less than the magnitude of the
      // remaining free space, use this as the remaining free space.
      if ((free_space_magnitude >= LayoutUnit() &&
           free_space_magnitude < remaining_free_space) ||
          (free_space_magnitude < LayoutUnit() &&
           free_space_magnitude > remaining_free_space)) {
        remaining_free_space = free_space_magnitude;
      }
    }

    // c. Distribute free space proportional to the flex factors.
    // If the remaining free space is zero, do nothing.
    if (remaining_free_space != LayoutUnit()) {
      if (flex_factor_grow_) {
        // If using the flex grow factor.
        for (auto& item : flexible_items) {
          // Find the ratio of the item's flex grow factor to the sum of the
          // flex grow factors of all unfrozen items on the line.
          float ratio = item->flex_factor() / unfrozen_flex_factor_sum;
          // Set the item's target main size to its flex base size plus a
          // fraction of the remaining free space proportional to the ratio.
          item->set_target_main_size(item->flex_base_size() +
                                     remaining_free_space * ratio);
        }
      } else {
        // If using the flex shrink factor,
        for (auto& item : flexible_items) {
          // Find the ratio of the item's scaled flex shrink factor to the sum
          // of the scaled flex shrink factors.
          float ratio = item->scaled_flex_shrink_factor().toFloat() /
                        scaled_flex_shrink_factor_sum.toFloat();
          // Set the item's target main size to its flex base size minus a
          // fraction of the absolute value of the remaining free space
          // proportional to the ratio.
          item->set_target_main_size(item->flex_base_size() +
                                     remaining_free_space * ratio);
        }
      }
    }

    // d. Fix min/max violations.
    // Clamp each non-frozen item's target main size by its used min and max
    // main sizes. and floor its content-box size at zero.
    LayoutUnit unclamped_size = LayoutUnit();
    LayoutUnit clamped_size = LayoutUnit();
    for (auto& item : flexible_items) {
      base::Optional<LayoutUnit> maybe_used_min_space;
      if (flex_factor_grow_) {
        maybe_used_min_space = item->GetUsedMinMainAxisSizeIfNotAuto(
            layout_params_.containing_block_size);
      } else {
        maybe_used_min_space = item->GetContentBasedMinimumSize(
            layout_params_.containing_block_size);
      }
      base::Optional<LayoutUnit> used_max_space =
          item->GetUsedMaxMainAxisSizeIfNotNone(
              layout_params_.containing_block_size);

      unclamped_size += item->target_main_size();
      if (maybe_used_min_space &&
          (item->target_main_size() < *maybe_used_min_space)) {
        item->set_target_main_size(*maybe_used_min_space);
        item->set_min_violation(true);
      } else if (used_max_space && item->target_main_size() > *used_max_space) {
        item->set_target_main_size(*used_max_space);
        item->set_max_violation(true);
      } else if (item->target_main_size() < LayoutUnit()) {
        item->set_target_main_size(LayoutUnit());
        item->set_min_violation(true);
      }
      clamped_size += item->target_main_size();
    }

    // e. Freeze over-flexed items.

    // If the total violation is zero, freeze all items.
    bool freeze_all = clamped_size == unclamped_size;
    // If the total violation is positive, freeze all the items with min
    // violations.
    bool freeze_min_violations = clamped_size > unclamped_size;
    // If the total violation is negative, freeze all the items with max
    // violations.
    bool freeze_max_violations = clamped_size < unclamped_size;
    // Otherwise, do nothing.
    if (!(freeze_all || freeze_min_violations || freeze_max_violations)) {
      continue;
    }

    // Freeze the items by removing them from flexible_items and adding their
    // outer main size to the frozen space.
    for (auto item_iterator = flexible_items.begin();
         item_iterator != flexible_items.end();) {
      auto current_iterator = item_iterator++;
      auto& item = *current_iterator;
      if (freeze_all || (freeze_min_violations && item->min_violation()) ||
          (freeze_max_violations && item->max_violation())) {
        frozen_space +=
            item->GetContentToMarginMainAxis() + item->target_main_size();
        flex_space -= item->flex_space();
        if (!flex_factor_grow_) {
          scaled_flex_shrink_factor_sum -= item->scaled_flex_shrink_factor();
        }
        flexible_items.erase(current_iterator);
      }
    }
    // f. return to the start of this loop.
  }
  items_outer_main_size_ = frozen_space;

  // 5. Set each item's used main size to its target main size.
  //   https://www.w3.org/TR/css-flexbox-1/#resolve-flexible-lengths
  // Also, algorithm for Flex Layout continued from step 7:
  //   https://www.w3.org/TR/css-flexbox-1/#layout-algorithm
  // Cross Size Determination:
  // 7. Determine the hypothetical cross size of each item
  // By performing layout with the used main size and the available space.
  for (auto& item : items_) {
    item->DetermineHypotheticalCrossSize(layout_params_);
  }
}

void FlexLine::CalculateCrossSize() {
  // Algorithm for Calculate the cross size of each flex line.
  //   https://www.w3.org/TR/css-flexbox-1/#algo-cross-line

  LayoutUnit max_baseline_to_bottom = LayoutUnit();
  LayoutUnit max_hypothetical_cross_size = LayoutUnit();
  for (auto& item : items_) {
    // 1. Collect all the flex items whose inline-axis is parallel to the
    // main-axis, whose align-self is baseline, and whose cross-axis margins
    // are both non-auto.
    if (main_direction_is_horizontal_ &&
        item->GetUsedAlignSelfPropertyValue() ==
            cssom::KeywordValue::GetBaseline() &&
        !item->MarginCrossStartIsAuto() && !item->MarginCrossEndIsAuto()) {
      // Find the largest of the distances between each item's baseline and its
      // hypothetical outer cross-start edge,
      LayoutUnit baseline_to_top =
          item->box()->GetBaselineOffsetFromTopMarginEdge();
      max_baseline_to_top_ = std::max(
          max_baseline_to_top_.value_or(LayoutUnit()), baseline_to_top);
      // and the largest of the distances between each item's baseline and its
      // hypothetical outer cross-end edge,
      LayoutUnit baseline_to_bottom = item->box()->height() - baseline_to_top;
      max_baseline_to_bottom =
          std::max(max_baseline_to_bottom, baseline_to_bottom);
    } else {
      // 2. Among all the items not collected by the previous step, find the
      // largest outer hypothetical cross size.
      LayoutUnit hypothetical_cross_size = item->GetMarginBoxCrossSize();
      if (hypothetical_cross_size > max_hypothetical_cross_size) {
        max_hypothetical_cross_size = hypothetical_cross_size;
      }
    }
  }
  // ... and sum these two values.
  LayoutUnit max_baseline_cross_size =
      max_baseline_to_top_.value_or(LayoutUnit()) + max_baseline_to_bottom;

  // 3. The used cross-size of the flex line is the largest of the numbers
  // found in the previous two steps and zero.
  cross_size_ = std::max(max_hypothetical_cross_size, max_baseline_cross_size);
}

void FlexLine::DetermineUsedCrossSizes(LayoutUnit container_cross_size) {
  // 11. Determine the used cross size of each flex item->
  //   https://www.w3.org/TR/css-flexbox-1/#algo-stretch
  SizeLayoutUnit containing_block_size(LayoutUnit(), container_cross_size);
  for (auto& item : items_) {
    // If a flex item has align-self: stretch,
    // its computed cross size property is auto,
    // and neither of its cross-axis margins are auto,
    if (item->GetUsedAlignSelfPropertyValue() ==
            cssom::KeywordValue::GetStretch() &&
        item->CrossSizeIsAuto() && !item->MarginCrossStartIsAuto() &&
        !item->MarginCrossEndIsAuto()) {
      // The used outer cross size is the used cross size of its flex line,
      // clamped according to the item's used min and max cross sizes.
      LayoutUnit cross_size = cross_size_ - item->GetContentToMarginCrossAxis();
      base::Optional<LayoutUnit> min_cross_size =
          item->GetUsedMinCrossAxisSizeIfNotAuto(containing_block_size);
      if (min_cross_size && (*min_cross_size > cross_size)) {
        cross_size = *min_cross_size;
      }
      base::Optional<LayoutUnit> max_cross_size =
          item->GetUsedMaxCrossAxisSizeIfNotNone(containing_block_size);
      if (max_cross_size && *max_cross_size < cross_size) {
        cross_size = *max_cross_size;
      }
      item->SetCrossSize(cross_size);

      // TODO: If the flex item has align-self: stretch, redo layout for its
      // contents, treating this used size as its definite cross size so that
      // percentage-sized children can be resolved.
    }
  }
}

void FlexLine::SetMainAxisPosition(LayoutUnit pos, FlexItem* item) {
  if (direction_is_reversed_) {
    item->SetMainAxisStart(main_size_ - pos - item->GetMarginBoxMainSize());
  } else {
    item->SetMainAxisStart(pos);
  }
}

void FlexLine::DoMainAxisAlignment() {
  // Algorithm for main axis alignment:
  //   https://www.w3.org/TR/css-flexbox-1/#main-alignment
  // 12. Distribute any remaining free space.
  //   https://www.w3.org/TR/css-flexbox-1/#algo-main-align

  // If the remaining free space is positive and at least one main-axis margin
  // on this line is auto, distribute the free space equally among these
  // margins.
  std::vector<bool> auto_margins(items_.size() * 2);
  int auto_margin_count = 0;
  int margin_idx = 0;
  for (auto& item : items_) {
    bool auto_main_start = item->MarginMainStartIsAuto();
    bool auto_main_end = item->MarginMainEndIsAuto();
    auto_margins[margin_idx++] = auto_main_start;
    auto_margins[margin_idx++] = auto_main_end;
    auto_margin_count += (auto_main_start ? 1 : 0) + (auto_main_end ? 1 : 0);
  }
  LayoutUnit leftover_free_space = main_size_ - items_outer_main_size_;
  if (auto_margin_count > 0) {
    LayoutUnit free_space_between = leftover_free_space / auto_margin_count;

    margin_idx = 0;
    LayoutUnit pos = LayoutUnit();
    for (auto& item : items_) {
      pos += auto_margins[margin_idx++] ? free_space_between : LayoutUnit();
      LayoutUnit main_size = item->GetMarginBoxMainSize();
      SetMainAxisPosition(pos, item.get());
      pos += main_size;
      pos += auto_margins[margin_idx++] ? free_space_between : LayoutUnit();
    }

    return;
  }

  DCHECK(!items_.empty());

  // Align the items along the main-axis per justify-content.
  const scoped_refptr<cobalt::cssom::PropertyValue>& justify_content =
      items_.front()->GetUsedJustifyContentPropertyValue();

  bool leftover_free_space_is_negative = leftover_free_space < LayoutUnit();

  if (justify_content == cssom::KeywordValue::GetFlexStart() ||
      (leftover_free_space_is_negative &&
       justify_content == cssom::KeywordValue::GetSpaceBetween())) {
    // Flex items are packed toward the start of the line.
    //   https://www.w3.org/TR/css-flexbox-1/#valdef-justify-content-flex-start
    // If the leftover free-space is negative, space-between is identical to
    // flex-start.
    //   https://www.w3.org/TR/css-flexbox-1/#valdef-justify-content-space-between
    LayoutUnit pos = LayoutUnit();
    for (auto& item : items_) {
      LayoutUnit main_size = item->GetMarginBoxMainSize();
      SetMainAxisPosition(pos, item.get());
      pos += main_size;
    }
  } else if (justify_content == cssom::KeywordValue::GetFlexEnd()) {
    // Flex items are packed toward the end of the line.
    //   https://www.w3.org/TR/css-flexbox-1/#valdef-justify-content-flex-end
    LayoutUnit pos = main_size_;
    for (auto item_iterator = items_.rbegin(); item_iterator != items_.rend();
         ++item_iterator) {
      auto& item = *item_iterator;
      LayoutUnit main_size = item->GetMarginBoxMainSize();
      pos -= main_size;
      SetMainAxisPosition(pos, item.get());
    }
  } else if (justify_content == cssom::KeywordValue::GetCenter() ||
             (leftover_free_space_is_negative &&
              justify_content == cssom::KeywordValue::GetSpaceAround())) {
    // Flex items are packed toward the center of the line.
    //   https://www.w3.org/TR/css-flexbox-1/#valdef-justify-content-center
    // If the leftover free-space is negative, space-around is identical to
    // center.
    //   https://www.w3.org/TR/css-flexbox-1/#valdef-justify-content-space-around
    LayoutUnit pos = leftover_free_space / 2;
    for (auto& item : items_) {
      LayoutUnit main_size = item->GetMarginBoxMainSize();
      SetMainAxisPosition(pos, item.get());
      pos += main_size;
    }
  } else if (justify_content == cssom::KeywordValue::GetSpaceBetween()) {
    // Flex items are evenly distributed in the line.
    //   https://www.w3.org/TR/css-flexbox-1/#valdef-justify-content-space-between
    LayoutUnit free_space_between =
        (items_.size() < 2)
            ? LayoutUnit()
            : leftover_free_space / static_cast<int>(items_.size() - 1);
    LayoutUnit pos = LayoutUnit();
    for (auto& item : items_) {
      LayoutUnit main_size = item->GetMarginBoxMainSize();
      SetMainAxisPosition(pos, item.get());
      pos += main_size + free_space_between;
    }
  } else if (justify_content == cssom::KeywordValue::GetSpaceAround()) {
    // Flex items are evenly distributed in the line, with half-size spaces on
    // either end.
    //   https://www.w3.org/TR/css-flexbox-1/#valdef-justify-content-space-around
    LayoutUnit free_space_between =
        leftover_free_space / static_cast<int>(items_.size());
    LayoutUnit free_space_before = free_space_between / 2;
    LayoutUnit pos = LayoutUnit();

    for (auto& item : items_) {
      LayoutUnit main_size = item->GetMarginBoxMainSize();
      SetMainAxisPosition(pos + free_space_before, item.get());
      pos += main_size + free_space_between;
    }
  } else {
    // Added as sanity check for unsupported values.
    NOTREACHED();
  }
}

void FlexLine::DoCrossAxisAlignment(LayoutUnit line_cross_axis_start) {
  // Algorithm for cross axis alignment:
  //   https://www.w3.org/TR/css-flexbox-1/#cross-alignment
  // 13. Resolve cross-axis auto margins.
  // 14. Align all flex items along the cross-axis per align-self.
  for (auto& item : items_) {
    LayoutUnit cross_axis_start = LayoutUnit();

    bool auto_margin_cross_start = item->MarginCrossStartIsAuto();
    bool auto_margin_cross_end = item->MarginCrossEndIsAuto();
    LayoutUnit cross_size = item->GetMarginBoxCrossSize();
    if (auto_margin_cross_start || auto_margin_cross_end) {
      if (auto_margin_cross_start) {
        cross_axis_start =
            (cross_size_ - cross_size) / (auto_margin_cross_end ? 2 : 1);
      }
    } else {
      const auto& align_self = item->GetUsedAlignSelfPropertyValue();
      // Only flex-end, center, and baseline can result in a cross_axis_start
      // that is not aligned to the line cross start edge.
      if (align_self == cssom::KeywordValue::GetFlexEnd()) {
        cross_axis_start = cross_size_ - cross_size;
      } else if (align_self == cssom::KeywordValue::GetCenter()) {
        cross_axis_start = (cross_size_ - cross_size) / 2;
      } else if (align_self == cssom::KeywordValue::GetBaseline()) {
        if (main_direction_is_horizontal_ && max_baseline_to_top_.has_value()) {
          LayoutUnit baseline_to_top =
              item->box()->GetBaselineOffsetFromTopMarginEdge();
          cross_axis_start = *max_baseline_to_top_ - baseline_to_top;
        }
      } else {
        DCHECK((align_self == cssom::KeywordValue::GetFlexStart()) ||
               (align_self == cssom::KeywordValue::GetStretch()));
      }
    }
    item->SetCrossAxisStart(line_cross_axis_start + cross_axis_start);
  }
}

LayoutUnit FlexLine::GetBaseline() {
  if (max_baseline_to_top_.has_value()) {
    return *max_baseline_to_top_;
  }
  LayoutUnit baseline = cross_size_;
  if (!items_.empty()) {
    Box* box = items_.front()->box();
    baseline = box->top() + box->GetBaselineOffsetFromTopMarginEdge();
  }
  return baseline;
}

}  // namespace layout
}  // namespace cobalt
