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

#include "cobalt/browser/render_tree_combiner.h"

#include "cobalt/render_tree/composition_node.h"
#include "cobalt/render_tree/rect_node.h"

namespace cobalt {
namespace browser {

#if defined(ENABLE_DEBUG_CONSOLE)
RenderTreeCombiner::RenderTreeCombiner(
    renderer::RendererModule* renderer_module, const math::Size& viewport_size)
    : render_debug_console_(true),
      renderer_module_(renderer_module),
      viewport_size_(viewport_size) {}

RenderTreeCombiner::~RenderTreeCombiner() {}

void RenderTreeCombiner::Reset() {
  main_render_tree_ = base::nullopt;
  debug_console_render_tree_ = base::nullopt;
  main_render_tree_receipt_time_ = base::nullopt;
}

void RenderTreeCombiner::UpdateMainRenderTree(
    const renderer::Submission& render_tree_submission) {
  main_render_tree_ = render_tree_submission;
  main_render_tree_receipt_time_ = base::TimeTicks::HighResNow();
  SubmitToRenderer();
}

void RenderTreeCombiner::UpdateDebugConsoleRenderTree(
    const base::optional<renderer::Submission>& render_tree_submission) {
  debug_console_render_tree_ = render_tree_submission;
  SubmitToRenderer();
}

void RenderTreeCombiner::SubmitToRenderer() {
  if (render_debug_console_ && debug_console_render_tree_) {
    if (main_render_tree_) {
      render_tree::CompositionNode::Builder builder;
      builder.AddChild(main_render_tree_->render_tree);
      builder.AddChild(debug_console_render_tree_->render_tree);
      scoped_refptr<render_tree::Node> combined_tree =
          new render_tree::CompositionNode(builder);

      // Setup time to be based off of the main submitted tree only.
      // TODO: Setup a "layers" interface on the Pipeline so that
      // trees can be combined and animated there, properly.
      renderer::Submission combined_submission(*main_render_tree_);
      combined_submission.render_tree = combined_tree;
      combined_submission.time_offset =
          main_render_tree_->time_offset +
          (base::TimeTicks::HighResNow() - *main_render_tree_receipt_time_);

      renderer_module_->pipeline()->Submit(combined_submission);
    } else {
      // If we are rendering the debug console by itself, give it a solid black
      // background to it.
      render_tree::CompositionNode::Builder builder;
      builder.AddChild(new render_tree::RectNode(
          math::RectF(viewport_size_),
          scoped_ptr<render_tree::Brush>(new render_tree::SolidColorBrush(
              render_tree::ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f)))));
      builder.AddChild(debug_console_render_tree_->render_tree);

      renderer::Submission combined_submission(*debug_console_render_tree_);
      combined_submission.render_tree =
          new render_tree::CompositionNode(builder);
      renderer_module_->pipeline()->Submit(combined_submission);
    }
  } else if (main_render_tree_) {
    renderer_module_->pipeline()->Submit(*main_render_tree_);
  }
}
#else   // ENABLE_DEBUG_CONSOLE
RenderTreeCombiner::RenderTreeCombiner(
    renderer::RendererModule* renderer_module, const math::Size& viewport_size)
    : renderer_module_(renderer_module) {
  UNREFERENCED_PARAMETER(viewport_size);
}

RenderTreeCombiner::~RenderTreeCombiner() {}

void RenderTreeCombiner::Reset() {}

void RenderTreeCombiner::UpdateMainRenderTree(
    const renderer::Submission& render_tree_submission) {
  renderer_module_->pipeline()->Submit(render_tree_submission);
}

void RenderTreeCombiner::UpdateDebugConsoleRenderTree(
    const base::optional<renderer::Submission>& render_tree_submission) {
  UNREFERENCED_PARAMETER(render_tree_submission);
}
#endif  // ENABLE_DEBUG_CONSOLE

}  // namespace browser
}  // namespace cobalt
