// 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/transform_util.h"
#include "ui/gfx/geometry/vector3d_f.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 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);
}

TEST(UiScene, IsVisibleInHiddenSubtree) {
  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();
  scene.AddUiElement(kRoot, std::move(element));

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

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

  // Set initial computed opacity.
  scene.OnBeginFrame(gfx::MsToTicks(1), kStartHeadPose);

  parent->SetVisible(false);

  scene.OnBeginFrame(gfx::MsToTicks(2), kStartHeadPose);

  // On the second walk, we should skip the child.
  scene.OnBeginFrame(gfx::MsToTicks(3), kStartHeadPose);

  EXPECT_FALSE(child->IsVisible());
}

// 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(gfx::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(gfx::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.GetWebVrOverlayElementsToDraw().empty());
  child->SetVisible(false);
  scene.OnBeginFrame(gfx::MsToTicks(0), kStartHeadPose);
  EXPECT_TRUE(scene.GetWebVrOverlayElementsToDraw().empty());
}

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

  element_ptr->SetVisible(false);
  element_ptr->UpdateComputedOpacity();
  EXPECT_FALSE(scene.OnBeginFrame(gfx::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(gfx::MsToTicks(1), kStartHeadPose));

  model.foo = 2;
  element_ptr->SetVisible(false);
  element_ptr->UpdateComputedOpacity();
  EXPECT_FALSE(scene.OnBeginFrame(gfx::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(gfx::MsToTicks(1), kStartHeadPose));

  element_ptr->SetVisible(false);
  element_ptr->UpdateComputedOpacity();
  EXPECT_FALSE(scene.OnBeginFrame(gfx::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_contributes_to_parent_bounds(false);
  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(gfx::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_SUITE_P(AlignmentTestCases,
                         AlignmentTest,
                         ::testing::ValuesIn(alignment_test_cases));

}  // namespace vr
