// Copyright 2018 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 "ui/views/touchui/touch_selection_controller_impl.h"

#include <set>

#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/aura/window_targeter.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/image/image.h"
#include "ui/resources/grit/ui_resources.h"
#include "ui/views/views_delegate.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/wm/core/coordinate_conversion.h"

namespace {

// Constants defining the visual attributes of selection handles

// The distance by which a handle image is offset from the bottom of the
// selection/text baseline.
constexpr int kSelectionHandleVerticalVisualOffset = 2;

// When a handle is dragged, the drag position reported to the client view is
// offset vertically to represent the cursor position. This constant specifies
// the offset in pixels above the bottom of the selection (see pic below). This
// is required because say if this is zero, that means the drag position we
// report is right on the text baseline. In that case, a vertical movement of
// even one pixel will make the handle jump to the line below it. So when the
// user just starts dragging, the handle will jump to the next line if the user
// makes any vertical movement. So we have this non-zero offset to prevent this
// jumping.
//
// Editing handle widget showing the padding and difference between the position
// of the ET_GESTURE_SCROLL_UPDATE event and the drag position reported to the
// client:
//                            ___________
//    Selection Highlight --->_____|__|<-|---- Drag position reported to client
//                              _  |  O  |
//          Vertical Padding __|   |   <-|---- ET_GESTURE_SCROLL_UPDATE position
//                             |_  |_____|<--- Editing handle widget
//
//                                 | |
//                                  T
//                          Horizontal Padding
//
constexpr int kSelectionHandleVerticalDragOffset = 5;

// Padding around the selection handle defining the area that will be included
// in the touch target to make dragging the handle easier (see pic above).
constexpr int kSelectionHandleHorizPadding = 10;
constexpr int kSelectionHandleVertPadding = 20;

constexpr int kQuickMenuTimoutMs = 200;

constexpr int kSelectionHandleQuickFadeDurationMs = 50;

// Minimum height for selection handle bar. If the bar height is going to be
// less than this value, handle will not be shown.
constexpr int kSelectionHandleBarMinHeight = 5;
// Maximum amount that selection handle bar can stick out of client view's
// boundaries.
constexpr int kSelectionHandleBarBottomAllowance = 3;

// Creates a widget to host SelectionHandleView.
views::Widget* CreateTouchSelectionPopupWidget(
    gfx::NativeView parent,
    views::WidgetDelegate* widget_delegate) {
  views::Widget* widget = new views::Widget;
  views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
  params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
  params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE;
  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
  params.parent = parent;
  params.delegate = widget_delegate;
  widget->Init(params);
  return widget;
}

gfx::Image* GetCenterHandleImage() {
  static gfx::Image* handle_image = nullptr;
  if (!handle_image) {
    handle_image = &ui::ResourceBundle::GetSharedInstance().GetImageNamed(
        IDR_TEXT_SELECTION_HANDLE_CENTER);
  }
  return handle_image;
}

gfx::Image* GetLeftHandleImage() {
  static gfx::Image* handle_image = nullptr;
  if (!handle_image) {
    handle_image = &ui::ResourceBundle::GetSharedInstance().GetImageNamed(
        IDR_TEXT_SELECTION_HANDLE_LEFT);
  }
  return handle_image;
}

gfx::Image* GetRightHandleImage() {
  static gfx::Image* handle_image = nullptr;
  if (!handle_image) {
    handle_image = &ui::ResourceBundle::GetSharedInstance().GetImageNamed(
        IDR_TEXT_SELECTION_HANDLE_RIGHT);
  }
  return handle_image;
}

// Return the appropriate handle image based on the bound's type
gfx::Image* GetHandleImage(gfx::SelectionBound::Type bound_type) {
  switch (bound_type) {
    case gfx::SelectionBound::LEFT:
      return GetLeftHandleImage();
    case gfx::SelectionBound::CENTER:
      return GetCenterHandleImage();
    case gfx::SelectionBound::RIGHT:
      return GetRightHandleImage();
    default:
      NOTREACHED() << "Invalid touch handle bound type: " << bound_type;
      return nullptr;
  }
}

// Calculates the bounds of the widget containing the selection handle based
// on the SelectionBound's type and location.
gfx::Rect GetSelectionWidgetBounds(const gfx::SelectionBound& bound) {
  gfx::Size image_size = GetHandleImage(bound.type())->Size();
  int widget_width = image_size.width() + 2 * kSelectionHandleHorizPadding;
  // Extend the widget height to handle touch events below the painted image.
  int widget_height = bound.GetHeight() + image_size.height() +
                      kSelectionHandleVerticalVisualOffset +
                      kSelectionHandleVertPadding;
  // Due to the shape of the handle images, the widget is aligned differently to
  // the selection bound depending on the type of the bound.
  int widget_left = 0;
  switch (bound.type()) {
    case gfx::SelectionBound::LEFT:
      widget_left = bound.edge_top_rounded().x() - image_size.width() -
                    kSelectionHandleHorizPadding;
      break;
    case gfx::SelectionBound::RIGHT:
      widget_left = bound.edge_top_rounded().x() - kSelectionHandleHorizPadding;
      break;
    case gfx::SelectionBound::CENTER:
      widget_left = bound.edge_top_rounded().x() - widget_width / 2;
      break;
    default:
      NOTREACHED() << "Undefined bound type.";
      break;
  }
  return gfx::Rect(
      widget_left, bound.edge_top_rounded().y(), widget_width, widget_height);
}

gfx::Size GetMaxHandleImageSize() {
  gfx::Rect center_rect = gfx::Rect(GetCenterHandleImage()->Size());
  gfx::Rect left_rect = gfx::Rect(GetLeftHandleImage()->Size());
  gfx::Rect right_rect = gfx::Rect(GetRightHandleImage()->Size());
  gfx::Rect union_rect = center_rect;
  union_rect.Union(left_rect);
  union_rect.Union(right_rect);
  return union_rect.size();
}

// Convenience methods to convert a |bound| from screen to the |client|'s
// coordinate system and vice versa.
// Note that this is not quite correct because it does not take into account
// transforms such as rotation and scaling. This should be in TouchEditable.
// TODO(varunjain): Fix this.
gfx::SelectionBound ConvertFromScreen(ui::TouchEditable* client,
                                      const gfx::SelectionBound& bound) {
  gfx::SelectionBound result = bound;
  gfx::Point edge_bottom = bound.edge_bottom_rounded();
  gfx::Point edge_top = bound.edge_top_rounded();
  client->ConvertPointFromScreen(&edge_bottom);
  client->ConvertPointFromScreen(&edge_top);
  result.SetEdge(gfx::PointF(edge_top), gfx::PointF(edge_bottom));
  return result;
}

gfx::SelectionBound ConvertToScreen(ui::TouchEditable* client,
                                    const gfx::SelectionBound& bound) {
  gfx::SelectionBound result = bound;
  gfx::Point edge_bottom = bound.edge_bottom_rounded();
  gfx::Point edge_top = bound.edge_top_rounded();
  client->ConvertPointToScreen(&edge_bottom);
  client->ConvertPointToScreen(&edge_top);
  result.SetEdge(gfx::PointF(edge_top), gfx::PointF(edge_bottom));
  return result;
}

gfx::Rect BoundToRect(const gfx::SelectionBound& bound) {
  return gfx::BoundingRect(bound.edge_top_rounded(),
                           bound.edge_bottom_rounded());
}

}  // namespace

namespace views {

using EditingHandleView = TouchSelectionControllerImpl::EditingHandleView;

// A View that displays the text selection handle.
class TouchSelectionControllerImpl::EditingHandleView
    : public WidgetDelegateView {
 public:
  EditingHandleView(TouchSelectionControllerImpl* controller,
                    gfx::NativeView parent,
                    bool is_cursor_handle)
      : controller_(controller),
        image_(GetCenterHandleImage()),
        is_cursor_handle_(is_cursor_handle),
        draw_invisible_(false),
        weak_ptr_factory_(this) {
    widget_.reset(CreateTouchSelectionPopupWidget(parent, this));

    targeter_ = new aura::WindowTargeter();
    aura::Window* window = widget_->GetNativeWindow();
    window->SetEventTargeter(std::unique_ptr<aura::WindowTargeter>(targeter_));

    // We are owned by the TouchSelectionControllerImpl.
    set_owned_by_client();
  }

  ~EditingHandleView() override { SetWidgetVisible(false, false); }

  gfx::SelectionBound::Type selection_bound_type() {
    return selection_bound_.type();
  }

  // WidgetDelegateView:
  void DeleteDelegate() override {
    // We are owned and deleted by TouchSelectionControllerImpl.
  }

  // View:
  void OnPaint(gfx::Canvas* canvas) override {
    if (draw_invisible_)
      return;

    // Draw the handle image.
    canvas->DrawImageInt(
        *image_->ToImageSkia(),
        kSelectionHandleHorizPadding,
        selection_bound_.GetHeight() + kSelectionHandleVerticalVisualOffset);
  }

  void OnGestureEvent(ui::GestureEvent* event) override {
    event->SetHandled();
    switch (event->type()) {
      case ui::ET_GESTURE_SCROLL_BEGIN: {
        widget_->SetCapture(this);
        controller_->SetDraggingHandle(this);
        // Distance from the point which is |kSelectionHandleVerticalDragOffset|
        // pixels above the bottom of the selection bound edge to the event
        // location (aka the touch-drag point).
        drag_offset_ = selection_bound_.edge_bottom_rounded() -
                       gfx::Vector2d(0, kSelectionHandleVerticalDragOffset) -
                       event->location();
        break;
      }
      case ui::ET_GESTURE_SCROLL_UPDATE: {
        controller_->SelectionHandleDragged(event->location() + drag_offset_);
        break;
      }
      case ui::ET_GESTURE_SCROLL_END:
      case ui::ET_SCROLL_FLING_START: {
        // Use a weak pointer to the handle to make sure the handle and its
        // owning selection controller is not destroyed by the capture release
        // to diagnose a crash on Windows (see crbug.com/459423)
        // TODO(mohsen): Delete the diagnostics code when the crash is fixed.
        base::WeakPtr<EditingHandleView> weak_ptr =
            weak_ptr_factory_.GetWeakPtr();
        widget_->ReleaseCapture();
        CHECK(weak_ptr);
        controller_->SetDraggingHandle(nullptr);
        break;
      }
      default:
        break;
    }
  }

  gfx::Size CalculatePreferredSize() const override {
    // This function will be called during widget initialization, i.e. before
    // SetBoundInScreen has been called. No-op in that case.
    if (selection_bound_.type() == gfx::SelectionBound::EMPTY)
      return gfx::Size();
    return GetSelectionWidgetBounds(selection_bound_).size();
  }

  bool IsWidgetVisible() const {
    return widget_->IsVisible();
  }

  void SetWidgetVisible(bool visible, bool quick) {
    if (widget_->IsVisible() == visible)
      return;
    widget_->SetVisibilityAnimationDuration(
        base::TimeDelta::FromMilliseconds(
            quick ? kSelectionHandleQuickFadeDurationMs : 0));
    if (visible)
      widget_->Show();
    else
      widget_->Hide();
  }

  // If |is_visible| is true, this will update the widget and trigger a repaint
  // if necessary. Otherwise this will only update the internal state:
  // |selection_bound_| and |image_|, so that the state is valid for the time
  // this becomes visible.
  void SetBoundInScreen(const gfx::SelectionBound& bound, bool is_visible) {
    bool update_bound_type = false;
    // Cursor handle should always have the bound type CENTER
    DCHECK(!is_cursor_handle_ || bound.type() == gfx::SelectionBound::CENTER);

    if (bound.type() != selection_bound_.type()) {
      // Unless this is a cursor handle, do not set the type to CENTER -
      // selection handles corresponding to a selection should always use left
      // or right handle image. If selection handles are dragged to be located
      // at the same spot, the |bound|'s type here will be CENTER for both of
      // them. In this case do not update the type of the |selection_bound_|.
      if (bound.type() != gfx::SelectionBound::CENTER || is_cursor_handle_)
        update_bound_type = true;
    }
    if (update_bound_type) {
      selection_bound_.set_type(bound.type());
      image_ = GetHandleImage(bound.type());
      if (is_visible)
        SchedulePaint();
    }

    if (is_visible) {
      selection_bound_.SetEdge(bound.edge_top(), bound.edge_bottom());

      widget_->SetBounds(GetSelectionWidgetBounds(selection_bound_));

      aura::Window* window = widget_->GetNativeView();
      gfx::Point edge_top = selection_bound_.edge_top_rounded();
      gfx::Point edge_bottom = selection_bound_.edge_bottom_rounded();
      wm::ConvertPointFromScreen(window, &edge_top);
      wm::ConvertPointFromScreen(window, &edge_bottom);
      selection_bound_.SetEdge(gfx::PointF(edge_top), gfx::PointF(edge_bottom));
    }

    const gfx::Insets insets(
        selection_bound_.GetHeight() + kSelectionHandleVerticalVisualOffset, 0,
        0, 0);
    targeter_->SetInsets(insets, insets);
  }

  void SetDrawInvisible(bool draw_invisible) {
    if (draw_invisible_ == draw_invisible)
      return;
    draw_invisible_ = draw_invisible;
    SchedulePaint();
  }

 private:
  std::unique_ptr<Widget> widget_;
  TouchSelectionControllerImpl* controller_;

  // A WindowTargeter that shifts the hit-test target below the apparent bounds
  // to make dragging easier. The |widget_|'s NativeWindow takes ownership over
  // the |targeter_| but since the |widget_|'s lifetime is known to this class,
  // it can safely access the |targeter_|.
  aura::WindowTargeter* targeter_;

  // In local coordinates
  gfx::SelectionBound selection_bound_;
  gfx::Image* image_;

  // If true, this is a handle corresponding to the single cursor, otherwise it
  // is a handle corresponding to one of the two selection bounds.
  bool is_cursor_handle_;

  // Offset applied to the scroll events location when calling
  // TouchSelectionControllerImpl::SelectionHandleDragged while dragging the
  // handle.
  gfx::Vector2d drag_offset_;

  // If set to true, the handle will not draw anything, hence providing an empty
  // widget. We need this because we may want to stop showing the handle while
  // it is being dragged. Since it is being dragged, we cannot destroy the
  // handle.
  bool draw_invisible_;

  base::WeakPtrFactory<EditingHandleView> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(EditingHandleView);
};

TouchSelectionControllerImpl::TouchSelectionControllerImpl(
    ui::TouchEditable* client_view)
    : client_view_(client_view),
      selection_handle_1_(
          new EditingHandleView(this, client_view->GetNativeView(), false)),
      selection_handle_2_(
          new EditingHandleView(this, client_view->GetNativeView(), false)),
      cursor_handle_(
          new EditingHandleView(this, client_view->GetNativeView(), true)) {
  selection_start_time_ = base::TimeTicks::Now();
  aura::Window* client_window = client_view_->GetNativeView();
  client_widget_ = Widget::GetTopLevelWidgetForNativeView(client_window);
  // Observe client widget moves and resizes to update the selection handles.
  if (client_widget_)
    client_widget_->AddObserver(this);

  // Observe certain event types sent to any event target, to hide this ui.
  aura::Env* env = aura::Env::GetInstance();
  std::set<ui::EventType> types = {ui::ET_MOUSE_PRESSED, ui::ET_MOUSE_MOVED,
                                   ui::ET_KEY_PRESSED, ui::ET_MOUSEWHEEL};
  env->AddEventObserver(this, env, types);
}

TouchSelectionControllerImpl::~TouchSelectionControllerImpl() {
  UMA_HISTOGRAM_BOOLEAN("Event.TouchSelection.EndedWithAction",
                        command_executed_);
  HideQuickMenu();
  aura::Env::GetInstance()->RemoveEventObserver(this);
  if (client_widget_)
    client_widget_->RemoveObserver(this);
}

void TouchSelectionControllerImpl::SelectionChanged() {
  gfx::SelectionBound anchor, focus;
  client_view_->GetSelectionEndPoints(&anchor, &focus);
  gfx::SelectionBound screen_bound_anchor =
      ConvertToScreen(client_view_, anchor);
  gfx::SelectionBound screen_bound_focus = ConvertToScreen(client_view_, focus);
  gfx::Rect client_bounds = client_view_->GetBounds();
  if (anchor.edge_top().y() < client_bounds.y()) {
    auto anchor_edge_top = gfx::PointF(anchor.edge_top_rounded());
    anchor_edge_top.set_y(client_bounds.y());
    anchor.SetEdgeTop(anchor_edge_top);
  }
  if (focus.edge_top().y() < client_bounds.y()) {
    auto focus_edge_top = gfx::PointF(focus.edge_top_rounded());
    focus_edge_top.set_y(client_bounds.y());
    focus.SetEdgeTop(focus_edge_top);
  }
  gfx::SelectionBound screen_bound_anchor_clipped =
      ConvertToScreen(client_view_, anchor);
  gfx::SelectionBound screen_bound_focus_clipped =
      ConvertToScreen(client_view_, focus);
  if (screen_bound_anchor_clipped == selection_bound_1_clipped_ &&
      screen_bound_focus_clipped == selection_bound_2_clipped_)
    return;

  selection_bound_1_ = screen_bound_anchor;
  selection_bound_2_ = screen_bound_focus;
  selection_bound_1_clipped_ = screen_bound_anchor_clipped;
  selection_bound_2_clipped_ = screen_bound_focus_clipped;

  if (client_view_->DrawsHandles()) {
    UpdateQuickMenu();
    return;
  }

  if (dragging_handle_) {
    // We need to reposition only the selection handle that is being dragged.
    // The other handle stays the same. Also, the selection handle being dragged
    // will always be at the end of selection, while the other handle will be at
    // the start.
    // If the new location of this handle is out of client view, its widget
    // should not get hidden, since it should still receive touch events.
    // Hence, we are not using |SetHandleBound()| method here.
    dragging_handle_->SetBoundInScreen(screen_bound_focus_clipped, true);

    // Temporary fix for selection handle going outside a window. On a webpage,
    // the page should scroll if the selection handle is dragged outside the
    // window. That does not happen currently. So we just hide the handle for
    // now.
    // TODO(varunjain): Fix this: crbug.com/269003
    dragging_handle_->SetDrawInvisible(!ShouldShowHandleFor(focus));

    if (dragging_handle_ != cursor_handle_.get()) {
      // The non-dragging-handle might have recently become visible.
      EditingHandleView* non_dragging_handle = selection_handle_1_.get();
      if (dragging_handle_ == selection_handle_1_.get()) {
        non_dragging_handle = selection_handle_2_.get();
        // if handle 1 is being dragged, it is corresponding to the end of
        // selection and the other handle to the start of selection.
        selection_bound_1_ = screen_bound_focus;
        selection_bound_2_ = screen_bound_anchor;
        selection_bound_1_clipped_ = screen_bound_focus_clipped;
        selection_bound_2_clipped_ = screen_bound_anchor_clipped;
      }
      SetHandleBound(non_dragging_handle, anchor, screen_bound_anchor_clipped);
    }
  } else {
    UpdateQuickMenu();

    // Check if there is any selection at all.
    if (screen_bound_anchor.edge_top() == screen_bound_focus.edge_top() &&
        screen_bound_anchor.edge_bottom() == screen_bound_focus.edge_bottom()) {
      selection_handle_1_->SetWidgetVisible(false, false);
      selection_handle_2_->SetWidgetVisible(false, false);
      SetHandleBound(cursor_handle_.get(), anchor, screen_bound_anchor_clipped);
      return;
    }

    cursor_handle_->SetWidgetVisible(false, false);
    SetHandleBound(
        selection_handle_1_.get(), anchor, screen_bound_anchor_clipped);
    SetHandleBound(
        selection_handle_2_.get(), focus, screen_bound_focus_clipped);
  }
}

bool TouchSelectionControllerImpl::IsHandleDragInProgress() {
  return !!dragging_handle_;
}

void TouchSelectionControllerImpl::HideHandles(bool quick) {
  selection_handle_1_->SetWidgetVisible(false, quick);
  selection_handle_2_->SetWidgetVisible(false, quick);
  cursor_handle_->SetWidgetVisible(false, quick);
}

void TouchSelectionControllerImpl::SetDraggingHandle(
    EditingHandleView* handle) {
  dragging_handle_ = handle;
  if (dragging_handle_)
    HideQuickMenu();
  else
    StartQuickMenuTimer();
}

void TouchSelectionControllerImpl::SelectionHandleDragged(
    const gfx::Point& drag_pos) {
  DCHECK(dragging_handle_);
  gfx::Point drag_pos_in_client = drag_pos;
  ConvertPointToClientView(dragging_handle_, &drag_pos_in_client);

  if (dragging_handle_ == cursor_handle_.get()) {
    client_view_->MoveCaretTo(drag_pos_in_client);
    return;
  }

  // Find the stationary selection handle.
  gfx::SelectionBound anchor_bound =
      selection_handle_1_.get() == dragging_handle_ ? selection_bound_2_
                                                    : selection_bound_1_;

  // Find selection end points in client_view's coordinate system.
  gfx::Point p2 = anchor_bound.edge_top_rounded();
  p2.Offset(0, anchor_bound.GetHeight() / 2);
  client_view_->ConvertPointFromScreen(&p2);

  // Instruct client_view to select the region between p1 and p2. The position
  // of |fixed_handle| is the start and that of |dragging_handle| is the end
  // of selection.
  client_view_->SelectRect(p2, drag_pos_in_client);
}

void TouchSelectionControllerImpl::ConvertPointToClientView(
    EditingHandleView* source, gfx::Point* point) {
  View::ConvertPointToScreen(source, point);
  client_view_->ConvertPointFromScreen(point);
}

void TouchSelectionControllerImpl::SetHandleBound(
    EditingHandleView* handle,
    const gfx::SelectionBound& bound,
    const gfx::SelectionBound& bound_in_screen) {
  handle->SetWidgetVisible(ShouldShowHandleFor(bound), false);
  handle->SetBoundInScreen(bound_in_screen, handle->IsWidgetVisible());
}

bool TouchSelectionControllerImpl::ShouldShowHandleFor(
    const gfx::SelectionBound& bound) const {
  if (bound.GetHeight() < kSelectionHandleBarMinHeight)
    return false;
  gfx::Rect client_bounds = client_view_->GetBounds();
  client_bounds.Inset(0, 0, 0, -kSelectionHandleBarBottomAllowance);
  return client_bounds.Contains(BoundToRect(bound));
}

bool TouchSelectionControllerImpl::IsCommandIdEnabled(int command_id) const {
  return client_view_->IsCommandIdEnabled(command_id);
}

void TouchSelectionControllerImpl::ExecuteCommand(int command_id,
                                                  int event_flags) {
  command_executed_ = true;
  base::TimeDelta duration = base::TimeTicks::Now() - selection_start_time_;
  // Note that we only log the duration stats for the 'successful' selections,
  // i.e. selections ending with the execution of a command.
  UMA_HISTOGRAM_CUSTOM_TIMES("Event.TouchSelection.Duration",
                             duration,
                             base::TimeDelta::FromMilliseconds(500),
                             base::TimeDelta::FromSeconds(60),
                             60);
  client_view_->ExecuteCommand(command_id, event_flags);
}

void TouchSelectionControllerImpl::RunContextMenu() {
  // Context menu should appear centered on top of the selected region.
  const gfx::Rect rect = GetQuickMenuAnchorRect();
  const gfx::Point anchor(rect.CenterPoint().x(), rect.y());
  client_view_->OpenContextMenu(anchor);
}

bool TouchSelectionControllerImpl::ShouldShowQuickMenu() {
  return false;
}

base::string16 TouchSelectionControllerImpl::GetSelectedText() {
  return base::string16();
}

void TouchSelectionControllerImpl::OnWidgetClosing(Widget* widget) {
  DCHECK_EQ(client_widget_, widget);
  client_widget_->RemoveObserver(this);
  client_widget_ = nullptr;
}

void TouchSelectionControllerImpl::OnWidgetBoundsChanged(
    Widget* widget,
    const gfx::Rect& new_bounds) {
  DCHECK_EQ(client_widget_, widget);
  SelectionChanged();
}

void TouchSelectionControllerImpl::OnEvent(const ui::Event& event) {
  if (event.IsMouseEvent()) {
    auto* cursor = aura::client::GetCursorClient(
        client_view_->GetNativeView()->GetRootWindow());
    if (cursor && !cursor->IsMouseEventsEnabled())
      return;

    // Windows OS unhandled WM_POINTER* may be redispatched as WM_MOUSE*.
    // Avoid adjusting the handles on synthesized events or events generated
    // from touch as this can clear an active selection generated by the pen.
    if ((event.flags() & (ui::EF_IS_SYNTHESIZED | ui::EF_FROM_TOUCH)) ||
        event.AsMouseEvent()->pointer_details().pointer_type ==
            ui::EventPointerType::POINTER_TYPE_PEN) {
      return;
    }
  }

  client_view_->DestroyTouchSelection();
}

void TouchSelectionControllerImpl::QuickMenuTimerFired() {
  gfx::Rect menu_anchor = GetQuickMenuAnchorRect();
  if (menu_anchor == gfx::Rect())
    return;

  ui::TouchSelectionMenuRunner::GetInstance()->OpenMenu(
      this, menu_anchor, GetMaxHandleImageSize(),
      client_view_->GetNativeView());
}

void TouchSelectionControllerImpl::StartQuickMenuTimer() {
  if (quick_menu_timer_.IsRunning())
    return;
  quick_menu_timer_.Start(
      FROM_HERE,
      base::TimeDelta::FromMilliseconds(kQuickMenuTimoutMs),
      this,
      &TouchSelectionControllerImpl::QuickMenuTimerFired);
}

void TouchSelectionControllerImpl::UpdateQuickMenu() {
  // Hide quick menu to be shown when the timer fires.
  HideQuickMenu();
  StartQuickMenuTimer();
}

void TouchSelectionControllerImpl::HideQuickMenu() {
  if (ui::TouchSelectionMenuRunner::GetInstance()->IsRunning())
    ui::TouchSelectionMenuRunner::GetInstance()->CloseMenu();
  quick_menu_timer_.Stop();
}

gfx::Rect TouchSelectionControllerImpl::GetQuickMenuAnchorRect() const {
  // Get selection end points in client_view's space.
  gfx::SelectionBound b1_in_screen = selection_bound_1_clipped_;
  gfx::SelectionBound b2_in_screen = cursor_handle_->IsWidgetVisible()
                                         ? b1_in_screen
                                         : selection_bound_2_clipped_;
  // Convert from screen to client.
  gfx::SelectionBound b1 = ConvertFromScreen(client_view_, b1_in_screen);
  gfx::SelectionBound b2 = ConvertFromScreen(client_view_, b2_in_screen);

  // if selection is completely inside the view, we display the quick menu in
  // the middle of the end points on the top. Else, we show it above the visible
  // handle. If no handle is visible, we do not show the menu.
  gfx::Rect menu_anchor;
  if (ShouldShowHandleFor(b1) && ShouldShowHandleFor(b2))
    menu_anchor = gfx::RectBetweenSelectionBounds(b1_in_screen, b2_in_screen);
  else if (ShouldShowHandleFor(b1))
    menu_anchor = BoundToRect(b1_in_screen);
  else if (ShouldShowHandleFor(b2))
    menu_anchor = BoundToRect(b2_in_screen);
  else
    return menu_anchor;

  // Enlarge the anchor rect so that the menu is offset from the text at least
  // by the same distance the handles are offset from the text.
  menu_anchor.Inset(0, -kSelectionHandleVerticalVisualOffset);

  return menu_anchor;
}

gfx::NativeView TouchSelectionControllerImpl::GetCursorHandleNativeView() {
  return cursor_handle_->GetWidget()->GetNativeView();
}

gfx::SelectionBound::Type
TouchSelectionControllerImpl::GetSelectionHandle1Type() {
  return selection_handle_1_->selection_bound_type();
}

gfx::Rect TouchSelectionControllerImpl::GetSelectionHandle1Bounds() {
  return selection_handle_1_->GetBoundsInScreen();
}

gfx::Rect TouchSelectionControllerImpl::GetSelectionHandle2Bounds() {
  return selection_handle_2_->GetBoundsInScreen();
}

gfx::Rect TouchSelectionControllerImpl::GetCursorHandleBounds() {
  return cursor_handle_->GetBoundsInScreen();
}

bool TouchSelectionControllerImpl::IsSelectionHandle1Visible() {
  return selection_handle_1_->IsWidgetVisible();
}

bool TouchSelectionControllerImpl::IsSelectionHandle2Visible() {
  return selection_handle_2_->IsWidgetVisible();
}

bool TouchSelectionControllerImpl::IsCursorHandleVisible() {
  return cursor_handle_->IsWidgetVisible();
}

gfx::Rect TouchSelectionControllerImpl::GetExpectedHandleBounds(
    const gfx::SelectionBound& bound) {
  return GetSelectionWidgetBounds(bound);
}

WidgetDelegateView* TouchSelectionControllerImpl::GetHandle1View() {
  return selection_handle_1_.get();
}

WidgetDelegateView* TouchSelectionControllerImpl::GetHandle2View() {
  return selection_handle_2_.get();
}

}  // namespace views
