// 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 "ash/public/cpp/shell_window_ids.h"
#include "ash/shell.h"
#include "ash/window_factory.h"
#include "ash/wm/root_window_finder.h"
#include "ui/aura/client/window_parenting_client.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/wm/core/coordinate_conversion.h"
#include "ui/wm/public/activation_delegate.h"

namespace ash {
namespace {

// An activation delegate which disables activating the drag and drop window.
class CaptureWindowActivationDelegate : public ::wm::ActivationDelegate {
 public:
  CaptureWindowActivationDelegate() = default;
  ~CaptureWindowActivationDelegate() override = default;

  // wm::ActivationDelegate overrides:
  bool ShouldActivate() const override { return false; }

 private:
  DISALLOW_COPY_AND_ASSIGN(CaptureWindowActivationDelegate);
};

// Creates a window for capturing drag events.
std::unique_ptr<aura::Window> CreateCaptureWindow(
    aura::Window* context_root,
    aura::WindowDelegate* delegate) {
  static CaptureWindowActivationDelegate* activation_delegate_instance = NULL;
  if (!activation_delegate_instance)
    activation_delegate_instance = new CaptureWindowActivationDelegate;
  std::unique_ptr<aura::Window> window = window_factory::NewWindow(delegate);
  // Set type of window as popup to prevent different window manager codes
  // trying to manage this window.
  window->SetType(aura::client::WINDOW_TYPE_POPUP);
  window->Init(ui::LAYER_NOT_DRAWN);
  aura::client::ParentWindowWithContext(window.get(), context_root,
                                        gfx::Rect());
  ::wm::SetActivationDelegate(window.get(), activation_delegate_instance);
  window->Show();
  DCHECK(window->bounds().size().IsEmpty());
  return window;
}

}  // namespace

DragDropTracker::DragDropTracker(aura::Window* context_root,
                                 aura::WindowDelegate* delegate)
    : capture_window_(CreateCaptureWindow(context_root, delegate)) {}

DragDropTracker::~DragDropTracker() {
  capture_window_->ReleaseCapture();
}

void DragDropTracker::TakeCapture() {
  capture_window_->SetCapture();
}

aura::Window* DragDropTracker::GetTarget(const ui::LocatedEvent& event) {
  DCHECK(capture_window_.get());
  gfx::Point location_in_screen = event.location();
  ::wm::ConvertPointToScreen(capture_window_.get(), &location_in_screen);
  aura::Window* root_window_at_point = wm::GetRootWindowAt(location_in_screen);
  gfx::Point location_in_root = location_in_screen;
  ::wm::ConvertPointFromScreen(root_window_at_point, &location_in_root);
  return root_window_at_point->GetEventHandlerForPoint(location_in_root);
}

ui::LocatedEvent* DragDropTracker::ConvertEvent(aura::Window* target,
                                                const ui::LocatedEvent& event) {
  DCHECK(capture_window_.get());
  gfx::Point target_location = event.location();
  aura::Window::ConvertPointToTarget(capture_window_.get(), target,
                                     &target_location);
  gfx::Point location_in_screen = event.location();
  ::wm::ConvertPointToScreen(capture_window_.get(), &location_in_screen);
  gfx::Point target_root_location = event.root_location();
  aura::Window::ConvertPointToTarget(capture_window_->GetRootWindow(),
                                     wm::GetRootWindowAt(location_in_screen),
                                     &target_root_location);
  int changed_button_flags = 0;
  if (event.IsMouseEvent())
    changed_button_flags = event.AsMouseEvent()->changed_button_flags();
  return new ui::MouseEvent(event.type(), target_location, target_root_location,
                            ui::EventTimeForNow(), event.flags(),
                            changed_button_flags);
}

}  // namespace ash
