// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/ui/examples/standalone_app/app.h"

// clang-format off
#include "src/ui/lib/glm_workaround/glm_workaround.h"
// clang-format on

#include <fuchsia/ui/gfx/cpp/fidl.h>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/quaternion.hpp>
#include <lib/async/cpp/task.h>

#include <lib/ui/scenic/cpp/commands.h>
#include <src/lib/ui/scenic/cpp/host_memory.h>
#include <lib/zx/time.h>
#include <lib/syslog/cpp/macros.h>
#include <string>

#include "src/ui/lib/escher/util/image_utils.h"

using namespace scenic;

namespace standalone_app {

static constexpr uint64_t kBillion = 1000000000;

fuchsia::ui::gfx::ShadowTechnique GetShadowTechniqueFromCommandLine(
    const fxl::CommandLine& command_line) {
  using fuchsia::ui::gfx::ShadowTechnique;

  std::string shadow_type;
  if (command_line.GetOptionValue("shadow_type", &shadow_type)) {
    if (shadow_type == "UNSHADOWED") {
      return ShadowTechnique::UNSHADOWED;
    } else if (shadow_type == "STENCIL_SHADOW_VOLUME") {
      return ShadowTechnique::STENCIL_SHADOW_VOLUME;
    } else {
      FX_LOGS(WARNING) << "Unknown/unsupported shadow type: " << shadow_type
                       << ".  Valid choices are: UNSHADOWED, "
                          "STENCIL_SHADOW_VOLUME.  Using UNSHADOWED instead";
    }
  }
  return ShadowTechnique::UNSHADOWED;
}

App::App(async::Loop* loop, const fxl::CommandLine& command_line)
    : component_context_(sys::ComponentContext::CreateAndServeOutgoingDirectory()),
      loop_(loop),
      shadow_technique_(GetShadowTechniqueFromCommandLine(command_line)) {
  scenic_ = component_context_->svc()->Connect<fuchsia::ui::scenic::Scenic>();
  scenic_.set_error_handler([this](zx_status_t status) {
    FX_LOGS(INFO) << "Lost connection to Scenic service.";
    loop_->Quit();
  });
  scenic_->GetDisplayInfo(
      [this](fuchsia::ui::gfx::DisplayInfo display_info) { Init(std::move(display_info)); });
}

void App::InitCheckerboardMaterial(Material* uninitialized_material) {
  // Generate a checkerboard material.  This is a multi-step process:
  //   - generate pixels for the material.
  //   - create a VMO that contains these pixels.
  //   - duplicate the VMO handle and use it to create a Session Memory obj.
  //   - use the Memory obj to create an Image obj.
  //   - use the Image obj as a Material's texture.
  size_t checkerboard_width = 8;
  size_t checkerboard_height = 8;
  size_t checkerboard_pixels_size;
  auto checkerboard_pixels = escher::image_utils::NewGradientPixels(
      checkerboard_width, checkerboard_height, &checkerboard_pixels_size);

  scenic_util::HostMemory checkerboard_memory(session_.get(), checkerboard_pixels_size);
  memcpy(checkerboard_memory.data_ptr(), checkerboard_pixels.get(), checkerboard_pixels_size);

  // Create an Image to wrap the checkerboard.
  fuchsia::images::ImageInfo checkerboard_image_info;
  checkerboard_image_info.width = checkerboard_width;
  checkerboard_image_info.height = checkerboard_height;
  const size_t kBytesPerPixel = 4u;
  checkerboard_image_info.stride = checkerboard_width * kBytesPerPixel;
  checkerboard_image_info.pixel_format = fuchsia::images::PixelFormat::BGRA_8;
  checkerboard_image_info.color_space = fuchsia::images::ColorSpace::SRGB;
  checkerboard_image_info.tiling = fuchsia::images::Tiling::LINEAR;

  scenic_util::HostImage checkerboard_image(checkerboard_memory, 0,
                                            std::move(checkerboard_image_info));

  uninitialized_material->SetTexture(checkerboard_image.id());
}

void App::CreateExampleScene(float display_width, float display_height) {
  auto session = session_.get();

  // The top-level nesting for drawing anything is compositor -> layer-stack
  // -> layer.  Layer content can come from an image, or by rendering a scene.
  // In this case, we do the latter, so we nest layer -> renderer -> camera ->
  // scene.
  compositor_ = std::make_unique<DisplayCompositor>(session);
  LayerStack layer_stack(session);
  Layer layer(session);
  Renderer renderer(session);
  Scene scene(session);
  camera_ = std::make_unique<Camera>(scene);

  compositor_->SetLayerStack(layer_stack);
  layer_stack.AddLayer(layer);
  layer.SetSize(display_width, display_height);
  layer.SetRenderer(renderer);
  renderer.SetCamera(camera_->id());
  fuchsia::ui::gfx::RendererParam param;
  param.set_shadow_technique(shadow_technique_);
  renderer.SetParam(std::move(param));

  if (shadow_technique_ == fuchsia::ui::gfx::ShadowTechnique::UNSHADOWED) {
    AmbientLight ambient_light(session);
    ambient_light.SetColor(1.f, 1.f, 1.f);
    scene.AddLight(ambient_light);
  } else if (shadow_technique_ == fuchsia::ui::gfx::ShadowTechnique::STENCIL_SHADOW_VOLUME) {
    AmbientLight ambient_light(session);
    PointLight point_light1(session);
    PointLight point_light2(session);

    scene.AddLight(ambient_light);
    scene.AddLight(point_light1);
    scene.AddLight(point_light2);

    // Specify colors for the three lights.  The first two values are tweakable,
    // and are used to generate the colors of the two point lights.  The color
    // of the three lights sum to (1.0, 1.0, 1.0).  kPointLightColorDiff causes
    // the two point lights to differ in color from each other.
    const glm::vec3 kAmbientLightColor(0.4f, 0.4f, 0.4f);
    const glm::vec3 kPointLightColorDiff(0.05f, -0.1f, 0.f);
    const glm::vec3 kPointLightAverageColor = 0.5f * (glm::vec3(1, 1, 1) - kAmbientLightColor);
    const glm::vec3 kPointLight1Color = kPointLightAverageColor + kPointLightColorDiff;
    const glm::vec3 kPointLight2Color = kPointLightAverageColor - kPointLightColorDiff;

    ambient_light.SetColor({kAmbientLightColor[0], kAmbientLightColor[1], kAmbientLightColor[2]});
    point_light1.SetColor({kPointLight1Color[0], kPointLight1Color[1], kPointLight1Color[2]});
    point_light2.SetColor({kPointLight2Color[0], kPointLight2Color[1], kPointLight2Color[2]});
    point_light1.SetPosition(0.3f * display_width, 0.3f * display_height, -1000.f);
    point_light2.SetPosition(display_width, 0.2f * display_height, -1000.f);
    point_light1.SetFalloff(0.f);
    point_light2.SetFalloff(0.f);
  } else {
    AmbientLight ambient_light(session);
    DirectionalLight directional_light(session);
    scene.AddLight(ambient_light);
    scene.AddLight(directional_light);
    ambient_light.SetColor(0.3f, 0.3f, 0.3f);
    directional_light.SetColor(0.7f, 0.7f, 0.7f);
    directional_light.SetDirection(1.f, 1.f, 2.f);
  }

  // Create an EntityNode to serve as the scene root.
  EntityNode root_node(session);
  scene.AddChild(root_node.id());

  static constexpr float kPaneMargin = 100.f;
  static const float pane_width = (display_width - 3 * kPaneMargin) / 2.f;
  static const float pane_height = display_height - 2 * kPaneMargin;

  // The root node will enclose two "panes", each with a rounded-rect part
  // that acts as a background clipper.
  RoundedRectangle pane_shape(session, pane_width, pane_height, 20, 20, 80, 10);
  Material pane_material(session);
  pane_material.SetColor(120, 120, 255, 255);

  EntityNode pane_node_1(session);
  ShapeNode pane_bg_1(session);
  pane_bg_1.SetShape(pane_shape);
  pane_bg_1.SetMaterial(pane_material);
  pane_node_1.AddChild(pane_bg_1);
  pane_node_1.SetTranslation(kPaneMargin + pane_width * 0.5, kPaneMargin + pane_height * 0.5, -20);
  root_node.AddChild(pane_node_1);

  EntityNode pane_node_2(session);
  ShapeNode pane_bg_2(session);
  pane_bg_2.SetShape(pane_shape);
  pane_bg_2.SetMaterial(pane_material);
  pane_node_2.AddChild(pane_bg_2);
  pane_node_2.SetTranslation(kPaneMargin * 2 + pane_width * 1.5, kPaneMargin + pane_height * 0.5,
                             -20);
  root_node.AddChild(pane_node_2);

  // Create a Material with the checkerboard image.  This will be used for
  // the objects in each pane.
  Material checkerboard_material(session);
  InitCheckerboardMaterial(&checkerboard_material);
  checkerboard_material.SetColor(255, 100, 100, 255);

  Material green_material(session);
  green_material.SetColor(50, 150, 50, 255);

  // The first pane will contain an animated rounded-rect.
  rrect_node_ = std::make_unique<ShapeNode>(session);
  rrect_node_->SetMaterial(checkerboard_material);
  rrect_node_->SetShape(RoundedRectangle(session, 200, 300, 20, 20, 80, 10));
  pane_node_1.AddChild(rrect_node_->id());

  // The second pane will contain two large circles that are clipped by a pair
  // of smaller animated circles.
  pane_2_contents_ = std::make_unique<EntityNode>(session);

  Circle clippee_circle(session, 400);
  ShapeNode clippee1(session);
  clippee1.SetShape(clippee_circle);
  clippee1.SetMaterial(green_material);
  clippee1.SetTranslation(0, 300, 0);
  ShapeNode clippee2(session);
  clippee2.SetShape(clippee_circle);
  clippee2.SetMaterial(checkerboard_material);
  clippee2.SetTranslation(0, -300, -100);

  pane_2_contents_->AddChild(clippee1);
  pane_2_contents_->AddChild(clippee2);

  pane_node_2.AddChild(*pane_2_contents_.get());
  pane_2_contents_->SetTranslation(0, 0, -100);
}

void App::Init(fuchsia::ui::gfx::DisplayInfo display_info) {
  FX_LOGS(INFO) << "Creating new Session";

  // TODO: set up SessionListener.
  session_ = std::make_unique<scenic::Session>(scenic_.get());
  session_->SetDebugName("Standalone App");
  session_->set_error_handler([this](zx_status_t status) {
    FX_LOGS(INFO) << "Session terminated.";
    loop_->Quit();
  });

  // Wait kSessionDuration seconds, and close the session.
  constexpr int kSessionDuration = 40;
  async::PostDelayedTask(
      loop_->dispatcher(), [this] { ReleaseSessionResources(); }, zx::sec(kSessionDuration));

  // Set up initial scene.
  const float display_width = static_cast<float>(display_info.width_in_px);
  const float display_height = static_cast<float>(display_info.height_in_px);
  CreateExampleScene(display_width, display_height);

  start_time_ = zx_clock_get_monotonic();
  camera_anim_start_time_ = start_time_;
  Update(start_time_);
}

void App::Update(uint64_t next_presentation_time) {
  {
    double secs = static_cast<double>(next_presentation_time - start_time_) / kBillion;

    // Translate / rotate the rounded rect.
    rrect_node_->SetTranslation(sin(secs * 0.8) * 500.f, sin(secs * 0.6) * 570.f, -200.f);

    auto quaternion = glm::angleAxis(static_cast<float>(secs / 2.0), glm::vec3(0, 0, 1));
    rrect_node_->SetRotation(quaternion.x, quaternion.y, quaternion.z, quaternion.w);

    // Set a moving clip plane, clipping only the two circles.
    fuchsia::ui::gfx::Plane3 clip_plane;
    clip_plane.dir.x = sin(secs * 0.5);
    clip_plane.dir.y = cos(secs * 0.5);
    clip_plane.dir.z = 0.f;
    clip_plane.dist = -200.f;
    pane_2_contents_->SetClipPlanes({clip_plane});
  }

  // Move the camera.
  {
    double secs = static_cast<double>(next_presentation_time - camera_anim_start_time_) / kBillion;
    const double kCameraModeDuration = 5.0;
    float param = secs / kCameraModeDuration;
    if (param > 1.0) {
      param = 0.0;
      camera_anim_returning_ = !camera_anim_returning_;
      camera_anim_start_time_ = next_presentation_time;
    }
    if (camera_anim_returning_) {
      param = 1.0 - param;
    }

    // Animate the eye position.
    glm::vec3 eye_start(1080, 720, -6000);
    glm::vec3 eye_end(0, 10000, -7000);
    glm::vec3 eye = glm::mix(eye_start, eye_end, glm::smoothstep(0.f, 1.f, param));

    // Always look at the middle of the stage.
    std::array<float, 3> target = {1080, 720, 0};
    std::array<float, 3> up = {0, -1, 0};

    camera_->SetTransform({eye.x, eye.y, eye.z}, target, up);
    camera_->SetProjection(glm::radians(15.f));
  }

  // Present
  session_->Present(next_presentation_time, [this](fuchsia::images::PresentationInfo info) {
    Update(info.presentation_time + info.presentation_interval);
  });
}

void App::ReleaseSessionResources() {
  FX_LOGS(INFO) << "Closing session.";

  compositor_.reset();
  camera_.reset();
  clipper_2_.reset();
  clipper_1_.reset();
  rrect_node_.reset();
  pane_2_contents_.reset();

  session_.reset();
}

}  // namespace standalone_app
