// Copyright 2014 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/layout.h"

#include <utility>

#include "base/trace_event/trace_event.h"
#include "cobalt/base/stop_watch.h"
#include "cobalt/cssom/computed_style.h"
#include "cobalt/cssom/css_style_declaration.h"
#include "cobalt/dom/document.h"
#include "cobalt/dom/html_body_element.h"
#include "cobalt/dom/html_element_context.h"
#include "cobalt/dom/html_html_element.h"
#include "cobalt/layout/benchmark_stat_names.h"
#include "cobalt/layout/box_generator.h"
#include "cobalt/layout/initial_containing_block.h"
#include "cobalt/layout/layout_boxes.h"
#include "cobalt/layout/used_style.h"
#include "cobalt/render_tree/animations/animate_node.h"
#include "cobalt/render_tree/matrix_transform_node.h"
#include "starboard/extension/graphics.h"

namespace cobalt {
namespace layout {

namespace {

class ScopedParagraph {
 public:
  explicit ScopedParagraph(const scoped_refptr<Paragraph>& paragraph)
      : paragraph_(paragraph) {}

  ~ScopedParagraph() { paragraph_->Close(); }

  scoped_refptr<Paragraph>& get() { return paragraph_; }

 private:
  scoped_refptr<Paragraph> paragraph_;
};

}  // namespace

void UpdateComputedStylesAndLayoutBoxTree(
    const icu::Locale& locale, const scoped_refptr<dom::Document>& document,
    int dom_max_element_depth, UsedStyleProvider* used_style_provider,
    LayoutStatTracker* layout_stat_tracker,
    icu::BreakIterator* line_break_iterator,
    icu::BreakIterator* character_break_iterator,
    scoped_refptr<BlockLevelBlockContainerBox>* initial_containing_block,
    bool clear_window_with_background_color) {
  TRACE_EVENT0("cobalt::layout", "UpdateComputedStylesAndLayoutBoxTree()");
  // Layout-related cleanup is performed on the UsedStyleProvider in this
  // object's destructor.
  UsedStyleProviderLayoutScope used_style_provider_layout_scope(
      used_style_provider);

  // Update the computed style of all elements in the DOM, if necessary.
  document->UpdateComputedStyles();

  base::StopWatch stop_watch_layout_box_tree(
      LayoutStatTracker::kStopWatchTypeLayoutBoxTree,
      base::StopWatch::kAutoStartOn, layout_stat_tracker);

  // Create initial containing block.
  InitialContainingBlockCreationResults
      initial_containing_block_creation_results = CreateInitialContainingBlock(
          *document->initial_computed_style_data(), document,
          used_style_provider, layout_stat_tracker);
  *initial_containing_block = initial_containing_block_creation_results.box;

  if (clear_window_with_background_color) {
    (*initial_containing_block)->set_blend_background_color(false);
  }

  // Associate the UI navigation root with the initial containing block.
  if (document->window()) {
    (*initial_containing_block)
        ->SetUiNavItem(document->window()->GetUiNavRoot());
  }

  // Generate boxes.
  if (document->html()) {
    TRACE_EVENT0("cobalt::layout", kBenchmarkStatBoxGeneration);
    base::StopWatch stop_watch_box_generation(
        LayoutStatTracker::kStopWatchTypeBoxGeneration,
        base::StopWatch::kAutoStartOn, layout_stat_tracker);

    // If the implicit root is a root for any observers, the initial containing
    // block should reference the corresponding IntersectionObserverRoots.
    dom::HTMLElement* html_element =
        document->document_element()->AsHTMLElement();
    BoxIntersectionObserverModule::IntersectionObserverRootVector roots =
        html_element->GetLayoutIntersectionObserverRoots();
    BoxIntersectionObserverModule::IntersectionObserverTargetVector targets =
        html_element->GetLayoutIntersectionObserverTargets();
    (*initial_containing_block)
        ->AddIntersectionObserverRootsAndTargets(std::move(roots),
                                                 std::move(targets));

    ScopedParagraph scoped_paragraph(
        new Paragraph(locale, (*initial_containing_block)->base_direction(),
                      Paragraph::DirectionalFormattingStack(),
                      line_break_iterator, character_break_iterator));
    BoxGenerator::Context context(
        used_style_provider, layout_stat_tracker, line_break_iterator,
        character_break_iterator,
        initial_containing_block_creation_results.background_style_source,
        dom_max_element_depth);
    BoxGenerator root_box_generator(
        (*initial_containing_block)->css_computed_style_declaration(),
        (*initial_containing_block)
            ->css_computed_style_declaration()
            ->animations(),
        &(scoped_paragraph.get()), 1 /* dom_element_depth */, &context);
    document->html()->Accept(&root_box_generator);
    const Boxes& root_boxes = root_box_generator.boxes();
    for (Boxes::const_iterator root_box_iterator = root_boxes.begin();
         root_box_iterator != root_boxes.end(); ++root_box_iterator) {
      (*initial_containing_block)->AddChild(*root_box_iterator);
    }
  }

  // Split bidi level runs.
  // The bidi levels were calculated for the paragraphs during box generation.
  // Now the text boxes are split between level runs, so that they will be
  // reversible during layout without requiring additional run-induced splits.
  {
    TRACE_EVENT0("cobalt::layout", "SplitBidiLevelRuns");
    (*initial_containing_block)->SplitBidiLevelRuns();
  }

  // Layout.
  {
    TRACE_EVENT0("cobalt::layout", kBenchmarkStatUpdateUsedSizes);
    base::StopWatch stop_watch_update_used_sizes(
        LayoutStatTracker::kStopWatchTypeUpdateUsedSizes,
        base::StopWatch::kAutoStartOn, layout_stat_tracker);

    (*initial_containing_block)->set_left(LayoutUnit());
    (*initial_containing_block)->set_top(LayoutUnit());
    (*initial_containing_block)->UpdateSize(LayoutParams());
  }

  // Update all UI navigation elements with the sizes and positions of their
  // corresponding layout boxes.
  if (document->ui_nav_needs_layout()) {
    TRACE_EVENT0("cobalt::layout", "UpdateUiNavigationItems");
    document->set_ui_nav_needs_layout(false);

    const auto& ui_nav_elements = document->ui_navigation_elements();
    (*initial_containing_block)->UpdateUiNavigationItem();
    for (dom::HTMLElement* html_element : ui_nav_elements) {
      LayoutBoxes* layout_boxes = base::polymorphic_downcast<LayoutBoxes*>(
          html_element->layout_boxes());
      if (layout_boxes) {
        for (Box* box : layout_boxes->boxes()) {
          box->UpdateUiNavigationItem();
        }
      }
    }
  }
}

void UpdateUiNavItemBoundaries(const scoped_refptr<dom::Document>& document) {
  TRACE_EVENT0("cobalt::layout", "UpdateUiNavItemBoundaries()");
  const auto& ui_nav_elements = document->ui_navigation_elements();
  for (dom::HTMLElement* html_element : ui_nav_elements) {
    html_element->SetUiNavItemBounds();
  }
}

scoped_refptr<render_tree::Node> GenerateRenderTreeFromBoxTree(
    UsedStyleProvider* used_style_provider,
    LayoutStatTracker* layout_stat_tracker,
    scoped_refptr<BlockLevelBlockContainerBox>* initial_containing_block) {
  TRACE_EVENT0("cobalt::layout", "GenerateRenderTreeFromBoxTree()");
  render_tree::CompositionNode::Builder render_tree_root_builder;
  {
    TRACE_EVENT0("cobalt::layout", kBenchmarkStatRenderAndAnimate);
    base::StopWatch stop_watch_render_and_animate(
        LayoutStatTracker::kStopWatchTypeRenderAndAnimate,
        base::StopWatch::kAutoStartOn, layout_stat_tracker);

    (*initial_containing_block)
        ->RenderAndAnimate(&render_tree_root_builder, math::Vector2dF(0, 0),
                           (initial_containing_block->get()));
  }

  // During computed style update and RenderAndAnimate, we get the actual images
  // that are linked to their URLs. Now go through them and update the playing
  // status for animated images.
  used_style_provider->UpdateAnimatedImages();

  render_tree::Node* static_root_node =
      new render_tree::CompositionNode(std::move(render_tree_root_builder));

  // Support insertion of a custom transform at the render tree root.
  static const CobaltExtensionGraphicsApi* s_graphics_extension =
      static_cast<const CobaltExtensionGraphicsApi*>(
          SbSystemGetExtension(kCobaltExtensionGraphicsName));
  float m00, m01, m02, m10, m11, m12, m20, m21, m22;
  if (s_graphics_extension &&
      strcmp(s_graphics_extension->name, kCobaltExtensionGraphicsName) == 0 &&
      s_graphics_extension->version >= 5 &&
      s_graphics_extension->GetRenderRootTransform(&m00, &m01, &m02, &m10, &m11,
                                                   &m12, &m20, &m21, &m22)) {
    static_root_node = new render_tree::MatrixTransformNode(
        static_root_node, math::Matrix3F::FromValues(m00, m01, m02, m10, m11,
                                                     m12, m20, m21, m22));
  }

  // Make it easy to animate the entire tree by placing an AnimateNode at the
  // root to merge any sub-AnimateNodes.
  render_tree::animations::AnimateNode* animate_node =
      new render_tree::animations::AnimateNode(static_root_node);

  return animate_node;
}

}  // namespace layout
}  // namespace cobalt
