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

#ifndef COBALT_LAYOUT_BLOCK_CONTAINER_BOX_H_
#define COBALT_LAYOUT_BLOCK_CONTAINER_BOX_H_

#include "base/optional.h"
#include "cobalt/layout/base_direction.h"
#include "cobalt/layout/container_box.h"
#include "cobalt/layout/size_layout_unit.h"

namespace cobalt {
namespace layout {

class FormattingContext;

// A base class for block container boxes which implements most of the
// functionality except establishing a formatting context.
//
// Derived classes establish either:
//   - a block formatting context (and thus contain only block-level boxes);
//   - an inline formatting context (and thus contain only inline-level boxes).
//   https://www.w3.org/TR/CSS21/visuren.html#block-boxes
//
// Note that "block container box" and "block-level box" are different concepts.
// A block container box itself may either be a block-level box or
// an inline-level box.
//   https://www.w3.org/TR/CSS21/visuren.html#inline-boxes
class BlockContainerBox : public ContainerBox {
 public:
  BlockContainerBox(const scoped_refptr<cssom::CSSComputedStyleDeclaration>&
                        css_computed_style_declaration,
                    BaseDirection base_direction,
                    UsedStyleProvider* used_style_provider,
                    LayoutStatTracker* layout_stat_tracker);
  ~BlockContainerBox() OVERRIDE;

  // From |Box|.
  void UpdateContentSizeAndMargins(const LayoutParams& layout_params) OVERRIDE;
  WrapResult TryWrapAt(WrapAtPolicy wrap_at_policy,
                       WrapOpportunityPolicy wrap_opportunity_policy,
                       bool is_line_existence_justified,
                       LayoutUnit available_width,
                       bool should_collapse_trailing_white_space) OVERRIDE;

  bool TrySplitAtSecondBidiLevelRun() OVERRIDE;
  base::optional<int> GetBidiLevel() const OVERRIDE;

  void SetShouldCollapseLeadingWhiteSpace(
      bool should_collapse_leading_white_space) OVERRIDE;
  void SetShouldCollapseTrailingWhiteSpace(
      bool should_collapse_trailing_white_space) OVERRIDE;
  bool HasLeadingWhiteSpace() const OVERRIDE;
  bool HasTrailingWhiteSpace() const OVERRIDE;
  bool IsCollapsed() const OVERRIDE;

  bool JustifiesLineExistence() const OVERRIDE;
  bool AffectsBaselineInBlockFormattingContext() const OVERRIDE;
  LayoutUnit GetBaselineOffsetFromTopMarginEdge() const OVERRIDE;

  // From |ContainerBox|.
  scoped_refptr<ContainerBox> TrySplitAtEnd() OVERRIDE;

  BaseDirection GetBaseDirection() const;

 protected:
  // From |Box|.
  bool IsTransformable() const OVERRIDE;

#ifdef COBALT_BOX_DUMP_ENABLED
  void DumpProperties(std::ostream* stream) const OVERRIDE;
#endif  // COBALT_BOX_DUMP_ENABLED

  // Rest of the protected methods.

  // Lays out children recursively.
  virtual scoped_ptr<FormattingContext> UpdateRectOfInFlowChildBoxes(
      const LayoutParams& child_layout_params) = 0;

 private:
  void UpdateContentWidthAndMargins(
      LayoutUnit containing_block_width, bool shrink_to_fit_width_forced,
      bool width_depends_on_containing_block,
      const base::optional<LayoutUnit>& maybe_left,
      const base::optional<LayoutUnit>& maybe_right,
      const base::optional<LayoutUnit>& maybe_margin_left,
      const base::optional<LayoutUnit>& maybe_margin_right,
      const base::optional<LayoutUnit>& maybe_width,
      const base::optional<LayoutUnit>& maybe_height);
  void UpdateContentHeightAndMargins(
      const SizeLayoutUnit& containing_block_size,
      const base::optional<LayoutUnit>& maybe_top,
      const base::optional<LayoutUnit>& maybe_bottom,
      const base::optional<LayoutUnit>& maybe_margin_top,
      const base::optional<LayoutUnit>& maybe_margin_bottom,
      const base::optional<LayoutUnit>& maybe_height);

  void UpdateWidthAssumingAbsolutelyPositionedBox(
      LayoutUnit containing_block_width,
      const base::optional<LayoutUnit>& maybe_left,
      const base::optional<LayoutUnit>& maybe_right,
      const base::optional<LayoutUnit>& maybe_width,
      const base::optional<LayoutUnit>& maybe_margin_left,
      const base::optional<LayoutUnit>& maybe_margin_right,
      const base::optional<LayoutUnit>& maybe_height);
  void UpdateHeightAssumingAbsolutelyPositionedBox(
      LayoutUnit containing_block_height,
      const base::optional<LayoutUnit>& maybe_top,
      const base::optional<LayoutUnit>& maybe_bottom,
      const base::optional<LayoutUnit>& maybe_height,
      const base::optional<LayoutUnit>& maybe_margin_top,
      const base::optional<LayoutUnit>& maybe_margin_bottom,
      const FormattingContext& formatting_context);

  void UpdateWidthAssumingBlockLevelInFlowBox(
      LayoutUnit containing_block_width,
      const base::optional<LayoutUnit>& maybe_width,
      const base::optional<LayoutUnit>& maybe_margin_left,
      const base::optional<LayoutUnit>& maybe_margin_right);
  void UpdateWidthAssumingInlineLevelInFlowBox(
      LayoutUnit containing_block_width,
      const base::optional<LayoutUnit>& maybe_width,
      const base::optional<LayoutUnit>& maybe_margin_left,
      const base::optional<LayoutUnit>& maybe_margin_right,
      const base::optional<LayoutUnit>& maybe_height);

  void UpdateHeightAssumingInFlowBox(
      const base::optional<LayoutUnit>& maybe_height,
      const base::optional<LayoutUnit>& maybe_margin_top,
      const base::optional<LayoutUnit>& maybe_margin_bottom,
      const FormattingContext& formatting_context);

  LayoutUnit GetShrinkToFitWidth(
      LayoutUnit containing_block_width,
      const base::optional<LayoutUnit>& maybe_height);

  // A vertical offset of the baseline of the last child box that has one,
  // relatively to the origin of the block container box. Disengaged, if none
  // of the child boxes have a baseline.
  base::optional<LayoutUnit> maybe_baseline_offset_from_top_margin_edge_;

  // The primary direction in which inline content is ordered on a line and the
  // sides on which the "start" and "end" of a line are.
  // https://www.w3.org/TR/css-writing-modes-3/#inline-base-direction
  BaseDirection base_direction_;

  DISALLOW_COPY_AND_ASSIGN(BlockContainerBox);
};

}  // namespace layout
}  // namespace cobalt

#endif  // COBALT_LAYOUT_BLOCK_CONTAINER_BOX_H_
