/*
 * 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 "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop.h"
#include "cobalt/base/wrap_main.h"
#include "cobalt/math/size.h"
#include "cobalt/renderer/pipeline.h"
#include "cobalt/renderer/renderer_module.h"
#include "cobalt/renderer/submission.h"
#include "cobalt/renderer/test/scenes/all_scenes_combined_scene.h"
#include "cobalt/system_window/system_window.h"
#include "cobalt/trace_event/scoped_trace_to_file.h"

using cobalt::render_tree::ResourceProvider;
using cobalt::renderer::test::scenes::AddBlankBackgroundToScene;
using cobalt::renderer::test::scenes::CreateAllScenesCombinedScene;
using cobalt::system_window::SystemWindow;

namespace {

const int kViewportWidth = 1920;
const int kViewportHeight = 1080;

class RendererSandbox {
 public:
  RendererSandbox();

 private:
  cobalt::trace_event::ScopedTraceToFile trace_to_file_;
  base::EventDispatcher event_dispatcher_;
  scoped_ptr<SystemWindow> system_window_;
  scoped_ptr<cobalt::renderer::RendererModule> renderer_module_;
};

RendererSandbox::RendererSandbox()
    : trace_to_file_(
          FilePath(FILE_PATH_LITERAL("renderer_sandbox_trace.json"))) {
  // Create a system window to use as a render target.
  system_window_ = cobalt::system_window::CreateSystemWindow(
      &event_dispatcher_, cobalt::math::Size(kViewportWidth, kViewportHeight));

  // Construct a renderer module using default options.
  cobalt::renderer::RendererModule::Options renderer_module_options;
  renderer_module_.reset(new cobalt::renderer::RendererModule(
      system_window_.get(), renderer_module_options));

  cobalt::math::SizeF output_dimensions(
      renderer_module_->render_target()->GetSize());

  // Construct our render tree and associated animations to be passed into
  // the renderer pipeline for display.
  base::TimeDelta start_time = base::Time::Now() - base::Time::UnixEpoch();
  scoped_refptr<cobalt::render_tree::Node> scene = AddBlankBackgroundToScene(
      CreateAllScenesCombinedScene(
          renderer_module_->pipeline()->GetResourceProvider(),
          output_dimensions, start_time),
      output_dimensions);

  // Pass the render tree along with associated animations into the renderer
  // module to be displayed.
  renderer_module_->pipeline()->Submit(
      cobalt::renderer::Submission(scene, start_time));
}

RendererSandbox* g_renderer_sandbox = NULL;

void StartApplication(int /*argc*/, char** /*argv*/, const char* /*link*/,
                      const base::Closure& quit_closure) {
  DCHECK(!g_renderer_sandbox);
  g_renderer_sandbox = new RendererSandbox();
  DCHECK(g_renderer_sandbox);

  MessageLoop::current()->PostDelayedTask(FROM_HERE, quit_closure,
                                          base::TimeDelta::FromSeconds(30));
}

void StopApplication() {
  DCHECK(g_renderer_sandbox);
  delete g_renderer_sandbox;
  g_renderer_sandbox = NULL;
}

}  // namespace

COBALT_WRAP_BASE_MAIN(StartApplication, StopApplication);
