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

#include <algorithm>
#include <cmath>
#include <string>

#include "base/bind.h"
#include "base/debug/trace_event.h"
#include "base/memory/scoped_ptr.h"
#include "base/timer.h"
#include "cobalt/cssom/cascade_precedence.h"
#include "cobalt/dom/camera_3d.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/block_formatting_block_container_box.h"
#include "cobalt/layout/initial_containing_block.h"
#include "cobalt/layout/layout.h"
#include "cobalt/render_tree/animations/animate_node.h"
#include "cobalt/render_tree/matrix_transform_3d_node.h"
#include "third_party/icu/source/common/unicode/brkiter.h"
#include "third_party/icu/source/common/unicode/locid.h"

namespace cobalt {
namespace layout {

class LayoutManager::Impl : public dom::DocumentObserver {
 public:
  Impl(const std::string& name, const scoped_refptr<dom::Window>& window,
       const OnRenderTreeProducedCallback& on_render_tree_produced,
       LayoutTrigger layout_trigger, int dom_max_element_depth,
       float layout_refresh_rate, const std::string& language,
       LayoutStatTracker* layout_stat_tracker);
  ~Impl();

  // From dom::DocumentObserver.
  void OnLoad() OVERRIDE;
  void OnMutation() OVERRIDE;
  void OnFocusChanged() OVERRIDE {}

  // Called to perform a synchronous layout.
  void DoSynchronousLayout();

  void Suspend();
  void Resume();

  bool IsNewRenderTreePending() const;

 private:
  void StartLayoutTimer();
  void DoLayoutAndProduceRenderTree();

#if defined(ENABLE_TEST_RUNNER)
  void DoTestRunnerLayoutCallback();
#endif  // ENABLE_TEST_RUNNER

  const scoped_refptr<dom::Window> window_;
  const icu::Locale locale_;
  const scoped_ptr<UsedStyleProvider> used_style_provider_;
  const OnRenderTreeProducedCallback on_render_tree_produced_callback_;
  const LayoutTrigger layout_trigger_;

  // This flag indicates whether or not we should do a re-layout.  The flag
  // is checked at a regular interval (e.g. 60Hz) and if it is set to true,
  // a layout is initiated and it is set back to false.  Events such as
  // DOM mutations will set this flag back to true.
  base::CVal<bool> layout_dirty_;

  // Construction of |BreakIterator| requires a disk read, so we cache them
  // in the layout manager in order to reuse them with all layouts happening
  // in the context of one |WebModule|.
  //   http://userguide.icu-project.org/boundaryanalysis#TOC-Reuse
  scoped_ptr<icu::BreakIterator> line_break_iterator_;
  scoped_ptr<icu::BreakIterator> character_break_iterator_;

  base::Timer layout_timer_;
  int dom_max_element_depth_;
  float layout_refresh_rate_;

  LayoutStatTracker* const layout_stat_tracker_;

  // The initial containing block is kept until the next layout, so that
  // the box tree remains valid.
  scoped_refptr<BlockLevelBlockContainerBox> initial_containing_block_;

  bool suspended_;

  DISALLOW_COPY_AND_ASSIGN(Impl);
};

namespace {

void UpdateCamera(
    float width_to_height_aspect_ratio, scoped_refptr<input::Camera3D> camera,
    float max_horizontal_fov_rad, float max_vertical_fov_rad,
    render_tree::MatrixTransform3DNode::Builder* transform_node_builder,
    base::TimeDelta time) {
  UNREFERENCED_PARAMETER(time);
  float vertical_fov_rad =
      std::min(max_vertical_fov_rad,
               2 * static_cast<float>(atan(tan(max_horizontal_fov_rad * 0.5f) /
                                           width_to_height_aspect_ratio)));
  camera->UpdatePerspective(width_to_height_aspect_ratio, vertical_fov_rad);
  base::CameraTransform transform(
      camera->GetCameraTransformAndUpdateOrientation());
  DCHECK(!transform.right_eye);
  transform_node_builder->transform =
      transform.left_eye_or_mono.projection_matrix *
      transform.left_eye_or_mono.view_matrix;
}

scoped_refptr<render_tree::Node> AttachCameraNodes(
    const scoped_refptr<dom::Window> window,
    const scoped_refptr<render_tree::Node>& source,
    float max_horizontal_fov_rad, float max_vertical_fov_rad) {
  // Attach a 3D transform node that applies the current camera matrix transform
  // to the rest of the render tree.
  scoped_refptr<render_tree::MatrixTransform3DNode> transform_node =
      new render_tree::MatrixTransform3DNode(
          source, glm::mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1));

  // We setup an animation on the camera transform node such that the camera
  // is driven by the renderer thread and can bypass layout entirely.
  render_tree::animations::AnimateNode::Builder animate_node_builder;
  animate_node_builder.Add(
      transform_node,
      base::Bind(&UpdateCamera, window->inner_width() / window->inner_height(),
                 window->camera_3d()->impl(), max_horizontal_fov_rad,
                 max_vertical_fov_rad));
  return new render_tree::animations::AnimateNode(animate_node_builder,
                                                  transform_node);
}

}  // namespace

LayoutManager::Impl::Impl(
    const std::string& name, const scoped_refptr<dom::Window>& window,
    const OnRenderTreeProducedCallback& on_render_tree_produced,
    LayoutTrigger layout_trigger, int dom_max_element_depth,
    float layout_refresh_rate, const std::string& language,
    LayoutStatTracker* layout_stat_tracker)
    : window_(window),
      locale_(icu::Locale::createCanonical(language.c_str())),
      used_style_provider_(new UsedStyleProvider(
          window->html_element_context(), window->document()->font_cache(),
          base::Bind(&AttachCameraNodes, window))),
      on_render_tree_produced_callback_(on_render_tree_produced),
      layout_trigger_(layout_trigger),
      layout_dirty_(StringPrintf("%s.Layout.IsDirty", name.c_str()), true,
                    "Non-zero when the layout is dirty and a new render tree "
                    "is pending."),
      layout_timer_(true, true, true),
      dom_max_element_depth_(dom_max_element_depth),
      layout_refresh_rate_(layout_refresh_rate),
      layout_stat_tracker_(layout_stat_tracker),
      suspended_(false) {
  window_->document()->AddObserver(this);
  window_->SetSynchronousLayoutCallback(
      base::Bind(&Impl::DoSynchronousLayout, base::Unretained(this)));

  UErrorCode status = U_ZERO_ERROR;
  line_break_iterator_ =
      make_scoped_ptr(icu::BreakIterator::createLineInstance(locale_, status));
  CHECK(U_SUCCESS(status));
  status = U_ZERO_ERROR;
  character_break_iterator_ = make_scoped_ptr(
      icu::BreakIterator::createCharacterInstance(locale_, status));
  CHECK(U_SUCCESS(status));

#if defined(ENABLE_TEST_RUNNER)
  if (layout_trigger_ == kTestRunnerMode) {
    window_->test_runner()->set_trigger_layout_callback(
        base::Bind(&LayoutManager::Impl::DoTestRunnerLayoutCallback,
                   base::Unretained(this)));
  }
#endif  // ENABLE_TEST_RUNNER
}

LayoutManager::Impl::~Impl() { window_->document()->RemoveObserver(this); }

void LayoutManager::Impl::OnLoad() {
#if defined(ENABLE_TEST_RUNNER)
  if (layout_trigger_ != kTestRunnerMode) {
#else
  {
#endif
    // Start the layout timer.  If the TestRunner is active, then we do not
    // start a timer as the TestRunner will drive the triggering of layouts.
    StartLayoutTimer();
  }

#if defined(ENABLE_TEST_RUNNER)
  if (layout_trigger_ == kTestRunnerMode &&
      !window_->test_runner()->should_wait()) {
    layout_dirty_ = true;

    // Run the |DoLayoutAndProduceRenderTree| task after onload event finished.
    MessageLoop::current()->PostTask(
        FROM_HERE,
        base::Bind(&LayoutManager::Impl::DoLayoutAndProduceRenderTree,
                   base::Unretained(this)));
  }
#endif  // ENABLE_TEST_RUNNER
}

void LayoutManager::Impl::OnMutation() {
  if (layout_trigger_ == kOnDocumentMutation) {
    layout_dirty_ = true;
  }
}

void LayoutManager::Impl::DoSynchronousLayout() {
  TRACE_EVENT0("cobalt::layout", "LayoutManager::Impl::DoSynchronousLayout()");
  if (suspended_) {
    return;
  }

  layout::UpdateComputedStylesAndLayoutBoxTree(
      locale_, window_->document(), dom_max_element_depth_,
      used_style_provider_.get(), layout_stat_tracker_,
      line_break_iterator_.get(), character_break_iterator_.get(),
      &initial_containing_block_);
}

void LayoutManager::Impl::Suspend() {
  // Mark that we are suspended so that we don't try to perform any layouts.
  suspended_ = true;

  // Invalidate any cached layout boxes from the document prior to clearing
  // the initial containing block. That'll ensure that the full box tree is
  // destroyed when the containing block is destroyed and that no children of
  // |initial_containing_block_| are holding on to stale parent pointers.
  window_->document()->InvalidateLayoutBoxes();

  // Clear our reference to the initial containing block to allow any resources
  // like images that were referenced by it to be released.
  initial_containing_block_ = NULL;
}

void LayoutManager::Impl::Resume() {
  // Mark that we are no longer suspended and indicate that the layout is
  // dirty since when Suspend() was called we invalidated our previous layout.
  layout_dirty_ = true;
  suspended_ = false;
}

bool LayoutManager::Impl::IsNewRenderTreePending() const {
  return layout_dirty_;
}

#if defined(ENABLE_TEST_RUNNER)
void LayoutManager::Impl::DoTestRunnerLayoutCallback() {
  DCHECK_EQ(kTestRunnerMode, layout_trigger_);
  layout_dirty_ = true;

  if (layout_trigger_ == kTestRunnerMode &&
      window_->test_runner()->should_wait()) {
    TRACE_EVENT_BEGIN0("cobalt::layout", kBenchmarkStatNonMeasuredLayout);
  }

  DoLayoutAndProduceRenderTree();

  if (layout_trigger_ == kTestRunnerMode &&
      window_->test_runner()->should_wait()) {
    TRACE_EVENT_END0("cobalt::layout", kBenchmarkStatNonMeasuredLayout);
  }
}
#endif  // ENABLE_TEST_RUNNER

void LayoutManager::Impl::StartLayoutTimer() {
  // TODO: Eventually we would like to instead base our layouts off of a
  //       "refresh" signal generated by the rasterizer, instead of trying to
  //       match timers to the graphics' refresh rate, which is error prone.
  const int64_t timer_interval_in_microseconds =
      static_cast<int64_t>(base::Time::kMicrosecondsPerSecond * 1.0f /
                           (layout_refresh_rate_ + 1.0f));

  layout_timer_.Start(
      FROM_HERE,
      base::TimeDelta::FromMicroseconds(timer_interval_in_microseconds),
      base::Bind(&LayoutManager::Impl::DoLayoutAndProduceRenderTree,
                 base::Unretained(this)));
}

void LayoutManager::Impl::DoLayoutAndProduceRenderTree() {
  TRACE_EVENT0("cobalt::layout",
               "LayoutManager::Impl::DoLayoutAndProduceRenderTree()");

  if (suspended_) return;

  const scoped_refptr<dom::Document>& document = window_->document();

  if (!document->html()) {
    return;
  }

  // Update the document's sample time, used for updating animations.
  document->SampleTimelineTime();

  bool has_layout_processing_started = false;
  if (window_->HasPendingAnimationFrameCallbacks()) {
    if (layout_dirty_) {
      has_layout_processing_started = true;
      TRACE_EVENT_BEGIN0("cobalt::layout", kBenchmarkStatLayout);
      // Update our computed style before running animation callbacks, so that
      // any transitioning elements adjusted during the animation callback will
      // transition from their previously set value.
      document->UpdateComputedStyles();
    }

    // Note that according to:
    //     https://www.w3.org/TR/2015/WD-web-animations-1-20150707/#model-liveness,
    // "The time passed to a requestAnimationFrame callback will be equal to
    // document.timeline.currentTime".  In our case,
    // document.timeline.currentTime is derived from the latest sample time.
    window_->RunAnimationFrameCallbacks();
  }

  if (layout_dirty_) {
    if (!has_layout_processing_started) {
      // We want to catch the beginning of all layout processing.  If it didn't
      // begin before the call to RunAnimationFrameCallbacks(), then the flow
      // starts here instead.
      TRACE_EVENT_BEGIN0("cobalt::layout", kBenchmarkStatLayout);
    }

    scoped_refptr<render_tree::Node> render_tree_root = layout::Layout(
        locale_, window_->document(), dom_max_element_depth_,
        used_style_provider_.get(), layout_stat_tracker_,
        line_break_iterator_.get(), character_break_iterator_.get(),
        &initial_containing_block_);
    bool run_on_render_tree_produced_callback = true;
#if defined(ENABLE_TEST_RUNNER)
    if (layout_trigger_ == kTestRunnerMode &&
        window_->test_runner()->should_wait()) {
      run_on_render_tree_produced_callback = false;
    }
#endif  // ENABLE_TEST_RUNNER

    if (run_on_render_tree_produced_callback) {
      on_render_tree_produced_callback_.Run(LayoutResults(
          render_tree_root, base::TimeDelta::FromMillisecondsD(
                                *document->timeline()->current_time())));
    }

    layout_dirty_ = false;

    TRACE_EVENT_END0("cobalt::layout", kBenchmarkStatLayout);
  }
}

LayoutManager::LayoutManager(
    const std::string& name, const scoped_refptr<dom::Window>& window,
    const OnRenderTreeProducedCallback& on_render_tree_produced,
    LayoutTrigger layout_trigger, const int dom_max_element_depth,
    const float layout_refresh_rate, const std::string& language,
    LayoutStatTracker* layout_stat_tracker)
    : impl_(new Impl(name, window, on_render_tree_produced, layout_trigger,
                     dom_max_element_depth, layout_refresh_rate, language,
                     layout_stat_tracker)) {}

LayoutManager::~LayoutManager() {}

void LayoutManager::Suspend() { impl_->Suspend(); }
void LayoutManager::Resume() { impl_->Resume(); }
bool LayoutManager::IsNewRenderTreePending() const {
  return impl_->IsNewRenderTreePending();
}

}  // namespace layout
}  // namespace cobalt
