// 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 "ash/drag_drop/drag_drop_controller.h"

#include "ash/shell.h"
#include "ash/test/ash_interactive_ui_test_base.h"
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/base/test/ui_controls.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"

namespace ash {
namespace {

class DraggableView : public views::View {
 public:
  DraggableView() {}
  ~DraggableView() override {}

  // views::View overrides:
  int GetDragOperations(const gfx::Point& press_pt) override {
    return ui::DragDropTypes::DRAG_MOVE;
  }
  void WriteDragData(const gfx::Point& press_pt,
                     OSExchangeData* data) override {
    data->SetString(base::UTF8ToUTF16("test"));
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(DraggableView);
};

class TargetView : public views::View {
 public:
  TargetView() : dropped_(false) {}
  ~TargetView() override {}

  // views::View overrides:
  bool GetDropFormats(
      int* formats,
      std::set<ui::Clipboard::FormatType>* format_types) override {
    *formats = ui::OSExchangeData::STRING;
    return true;
  }
  bool AreDropTypesRequired() override { return false; }
  bool CanDrop(const OSExchangeData& data) override { return true; }
  int OnDragUpdated(const ui::DropTargetEvent& event) override {
    return ui::DragDropTypes::DRAG_MOVE;
  }
  int OnPerformDrop(const ui::DropTargetEvent& event) override {
    dropped_ = true;
    return ui::DragDropTypes::DRAG_MOVE;
  }

  bool dropped() const { return dropped_; }

 private:
  bool dropped_;

  DISALLOW_COPY_AND_ASSIGN(TargetView);
};

views::Widget* CreateWidget(views::View* contents_view,
                            const gfx::Rect& bounds) {
  views::Widget* widget = new views::Widget;
  views::Widget::InitParams params;
  params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
  params.accept_events = true;
  params.context = Shell::GetPrimaryRootWindow();
  params.bounds = bounds;
  widget->Init(params);

  widget->SetContentsView(contents_view);
  widget->Show();
  return widget;
}

void QuitLoop() {
  base::MessageLoop::current()->QuitWhenIdle();
}

void DragDropAcrossMultiDisplay_Step4() {
  ui_controls::SendMouseEventsNotifyWhenDone(ui_controls::LEFT, ui_controls::UP,
                                             base::Bind(&QuitLoop));
}

void DragDropAcrossMultiDisplay_Step3() {
  // Move to the edge of the 1st display so that the mouse
  // is moved to 2nd display by ash.
  ui_controls::SendMouseMoveNotifyWhenDone(
      399, 10, base::Bind(&DragDropAcrossMultiDisplay_Step4));
}

void DragDropAcrossMultiDisplay_Step2() {
  ui_controls::SendMouseMoveNotifyWhenDone(
      20, 10, base::Bind(&DragDropAcrossMultiDisplay_Step3));
}

void DragDropAcrossMultiDisplay_Step1() {
  ui_controls::SendMouseEventsNotifyWhenDone(
      ui_controls::LEFT, ui_controls::DOWN,
      base::Bind(&DragDropAcrossMultiDisplay_Step2));
}

}  // namespace

using DragDropTest = test::AshInteractiveUITestBase;

#if !defined(OS_CHROMEOS)
#define MAYBE_DragDropAcrossMultiDisplay DISABLED_DragDropAcrossMultiDisplay
#else
#define MAYBE_DragDropAcrossMultiDisplay DragDropAcrossMultiDisplay
#endif

// Test if the mouse gets moved properly to another display
// during drag & drop operation.
TEST_F(DragDropTest, MAYBE_DragDropAcrossMultiDisplay) {
  if (!SupportsMultipleDisplays())
    return;

  UpdateDisplay("400x400,400x400");
  aura::Window::Windows root_windows =
      Shell::GetInstance()->GetAllRootWindows();
  views::View* draggable_view = new DraggableView();
  draggable_view->set_drag_controller(NULL);
  draggable_view->SetBounds(0, 0, 100, 100);
  views::Widget* source =
      CreateWidget(draggable_view, gfx::Rect(0, 0, 100, 100));

  TargetView* target_view = new TargetView();
  target_view->SetBounds(0, 0, 100, 100);
  views::Widget* target =
      CreateWidget(target_view, gfx::Rect(400, 0, 100, 100));

  // Make sure they're on the different root windows.
  EXPECT_EQ(root_windows[0], source->GetNativeView()->GetRootWindow());
  EXPECT_EQ(root_windows[1], target->GetNativeView()->GetRootWindow());

  ui_controls::SendMouseMoveNotifyWhenDone(
      10, 10, base::Bind(&DragDropAcrossMultiDisplay_Step1));

  base::MessageLoop::current()->Run();

  EXPECT_TRUE(target_view->dropped());

  source->Close();
  target->Close();
}

}  // namespace ash
