// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/foundation.dart';
import 'package:vector_math/vector_math_64.dart';

import 'layer.dart';
import 'object.dart';

/// The result after handling a [SelectionEvent].
///
/// [SelectionEvent]s are sent from [SelectionRegistrar] to be handled by
/// [SelectionHandler.dispatchSelectionEvent]. The subclasses of
/// [SelectionHandler] or [Selectable] must return appropriate
/// [SelectionResult]s after handling the events.
///
/// This is used by the [SelectionContainer] to determine how a selection
/// expands across its [Selectable] children.
enum SelectionResult {
  /// There is nothing left to select forward in this [Selectable], and further
  /// selection should extend to the next [Selectable] in screen order.
  ///
  /// {@template flutter.rendering.selection.SelectionResult.footNote}
  /// This is used after subclasses [SelectionHandler] or [Selectable] handled
  /// [SelectionEdgeUpdateEvent].
  /// {@endtemplate}
  next,
  /// Selection does not reach this [Selectable] and is located before it in
  /// screen order.
  ///
  /// {@macro flutter.rendering.selection.SelectionResult.footNote}
  previous,
  /// Selection ends in this [Selectable].
  ///
  /// Part of the [Selectable] may or may not be selected, but there is still
  /// content to select forward or backward.
  ///
  /// {@macro flutter.rendering.selection.SelectionResult.footNote}
  end,
  /// The result can't be determined in this frame.
  ///
  /// This is typically used when the subtree is scrolling to reveal more
  /// content.
  ///
  /// {@macro flutter.rendering.selection.SelectionResult.footNote}
  // See `_SelectableRegionState._triggerSelectionEndEdgeUpdate` for how this
  // result affects the selection.
  pending,
  /// There is no result for the selection event.
  ///
  /// This is used when a selection result is not applicable, e.g.
  /// [SelectAllSelectionEvent], [ClearSelectionEvent], and
  /// [SelectWordSelectionEvent].
  none,
}

/// The abstract interface to handle [SelectionEvent]s.
///
/// This interface is extended by [Selectable] and [SelectionContainerDelegate]
/// and is typically not use directly.
///
/// {@template flutter.rendering.SelectionHandler}
/// This class returns a [SelectionGeometry] as its [value], and is responsible
/// to notify its listener when its selection geometry has changed as the result
/// of receiving selection events.
/// {@endtemplate}
abstract class SelectionHandler implements ValueListenable<SelectionGeometry> {
  /// Marks this handler to be responsible for pushing [LeaderLayer]s for the
  /// selection handles.
  ///
  /// This handler is responsible for pushing the leader layers with the
  /// given layer links if they are not null. It is possible that only one layer
  /// is non-null if this handler is only responsible for pushing one layer
  /// link.
  ///
  /// The `startHandle` needs to be placed at the visual location of selection
  /// start, the `endHandle` needs to be placed at the visual location of selection
  /// end. Typically, the visual locations should be the same as
  /// [SelectionGeometry.startSelectionPoint] and
  /// [SelectionGeometry.endSelectionPoint].
  void pushHandleLayers(LayerLink? startHandle, LayerLink? endHandle);

  /// Gets the selected content in this object.
  ///
  /// Return `null` if nothing is selected.
  SelectedContent? getSelectedContent();

  /// Handles the [SelectionEvent] sent to this object.
  ///
  /// The subclasses need to update their selections or delegate the
  /// [SelectionEvent]s to their subtrees.
  ///
  /// The `event`s are subclasses of [SelectionEvent]. Check
  /// [SelectionEvent.type] to determine what kinds of event are dispatched to
  /// this handler and handle them accordingly.
  ///
  /// See also:
  ///  * [SelectionEventType], which contains all of the possible types.
  SelectionResult dispatchSelectionEvent(SelectionEvent event);
}

/// The selected content in a [Selectable] or [SelectionHandler].
// TODO(chunhtai): Add more support for rich content.
// https://github.com/flutter/flutter/issues/104206.
class SelectedContent {
  /// Creates a selected content object.
  ///
  /// Only supports plain text.
  const SelectedContent({required this.plainText});

  /// The selected content in plain text format.
  final String plainText;
}

/// A mixin that can be selected by users when under a [SelectionArea] widget.
///
/// This object receives selection events and the [value] must reflect the
/// current selection in this [Selectable]. The object must also notify its
/// listener if the [value] ever changes.
///
/// This object is responsible for drawing the selection highlight.
///
/// In order to receive the selection event, the mixer needs to register
/// itself to [SelectionRegistrar]s. Use
/// [SelectionContainer.maybeOf] to get the selection registrar, and
/// mix the [SelectionRegistrant] to subscribe to the [SelectionRegistrar]
/// automatically.
///
/// This mixin is typically mixed by [RenderObject]s. The [RenderObject.paint]
/// methods are responsible to push the [LayerLink]s provided to
/// [pushHandleLayers].
///
/// {@macro flutter.rendering.SelectionHandler}
///
/// See also:
///  * [SelectionArea], which provides an overview of selection system.
mixin Selectable implements SelectionHandler {
  /// {@macro flutter.rendering.RenderObject.getTransformTo}
  Matrix4 getTransformTo(RenderObject? ancestor);

  /// The size of this [Selectable].
  Size get size;

  /// Disposes resources held by the mixer.
  void dispose();
}

/// A mixin to auto-register the mixer to the [registrar].
///
/// To use this mixin, the mixer needs to set the [registrar] to the
/// [SelectionRegistrar] it wants to register to.
///
/// This mixin only registers the mixer with the [registrar] if the
/// [SelectionGeometry.hasContent] returned by the mixer is true.
mixin SelectionRegistrant on Selectable {
  /// The [SelectionRegistrar] the mixer will be or is registered to.
  ///
  /// This [Selectable] only registers the mixer if the
  /// [SelectionGeometry.hasContent] returned by the [Selectable] is true.
  SelectionRegistrar? get registrar => _registrar;
  SelectionRegistrar? _registrar;
  set registrar(SelectionRegistrar? value) {
    if (value == _registrar) {
      return;
    }
    if (value == null) {
      // When registrar goes from non-null to null;
      removeListener(_updateSelectionRegistrarSubscription);
    } else if (_registrar == null) {
      // When registrar goes from null to non-null;
      addListener(_updateSelectionRegistrarSubscription);
    }
    _removeSelectionRegistrarSubscription();
    _registrar = value;
    _updateSelectionRegistrarSubscription();
  }

  @override
  void dispose() {
    _removeSelectionRegistrarSubscription();
    super.dispose();
  }

  bool _subscribedToSelectionRegistrar = false;
  void _updateSelectionRegistrarSubscription() {
    if (_registrar == null) {
      _subscribedToSelectionRegistrar = false;
      return;
    }
    if (_subscribedToSelectionRegistrar && !value.hasContent) {
      _registrar!.remove(this);
      _subscribedToSelectionRegistrar = false;
    } else if (!_subscribedToSelectionRegistrar && value.hasContent) {
      _registrar!.add(this);
      _subscribedToSelectionRegistrar = true;
    }
  }

  void _removeSelectionRegistrarSubscription() {
    if (_subscribedToSelectionRegistrar) {
      _registrar!.remove(this);
      _subscribedToSelectionRegistrar = false;
    }
  }
}

/// A utility class that provides useful methods for handling selection events.
abstract final class SelectionUtils {
  /// Determines [SelectionResult] purely based on the target rectangle.
  ///
  /// This method returns [SelectionResult.end] if the `point` is inside the
  /// `targetRect`. Returns [SelectionResult.previous] if the `point` is
  /// considered to be lower than `targetRect` in screen order. Returns
  /// [SelectionResult.next] if the point is considered to be higher than
  /// `targetRect` in screen order.
  static SelectionResult getResultBasedOnRect(Rect targetRect, Offset point) {
    if (targetRect.contains(point)) {
      return SelectionResult.end;
    }
    if (point.dy < targetRect.top) {
      return SelectionResult.previous;
    }
    if (point.dy > targetRect.bottom) {
      return SelectionResult.next;
    }
    return point.dx >= targetRect.right
        ? SelectionResult.next
        : SelectionResult.previous;
  }

  /// Adjusts the dragging offset based on the target rect.
  ///
  /// This method moves the offsets to be within the target rect in case they are
  /// outside the rect.
  ///
  /// This is used in the case where a drag happens outside of the rectangle
  /// of a [Selectable].
  ///
  /// The logic works as the following:
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/rendering/adjust_drag_offset.png)
  ///
  /// For points inside the rect:
  ///   Their effective locations are unchanged.
  ///
  /// For points in Area 1:
  ///   Move them to top-left of the rect if text direction is ltr, or top-right
  ///   if rtl.
  ///
  /// For points in Area 2:
  ///   Move them to bottom-right of the rect if text direction is ltr, or
  ///   bottom-left if rtl.
  static Offset adjustDragOffset(Rect targetRect, Offset point, {TextDirection direction = TextDirection.ltr}) {
    if (targetRect.contains(point)) {
      return point;
    }
    if (point.dy <= targetRect.top ||
        point.dy <= targetRect.bottom && point.dx <= targetRect.left) {
      // Area 1
      return direction == TextDirection.ltr ? targetRect.topLeft : targetRect.topRight;
    } else {
      // Area 2
      return direction == TextDirection.ltr ? targetRect.bottomRight : targetRect.bottomLeft;
    }
  }
}

/// The type of a [SelectionEvent].
///
/// Used by [SelectionEvent.type] to distinguish different types of events.
enum SelectionEventType {
  /// An event to update the selection start edge.
  ///
  /// Used by [SelectionEdgeUpdateEvent].
  startEdgeUpdate,

  /// An event to update the selection end edge.
  ///
  /// Used by [SelectionEdgeUpdateEvent].
  endEdgeUpdate,

  /// An event to clear the current selection.
  ///
  /// Used by [ClearSelectionEvent].
  clear,

  /// An event to select all the available content.
  ///
  /// Used by [SelectAllSelectionEvent].
  selectAll,

  /// An event to select a word at the location
  /// [SelectWordSelectionEvent.globalPosition].
  ///
  /// Used by [SelectWordSelectionEvent].
  selectWord,

  /// An event that extends the selection by a specific [TextGranularity].
  granularlyExtendSelection,

  /// An event that extends the selection in a specific direction.
  directionallyExtendSelection,
}

/// The unit of how selection handles move in text.
///
/// The [GranularlyExtendSelectionEvent] uses this enum to describe how
/// [Selectable] should extend its selection.
enum TextGranularity {
  /// Treats each character as an atomic unit when moving the selection handles.
  character,

  /// Treats word as an atomic unit when moving the selection handles.
  word,

  /// Treats each line break as an atomic unit when moving the selection handles.
  line,

  /// Treats the entire document as an atomic unit when moving the selection handles.
  document,
}

/// An abstract base class for selection events.
///
/// This should not be directly used. To handle a selection event, it should
/// be downcast to a specific subclass. One can use [type] to look up which
/// subclasses to downcast to.
///
/// See also:
/// * [SelectAllSelectionEvent], for events to select all contents.
/// * [ClearSelectionEvent], for events to clear selections.
/// * [SelectWordSelectionEvent], for events to select words at the locations.
/// * [SelectionEdgeUpdateEvent], for events to update selection edges.
/// * [SelectionEventType], for determining the subclass types.
abstract class SelectionEvent {
  const SelectionEvent._(this.type);

  /// The type of this selection event.
  final SelectionEventType type;
}

/// Selects all selectable contents.
///
/// This event can be sent as the result of keyboard select-all, i.e.
/// ctrl + A, or cmd + A in macOS.
class SelectAllSelectionEvent extends SelectionEvent {
  /// Creates a select all selection event.
  const SelectAllSelectionEvent(): super._(SelectionEventType.selectAll);
}

/// Clears the selection from the [Selectable] and removes any existing
/// highlight as if there is no selection at all.
class ClearSelectionEvent extends SelectionEvent {
  /// Create a clear selection event.
  const ClearSelectionEvent(): super._(SelectionEventType.clear);
}

/// Selects the whole word at the location.
///
/// This event can be sent as the result of mobile long press selection.
class SelectWordSelectionEvent extends SelectionEvent {
  /// Creates a select word event at the [globalPosition].
  const SelectWordSelectionEvent({required this.globalPosition}): super._(SelectionEventType.selectWord);

  /// The position in global coordinates to select word at.
  final Offset globalPosition;
}

/// Updates a selection edge.
///
/// An active selection contains two edges, start and end. Use the [type] to
/// determine which edge this event applies to. If the [type] is
/// [SelectionEventType.startEdgeUpdate], the event updates start edge. If the
/// [type] is [SelectionEventType.endEdgeUpdate], the event updates end edge.
///
/// The [globalPosition] contains the new offset of the edge.
///
/// This event is dispatched when the framework detects [DragStartDetails] in
/// [SelectionArea]'s gesture recognizers for mouse devices, or the selection
/// handles have been dragged to new locations.
class SelectionEdgeUpdateEvent extends SelectionEvent {
  /// Creates a selection start edge update event.
  ///
  /// The [globalPosition] contains the location of the selection start edge.
  const SelectionEdgeUpdateEvent.forStart({
    required this.globalPosition
  }) : super._(SelectionEventType.startEdgeUpdate);

  /// Creates a selection end edge update event.
  ///
  /// The [globalPosition] contains the new location of the selection end edge.
  const SelectionEdgeUpdateEvent.forEnd({
    required this.globalPosition
  }) : super._(SelectionEventType.endEdgeUpdate);

  /// The new location of the selection edge.
  final Offset globalPosition;
}

/// Extends the start or end of the selection by a given [TextGranularity].
///
/// To handle this event, move the associated selection edge, as dictated by
/// [isEnd], according to the [granularity].
class GranularlyExtendSelectionEvent extends SelectionEvent {
  /// Creates a [GranularlyExtendSelectionEvent].
  ///
  /// All parameters are required and must not be null.
  const GranularlyExtendSelectionEvent({
    required this.forward,
    required this.isEnd,
    required this.granularity,
  }) : super._(SelectionEventType.granularlyExtendSelection);

  /// Whether to extend the selection forward.
  final bool forward;

  /// Whether this event is updating the end selection edge.
  final bool isEnd;

  /// The granularity for which the selection extend.
  final TextGranularity granularity;
}

/// The direction to extend a selection.
///
/// The [DirectionallyExtendSelectionEvent] uses this enum to describe how
/// [Selectable] should extend their selection.
enum SelectionExtendDirection {
  /// Move one edge of the selection vertically to the previous adjacent line.
  ///
  /// For text selection, it should consider both soft and hard linebreak.
  ///
  /// See [DirectionallyExtendSelectionEvent.dx] on how to
  /// calculate the horizontal offset.
  previousLine,

  /// Move one edge of the selection vertically to the next adjacent line.
  ///
  /// For text selection, it should consider both soft and hard linebreak.
  ///
  /// See [DirectionallyExtendSelectionEvent.dx] on how to
  /// calculate the horizontal offset.
  nextLine,

  /// Move the selection edges forward to a certain horizontal offset in the
  /// same line.
  ///
  /// If there is no on-going selection, the selection must start with the first
  /// line (or equivalence of first line in a non-text selectable) and select
  /// toward the horizontal offset in the same line.
  ///
  /// The selectable that receives [DirectionallyExtendSelectionEvent] with this
  /// enum must return [SelectionResult.end].
  ///
  /// See [DirectionallyExtendSelectionEvent.dx] on how to
  /// calculate the horizontal offset.
  forward,

  /// Move the selection edges backward to a certain horizontal offset in the
  /// same line.
  ///
  /// If there is no on-going selection, the selection must start with the last
  /// line (or equivalence of last line in a non-text selectable) and select
  /// backward the horizontal offset in the same line.
  ///
  /// The selectable that receives [DirectionallyExtendSelectionEvent] with this
  /// enum must return [SelectionResult.end].
  ///
  /// See [DirectionallyExtendSelectionEvent.dx] on how to
  /// calculate the horizontal offset.
  backward,
}

/// Extends the current selection with respect to a [direction].
///
/// To handle this event, move the associated selection edge, as dictated by
/// [isEnd], according to the [direction].
///
/// The movements are always based on [dx]. The value is in
/// global coordinates and is the horizontal offset the selection edge should
/// move to when moving to across lines.
class DirectionallyExtendSelectionEvent extends SelectionEvent {
  /// Creates a [DirectionallyExtendSelectionEvent].
  ///
  /// All parameters are required and must not be null.
  const DirectionallyExtendSelectionEvent({
    required this.dx,
    required this.isEnd,
    required this.direction,
  }) : super._(SelectionEventType.directionallyExtendSelection);

  /// The horizontal offset the selection should move to.
  ///
  /// The offset is in global coordinates.
  final double dx;

  /// Whether this event is updating the end selection edge.
  final bool isEnd;

  /// The directional movement of this event.
  ///
  /// See also:
  ///  * [SelectionExtendDirection], which explains how to handle each enum.
  final SelectionExtendDirection direction;

  /// Makes a copy of this object with its property replaced with the new
  /// values.
  DirectionallyExtendSelectionEvent copyWith({
    double? dx,
    bool? isEnd,
    SelectionExtendDirection? direction,
  }) {
    return DirectionallyExtendSelectionEvent(
      dx: dx ?? this.dx,
      isEnd: isEnd ?? this.isEnd,
      direction: direction ?? this.direction,
    );
  }
}

/// A registrar that keeps track of [Selectable]s in the subtree.
///
/// A [Selectable] is only included in the [SelectableRegion] if they are
/// registered with a [SelectionRegistrar]. Once a [Selectable] is registered,
/// it will receive [SelectionEvent]s in
/// [SelectionHandler.dispatchSelectionEvent].
///
/// Use [SelectionContainer.maybeOf] to get the immediate [SelectionRegistrar]
/// in the ancestor chain above the build context.
///
/// See also:
///  * [SelectableRegion], which provides an overview of the selection system.
///  * [SelectionRegistrarScope], which hosts the [SelectionRegistrar] for the
///    subtree.
///  * [SelectionRegistrant], which auto registers the object with the mixin to
///    [SelectionRegistrar].
abstract class SelectionRegistrar {
  /// Adds the [selectable] into the registrar.
  ///
  /// A [Selectable] must register with the [SelectionRegistrar] in order to
  /// receive selection events.
  void add(Selectable selectable);

  /// Removes the [selectable] from the registrar.
  ///
  /// A [Selectable] must unregister itself if it is removed from the rendering
  /// tree.
  void remove(Selectable selectable);
}

/// The status that indicates whether there is a selection and whether the
/// selection is collapsed.
///
/// A collapsed selection means the selection starts and ends at the same
/// location.
enum SelectionStatus {
  /// The selection is not collapsed.
  ///
  /// For example if `{}` represent the selection edges:
  ///   'ab{cd}', the collapsing status is [uncollapsed].
  ///   '{abcd}', the collapsing status is [uncollapsed].
  uncollapsed,

  /// The selection is collapsed.
  ///
  /// For example if `{}` represent the selection edges:
  ///   'ab{}cd', the collapsing status is [collapsed].
  ///   '{}abcd', the collapsing status is [collapsed].
  ///   'abcd{}', the collapsing status is [collapsed].
  collapsed,

  /// No selection.
  none,
}

/// The geometry of the current selection.
///
/// This includes details such as the locations of the selection start and end,
/// line height, etc. This information is used for drawing selection controls
/// for mobile platforms.
///
/// The positions in geometry are in local coordinates of the [SelectionHandler]
/// or [Selectable].
@immutable
class SelectionGeometry {
  /// Creates a selection geometry object.
  ///
  /// If any of the [startSelectionPoint] and [endSelectionPoint] is not null,
  /// the [status] must not be [SelectionStatus.none].
  const SelectionGeometry({
    this.startSelectionPoint,
    this.endSelectionPoint,
    required this.status,
    required this.hasContent,
  }) : assert((startSelectionPoint == null && endSelectionPoint == null) || status != SelectionStatus.none);

  /// The geometry information at the selection start.
  ///
  /// This information is used for drawing mobile selection controls. The
  /// [SelectionPoint.localPosition] of the selection start is typically at the
  /// start of the selection highlight at where the start selection handle
  /// should be drawn.
  ///
  /// The [SelectionPoint.handleType] should be [TextSelectionHandleType.left]
  /// for forward selection or [TextSelectionHandleType.right] for backward
  /// selection in most cases.
  ///
  /// Can be null if the selection start is offstage, for example, when the
  /// selection is outside of the viewport or is kept alive by a scrollable.
  final SelectionPoint? startSelectionPoint;

  /// The geometry information at the selection end.
  ///
  /// This information is used for drawing mobile selection controls. The
  /// [SelectionPoint.localPosition] of the selection end is typically at the end
  /// of the selection highlight at where the end selection handle should be
  /// drawn.
  ///
  /// The [SelectionPoint.handleType] should be [TextSelectionHandleType.right]
  /// for forward selection or [TextSelectionHandleType.left] for backward
  /// selection in most cases.
  ///
  /// Can be null if the selection end is offstage, for example, when the
  /// selection is outside of the viewport or is kept alive by a scrollable.
  final SelectionPoint? endSelectionPoint;

  /// The status of ongoing selection in the [Selectable] or [SelectionHandler].
  final SelectionStatus status;

  /// Whether there is any selectable content in the [Selectable] or
  /// [SelectionHandler].
  final bool hasContent;

  /// Whether there is an ongoing selection.
  bool get hasSelection => status != SelectionStatus.none;

  /// Makes a copy of this object with the given values updated.
  SelectionGeometry copyWith({
    SelectionPoint? startSelectionPoint,
    SelectionPoint? endSelectionPoint,
    SelectionStatus? status,
    bool? hasContent,
  }) {
    return SelectionGeometry(
      startSelectionPoint: startSelectionPoint ?? this.startSelectionPoint,
      endSelectionPoint: endSelectionPoint ?? this.endSelectionPoint,
      status: status ?? this.status,
      hasContent: hasContent ?? this.hasContent,
    );
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) {
      return true;
    }
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is SelectionGeometry
        && other.startSelectionPoint == startSelectionPoint
        && other.endSelectionPoint == endSelectionPoint
        && other.status == status
        && other.hasContent == hasContent;
  }

  @override
  int get hashCode {
    return Object.hash(
      startSelectionPoint,
      endSelectionPoint,
      status,
      hasContent,
    );
  }
}

/// The geometry information of a selection point.
@immutable
class SelectionPoint {
  /// Creates a selection point object.
  ///
  /// All properties must not be null.
  const SelectionPoint({
    required this.localPosition,
    required this.lineHeight,
    required this.handleType,
  });

  /// The position of the selection point in the local coordinates of the
  /// containing [Selectable].
  final Offset localPosition;

  /// The line height at the selection point.
  final double lineHeight;

  /// The selection handle type that should be used at the selection point.
  ///
  /// This is used for building the mobile selection handle.
  final TextSelectionHandleType handleType;

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) {
      return true;
    }
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is SelectionPoint
        && other.localPosition == localPosition
        && other.lineHeight == lineHeight
        && other.handleType == handleType;
  }

  @override
  int get hashCode {
    return Object.hash(
      localPosition,
      lineHeight,
      handleType,
    );
  }
}

/// The type of selection handle to be displayed.
///
/// With mixed-direction text, both handles may be the same type. Examples:
///
/// * LTR text: 'the &lt;quick brown&gt; fox':
///
///   The '&lt;' is drawn with the [left] type, the '&gt;' with the [right]
///
/// * RTL text: 'XOF &lt;NWORB KCIUQ&gt; EHT':
///
///   Same as above.
///
/// * mixed text: '&lt;the NWOR&lt;B KCIUQ fox'
///
///   Here 'the QUICK B' is selected, but 'QUICK BROWN' is RTL. Both are drawn
///   with the [left] type.
///
/// See also:
///
///  * [TextDirection], which discusses left-to-right and right-to-left text in
///    more detail.
enum TextSelectionHandleType {
  /// The selection handle is to the left of the selection end point.
  left,

  /// The selection handle is to the right of the selection end point.
  right,

  /// The start and end of the selection are co-incident at this point.
  collapsed,
}
