// Copyright (c) 2013 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 "ui/aura/window_targeter.h"

#include <utility>

#include "base/macros.h"
#include "ui/aura/scoped_window_targeter.h"
#include "ui/aura/test/aura_mus_test_base.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/mus/test_window_tree.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/events/event_utils.h"
#include "ui/events/test/test_event_handler.h"

namespace aura {

// Always returns the same window.
class StaticWindowTargeter : public WindowTargeter {
 public:
  explicit StaticWindowTargeter(aura::Window* window)
      : window_(window) {}
  ~StaticWindowTargeter() override {}

 private:
  // aura::WindowTargeter:
  Window* FindTargetForLocatedEvent(Window* window,
                                    ui::LocatedEvent* event) override {
    return window_;
  }

  Window* window_;

  DISALLOW_COPY_AND_ASSIGN(StaticWindowTargeter);
};

gfx::RectF GetEffectiveVisibleBoundsInRootWindow(Window* window) {
  gfx::RectF bounds = gfx::RectF(gfx::SizeF(window->bounds().size()));
  Window* root = window->GetRootWindow();
  CHECK(window->layer());
  CHECK(root->layer());
  gfx::Transform transform;
  if (!window->layer()->GetTargetTransformRelativeTo(root->layer(), &transform))
    return gfx::RectF();
  transform.TransformRect(&bounds);
  return bounds;
}

using WindowTargeterTest = test::AuraTestBaseWithType;

TEST_P(WindowTargeterTest, Basic) {
  test::TestWindowDelegate delegate;
  std::unique_ptr<Window> window(
      CreateNormalWindow(1, root_window(), &delegate));
  Window* one = CreateNormalWindow(2, window.get(), &delegate);
  Window* two = CreateNormalWindow(3, window.get(), &delegate);

  window->SetBounds(gfx::Rect(0, 0, 1000, 1000));
  one->SetBounds(gfx::Rect(0, 0, 500, 100));
  two->SetBounds(gfx::Rect(501, 0, 500, 1000));

  root_window()->Show();

  ui::test::TestEventHandler handler;
  one->AddPreTargetHandler(&handler);

  ui::MouseEvent press(ui::ET_MOUSE_PRESSED, gfx::Point(20, 20),
                       gfx::Point(20, 20), ui::EventTimeForNow(), ui::EF_NONE,
                       ui::EF_NONE);
  DispatchEventUsingWindowDispatcher(&press);
  EXPECT_EQ(1, handler.num_mouse_events());

  handler.Reset();
  DispatchEventUsingWindowDispatcher(&press);
  EXPECT_EQ(1, handler.num_mouse_events());

  one->RemovePreTargetHandler(&handler);
}

TEST_P(WindowTargeterTest, FindTargetInRootWindow) {
  WindowTargeter targeter;

  display::Display display =
      display::Screen::GetScreen()->GetDisplayNearestWindow(root_window());
  EXPECT_EQ(display.bounds(), root_window()->GetBoundsInScreen());
  EXPECT_EQ(display.bounds(), gfx::Rect(0, 0, 800, 600));

  // Mouse and touch presses inside the display yield null targets.
  gfx::Point inside = display.bounds().CenterPoint();
  ui::MouseEvent mouse1(ui::ET_MOUSE_PRESSED, inside, inside,
                        ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
  ui::TouchEvent touch1(ui::ET_TOUCH_PRESSED, inside, ui::EventTimeForNow(),
                        ui::PointerDetails());
  touch1.set_root_location(inside);
  EXPECT_EQ(nullptr, targeter.FindTargetInRootWindow(root_window(), mouse1));
  EXPECT_EQ(nullptr, targeter.FindTargetInRootWindow(root_window(), touch1));

  // Touch presses outside the display yields the root window as a target.
  gfx::Point outside(display.bounds().right() + 10, inside.y());
  ui::MouseEvent mouse2(ui::ET_MOUSE_PRESSED, outside, outside,
                        ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
  ui::TouchEvent touch2(ui::ET_TOUCH_PRESSED, outside, ui::EventTimeForNow(),
                        ui::PointerDetails());
  touch2.set_root_location(outside);
  EXPECT_EQ(nullptr, targeter.FindTargetInRootWindow(root_window(), mouse2));
  EXPECT_EQ(root_window(),
            targeter.FindTargetInRootWindow(root_window(), touch2));
}

TEST_P(WindowTargeterTest, ScopedWindowTargeter) {
  test::TestWindowDelegate delegate;
  std::unique_ptr<Window> window(
      CreateNormalWindow(1, root_window(), &delegate));
  Window* child = CreateNormalWindow(2, window.get(), &delegate);

  window->SetBounds(gfx::Rect(30, 30, 100, 100));
  child->SetBounds(gfx::Rect(20, 20, 50, 50));
  root_window()->Show();

  ui::EventTarget* root = root_window();
  ui::EventTargeter* targeter = root->GetEventTargeter();

  gfx::Point event_location(60, 60);
  {
    ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location,
                         ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
    EXPECT_EQ(child, targeter->FindTargetForEvent(root, &mouse));
  }

  // Install a targeter on |window| so that the events never reach the child.
  std::unique_ptr<ScopedWindowTargeter> scoped_targeter(
      new ScopedWindowTargeter(window.get(),
                               std::unique_ptr<WindowTargeter>(
                                   new StaticWindowTargeter(window.get()))));
  {
    ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location,
                         ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
    EXPECT_EQ(window.get(), targeter->FindTargetForEvent(root, &mouse));
  }
  scoped_targeter.reset();
  {
    ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location,
                         ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
    EXPECT_EQ(child, targeter->FindTargetForEvent(root, &mouse));
  }
}

// Test that ScopedWindowTargeter does not crash if the window for which it
// replaces the targeter gets destroyed before it does.
TEST_P(WindowTargeterTest, ScopedWindowTargeterWindowDestroyed) {
  test::TestWindowDelegate delegate;
  std::unique_ptr<Window> window(
      CreateNormalWindow(1, root_window(), &delegate));
  std::unique_ptr<ScopedWindowTargeter> scoped_targeter(
      new ScopedWindowTargeter(window.get(),
                               std::unique_ptr<aura::WindowTargeter>(
                                   new StaticWindowTargeter(window.get()))));

  window.reset();
  scoped_targeter.reset();

  // We did not crash!
}

TEST_P(WindowTargeterTest, TargetTransformedWindow) {
  root_window()->Show();

  test::TestWindowDelegate delegate;
  std::unique_ptr<Window> window(
      CreateNormalWindow(2, root_window(), &delegate));

  const gfx::Rect window_bounds(100, 20, 400, 80);
  window->SetBounds(window_bounds);

  ui::EventTarget* root_target = root_window();
  ui::EventTargeter* targeter = root_target->GetEventTargeter();
  gfx::Point event_location(490, 50);
  {
    ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location,
                         ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
    EXPECT_EQ(window.get(), targeter->FindTargetForEvent(root_target, &mouse));
  }

  // Scale |window| by 50%. This should move it away from underneath
  // |event_location|, so an event in that location will not be targeted to it.
  gfx::Transform transform;
  transform.Scale(0.5, 0.5);
  window->SetTransform(transform);
  EXPECT_EQ(gfx::RectF(100, 20, 200, 40).ToString(),
            GetEffectiveVisibleBoundsInRootWindow(window.get()).ToString());
  {
    ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location,
                         ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
    EXPECT_EQ(root_window(), targeter->FindTargetForEvent(root_target, &mouse));
  }

  transform = gfx::Transform();
  transform.Translate(200, 10);
  transform.Scale(0.5, 0.5);
  window->SetTransform(transform);
  EXPECT_EQ(gfx::RectF(300, 30, 200, 40).ToString(),
            GetEffectiveVisibleBoundsInRootWindow(window.get()).ToString());
  {
    ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, event_location, event_location,
                         ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
    EXPECT_EQ(window.get(), targeter->FindTargetForEvent(root_target, &mouse));
  }
}

class IdCheckingEventTargeter : public WindowTargeter {
 public:
  explicit IdCheckingEventTargeter(int id) : id_(id) {}
  ~IdCheckingEventTargeter() override {}

 protected:
  // WindowTargeter:
  bool SubtreeShouldBeExploredForEvent(Window* window,
                                       const ui::LocatedEvent& event) override {
    return (window->id() == id_ &&
            WindowTargeter::SubtreeShouldBeExploredForEvent(window, event));
  }

 private:
  int id_;
};

TEST_P(WindowTargeterTest, Bounds) {
  test::TestWindowDelegate delegate;
  std::unique_ptr<Window> parent(
      CreateNormalWindow(1, root_window(), &delegate));
  std::unique_ptr<Window> child(CreateNormalWindow(1, parent.get(), &delegate));
  std::unique_ptr<Window> grandchild(
      CreateNormalWindow(1, child.get(), &delegate));

  parent->SetBounds(gfx::Rect(0, 0, 30, 30));
  child->SetBounds(gfx::Rect(5, 5, 20, 20));
  grandchild->SetBounds(gfx::Rect(5, 5, 5, 5));

  ASSERT_EQ(1u, root_window()->children().size());
  ASSERT_EQ(1u, root_window()->children()[0]->children().size());
  ASSERT_EQ(1u, root_window()->children()[0]->children()[0]->children().size());

  Window* parent_r = root_window()->children()[0];
  Window* child_r = parent_r->children()[0];
  Window* grandchild_r = child_r->children()[0];

  ui::EventTarget* root_target = root_window();
  ui::EventTargeter* targeter = root_target->GetEventTargeter();

  // Dispatch a mouse event that falls on the parent, but not on the child. When
  // the default event-targeter used, the event will still reach |grandchild|,
  // because the default targeter does not look at the bounds.
  ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(1, 1), gfx::Point(1, 1),
                       ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
  EXPECT_EQ(parent_r, targeter->FindTargetForEvent(root_target, &mouse));

  // Install a targeter on the |child| that looks at the window id as well
  // as the bounds and makes sure the event reaches the target only if the id of
  // the window is equal to 2 (incorrect). This causes the event to get handled
  // by |parent|.
  ui::MouseEvent mouse2(ui::ET_MOUSE_MOVED, gfx::Point(8, 8), gfx::Point(8, 8),
                        ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
  std::unique_ptr<aura::WindowTargeter> original_targeter =
      child_r->SetEventTargeter(std::make_unique<IdCheckingEventTargeter>(2));
  EXPECT_EQ(parent_r, targeter->FindTargetForEvent(root_target, &mouse2));

  // Now install a targeter on the |child| that looks at the window id as well
  // as the bounds and makes sure the event reaches the target only if the id of
  // the window is equal to 1 (correct).
  ui::MouseEvent mouse3(ui::ET_MOUSE_MOVED, gfx::Point(8, 8), gfx::Point(8, 8),
                        ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
  child_r->SetEventTargeter(std::make_unique<IdCheckingEventTargeter>(1));
  EXPECT_EQ(child_r, targeter->FindTargetForEvent(root_target, &mouse3));

  // restore original WindowTargeter for |child|.
  child_r->SetEventTargeter(std::move(original_targeter));

  // Target |grandchild| location.
  ui::MouseEvent second(ui::ET_MOUSE_MOVED, gfx::Point(12, 12),
                        gfx::Point(12, 12), ui::EventTimeForNow(), ui::EF_NONE,
                        ui::EF_NONE);
  EXPECT_EQ(grandchild_r, targeter->FindTargetForEvent(root_target, &second));

  // Target |child| location.
  ui::MouseEvent third(ui::ET_MOUSE_MOVED, gfx::Point(8, 8), gfx::Point(8, 8),
                       ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
  EXPECT_EQ(child_r, targeter->FindTargetForEvent(root_target, &third));
}

class IgnoreWindowTargeter : public WindowTargeter {
 public:
  IgnoreWindowTargeter() {}
  ~IgnoreWindowTargeter() override {}

 private:
  // WindowTargeter:
  bool SubtreeShouldBeExploredForEvent(Window* window,
                                       const ui::LocatedEvent& event) override {
    return false;
  }
};

// Verifies that an EventTargeter installed on an EventTarget can dictate
// whether the target itself can process an event.
TEST_P(WindowTargeterTest, TargeterChecksOwningEventTarget) {
  test::TestWindowDelegate delegate;
  std::unique_ptr<Window> child(
      CreateNormalWindow(1, root_window(), &delegate));

  ui::EventTarget* root_target = root_window();
  ui::EventTargeter* targeter = root_target->GetEventTargeter();

  ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(10, 10),
                       gfx::Point(10, 10), ui::EventTimeForNow(), ui::EF_NONE,
                       ui::EF_NONE);
  EXPECT_EQ(child.get(), targeter->FindTargetForEvent(root_target, &mouse));

  // Install an event targeter on |child| which always prevents the target from
  // receiving event.
  child->SetEventTargeter(std::make_unique<IgnoreWindowTargeter>());

  ui::MouseEvent mouse2(ui::ET_MOUSE_MOVED, gfx::Point(10, 10),
                        gfx::Point(10, 10), ui::EventTimeForNow(), ui::EF_NONE,
                        ui::EF_NONE);
  EXPECT_EQ(root_window(), targeter->FindTargetForEvent(root_target, &mouse2));
}

INSTANTIATE_TEST_CASE_P(/* no prefix */,
                        WindowTargeterTest,
                        ::testing::Values(Env::Mode::LOCAL, Env::Mode::MUS));

using WindowTargeterMus = aura::test::AuraMusClientTestBase;

TEST_F(WindowTargeterMus, SetInsets) {
  aura::Window window(nullptr);
  window.Init(ui::LAYER_NOT_DRAWN);
  std::unique_ptr<WindowTargeter> window_targeter_ptr =
      std::make_unique<WindowTargeter>();
  WindowTargeter* window_targeter = window_targeter_ptr.get();
  window.SetEventTargeter(std::move(window_targeter_ptr));
  const gfx::Insets insets1(1, 2, 3, 4);
  const gfx::Insets insets2(11, 12, 13, 14);
  window_targeter->SetInsets(insets1, insets2);
  EXPECT_EQ(insets1, window_tree()->last_mouse_hit_test_insets());
  EXPECT_EQ(insets2, window_tree()->last_touch_hit_test_insets());
}

TEST_F(WindowTargeterMus, SetInsetsBeforeInstall) {
  aura::Window window(nullptr);
  window.Init(ui::LAYER_NOT_DRAWN);
  std::unique_ptr<WindowTargeter> window_targeter =
      std::make_unique<WindowTargeter>();
  const gfx::Insets insets1(1, 2, 3, 4);
  const gfx::Insets insets2(11, 12, 13, 14);
  window_targeter->SetInsets(insets1, insets2);
  window.SetEventTargeter(std::move(window_targeter));
  EXPECT_EQ(insets1, window_tree()->last_mouse_hit_test_insets());
  EXPECT_EQ(insets2, window_tree()->last_touch_hit_test_insets());
}

}  // namespace aura
