// Copyright 2015 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/display/unified_mouse_warp_controller.h"

#include <cmath>

#include "ash/display/display_util.h"
#include "ash/display/mirror_window_controller.h"
#include "ash/display/window_tree_host_manager.h"
#include "ash/host/ash_window_tree_host.h"
#include "ash/shell.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/layout.h"
#include "ui/display/display_finder.h"
#include "ui/display/display_layout.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/manager/display_manager_utilities.h"
#include "ui/display/screen.h"
#include "ui/events/event_utils.h"
#include "ui/wm/core/coordinate_conversion.h"

namespace ash {

namespace {

AshWindowTreeHost* GetMirroringAshWindowTreeHostForDisplayId(
    int64_t display_id) {
  return Shell::Get()
      ->window_tree_host_manager()
      ->mirror_window_controller()
      ->GetAshWindowTreeHostForDisplayId(display_id);
}

const aura::WindowTreeHost* GetMirroringSourceHostForCurrentEvent() {
  return Shell::Get()
      ->window_tree_host_manager()
      ->mirror_window_controller()
      ->current_event_targeter_src_host();
}

}  // namespace

UnifiedMouseWarpController::UnifiedMouseWarpController()
    : current_cursor_display_id_(display::kInvalidDisplayId),
      update_location_for_test_(false),
      display_boundaries_computed_(false) {}

UnifiedMouseWarpController::~UnifiedMouseWarpController() = default;

bool UnifiedMouseWarpController::WarpMouseCursor(ui::MouseEvent* event) {
  // Mirroring windows are created asynchronously, so compute the edge
  // beounds when we received an event instead of in constructor.
  if (!display_boundaries_computed_)
    ComputeBounds();

  aura::Window* target = static_cast<aura::Window*>(event->target());
  gfx::Point point_in_unified_host = event->location();
  ::wm::ConvertPointToScreen(target, &point_in_unified_host);
  // The display bounds of the mirroring windows isn't scaled, so
  // transform back to the host coordinates.
  target->GetHost()->GetRootTransform().TransformPoint(&point_in_unified_host);

  // A native event may not exist in unit test.
  if (!event->HasNativeEvent())
    return false;

  // TODO(dnicoara): crbug.com/415680 Move cursor warping into Ozone once Ozone
  // has access to the logical display layout.
  // Native events in Ozone are in the native window coordinate system. We need
  // to translate them to get the global position.
  const auto* host = GetMirroringSourceHostForCurrentEvent();
  if (!host)
    return false;

  gfx::Point point_in_native =
      ui::EventSystemLocationFromNative(event->native_event());
  point_in_native.Offset(host->GetBoundsInPixels().x(),
                         host->GetBoundsInPixels().y());

  // TODO(afakhry): Remove implicit grab. crbug.com/773348.
  const display::Display display =
      display::Screen::GetScreen()->GetDisplayNearestWindow(
          const_cast<aura::Window*>(host->window()));
  if (current_cursor_display_id_ != display::kInvalidDisplayId &&
      current_cursor_display_id_ != display.id()) {
    aura::client::CursorClient* cursor_client =
        aura::client::GetCursorClient(target->GetRootWindow());
    if (cursor_client) {
      cursor_client->SetDisplay(display);
      current_cursor_display_id_ = display::kInvalidDisplayId;
    }
  }

  return WarpMouseCursorInNativeCoords(display.id(), point_in_native,
                                       point_in_unified_host,
                                       update_location_for_test_);
}

void UnifiedMouseWarpController::SetEnabled(bool enabled) {
  // Mouse warp should be always on in Unified mode.
}

void UnifiedMouseWarpController::ComputeBounds() {
  display::Displays display_list =
      Shell::Get()->display_manager()->software_mirroring_display_list();

  if (display_list.size() < 2) {
    LOG(ERROR) << "Mirroring Display lost during re-configuration";
    return;
  }

  for (size_t i = 0; i < display_list.size() - 1; ++i) {
    const display::Display& first = display_list[i];
    for (size_t j = i + 1; j < display_list.size(); ++j) {
      const display::Display& second = display_list[j];
      gfx::Rect first_edge;
      gfx::Rect second_edge;
      if (display::ComputeBoundary(first, second, &first_edge, &second_edge)) {
        first_edge = GetNativeEdgeBounds(
            GetMirroringAshWindowTreeHostForDisplayId(first.id()), first_edge);
        second_edge = GetNativeEdgeBounds(
            GetMirroringAshWindowTreeHostForDisplayId(second.id()),
            second_edge);

        displays_edges_map_[first.id()].emplace_back(first.id(), second.id(),
                                                     first_edge);
        displays_edges_map_[second.id()].emplace_back(second.id(), first.id(),
                                                      second_edge);
      }
    }
  }

  display_boundaries_computed_ = true;
}

bool UnifiedMouseWarpController::WarpMouseCursorInNativeCoords(
    int64_t source_display,
    const gfx::Point& point_in_native,
    const gfx::Point& point_in_unified_host,
    bool update_mouse_location_now) {
  const auto edges_iter = displays_edges_map_.find(source_display);
  if (edges_iter == displays_edges_map_.end())
    return false;

  const std::vector<DisplayEdge>& potential_edges = edges_iter->second;
  for (const auto& edge : potential_edges) {
    if (edge.edge_native_bounds_in_source_display.Contains(point_in_native)) {
      // Wait updating the cursor until the cursor moves to the new display
      // to avoid showing the wrong sized cursor at the source display.
      current_cursor_display_id_ = edge.source_display_id;

      AshWindowTreeHost* target_ash_host =
          GetMirroringAshWindowTreeHostForDisplayId(edge.target_display_id);
      MoveCursorTo(target_ash_host, point_in_unified_host,
                   update_mouse_location_now);
      return true;
    }
  }

  return false;
}

}  // namespace ash
