// 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.

#ifndef COBALT_LAYOUT_FLEX_ITEM_H_
#define COBALT_LAYOUT_FLEX_ITEM_H_

#include <vector>

#include "base/logging.h"
#include "base/optional.h"
#include "cobalt/layout/box.h"
#include "cobalt/layout/layout_unit.h"

namespace cobalt {
namespace layout {

// Base class for all Flex Items.
class FlexItem {
 public:
  // Disallow Copy and Assign.
  explicit FlexItem(const FlexItem&) = delete;
  FlexItem& operator=(const FlexItem&) = delete;
  explicit FlexItem(FlexItem&& that) = delete;

  virtual ~FlexItem() = default;

  FlexItem(Box* box, bool main_direction_is_horizontal);

  static std::unique_ptr<FlexItem> Create(Box* box,
                                          bool main_direction_is_horizontal);

  Box* box() const { return box_; }
  const scoped_refptr<const cssom::CSSComputedStyleData>& computed_style()
      const {
    return box()->computed_style();
  }

  LayoutUnit flex_base_size() const { return flex_base_size_; }
  LayoutUnit hypothetical_main_size() const { return hypothetical_main_size_; }

  void set_target_main_size(LayoutUnit target_main_size) {
    target_main_size_ = target_main_size;
  }
  LayoutUnit target_main_size() const { return target_main_size_; }

  void set_flex_space(LayoutUnit flex_space) { flex_space_ = flex_space; }
  LayoutUnit flex_space() const { return flex_space_; }

  void set_scaled_flex_shrink_factor(LayoutUnit scaled_flex_shrink_factor) {
    scaled_flex_shrink_factor_ = scaled_flex_shrink_factor;
  }
  LayoutUnit scaled_flex_shrink_factor() const {
    return scaled_flex_shrink_factor_;
  }

  void set_flex_factor(float flex_factor) { flex_factor_ = flex_factor; }
  void DetermineFlexFactor(bool flex_factor_is_grow);
  float flex_factor() const { return flex_factor_; }

  void set_max_violation(bool max_violation) { max_violation_ = max_violation; }
  bool max_violation() const { return max_violation_; }
  void set_min_violation(bool min_violation) { min_violation_ = min_violation; }
  bool min_violation() const { return min_violation_; }

  const scoped_refptr<cobalt::cssom::PropertyValue>&
  GetUsedAlignSelfPropertyValue();
  const scoped_refptr<cobalt::cssom::PropertyValue>&
  GetUsedJustifyContentPropertyValue();

  // Determine the flex base size.
  //   https://www.w3.org/TR/css-flexbox-1/#flex-base-size
  void DetermineFlexBaseSize(const LayoutParams& layout_params,
                             const base::Optional<LayoutUnit>& main_space,
                             bool container_shrink_to_fit_width_forced);

  // Determine the hypothetical main size.
  //   https://www.w3.org/TR/css-flexbox-1/#hypothetical-main-size
  void DetermineHypotheticalMainSize(const SizeLayoutUnit& available_space);

  base::Optional<LayoutUnit> GetContentBasedMinimumSize(
      const SizeLayoutUnit& containing_block_size) const;

  // Return the size difference between the content and margin box on the main
  // axis.
  virtual LayoutUnit GetContentToMarginMainAxis() const = 0;

  // Return the size difference between the content and margin box on the cross
  // axis.
  virtual LayoutUnit GetContentToMarginCrossAxis() const = 0;

  // Return the used style for the size in the main axis.
  virtual base::Optional<LayoutUnit> GetUsedMainAxisSizeIfNotAuto(
      const SizeLayoutUnit& containing_block_size) const = 0;

  // Return the used style for the min size in the main axis.
  virtual base::Optional<LayoutUnit> GetUsedMinMainAxisSizeIfNotAuto(
      const SizeLayoutUnit& containing_block_size) const = 0;

  // Return the used style for the min size in the cross axis.
  virtual base::Optional<LayoutUnit> GetUsedMinCrossAxisSizeIfNotAuto(
      const SizeLayoutUnit& containing_block_size) const = 0;

  // Return the used style for the max size in the main axis.
  virtual base::Optional<LayoutUnit> GetUsedMaxMainAxisSizeIfNotNone(
      const SizeLayoutUnit& containing_block_size) const = 0;

  // Return the used style for the max size in the cross axis.
  virtual base::Optional<LayoutUnit> GetUsedMaxCrossAxisSizeIfNotNone(
      const SizeLayoutUnit& containing_block_size) const = 0;

  // Determine the hypothetical cross size.
  //   https://www.w3.org/TR/css-flexbox-1/#algo-cross-item
  virtual void DetermineHypotheticalCrossSize(
      const LayoutParams& layout_params) = 0;

  virtual LayoutUnit GetContentBoxMainSize() const = 0;
  virtual LayoutUnit GetMarginBoxMainSize() const = 0;
  virtual LayoutUnit GetMarginBoxCrossSize() const = 0;

  // Return true if the computed cross axis size is auto.
  virtual bool CrossSizeIsAuto() const = 0;
  // Return true if the margin at the main axis start is auto.
  virtual bool MarginMainStartIsAuto() const = 0;
  // Return true if the margin at the main axis end is auto.
  virtual bool MarginMainEndIsAuto() const = 0;
  // Return true if the margin at the cross axis start is auto.
  virtual bool MarginCrossStartIsAuto() const = 0;
  // Return true if the margin at the cross axis end is auto.
  virtual bool MarginCrossEndIsAuto() const = 0;

  virtual void SetCrossSize(LayoutUnit cross_size) = 0;
  virtual void SetMainAxisStart(LayoutUnit position) = 0;
  virtual void SetCrossAxisStart(LayoutUnit position) = 0;

 private:
  // Return true if the overflow is visible
  bool OverflowIsVisible() const;

  Box* const box_ = nullptr;
  const bool main_direction_is_horizontal_;
  LayoutUnit flex_base_size_ = LayoutUnit();
  LayoutUnit hypothetical_main_size_ = LayoutUnit();

  LayoutUnit target_main_size_ = LayoutUnit();
  LayoutUnit flex_space_ = LayoutUnit();
  LayoutUnit scaled_flex_shrink_factor_ = LayoutUnit();
  float flex_factor_ = 0;
  bool max_violation_ = false;
  bool min_violation_ = false;
};

#ifdef COBALT_BOX_DUMP_ENABLED

inline std::ostream& operator<<(std::ostream& stream, const FlexItem& item) {
  stream << "flex_base_size= " << item.flex_base_size()
         << " hypothetical_main_size = " << item.hypothetical_main_size()
         << " target_main_size = " << item.target_main_size()
         << " flex_space =" << item.flex_space() << "  box " << *item.box()
         << " flex_factor = " << item.flex_factor();
  return stream;
}

#endif  // COBALT_BOX_DUMP_ENABLED

}  // namespace layout
}  // namespace cobalt

#endif  // COBALT_LAYOUT_FLEX_ITEM_H_
