// 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.
class SelectionUtils {
  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,
  }) : assert(localPosition != null),
       assert(lineHeight != null),
       assert(handleType != null);

  /// 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,
}
