// Copyright 2014 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/touch_selection/touch_selection_controller.h"

#include <memory>

#include "base/auto_reset.h"
#include "base/check_op.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/notreached.h"

namespace ui {
namespace {

gfx::Vector2dF ComputeLineOffsetFromBottom(const gfx::SelectionBound& bound) {
  gfx::Vector2dF line_offset =
      gfx::ScaleVector2d(bound.edge_start() - bound.edge_end(), 0.5f);
  // An offset of 8 DIPs is sufficient for most line sizes. For small lines,
  // using half the line height avoids synthesizing a point on a line above
  // (or below) the intended line.
  const gfx::Vector2dF kMaxLineOffset(8.f, 8.f);
  line_offset.SetToMin(kMaxLineOffset);
  line_offset.SetToMax(-kMaxLineOffset);
  return line_offset;
}

TouchHandleOrientation ToTouchHandleOrientation(
    gfx::SelectionBound::Type type) {
  switch (type) {
    case gfx::SelectionBound::LEFT:
      return TouchHandleOrientation::LEFT;
    case gfx::SelectionBound::RIGHT:
      return TouchHandleOrientation::RIGHT;
    case gfx::SelectionBound::CENTER:
      return TouchHandleOrientation::CENTER;
    case gfx::SelectionBound::EMPTY:
      return TouchHandleOrientation::UNDEFINED;
  }
  NOTREACHED() << "Invalid selection bound type: " << type;
  return TouchHandleOrientation::UNDEFINED;
}

}  // namespace

TouchSelectionController::Config::Config()
    : max_tap_duration(base::Milliseconds(300)),
      tap_slop(8),
      enable_adaptive_handle_orientation(false),
      enable_longpress_drag_selection(false),
      hide_active_handle(false) {}

TouchSelectionController::Config::~Config() {
}

TouchSelectionController::TouchSelectionController(
    TouchSelectionControllerClient* client,
    const Config& config)
    : client_(client),
      config_(config),
      response_pending_input_event_(INPUT_EVENT_TYPE_NONE),
      start_orientation_(TouchHandleOrientation::UNDEFINED),
      end_orientation_(TouchHandleOrientation::UNDEFINED),
      active_status_(INACTIVE),
      temporarily_hidden_(false),
      anchor_drag_to_selection_start_(false),
      longpress_drag_selector_(this),
      selection_handle_dragged_(false),
      consume_touch_sequence_(false),
      show_touch_handles_(false) {
  DCHECK(client_);
}

TouchSelectionController::~TouchSelectionController() {
}

void TouchSelectionController::OnSelectionBoundsChanged(
    const gfx::SelectionBound& start,
    const gfx::SelectionBound& end) {
  if (start == start_ && end_ == end)
    return;

  if (start.type() == gfx::SelectionBound::EMPTY ||
      end.type() == gfx::SelectionBound::EMPTY ||
      !show_touch_handles_) {
    HideHandles();
    return;
  }

  // Swap the Handles when the start and end selection points cross each other.
  if (active_status_ == SELECTION_ACTIVE) {
    // Bounds have the same orientation.
    bool need_swap = (start_selection_handle_->IsActive() &&
                      end_.edge_end() == start.edge_end()) ||
                     (end_selection_handle_->IsActive() &&
                      end.edge_end() == start_.edge_end());

    // Bounds have different orientation.
    // Specifically, for writing-mode: vertical-*, selection bounds are
    // horizontal.
    // When vertical-lr:
    //   - start bound is from right to left,
    //   - end bound is from left to right.
    // When vertical-rl:
    //   - start bound is from left to right,
    //   - end bound is from right to left.
    // So when previous start/end bound become current end/start bound,
    // edge_start() and edge_end() are swapped. Therefore, we are comparing
    // edge_end() with edge_start() here.
    need_swap |= (start_selection_handle_->IsActive() &&
                  end_.edge_end() == start.edge_start()) ||
                 (end_selection_handle_->IsActive() &&
                  end.edge_end() == start_.edge_start());

    if (need_swap)
      start_selection_handle_.swap(end_selection_handle_);
  }

  // Update |anchor_drag_to_selection_start_| for long press drag selector.
  // Since selection can be updated with only one end at a time, if one end is
  // equal to the previous value, the updated end is the other.
  if (start_ == start)
    anchor_drag_to_selection_start_ = false;
  else if (end_ == end)
    anchor_drag_to_selection_start_ = true;

  start_ = start;
  end_ = end;
  start_orientation_ = ToTouchHandleOrientation(start_.type());
  end_orientation_ = ToTouchHandleOrientation(end_.type());

  // Ensure that |response_pending_input_event_| is cleared after the method
  // completes, while also making its current value available for the duration
  // of the call.
  InputEventType causal_input_event = response_pending_input_event_;
  response_pending_input_event_ = INPUT_EVENT_TYPE_NONE;
  base::AutoReset<InputEventType> auto_reset_response_pending_input_event(
      &response_pending_input_event_, causal_input_event);

  if ((start_orientation_ == TouchHandleOrientation::LEFT ||
       start_orientation_ == TouchHandleOrientation::RIGHT) &&
      (end_orientation_ == TouchHandleOrientation::RIGHT ||
       end_orientation_ == TouchHandleOrientation::LEFT)) {
    OnSelectionChanged();
    return;
  }

  if (start_orientation_ == TouchHandleOrientation::CENTER) {
    OnInsertionChanged();
    return;
  }

  HideHandles();
}

void TouchSelectionController::OnViewportChanged(
    const gfx::RectF viewport_rect) {
  // Trigger a force update if the viewport is changed, so that
  // it triggers a call to change the mirror values if required.
  if (viewport_rect_ == viewport_rect)
    return;

  viewport_rect_ = viewport_rect;

  if (active_status_ == INACTIVE)
    return;

  if (active_status_ == INSERTION_ACTIVE) {
    DCHECK(insertion_handle_);
    insertion_handle_->SetViewportRect(viewport_rect);
  } else if (active_status_ == SELECTION_ACTIVE) {
    DCHECK(start_selection_handle_);
    DCHECK(end_selection_handle_);
    start_selection_handle_->SetViewportRect(viewport_rect);
    end_selection_handle_->SetViewportRect(viewport_rect);
  }

  // Update handle layout after setting the new Viewport size.
  UpdateHandleLayoutIfNecessary();
}

bool TouchSelectionController::WillHandleTouchEvent(const MotionEvent& event) {
  bool handled = WillHandleTouchEventImpl(event);
  // If Action::DOWN is consumed, the rest of touch sequence should be consumed,
  // too, regardless of value of |handled|.
  // TODO(mohsen): This will consume touch events until the next Action::DOWN.
  // Ideally we should consume until the final Action::UP/Action::CANCEL.
  // But, apparently, we can't reliably determine the final Action::CANCEL in a
  // multi-touch scenario. See https://crbug.com/653212.
  if (event.GetAction() == MotionEvent::Action::DOWN)
    consume_touch_sequence_ = handled;
  return handled || consume_touch_sequence_;
}

void TouchSelectionController::HandleTapEvent(const gfx::PointF& location,
                                                  int tap_count) {
  if (tap_count > 1) {
    response_pending_input_event_ = REPEATED_TAP;
  } else {
    response_pending_input_event_ = TAP;
  }
}

void TouchSelectionController::HandleLongPressEvent(
    base::TimeTicks event_time,
    const gfx::PointF& location) {
  longpress_drag_selector_.OnLongPressEvent(event_time, location);
  response_pending_input_event_ = LONG_PRESS;
}

void TouchSelectionController::OnScrollBeginEvent() {
  // When there is an active selection, if the user performs a long-press that
  // does not trigger a new selection (e.g. a long-press on an empty area) and
  // then scrolls, the scroll will move the selection. In this case we will
  // think incorrectly that the selection change was due to the long-press and
  // will activate touch selection and start long-press drag gesture (see
  // ActivateInsertionIfNecessary()). To prevent this, we need to reset the
  // state of touch selection controller and long-press drag selector.
  // TODO(mohsen): Remove this workaround when we have enough information about
  // the cause of a selection change (see https://crbug.com/571897).
  longpress_drag_selector_.OnScrollBeginEvent();
  response_pending_input_event_ = INPUT_EVENT_TYPE_NONE;
}

void TouchSelectionController::HideHandles() {
  response_pending_input_event_ = INPUT_EVENT_TYPE_NONE;
  DeactivateInsertion();
  DeactivateSelection();
  start_ = gfx::SelectionBound();
  end_ = gfx::SelectionBound();
  start_orientation_ = ToTouchHandleOrientation(start_.type());
  end_orientation_ = ToTouchHandleOrientation(end_.type());
}

void TouchSelectionController::HideAndDisallowShowingAutomatically() {
  HideHandles();
  show_touch_handles_ = false;
}

void TouchSelectionController::SetTemporarilyHidden(bool hidden) {
  if (temporarily_hidden_ == hidden)
    return;
  temporarily_hidden_ = hidden;
  RefreshHandleVisibility();
}

bool TouchSelectionController::Animate(base::TimeTicks frame_time) {
  if (active_status_ == INSERTION_ACTIVE)
    return insertion_handle_->Animate(frame_time);

  if (active_status_ == SELECTION_ACTIVE) {
    bool needs_animate = start_selection_handle_->Animate(frame_time);
    needs_animate |= end_selection_handle_->Animate(frame_time);
    return needs_animate;
  }

  return false;
}

gfx::RectF TouchSelectionController::GetRectBetweenBounds() const {
  // Short-circuit for efficiency.
  if (active_status_ == INACTIVE)
    return gfx::RectF();

  if (start_.visible() && !end_.visible()) {
    // This BoundingRect is actually a line unless the selection is rotated.
    return gfx::BoundingRect(start_.edge_start(), start_.edge_end());
  }

  if (end_.visible() && !start_.visible()) {
    // This BoundingRect is actually a line unless the selection is rotated.
    return gfx::BoundingRect(end_.edge_start(), end_.edge_end());
  }

  // If both handles are visible, or both are invisible, use the entire rect.
  // Specifically, if both handles are on the same horizontal line for
  // writing-mode: vertical-*, or both are on the same vertical line for
  // writing-mode: horizontal, the entire rect is actually a line unless the
  // selection is rotated.
  return RectFBetweenSelectionBounds(start_, end_);
}

gfx::RectF TouchSelectionController::GetVisibleRectBetweenBounds() const {
  // Short-circuit for efficiency.
  if (active_status_ == INACTIVE)
    return gfx::RectF();

  // Returns the rect of the entire visible selection rect.
  return RectFBetweenVisibleSelectionBounds(start_, end_);
}

gfx::RectF TouchSelectionController::GetStartHandleRect() const {
  if (active_status_ == INSERTION_ACTIVE)
    return insertion_handle_->GetVisibleBounds();
  if (active_status_ == SELECTION_ACTIVE)
    return start_selection_handle_->GetVisibleBounds();
  return gfx::RectF();
}

gfx::RectF TouchSelectionController::GetEndHandleRect() const {
  if (active_status_ == INSERTION_ACTIVE)
    return insertion_handle_->GetVisibleBounds();
  if (active_status_ == SELECTION_ACTIVE)
    return end_selection_handle_->GetVisibleBounds();
  return gfx::RectF();
}

float TouchSelectionController::GetTouchHandleHeight() const {
  if (active_status_ == INSERTION_ACTIVE)
    return insertion_handle_->GetVisibleBounds().height();
  if (active_status_ == SELECTION_ACTIVE) {
    if (GetStartVisible())
      return start_selection_handle_->GetVisibleBounds().height();
    if (GetEndVisible())
      return end_selection_handle_->GetVisibleBounds().height();
  }
  return 0.f;
}

float TouchSelectionController::GetActiveHandleMiddleY() const {
  const gfx::SelectionBound* bound = nullptr;
  if (active_status_ == INSERTION_ACTIVE && insertion_handle_->IsActive())
    bound = &start_;
  if (active_status_ == SELECTION_ACTIVE) {
    if (start_selection_handle_->IsActive())
      bound = &start_;
    else if (end_selection_handle_->IsActive())
      bound = &end_;
  }

  if (!bound)
    return 0.f;
  return (bound->edge_start().y() + bound->edge_end().y()) / 2.f;
}

const gfx::PointF& TouchSelectionController::GetStartPosition() const {
  return start_.edge_end();
}

const gfx::PointF& TouchSelectionController::GetEndPosition() const {
  return end_.edge_end();
}

bool TouchSelectionController::WillHandleTouchEventImpl(
    const MotionEvent& event) {
  show_touch_handles_ = true;
  if (config_.enable_longpress_drag_selection &&
      longpress_drag_selector_.WillHandleTouchEvent(event)) {
    return true;
  }

  if (active_status_ == INSERTION_ACTIVE) {
    DCHECK(insertion_handle_);
    return insertion_handle_->WillHandleTouchEvent(event);
  }

  if (active_status_ == SELECTION_ACTIVE) {
    DCHECK(start_selection_handle_);
    DCHECK(end_selection_handle_);
    if (start_selection_handle_->IsActive())
      return start_selection_handle_->WillHandleTouchEvent(event);

    if (end_selection_handle_->IsActive())
      return end_selection_handle_->WillHandleTouchEvent(event);

    const gfx::PointF event_pos(event.GetX(), event.GetY());
    if ((event_pos - GetStartPosition()).LengthSquared() <=
        (event_pos - GetEndPosition()).LengthSquared()) {
      return start_selection_handle_->WillHandleTouchEvent(event);
    }
    return end_selection_handle_->WillHandleTouchEvent(event);
  }

  return false;
}

void TouchSelectionController::OnSwipeToMoveCursorBegin() {
  if (config_.hide_active_handle) {
    // Hide the handle when magnifier is showing since it can confuse the user.
    SetTemporarilyHidden(true);

    // If the user has typed something, the insertion handle might be hidden.
    // Prepare to show touch handles on end.
    show_touch_handles_ = true;
  }
}

void TouchSelectionController::OnSwipeToMoveCursorEnd() {
  // Show the handle at the end if magnifier was showing.
  if (config_.hide_active_handle)
    SetTemporarilyHidden(false);
}

void TouchSelectionController::OnDragBegin(
    const TouchSelectionDraggable& draggable,
    const gfx::PointF& drag_position) {
  if (&draggable == insertion_handle_.get()) {
    DCHECK_EQ(active_status_, INSERTION_ACTIVE);
    if (config_.hide_active_handle)
      insertion_handle_->SetTransparent();
    client_->OnSelectionEvent(INSERTION_HANDLE_DRAG_STARTED);
    anchor_drag_to_selection_start_ = true;
    return;
  }

  DCHECK_EQ(active_status_, SELECTION_ACTIVE);

  if (&draggable == start_selection_handle_.get()) {
    anchor_drag_to_selection_start_ = true;
  } else if (&draggable == end_selection_handle_.get()) {
    anchor_drag_to_selection_start_ = false;
  } else {
    DCHECK_EQ(&draggable, &longpress_drag_selector_);
    anchor_drag_to_selection_start_ =
        (drag_position - GetStartPosition()).LengthSquared() <
        (drag_position - GetEndPosition()).LengthSquared();
  }

  if (config_.hide_active_handle) {
    if (&draggable == start_selection_handle_.get()) {
      start_selection_handle_->SetTransparent();
    } else if (&draggable == end_selection_handle_.get()) {
      end_selection_handle_->SetTransparent();
    }
  }

  gfx::PointF base = GetStartPosition() + GetStartLineOffset();
  gfx::PointF extent = GetEndPosition() + GetEndLineOffset();
  if (anchor_drag_to_selection_start_)
    std::swap(base, extent);

  // If this is the first drag, log an action to allow user action sequencing.
  if (!selection_handle_dragged_)
    base::RecordAction(base::UserMetricsAction("SelectionChanged"));
  selection_handle_dragged_ = true;

  // When moving the handle we want to move only the extent point. Before doing
  // so we must make sure that the base point is set correctly.
  client_->SelectBetweenCoordinates(base, extent);
  client_->OnSelectionEvent(SELECTION_HANDLE_DRAG_STARTED);
}

void TouchSelectionController::OnDragUpdate(
    const TouchSelectionDraggable& draggable,
    const gfx::PointF& drag_position) {
  // As the position corresponds to the bottom left point of the selection
  // bound, offset it to some reasonable point on the current line of text.
  gfx::Vector2dF line_offset = anchor_drag_to_selection_start_
                                   ? GetStartLineOffset()
                                   : GetEndLineOffset();
  gfx::PointF line_position = drag_position + line_offset;
  if (&draggable == insertion_handle_.get())
    client_->MoveCaret(line_position);
  else
    client_->MoveRangeSelectionExtent(line_position);

  // We use the bound middle point to restrict the ability to move up and
  // down, but let user move it more freely in horizontal direction.
  if (&draggable == &longpress_drag_selector_) {
    // Show magnifier at the selection edge.
    const gfx::SelectionBound* bound =
        anchor_drag_to_selection_start_ ? &start_ : &end_;
    const float x = bound->edge_start().x();
    const float y = (bound->edge_start().y() + bound->edge_end().y()) / 2.f;
    client_->OnDragUpdate(TouchSelectionDraggable::Type::kLongpress,
                          gfx::PointF(x, y));
  } else {
    const float y = GetActiveHandleMiddleY();
    client_->OnDragUpdate(TouchSelectionDraggable::Type::kTouchHandle,
                          gfx::PointF(drag_position.x(), y));
  }
}

void TouchSelectionController::OnDragEnd(
    const TouchSelectionDraggable& draggable) {
  if (&draggable == insertion_handle_.get())
    client_->OnSelectionEvent(INSERTION_HANDLE_DRAG_STOPPED);
  else
    client_->OnSelectionEvent(SELECTION_HANDLE_DRAG_STOPPED);
}

bool TouchSelectionController::IsWithinTapSlop(
    const gfx::Vector2dF& delta) const {
  return delta.LengthSquared() <
         (static_cast<double>(config_.tap_slop) * config_.tap_slop);
}

void TouchSelectionController::OnHandleTapped(const TouchHandle& handle) {
  if (insertion_handle_ && &handle == insertion_handle_.get())
    client_->OnSelectionEvent(INSERTION_HANDLE_TAPPED);
}

void TouchSelectionController::SetNeedsAnimate() {
  client_->SetNeedsAnimate();
}

std::unique_ptr<TouchHandleDrawable>
TouchSelectionController::CreateDrawable() {
  return client_->CreateDrawable();
}

base::TimeDelta TouchSelectionController::GetMaxTapDuration() const {
  return config_.max_tap_duration;
}

bool TouchSelectionController::IsAdaptiveHandleOrientationEnabled() const {
  return config_.enable_adaptive_handle_orientation;
}

void TouchSelectionController::OnLongPressDragActiveStateChanged() {
  // The handles should remain hidden for the duration of a longpress drag,
  // including the time between a longpress and the start of drag motion.
  RefreshHandleVisibility();
}

gfx::PointF TouchSelectionController::GetSelectionStart() const {
  return GetStartPosition();
}

gfx::PointF TouchSelectionController::GetSelectionEnd() const {
  return GetEndPosition();
}

void TouchSelectionController::OnInsertionChanged() {
  DeactivateSelection();

  const bool activated = ActivateInsertionIfNecessary();

  const TouchHandle::AnimationStyle animation = GetAnimationStyle(!activated);
  insertion_handle_->SetFocus(start_.edge_start(), start_.edge_end());
  insertion_handle_->SetVisible(GetStartVisible(), animation);

  UpdateHandleLayoutIfNecessary();

  client_->OnSelectionEvent(activated ? INSERTION_HANDLE_SHOWN
                                      : INSERTION_HANDLE_MOVED);
}

void TouchSelectionController::OnSelectionChanged() {
  DeactivateInsertion();

  const bool activated = ActivateSelectionIfNecessary();

  const TouchHandle::AnimationStyle animation = GetAnimationStyle(!activated);

  start_selection_handle_->SetFocus(start_.edge_start(), start_.edge_end());
  end_selection_handle_->SetFocus(end_.edge_start(), end_.edge_end());

  start_selection_handle_->SetOrientation(start_orientation_);
  end_selection_handle_->SetOrientation(end_orientation_);

  start_selection_handle_->SetVisible(GetStartVisible(), animation);
  end_selection_handle_->SetVisible(GetEndVisible(), animation);

  UpdateHandleLayoutIfNecessary();

  client_->OnSelectionEvent(activated ? SELECTION_HANDLES_SHOWN
                                      : SELECTION_HANDLES_MOVED);
}

bool TouchSelectionController::ActivateInsertionIfNecessary() {
  DCHECK_NE(SELECTION_ACTIVE, active_status_);

  if (!insertion_handle_) {
    insertion_handle_ = std::make_unique<TouchHandle>(
        this, TouchHandleOrientation::CENTER, viewport_rect_);
  }

  if (active_status_ == INACTIVE || response_pending_input_event_ == TAP ||
      response_pending_input_event_ == LONG_PRESS) {
    active_status_ = INSERTION_ACTIVE;
    insertion_handle_->SetEnabled(true);
    insertion_handle_->SetViewportRect(viewport_rect_);
    response_pending_input_event_ = INPUT_EVENT_TYPE_NONE;
    return true;
  }
  return false;
}

void TouchSelectionController::DeactivateInsertion() {
  if (active_status_ != INSERTION_ACTIVE)
    return;
  DCHECK(insertion_handle_);
  active_status_ = INACTIVE;
  insertion_handle_->SetEnabled(false);
  client_->OnSelectionEvent(INSERTION_HANDLE_CLEARED);
}

bool TouchSelectionController::ActivateSelectionIfNecessary() {
  DCHECK_NE(INSERTION_ACTIVE, active_status_);

  if (!start_selection_handle_) {
    start_selection_handle_ =
        std::make_unique<TouchHandle>(this, start_orientation_, viewport_rect_);
  } else {
    start_selection_handle_->SetEnabled(true);
    start_selection_handle_->SetViewportRect(viewport_rect_);
  }

  if (!end_selection_handle_) {
    end_selection_handle_ =
        std::make_unique<TouchHandle>(this, end_orientation_, viewport_rect_);
  } else {
    end_selection_handle_->SetEnabled(true);
    end_selection_handle_->SetViewportRect(viewport_rect_);
  }

  // As a long press received while a selection is already active may trigger
  // an entirely new selection, notify the client but avoid sending an
  // intervening SELECTION_HANDLES_CLEARED update to avoid unnecessary state
  // changes.
  if (active_status_ == INACTIVE ||
      response_pending_input_event_ == LONG_PRESS ||
      response_pending_input_event_ == REPEATED_TAP) {
    if (active_status_ == SELECTION_ACTIVE) {
      // The active selection session finishes with the start of the new one.
      LogSelectionEnd();
    }
    active_status_ = SELECTION_ACTIVE;
    selection_handle_dragged_ = false;
    selection_start_time_ = base::TimeTicks::Now();
    response_pending_input_event_ = INPUT_EVENT_TYPE_NONE;
    longpress_drag_selector_.OnSelectionActivated();
    return true;
  }
  return false;
}

void TouchSelectionController::DeactivateSelection() {
  if (active_status_ != SELECTION_ACTIVE)
    return;
  DCHECK(start_selection_handle_);
  DCHECK(end_selection_handle_);
  LogSelectionEnd();
  longpress_drag_selector_.OnSelectionDeactivated();
  start_selection_handle_->SetEnabled(false);
  end_selection_handle_->SetEnabled(false);
  active_status_ = INACTIVE;
  client_->OnSelectionEvent(SELECTION_HANDLES_CLEARED);
}

void TouchSelectionController::UpdateHandleLayoutIfNecessary() {
  if (active_status_ == INSERTION_ACTIVE) {
    DCHECK(insertion_handle_);
    insertion_handle_->UpdateHandleLayout();
  } else if (active_status_ == SELECTION_ACTIVE) {
    DCHECK(start_selection_handle_);
    DCHECK(end_selection_handle_);
    start_selection_handle_->UpdateHandleLayout();
    end_selection_handle_->UpdateHandleLayout();
  }
}

void TouchSelectionController::RefreshHandleVisibility() {
  TouchHandle::AnimationStyle animation_style = GetAnimationStyle(true);
  if (active_status_ == SELECTION_ACTIVE) {
    start_selection_handle_->SetVisible(GetStartVisible(), animation_style);
    end_selection_handle_->SetVisible(GetEndVisible(), animation_style);
  }
  if (active_status_ == INSERTION_ACTIVE)
    insertion_handle_->SetVisible(GetStartVisible(), animation_style);

  // Update handle layout if handle visibility is explicitly changed.
  UpdateHandleLayoutIfNecessary();
}

gfx::Vector2dF TouchSelectionController::GetStartLineOffset() const {
  return ComputeLineOffsetFromBottom(start_);
}

gfx::Vector2dF TouchSelectionController::GetEndLineOffset() const {
  return ComputeLineOffsetFromBottom(end_);
}

bool TouchSelectionController::GetStartVisible() const {
  if (!start_.visible())
    return false;

  return !temporarily_hidden_ && !longpress_drag_selector_.IsActive();
}

bool TouchSelectionController::GetEndVisible() const {
  if (!end_.visible())
    return false;

  return !temporarily_hidden_ && !longpress_drag_selector_.IsActive();
}

TouchHandle::AnimationStyle TouchSelectionController::GetAnimationStyle(
    bool was_active) const {
  return was_active && client_->SupportsAnimation()
             ? TouchHandle::ANIMATION_SMOOTH
             : TouchHandle::ANIMATION_NONE;
}

void TouchSelectionController::LogSelectionEnd() {
  // TODO(mfomitchev): Once we are able to tell the difference between
  // 'successful' and 'unsuccessful' selections - log
  // Event.TouchSelection.Duration instead and get rid of
  // Event.TouchSelectionD.WasDraggeduration.
  if (selection_handle_dragged_) {
    base::TimeDelta duration = base::TimeTicks::Now() - selection_start_time_;
    UMA_HISTOGRAM_CUSTOM_TIMES("Event.TouchSelection.WasDraggedDuration",
                               duration, base::Milliseconds(500),
                               base::Seconds(60), 60);
  }
}

}  // namespace ui
