// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/display/display_alignment_controller.h"

#include "ash/display/display_alignment_indicator.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/ranges/algorithm.h"
#include "base/timer/timer.h"
#include "ui/events/event.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/geometry/rect.h"

namespace ash {

namespace {

// Number of times the mouse has to hit the edge to show the indicators.
constexpr int kTriggerThresholdCount = 2;
// Time between last time the mouse leaves a screen edge and the counter
// resetting.
constexpr base::TimeDelta kCounterResetTime = base::Seconds(1);
// How long the indicators are visible for.
constexpr base::TimeDelta kIndicatorVisibilityDuration = base::Seconds(2);

// Returns true if |screen_location| is on the edge of |display|. |display| must
// be valid.
bool IsOnBoundary(const gfx::Point& screen_location,
                  const display::Display& display) {
  DCHECK(display.is_valid());

  const gfx::Rect& bounds = display.bounds();

  const int top = bounds.y();
  const int bottom = bounds.bottom() - 1;
  const int left = bounds.x();
  const int right = bounds.right() - 1;

  // See if current screen_location is within 1px of the display's
  // borders. 1px leniency is necessary as some resolution/size factor
  // combination results in the mouse not being able to reach the edges of the
  // display by 1px.
  if (std::abs(screen_location.x() - left) <= 1)
    return true;
  if (std::abs(screen_location.x() - right) <= 1)
    return true;
  if (std::abs(screen_location.y() - top) <= 1)
    return true;

  return std::abs(screen_location.y() - bottom) <= 1;
}

}  // namespace

DisplayAlignmentController::DisplayAlignmentController()
    : action_trigger_timer_(std::make_unique<base::OneShotTimer>()) {
  Shell* shell = Shell::Get();
  shell->AddPreTargetHandler(this);
  shell->session_controller()->AddObserver(this);
  shell->window_tree_host_manager()->AddObserver(this);

  is_locked_ = shell->session_controller()->IsScreenLocked();

  RefreshState();
}

DisplayAlignmentController::~DisplayAlignmentController() {
  Shell* shell = Shell::Get();
  shell->window_tree_host_manager()->RemoveObserver(this);
  shell->session_controller()->RemoveObserver(this);
  shell->RemovePreTargetHandler(this);
}

void DisplayAlignmentController::OnDisplayConfigurationChanged() {
  RefreshState();
}

void DisplayAlignmentController::OnDisplaysInitialized() {
  RefreshState();
}

void DisplayAlignmentController::OnMouseEvent(ui::MouseEvent* event) {
  if (current_state_ == DisplayAlignmentState::kDisabled ||
      event->type() != ui::ET_MOUSE_MOVED) {
    return;
  }

  // If mouse enters the edge of the display.
  const gfx::Point screen_location = event->target()->GetScreenLocation(*event);

  const display::Display& src_display =
      Shell::Get()->display_manager()->FindDisplayContainingPoint(
          screen_location);

  if (!src_display.is_valid())
    return;

  const bool is_on_edge = IsOnBoundary(screen_location, src_display);

  // Restart the reset timer when the mouse moves off an edge.

  if (!is_on_edge) {
    if (current_state_ == DisplayAlignmentState::kOnEdge) {
      current_state_ = DisplayAlignmentState::kIdle;

      // The cursor was moved off the edge. Start the reset timer. If the cursor
      // does not hit an edge on the same display within |kCounterResetTime|,
      // state is reset by ResetState() and indicators will not be shown.
      action_trigger_timer_->Start(
          FROM_HERE, kCounterResetTime,
          base::BindOnce(&DisplayAlignmentController::ResetState,
                         base::Unretained(this)));
    }
    return;
  }

  if (current_state_ != DisplayAlignmentState::kIdle)
    return;

  // |trigger_count_| should only increment when the mouse hits the edges of
  // the same display.
  if (triggered_display_id_ == src_display.id()) {
    trigger_count_++;
  } else {
    triggered_display_id_ = src_display.id();
    trigger_count_ = 1;
  }

  action_trigger_timer_->Stop();
  current_state_ = DisplayAlignmentState::kOnEdge;

  if (trigger_count_ == kTriggerThresholdCount)
    ShowIndicators(src_display);
}

void DisplayAlignmentController::OnLockStateChanged(const bool locked) {
  is_locked_ = locked;
  RefreshState();
}

void DisplayAlignmentController::DisplayDragged(int64_t display_id,
                                                int32_t delta_x,
                                                int32_t delta_y) {
  if (current_state_ != DisplayAlignmentState::kLayoutPreview) {
    // Clear existing indicators. They are all regenerated via
    // OnDisplayConfigurationChanged() after dragging ends.
    ResetState();

    dragged_display_id_ = display_id;
    current_state_ = DisplayAlignmentState::kLayoutPreview;
  }

  // It is not possible to change display being dragged without dropping it
  // first (and causing update on display configuration).
  DCHECK_EQ(dragged_display_id_, display_id);
  DCHECK_NE(dragged_display_id_, display::kInvalidDisplayId);

  dragged_offset_ += gfx::Vector2d(delta_x, delta_y);

  ComputePreviewIndicators();
}

void DisplayAlignmentController::SetTimerForTesting(
    std::unique_ptr<base::OneShotTimer> timer) {
  action_trigger_timer_ = std::move(timer);
}

const std::vector<std::unique_ptr<DisplayAlignmentIndicator>>&
DisplayAlignmentController::GetActiveIndicatorsForTesting() {
  return active_indicators_;
}

int64_t DisplayAlignmentController::GetDraggedDisplayIdForTesting() const {
  return dragged_display_id_;
}

void DisplayAlignmentController::ShowIndicators(
    const display::Display& src_display) {
  DCHECK_EQ(src_display.id(), triggered_display_id_);

  current_state_ = DisplayAlignmentState::kIndicatorsVisible;

  // Iterate through all the active displays and see if they are neighbors to
  // |src_display|.
  display::DisplayManager* display_manager = Shell::Get()->display_manager();
  const display::Displays& display_list =
      display_manager->active_display_list();
  for (const display::Display& peer : display_list) {
    // Skip currently triggered display or it might be detected as a neighbor
    if (peer.id() == triggered_display_id_)
      continue;

    // Check whether |src_display| and |peer| are neighbors.
    gfx::Rect source_edge;
    gfx::Rect peer_edge;
    if (display::ComputeBoundary(src_display, peer, &source_edge, &peer_edge)) {
      // TODO(1070697): Handle pills overlapping for certain display
      // configuration.

      // Pills are created for the indicators in the src display, but not in the
      // peers.
      const std::string& dst_name =
          display_manager->GetDisplayInfo(peer.id()).name();
      active_indicators_.push_back(DisplayAlignmentIndicator::CreateWithPill(
          src_display, source_edge, dst_name));

      active_indicators_.push_back(
          DisplayAlignmentIndicator::Create(peer, peer_edge));
    }
  }

  action_trigger_timer_->Start(
      FROM_HERE, kIndicatorVisibilityDuration,
      base::BindOnce(&DisplayAlignmentController::ResetState,
                     base::Unretained(this)));
}

void DisplayAlignmentController::ResetState() {
  action_trigger_timer_->Stop();
  active_indicators_.clear();
  trigger_count_ = 0;

  dragged_display_id_ = display::kInvalidDisplayId;
  dragged_offset_ = gfx::Vector2d(0, 0);

  // Do not re-enable if disabled.
  if (current_state_ != DisplayAlignmentState::kDisabled)
    current_state_ = DisplayAlignmentState::kIdle;
}

void DisplayAlignmentController::RefreshState() {
  ResetState();

  // This feature is only enabled when the screen is not locked and there is
  // more than one display connected.
  if (is_locked_) {
    current_state_ = DisplayAlignmentState::kDisabled;
    return;
  }

  const display::Displays& display_list =
      Shell::Get()->display_manager()->active_display_list();
  if (display_list.size() < 2) {
    current_state_ = DisplayAlignmentState::kDisabled;
    return;
  }

  if (current_state_ == DisplayAlignmentState::kDisabled)
    current_state_ = DisplayAlignmentState::kIdle;
}

void DisplayAlignmentController::ComputePreviewIndicators() {
  DCHECK_EQ(current_state_, DisplayAlignmentState::kLayoutPreview);
  DCHECK_NE(dragged_display_id_, display::kInvalidDisplayId);

  const display::Display& dragged_display =
      Shell::Get()->display_manager()->GetDisplayForId(dragged_display_id_);
  DCHECK(dragged_display.is_valid());

  gfx::Rect bounds = dragged_display.bounds();
  bounds += dragged_offset_;

  const display::Displays& display_list =
      Shell::Get()->display_manager()->active_display_list();

  // Iterate through all the active displays and see if they are neighbors to
  // |dragged_display|.
  for (const display::Display& peer : display_list) {
    // Skip currently dragged display or it might be detected as a neighbor
    if (peer.id() == dragged_display_id_)
      continue;

    // True if |source| and |peer| are neighbors. Returns |source_edge| and
    // |peer_edge| that denotes shared edges between |source| and |peer|
    // displays.
    gfx::Rect source_edge;
    gfx::Rect peer_edge;
    const bool are_neighbors = display::ComputeBoundary(
        bounds, peer.bounds(), &source_edge, &peer_edge);

    const auto& existing_indicator_it = base::ranges::find(
        active_indicators_, peer.id(), &DisplayAlignmentIndicator::display_id);

    const bool indicator_exists =
        existing_indicator_it != active_indicators_.end();

    if (indicator_exists) {
      if (are_neighbors) {
        // Displays are already neighbors.
        (*existing_indicator_it)->Update(peer, peer_edge);
        (*existing_indicator_it)->Show();
      } else {
        // Displays are no longer neighbors but previously were neighbors.
        (*existing_indicator_it)->Hide();
      }
    } else if (are_neighbors) {
      // Displays are newly-neighbored.
      active_indicators_.push_back(
          DisplayAlignmentIndicator::Create(peer, peer_edge));
    }
  }
}

}  // namespace ash
