// Copyright 2013 The Flutter 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 <cmath>
#include <memory>
#include <vector>

#include "flutter/fml/mapping.h"
#include "flutter/testing/testing.h"
#include "impeller/geometry/color.h"
#include "impeller/geometry/constants.h"
#include "impeller/geometry/matrix.h"
#include "impeller/geometry/quaternion.h"
#include "impeller/geometry/vector.h"
#include "impeller/image/decompressed_image.h"
#include "impeller/playground/playground.h"
#include "impeller/playground/playground_test.h"
#include "impeller/renderer/formats.h"
#include "impeller/scene/animation/animation_clip.h"
#include "impeller/scene/camera.h"
#include "impeller/scene/geometry.h"
#include "impeller/scene/importer/scene_flatbuffers.h"
#include "impeller/scene/material.h"
#include "impeller/scene/mesh.h"
#include "impeller/scene/scene.h"
#include "third_party/flatbuffers/include/flatbuffers/verifier.h"
#include "third_party/imgui/imgui.h"

namespace impeller {
namespace scene {
namespace testing {

using SceneTest = PlaygroundTest;
INSTANTIATE_PLAYGROUND_SUITE(SceneTest);

TEST_P(SceneTest, CuboidUnlit) {
  auto scene_context = std::make_shared<SceneContext>(GetContext());

  Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
    auto allocator = GetContext()->GetResourceAllocator();
    auto scene = Scene(scene_context);

    {
      Mesh mesh;

      auto material = Material::MakeUnlit();
      material->SetColor(Color::Red());

      Vector3 size(1, 1, 0);
      mesh.AddPrimitive({Geometry::MakeCuboid(size), std::move(material)});

      Node& root = scene.GetRoot();
      root.SetLocalTransform(Matrix::MakeTranslation(-size / 2));
      root.SetMesh(std::move(mesh));
    }

    // Face towards the +Z direction (+X right, +Y up).
    auto camera = Camera::MakePerspective(
                      /* fov */ Radians(kPiOver4),
                      /* position */ {2, 2, -5})
                      .LookAt(
                          /* target */ Vector3(),
                          /* up */ {0, 1, 0});

    scene.Render(render_target, camera);
    return true;
  };

  OpenPlaygroundHere(callback);
}

TEST_P(SceneTest, FlutterLogo) {
  auto allocator = GetContext()->GetResourceAllocator();

  auto mapping =
      flutter::testing::OpenFixtureAsMapping("flutter_logo_baked.glb.ipscene");
  ASSERT_NE(mapping, nullptr);

  flatbuffers::Verifier verifier(mapping->GetMapping(), mapping->GetSize());
  ASSERT_TRUE(fb::VerifySceneBuffer(verifier));

  std::shared_ptr<Node> gltf_scene =
      Node::MakeFromFlatbuffer(*mapping, *allocator);
  ASSERT_NE(gltf_scene, nullptr);
  ASSERT_EQ(gltf_scene->GetChildren().size(), 1u);
  ASSERT_EQ(gltf_scene->GetChildren()[0]->GetMesh().GetPrimitives().size(), 1u);

  auto scene_context = std::make_shared<SceneContext>(GetContext());
  auto scene = Scene(scene_context);
  scene.GetRoot().AddChild(std::move(gltf_scene));
  scene.GetRoot().SetLocalTransform(Matrix::MakeScale({3, 3, 3}));

  Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
    Quaternion rotation({0, 1, 0}, -GetSecondsElapsed() * 0.5);
    Vector3 start_position(-1, -1.5, -5);

    // Face towards the +Z direction (+X right, +Y up).
    auto camera = Camera::MakePerspective(
                      /* fov */ Degrees(60),
                      /* position */ rotation * start_position)
                      .LookAt(
                          /* target */ Vector3(),
                          /* up */ {0, 1, 0});

    scene.Render(render_target, camera);
    return true;
  };

  OpenPlaygroundHere(callback);
}

TEST_P(SceneTest, TwoTriangles) {
  auto allocator = GetContext()->GetResourceAllocator();

  auto mapping =
      flutter::testing::OpenFixtureAsMapping("two_triangles.glb.ipscene");
  ASSERT_NE(mapping, nullptr);

  std::shared_ptr<Node> gltf_scene =
      Node::MakeFromFlatbuffer(*mapping, *allocator);
  ASSERT_NE(gltf_scene, nullptr);

  auto animation = gltf_scene->FindAnimationByName("Metronome");
  ASSERT_NE(animation, nullptr);

  AnimationClip* metronome_clip = gltf_scene->AddAnimation(animation);
  ASSERT_NE(metronome_clip, nullptr);
  metronome_clip->SetLoop(true);
  metronome_clip->Play();

  auto scene_context = std::make_shared<SceneContext>(GetContext());
  auto scene = Scene(scene_context);
  scene.GetRoot().AddChild(std::move(gltf_scene));

  Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
    ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
    {
      static Scalar playback_time_scale = 1;
      static Scalar weight = 1;
      static bool loop = true;

      ImGui::SliderFloat("Playback time scale", &playback_time_scale, -5, 5);
      ImGui::SliderFloat("Weight", &weight, -2, 2);
      ImGui::Checkbox("Loop", &loop);
      if (ImGui::Button("Play")) {
        metronome_clip->Play();
      }
      if (ImGui::Button("Pause")) {
        metronome_clip->Pause();
      }
      if (ImGui::Button("Stop")) {
        metronome_clip->Stop();
      }

      metronome_clip->SetPlaybackTimeScale(playback_time_scale);
      metronome_clip->SetWeight(weight);
      metronome_clip->SetLoop(loop);
    }

    ImGui::End();
    Node& node = *scene.GetRoot().GetChildren()[0];
    node.SetLocalTransform(node.GetLocalTransform() *
                           Matrix::MakeRotation(0.02, {0, 1, 0, 0}));

    static ImVec2 mouse_pos_prev = ImGui::GetMousePos();
    ImVec2 mouse_pos = ImGui::GetMousePos();
    Vector2 mouse_diff =
        Vector2(mouse_pos.x - mouse_pos_prev.x, mouse_pos.y - mouse_pos_prev.y);

    static Vector3 position(0, 1, -5);
    static Vector3 cam_position = position;
    auto strafe =
        Vector3(ImGui::IsKeyDown(ImGuiKey_D) - ImGui::IsKeyDown(ImGuiKey_A),
                ImGui::IsKeyDown(ImGuiKey_E) - ImGui::IsKeyDown(ImGuiKey_Q),
                ImGui::IsKeyDown(ImGuiKey_W) - ImGui::IsKeyDown(ImGuiKey_S));
    position += strafe * 0.5;
    cam_position = cam_position.Lerp(position, 0.02);

    // Face towards the +Z direction (+X right, +Y up).
    auto camera = Camera::MakePerspective(
                      /* fov */ Degrees(60),
                      /* position */ cam_position)
                      .LookAt(
                          /* target */ cam_position + Vector3(0, 0, 1),
                          /* up */ {0, 1, 0});

    scene.Render(render_target, camera);
    return true;
  };

  OpenPlaygroundHere(callback);
}

TEST_P(SceneTest, Dash) {
  auto allocator = GetContext()->GetResourceAllocator();

  auto mapping = flutter::testing::OpenFixtureAsMapping("dash.glb.ipscene");
  if (!mapping) {
    // TODO(bdero): Just skip this playground is the dash asset isn't found. I
    //              haven't checked it in because it's way too big right now,
    //              but this is still useful to keep around for debugging
    //              purposes.
    return;
  }
  ASSERT_NE(mapping, nullptr);

  std::shared_ptr<Node> gltf_scene =
      Node::MakeFromFlatbuffer(*mapping, *allocator);
  ASSERT_NE(gltf_scene, nullptr);

  auto walk_anim = gltf_scene->FindAnimationByName("Walk");
  ASSERT_NE(walk_anim, nullptr);

  AnimationClip* walk_clip = gltf_scene->AddAnimation(walk_anim);
  ASSERT_NE(walk_clip, nullptr);
  walk_clip->SetLoop(true);
  walk_clip->Play();

  auto run_anim = gltf_scene->FindAnimationByName("Run");
  ASSERT_NE(walk_anim, nullptr);

  AnimationClip* run_clip = gltf_scene->AddAnimation(run_anim);
  ASSERT_NE(run_clip, nullptr);
  run_clip->SetLoop(true);
  run_clip->Play();

  auto scene_context = std::make_shared<SceneContext>(GetContext());
  auto scene = Scene(scene_context);
  scene.GetRoot().AddChild(std::move(gltf_scene));

  Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
    ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
    {
      static Scalar playback_time_scale = 1;
      static Scalar walk = 0.5;
      static Scalar run = 0.5;
      static bool loop = true;

      ImGui::SliderFloat("Playback time scale", &playback_time_scale, -5, 5);
      ImGui::SliderFloat("Walk weight", &walk, 0, 1);
      ImGui::SliderFloat("Run weight", &run, 0, 1);
      ImGui::Checkbox("Loop", &loop);
      if (ImGui::Button("Play")) {
        walk_clip->Play();
        run_clip->Play();
      }
      if (ImGui::Button("Pause")) {
        walk_clip->Pause();
        run_clip->Pause();
      }
      if (ImGui::Button("Stop")) {
        walk_clip->Stop();
        run_clip->Stop();
      }

      walk_clip->SetPlaybackTimeScale(playback_time_scale);
      walk_clip->SetWeight(walk);
      walk_clip->SetLoop(loop);

      run_clip->SetPlaybackTimeScale(playback_time_scale);
      run_clip->SetWeight(run);
      run_clip->SetLoop(loop);
    }

    ImGui::End();
    Node& node = *scene.GetRoot().GetChildren()[0];
    node.SetLocalTransform(node.GetLocalTransform() *
                           Matrix::MakeRotation(0.02, {0, 1, 0, 0}));

    static ImVec2 mouse_pos_prev = ImGui::GetMousePos();
    ImVec2 mouse_pos = ImGui::GetMousePos();
    Vector2 mouse_diff =
        Vector2(mouse_pos.x - mouse_pos_prev.x, mouse_pos.y - mouse_pos_prev.y);

    static Vector3 position(0, 1, -5);
    static Vector3 cam_position = position;
    auto strafe =
        Vector3(ImGui::IsKeyDown(ImGuiKey_D) - ImGui::IsKeyDown(ImGuiKey_A),
                ImGui::IsKeyDown(ImGuiKey_E) - ImGui::IsKeyDown(ImGuiKey_Q),
                ImGui::IsKeyDown(ImGuiKey_W) - ImGui::IsKeyDown(ImGuiKey_S));
    position += strafe * 0.5;
    cam_position = cam_position.Lerp(position, 0.02);

    // Face towards the +Z direction (+X right, +Y up).
    auto camera = Camera::MakePerspective(
                      /* fov */ Degrees(60),
                      /* position */ cam_position)
                      .LookAt(
                          /* target */ cam_position + Vector3(0, 0, 1),
                          /* up */ {0, 1, 0});

    scene.Render(render_target, camera);
    return true;
  };

  OpenPlaygroundHere(callback);
}

}  // namespace testing
}  // namespace scene
}  // namespace impeller
