// Copyright (c) 2012 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 "ash/drag_drop/drag_drop_tracker.h"

#include <memory>

#include "ash/public/cpp/shell_window_ids.h"
#include "ash/scoped_root_window_for_new_windows.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm_window.h"
#include "ui/aura/test/test_windows.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/events/event_utils.h"

namespace ash {
namespace test {

class DragDropTrackerTest : public test::AshTestBase {
 public:
  void SetUp() override { AshTestBase::SetUp(); }

  aura::Window* CreateTestWindow(const gfx::Rect& bounds) {
    static int window_id = 0;
    return CreateTestWindowInShellWithDelegate(
        aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(),
        window_id++, bounds);
  }

  static aura::Window* GetTarget(const gfx::Point& location) {
    std::unique_ptr<DragDropTracker> tracker(
        new DragDropTracker(Shell::GetPrimaryRootWindow(), NULL));
    ui::MouseEvent e(ui::ET_MOUSE_DRAGGED, location, location,
                     ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
    aura::Window* target = tracker->GetTarget(e);
    return target;
  }

  static ui::LocatedEvent* ConvertEvent(aura::Window* target,
                                        const ui::MouseEvent& event) {
    std::unique_ptr<DragDropTracker> tracker(
        new DragDropTracker(Shell::GetPrimaryRootWindow(), NULL));
    ui::LocatedEvent* converted = tracker->ConvertEvent(target, event);
    return converted;
  }
};

TEST_F(DragDropTrackerTest, GetTarget) {
  UpdateDisplay("200x200,300x300");
  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  EXPECT_EQ(2U, root_windows.size());

  std::unique_ptr<aura::Window> window0(
      CreateTestWindow(gfx::Rect(0, 0, 100, 100)));
  window0->Show();

  std::unique_ptr<aura::Window> window1(
      CreateTestWindow(gfx::Rect(300, 100, 100, 100)));
  window1->Show();
  EXPECT_EQ(root_windows[0], window0->GetRootWindow());
  EXPECT_EQ(root_windows[1], window1->GetRootWindow());
  EXPECT_EQ("0,0 100x100", window0->GetBoundsInScreen().ToString());
  EXPECT_EQ("300,100 100x100", window1->GetBoundsInScreen().ToString());

  // RootWindow0 is active so the capture window is parented to it.
  EXPECT_EQ(WmWindow::Get(root_windows[0]),
            Shell::GetWmRootWindowForNewWindows());

  // Start tracking from the RootWindow1 and check the point on RootWindow0 that
  // |window0| covers.
  EXPECT_EQ(window0.get(), GetTarget(gfx::Point(50, 50)));

  // Start tracking from the RootWindow0 and check the point on RootWindow0 that
  // neither |window0| nor |window1| covers.
  EXPECT_NE(window0.get(), GetTarget(gfx::Point(150, 150)));
  EXPECT_NE(window1.get(), GetTarget(gfx::Point(150, 150)));

  // Start tracking from the RootWindow0 and check the point on RootWindow1 that
  // |window1| covers.
  EXPECT_EQ(window1.get(), GetTarget(gfx::Point(350, 150)));

  // Start tracking from the RootWindow0 and check the point on RootWindow1 that
  // neither |window0| nor |window1| covers.
  EXPECT_NE(window0.get(), GetTarget(gfx::Point(50, 250)));
  EXPECT_NE(window1.get(), GetTarget(gfx::Point(50, 250)));

  // Make RootWindow1 active so that capture window is parented to it.
  ScopedRootWindowForNewWindows root_for_new_windows(
      WmWindow::Get(root_windows[1]));

  // Start tracking from the RootWindow1 and check the point on RootWindow0 that
  // |window0| covers.
  EXPECT_EQ(window0.get(), GetTarget(gfx::Point(-150, 50)));

  // Start tracking from the RootWindow1 and check the point on RootWindow0 that
  // neither |window0| nor |window1| covers.
  EXPECT_NE(window0.get(), GetTarget(gfx::Point(150, -50)));
  EXPECT_NE(window1.get(), GetTarget(gfx::Point(150, -50)));

  // Start tracking from the RootWindow1 and check the point on RootWindow1 that
  // |window1| covers.
  EXPECT_EQ(window1.get(), GetTarget(gfx::Point(150, 150)));

  // Start tracking from the RootWindow1 and check the point on RootWindow1 that
  // neither |window0| nor |window1| covers.
  EXPECT_NE(window0.get(), GetTarget(gfx::Point(50, 50)));
  EXPECT_NE(window1.get(), GetTarget(gfx::Point(50, 50)));
}

TEST_F(DragDropTrackerTest, ConvertEvent) {
  UpdateDisplay("200x200,300x300");
  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  EXPECT_EQ(2U, root_windows.size());

  std::unique_ptr<aura::Window> window0(
      CreateTestWindow(gfx::Rect(0, 0, 100, 100)));
  window0->Show();

  std::unique_ptr<aura::Window> window1(
      CreateTestWindow(gfx::Rect(300, 100, 100, 100)));
  window1->Show();

  // RootWindow0 is active so the capture window is parented to it.
  EXPECT_EQ(WmWindow::Get(root_windows[0]),
            Shell::GetWmRootWindowForNewWindows());

  // Start tracking from the RootWindow0 and converts the mouse event into
  // |window0|'s coodinates.
  ui::MouseEvent original00(ui::ET_MOUSE_DRAGGED, gfx::Point(50, 50),
                            gfx::Point(50, 50), ui::EventTimeForNow(),
                            ui::EF_NONE, ui::EF_NONE);
  std::unique_ptr<ui::LocatedEvent> converted00(
      ConvertEvent(window0.get(), original00));
  EXPECT_EQ(original00.type(), converted00->type());
  EXPECT_EQ("50,50", converted00->location().ToString());
  EXPECT_EQ("50,50", converted00->root_location().ToString());
  EXPECT_EQ(original00.flags(), converted00->flags());

  // Start tracking from the RootWindow0 and converts the mouse event into
  // |window1|'s coodinates.
  ui::MouseEvent original01(ui::ET_MOUSE_DRAGGED, gfx::Point(350, 150),
                            gfx::Point(350, 150), ui::EventTimeForNow(),
                            ui::EF_NONE, ui::EF_NONE);
  std::unique_ptr<ui::LocatedEvent> converted01(
      ConvertEvent(window1.get(), original01));
  EXPECT_EQ(original01.type(), converted01->type());
  EXPECT_EQ("50,50", converted01->location().ToString());
  EXPECT_EQ("150,150", converted01->root_location().ToString());
  EXPECT_EQ(original01.flags(), converted01->flags());

  // Make RootWindow1 active so that capture window is parented to it.
  ScopedRootWindowForNewWindows root_for_new_windows(
      WmWindow::Get(root_windows[1]));

  // Start tracking from the RootWindow1 and converts the mouse event into
  // |window0|'s coodinates.
  ui::MouseEvent original10(ui::ET_MOUSE_DRAGGED, gfx::Point(-150, 50),
                            gfx::Point(-150, 50), ui::EventTimeForNow(),
                            ui::EF_NONE, ui::EF_NONE);
  std::unique_ptr<ui::LocatedEvent> converted10(
      ConvertEvent(window0.get(), original10));
  EXPECT_EQ(original10.type(), converted10->type());
  EXPECT_EQ("50,50", converted10->location().ToString());
  EXPECT_EQ("50,50", converted10->root_location().ToString());
  EXPECT_EQ(original10.flags(), converted10->flags());

  // Start tracking from the RootWindow1 and converts the mouse event into
  // |window1|'s coodinates.
  ui::MouseEvent original11(ui::ET_MOUSE_DRAGGED, gfx::Point(150, 150),
                            gfx::Point(150, 150), ui::EventTimeForNow(),
                            ui::EF_NONE, ui::EF_NONE);
  std::unique_ptr<ui::LocatedEvent> converted11(
      ConvertEvent(window1.get(), original11));
  EXPECT_EQ(original11.type(), converted11->type());
  EXPECT_EQ("50,50", converted11->location().ToString());
  EXPECT_EQ("150,150", converted11->root_location().ToString());
  EXPECT_EQ(original11.flags(), converted11->flags());
}

}  // namespace test
}  // namespace aura
