// Copyright (c) 2016 The Chromium 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 "chrome/browser/vr/ui_scene.h"

#include <utility>
#include <vector>

#include "base/numerics/math_constants.h"
#include "base/test/gtest_util.h"
#include "base/values.h"
#include "chrome/browser/vr/databinding/binding.h"
#include "chrome/browser/vr/elements/draw_phase.h"
#include "chrome/browser/vr/elements/transient_element.h"
#include "chrome/browser/vr/elements/ui_element.h"
#include "chrome/browser/vr/elements/viewport_aware_root.h"
#include "chrome/browser/vr/test/animation_utils.h"
#include "chrome/browser/vr/test/constants.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/vector3d_f.h"
#include "ui/gfx/transform_util.h"

#define TOLERANCE 0.0001

#define EXPECT_VEC3F_NEAR(a, b)         \
  EXPECT_NEAR(a.x(), b.x(), TOLERANCE); \
  EXPECT_NEAR(a.y(), b.y(), TOLERANCE); \
  EXPECT_NEAR(a.z(), b.z(), TOLERANCE);

namespace vr {

namespace {

size_t NumElementsInSubtree(UiElement* element) {
  size_t count = 1;
  for (auto& child : element->children()) {
    count += NumElementsInSubtree(child.get());
  }
  return count;
}

class AlwaysDirty : public UiElement {
 public:
  ~AlwaysDirty() override {}

  bool OnBeginFrame(const base::TimeTicks& time,
                    const gfx::Transform& head_pose) override {
    return true;
  }
};

}  // namespace

TEST(UiScene, AddRemoveElements) {
  UiScene scene;

  // Always start with the root element.
  EXPECT_EQ(NumElementsInSubtree(&scene.root_element()), 1u);

  auto element = std::make_unique<UiElement>();
  element->SetDrawPhase(kPhaseForeground);
  UiElement* parent = element.get();
  int parent_id = parent->id();
  scene.AddUiElement(kRoot, std::move(element));

  EXPECT_EQ(NumElementsInSubtree(&scene.root_element()), 2u);

  element = std::make_unique<UiElement>();
  element->SetDrawPhase(kPhaseForeground);
  UiElement* child = element.get();
  int child_id = child->id();

  parent->AddChild(std::move(element));

  EXPECT_EQ(NumElementsInSubtree(&scene.root_element()), 3u);

  EXPECT_NE(scene.GetUiElementById(parent_id), nullptr);
  EXPECT_NE(scene.GetUiElementById(child_id), nullptr);
  EXPECT_EQ(scene.GetUiElementById(-1), nullptr);

  auto removed_child = scene.RemoveUiElement(child_id);
  EXPECT_EQ(removed_child.get(), child);
  EXPECT_EQ(NumElementsInSubtree(&scene.root_element()), 2u);
  EXPECT_EQ(scene.GetUiElementById(child_id), nullptr);

  auto removed_parent = scene.RemoveUiElement(parent_id);
  EXPECT_EQ(removed_parent.get(), parent);
  EXPECT_EQ(NumElementsInSubtree(&scene.root_element()), 1u);
  EXPECT_EQ(scene.GetUiElementById(parent_id), nullptr);
}

// This test creates a parent and child UI element, each with their own
// transformations, and ensures that the child's computed total transform
// incorporates the parent's transform as well as its own.
TEST(UiScene, ParentTransformAppliesToChild) {
  UiScene scene;

  // Add a parent element, with distinct transformations.
  // Size of the parent should be ignored by the child.
  auto element = std::make_unique<UiElement>();
  UiElement* parent = element.get();
  element->SetSize(1000, 1000);

  element->SetTranslate(6, 1, 0);
  element->SetRotate(0, 0, 1, 0.5f * base::kPiFloat);
  element->SetScale(3, 3, 1);
  scene.AddUiElement(kRoot, std::move(element));

  // Add a child to the parent, with different transformations.
  element = std::make_unique<UiElement>();
  element->SetTranslate(3, 0, 0);
  element->SetRotate(0, 0, 1, 0.5f * base::kPiFloat);
  element->SetScale(2, 2, 1);
  UiElement* child = element.get();
  parent->AddChild(std::move(element));

  gfx::Point3F origin(0, 0, 0);
  gfx::Point3F point(1, 0, 0);

  scene.OnBeginFrame(MsToTicks(0), kStartHeadPose);
  child->world_space_transform().TransformPoint(&origin);
  child->world_space_transform().TransformPoint(&point);
  EXPECT_VEC3F_NEAR(gfx::Point3F(6, 10, 0), origin);
  EXPECT_VEC3F_NEAR(gfx::Point3F(0, 10, 0), point);
}

TEST(UiScene, Opacity) {
  UiScene scene;

  auto element = std::make_unique<UiElement>();
  UiElement* parent = element.get();
  element->SetOpacity(0.5);
  scene.AddUiElement(kRoot, std::move(element));

  element = std::make_unique<UiElement>();
  UiElement* child = element.get();
  element->SetOpacity(0.5);
  parent->AddChild(std::move(element));

  scene.OnBeginFrame(MsToTicks(0), kStartHeadPose);
  EXPECT_EQ(0.5f, parent->computed_opacity());
  EXPECT_EQ(0.25f, child->computed_opacity());
}

TEST(UiScene, NoViewportAwareElementWhenNoVisibleChild) {
  UiScene scene;
  auto element = std::make_unique<UiElement>();
  UiElement* container = element.get();
  element->SetName(kWebVrRoot);
  scene.AddUiElement(kRoot, std::move(element));

  auto root = std::make_unique<ViewportAwareRoot>();
  UiElement* viewport_aware_root = root.get();
  container->AddChild(std::move(root));

  element = std::make_unique<UiElement>();
  UiElement* child = element.get();
  element->SetDrawPhase(kPhaseOverlayForeground);
  viewport_aware_root->AddChild(std::move(element));

  element = std::make_unique<UiElement>();
  element->SetDrawPhase(kPhaseOverlayForeground);
  child->AddChild(std::move(element));

  EXPECT_FALSE(scene.GetVisibleWebVrOverlayElementsToDraw().empty());
  child->SetVisible(false);
  scene.OnBeginFrame(MsToTicks(0), kStartHeadPose);
  EXPECT_TRUE(scene.GetVisibleWebVrOverlayElementsToDraw().empty());
}

TEST(UiScene, InvisibleElementsDoNotCauseAnimationDirtiness) {
  UiScene scene;
  auto element = std::make_unique<UiElement>();
  element->AddAnimation(CreateBackgroundColorAnimation(
      1, 1, SK_ColorBLACK, SK_ColorWHITE, MsToDelta(1000)));
  UiElement* element_ptr = element.get();
  scene.AddUiElement(kRoot, std::move(element));
  EXPECT_TRUE(scene.OnBeginFrame(MsToTicks(1), kStartHeadPose));

  element_ptr->SetVisible(false);
  element_ptr->UpdateComputedOpacity();
  EXPECT_FALSE(scene.OnBeginFrame(MsToTicks(2), kStartHeadPose));
}

TEST(UiScene, InvisibleElementsDoNotCauseBindingDirtiness) {
  UiScene scene;
  auto element = std::make_unique<UiElement>();
  struct FakeModel {
    int foo = 1;
  } model;
  element->AddBinding(VR_BIND(int, FakeModel, &model, model->foo, UiElement,
                              element.get(), view->SetSize(1, value)));
  UiElement* element_ptr = element.get();
  scene.AddUiElement(kRoot, std::move(element));
  EXPECT_TRUE(scene.OnBeginFrame(MsToTicks(1), kStartHeadPose));

  model.foo = 2;
  element_ptr->SetVisible(false);
  element_ptr->UpdateComputedOpacity();
  EXPECT_FALSE(scene.OnBeginFrame(MsToTicks(2), kStartHeadPose));
}

TEST(UiScene, InvisibleElementsDoNotCauseOnBeginFrameDirtiness) {
  UiScene scene;
  auto element = std::make_unique<AlwaysDirty>();
  UiElement* element_ptr = element.get();
  scene.AddUiElement(kRoot, std::move(element));
  EXPECT_TRUE(scene.OnBeginFrame(MsToTicks(1), kStartHeadPose));

  element_ptr->SetVisible(false);
  element_ptr->UpdateComputedOpacity();
  EXPECT_FALSE(scene.OnBeginFrame(MsToTicks(2), kStartHeadPose));
}

typedef struct {
  LayoutAlignment x_anchoring;
  LayoutAlignment y_anchoring;
  LayoutAlignment x_centering;
  LayoutAlignment y_centering;
  float expected_x;
  float expected_y;
} AlignmentTestCase;

class AlignmentTest : public ::testing::TestWithParam<AlignmentTestCase> {};

TEST_P(AlignmentTest, VerifyCorrectPosition) {
  UiScene scene;

  // Create a parent element with non-unity size and scale.
  auto element = std::make_unique<UiElement>();
  UiElement* parent = element.get();
  element->SetSize(2, 2);
  element->SetScale(2, 2, 1);
  scene.AddUiElement(kRoot, std::move(element));

  // Add a child to the parent, with anchoring.
  element = std::make_unique<UiElement>();
  UiElement* child = element.get();
  element->SetSize(1, 1);
  element->set_x_anchoring(GetParam().x_anchoring);
  element->set_y_anchoring(GetParam().y_anchoring);
  element->set_x_centering(GetParam().x_centering);
  element->set_y_centering(GetParam().y_centering);
  parent->AddChild(std::move(element));

  scene.OnBeginFrame(MsToTicks(0), kStartHeadPose);
  EXPECT_NEAR(GetParam().expected_x, child->GetCenter().x(), TOLERANCE);
  EXPECT_NEAR(GetParam().expected_y, child->GetCenter().y(), TOLERANCE);
}

const std::vector<AlignmentTestCase> alignment_test_cases = {
    // Test anchoring.
    {NONE, NONE, NONE, NONE, 0, 0},
    {LEFT, NONE, NONE, NONE, -2, 0},
    {RIGHT, NONE, NONE, NONE, 2, 0},
    {NONE, TOP, NONE, NONE, 0, 2},
    {NONE, BOTTOM, NONE, NONE, 0, -2},
    {LEFT, TOP, NONE, NONE, -2, 2},
    // Test centering.
    {NONE, NONE, LEFT, NONE, 1, 0},
    {NONE, NONE, RIGHT, NONE, -1, 0},
    {NONE, NONE, NONE, TOP, 0, -1},
    {NONE, NONE, NONE, BOTTOM, 0, 1},
    {NONE, NONE, LEFT, TOP, 1, -1},
    // Test a combination of the two.
    {RIGHT, TOP, LEFT, BOTTOM, 3, 3},
};

INSTANTIATE_TEST_CASE_P(AlignmentTestCases,
                        AlignmentTest,
                        ::testing::ValuesIn(alignment_test_cases));

}  // namespace vr
