// 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/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/coordinate_conversion.h"
#include "ui/aura/client/window_tree_client.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/events/event.h"
#include "ui/gfx/screen.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 aura::client::ActivationDelegate {
 public:
  CaptureWindowActivationDelegate() {}
  virtual ~CaptureWindowActivationDelegate() {}

  // aura::client::ActivationDelegate overrides:
  virtual bool ShouldActivate() const OVERRIDE {
    return false;
  }

 private:

  DISALLOW_COPY_AND_ASSIGN(CaptureWindowActivationDelegate);
};

// Creates a window for capturing drag events.
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;
  aura::Window* window = new aura::Window(delegate);
  window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
  window->Init(aura::WINDOW_LAYER_NOT_DRAWN);
  aura::client::ParentWindowWithContext(window, context_root, gfx::Rect());
  aura::client::SetActivationDelegate(window, 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();
  ash::wm::ConvertPointToScreen(capture_window_.get(), &location_in_screen);
  gfx::Point target_root_location = event.root_location();
  aura::Window::ConvertPointToTarget(
      capture_window_->GetRootWindow(),
      ash::wm::GetRootWindowAt(location_in_screen),
      &target_root_location);
  return new ui::MouseEvent(event.type(),
                            target_location,
                            target_root_location,
                            event.flags(),
                            static_cast<const ui::MouseEvent&>(event).
                                changed_button_flags());
}

}  // namespace ash
