// 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/wm/toplevel_window_event_handler.h"

#include "ash/shell.h"
#include "ash/wm/window_state.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tracker.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/hit_test.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/events/gestures/gesture_recognizer.h"

namespace ash {

ToplevelWindowEventHandler::ToplevelWindowEventHandler()
    : weak_factory_(this) {}

ToplevelWindowEventHandler::~ToplevelWindowEventHandler() = default;

void ToplevelWindowEventHandler::OnKeyEvent(ui::KeyEvent* event) {
  wm_toplevel_window_event_handler_.OnKeyEvent(event);
}

void ToplevelWindowEventHandler::OnMouseEvent(ui::MouseEvent* event) {
  aura::Window* target = static_cast<aura::Window*>(event->target());
  wm_toplevel_window_event_handler_.OnMouseEvent(event, target);
}

void ToplevelWindowEventHandler::OnGestureEvent(ui::GestureEvent* event) {
  aura::Window* target = static_cast<aura::Window*>(event->target());
  wm_toplevel_window_event_handler_.OnGestureEvent(event, target);
}

bool ToplevelWindowEventHandler::AttemptToStartDrag(
    aura::Window* window,
    const gfx::Point& point_in_parent,
    int window_component,
    const wm::WmToplevelWindowEventHandler::EndClosure& end_closure) {
  aura::Window* gesture_target =
      wm_toplevel_window_event_handler_.gesture_target();
  ::wm::WindowMoveSource source = gesture_target
                                      ? ::wm::WINDOW_MOVE_SOURCE_TOUCH
                                      : ::wm::WINDOW_MOVE_SOURCE_MOUSE;
  if (gesture_target) {
    ui::GestureRecognizer::Get()->TransferEventsTo(
        gesture_target, window,
        ui::GestureRecognizer::ShouldCancelTouches::DontCancel);
  }
  return wm_toplevel_window_event_handler_.AttemptToStartDrag(
      window, point_in_parent, window_component, source, end_closure);
}

::wm::WindowMoveResult ToplevelWindowEventHandler::RunMoveLoop(
    aura::Window* source,
    const gfx::Vector2d& drag_offset,
    ::wm::WindowMoveSource move_source) {
  DCHECK(!in_move_loop_);  // Can only handle one nested loop at a time.
  aura::Window* root_window = source->GetRootWindow();
  DCHECK(root_window);
  gfx::Point drag_location;
  if (move_source == ::wm::WINDOW_MOVE_SOURCE_TOUCH &&
      aura::Env::GetInstance()->is_touch_down()) {
    gfx::PointF drag_location_f;
    bool has_point = ui::GestureRecognizer::Get()->GetLastTouchPointForTarget(
        source, &drag_location_f);
    drag_location = gfx::ToFlooredPoint(drag_location_f);
    DCHECK(has_point);
  } else {
    drag_location =
        root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot();
    aura::Window::ConvertPointToTarget(root_window, source->parent(),
                                       &drag_location);
  }
  // Set the cursor before calling AttemptToStartDrag(), as that will
  // eventually call LockCursor() and prevent the cursor from changing.
  aura::client::CursorClient* cursor_client =
      aura::client::GetCursorClient(root_window);
  if (cursor_client)
    cursor_client->SetCursor(ui::CursorType::kPointer);

  base::RunLoop run_loop;

  wm::WmToplevelWindowEventHandler::DragResult result =
      wm::WmToplevelWindowEventHandler::DragResult::SUCCESS;
  if (!wm_toplevel_window_event_handler_.AttemptToStartDrag(
          source, drag_location, HTCAPTION, move_source,
          base::Bind(&ToplevelWindowEventHandler::OnDragCompleted,
                     weak_factory_.GetWeakPtr(), &result, &run_loop))) {
    return ::wm::MOVE_CANCELED;
  }

  in_move_loop_ = true;
  base::WeakPtr<ToplevelWindowEventHandler> weak_ptr(
      weak_factory_.GetWeakPtr());
  base::MessageLoop* loop = base::MessageLoop::current();
  base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop);

  // Disable window position auto management while dragging and restore it
  // aftrewards.
  wm::WindowState* window_state = wm::GetWindowState(source);
  const bool window_position_managed = window_state->GetWindowPositionManaged();
  window_state->SetWindowPositionManaged(false);
  aura::WindowTracker tracker({source});

  run_loop.Run();

  if (!weak_ptr)
    return ::wm::MOVE_CANCELED;

  // Make sure the window hasn't been deleted.
  if (tracker.Contains(source))
    window_state->SetWindowPositionManaged(window_position_managed);

  in_move_loop_ = false;
  return result == wm::WmToplevelWindowEventHandler::DragResult::SUCCESS
             ? ::wm::MOVE_SUCCESSFUL
             : ::wm::MOVE_CANCELED;
}

void ToplevelWindowEventHandler::EndMoveLoop() {
  if (in_move_loop_)
    wm_toplevel_window_event_handler_.RevertDrag();
}

void ToplevelWindowEventHandler::OnDragCompleted(
    wm::WmToplevelWindowEventHandler::DragResult* result_return_value,
    base::RunLoop* run_loop,
    wm::WmToplevelWindowEventHandler::DragResult result) {
  *result_return_value = result;
  run_loop->Quit();
}

}  // namespace ash
