// 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:flutter/gestures.dart';

import 'test_async_utils.dart';

export 'dart:ui' show Offset;

/// A class for generating coherent artificial pointer events.
///
/// You can use this to manually simulate individual events, but the simplest
/// way to generate coherent gestures is to use [TestGesture].
class TestPointer {
  /// Creates a [TestPointer]. By default, the pointer identifier used is 1,
  /// however this can be overridden by providing an argument to the
  /// constructor.
  ///
  /// Multiple [TestPointer]s created with the same pointer identifier will
  /// interfere with each other if they are used in parallel.
  TestPointer([
    this.pointer = 1,
    this.kind = PointerDeviceKind.touch,
    int? device,
    int buttons = kPrimaryButton,
  ]) : _buttons = buttons {
    switch (kind) {
      case PointerDeviceKind.mouse:
        _device = device ?? 1;
        break;
      case PointerDeviceKind.stylus:
      case PointerDeviceKind.invertedStylus:
      case PointerDeviceKind.touch:
      case PointerDeviceKind.trackpad:
      case PointerDeviceKind.unknown:
        _device = device ?? 0;
        break;
    }
  }

  /// The device identifier used for events generated by this object.
  ///
  /// Set when the object is constructed. Defaults to 1 if the [kind] is
  /// [PointerDeviceKind.mouse], and 0 otherwise.
  int get device => _device;
  late int _device;

  /// The pointer identifier used for events generated by this object.
  ///
  /// Set when the object is constructed. Defaults to 1.
  final int pointer;

  /// The kind of pointing device to simulate. Defaults to
  /// [PointerDeviceKind.touch].
  final PointerDeviceKind kind;

  /// The kind of buttons to simulate on Down and Move events. Defaults to
  /// [kPrimaryButton].
  int get buttons => _buttons;
  int _buttons;

  /// Whether the pointer simulated by this object is currently down.
  ///
  /// A pointer is released (goes up) by calling [up] or [cancel].
  ///
  /// Once a pointer is released, it can no longer generate events.
  bool get isDown => _isDown;
  bool _isDown = false;

  /// Whether the pointer simulated by this object currently has
  /// an active pan/zoom gesture.
  ///
  /// A pan/zoom gesture begins when [panZoomStart] is called, and
  /// ends when [panZoomEnd] is called.
  bool get isPanZoomActive => _isPanZoomActive;
  bool _isPanZoomActive = false;

  /// The position of the last event sent by this object.
  ///
  /// If no event has ever been sent by this object, returns null.
  Offset? get location => _location;
  Offset? _location;


  /// The pan offset of the last pointer pan/zoom event sent by this object.
  ///
  /// If no pan/zoom event has ever been sent by this object, returns null.
  Offset? get pan => _pan;
  Offset? _pan;

  /// If a custom event is created outside of this class, this function is used
  /// to set the [isDown].
  bool setDownInfo(
    PointerEvent event,
    Offset newLocation, {
    int? buttons,
  }) {
    _location = newLocation;
    if (buttons != null) {
      _buttons = buttons;
    }
    switch (event.runtimeType) {
      case PointerDownEvent:
        assert(!isDown);
        _isDown = true;
        break;
      case PointerUpEvent:
      case PointerCancelEvent:
        assert(isDown);
        _isDown = false;
        break;
      default:
        break;
    }
    return isDown;
  }

  /// Create a [PointerDownEvent] at the given location.
  ///
  /// By default, the time stamp on the event is [Duration.zero]. You can give a
  /// specific time stamp by passing the `timeStamp` argument.
  ///
  /// By default, the set of buttons in the last down or move event is used.
  /// You can give a specific set of buttons by passing the `buttons` argument.
  PointerDownEvent down(
    Offset newLocation, {
    Duration timeStamp = Duration.zero,
    int? buttons,
  }) {
    assert(!isDown);
    assert(!isPanZoomActive);
    _isDown = true;
    _location = newLocation;
    if (buttons != null) {
      _buttons = buttons;
    }
    return PointerDownEvent(
      timeStamp: timeStamp,
      kind: kind,
      device: _device,
      pointer: pointer,
      position: location!,
      buttons: _buttons,
    );
  }

  /// Create a [PointerMoveEvent] to the given location.
  ///
  /// By default, the time stamp on the event is [Duration.zero]. You can give a
  /// specific time stamp by passing the `timeStamp` argument.
  ///
  /// [isDown] must be true when this is called, since move events can only
  /// be generated when the pointer is down.
  ///
  /// By default, the set of buttons in the last down or move event is used.
  /// You can give a specific set of buttons by passing the `buttons` argument.
  PointerMoveEvent move(
    Offset newLocation, {
    Duration timeStamp = Duration.zero,
    int? buttons,
  }) {
    assert(
        isDown,
        'Move events can only be generated when the pointer is down. To '
        'create a movement event simulating a pointer move when the pointer is '
        'up, use hover() instead.');
    assert(!isPanZoomActive);
    final Offset delta = newLocation - location!;
    _location = newLocation;
    if (buttons != null) {
      _buttons = buttons;
    }
    return PointerMoveEvent(
      timeStamp: timeStamp,
      kind: kind,
      device: _device,
      pointer: pointer,
      position: newLocation,
      delta: delta,
      buttons: _buttons,
    );
  }

  /// Create a [PointerUpEvent].
  ///
  /// By default, the time stamp on the event is [Duration.zero]. You can give a
  /// specific time stamp by passing the `timeStamp` argument.
  ///
  /// The object is no longer usable after this method has been called.
  PointerUpEvent up({ Duration timeStamp = Duration.zero }) {
    assert(!isPanZoomActive);
    assert(isDown);
    _isDown = false;
    return PointerUpEvent(
      timeStamp: timeStamp,
      kind: kind,
      device: _device,
      pointer: pointer,
      position: location!,
    );
  }

  /// Create a [PointerCancelEvent].
  ///
  /// By default, the time stamp on the event is [Duration.zero]. You can give a
  /// specific time stamp by passing the `timeStamp` argument.
  ///
  /// The object is no longer usable after this method has been called.
  PointerCancelEvent cancel({ Duration timeStamp = Duration.zero }) {
    assert(isDown);
    _isDown = false;
    return PointerCancelEvent(
      timeStamp: timeStamp,
      kind: kind,
      device: _device,
      pointer: pointer,
      position: location!,
    );
  }

  /// Create a [PointerAddedEvent] with the [PointerDeviceKind] the pointer was
  /// created with.
  ///
  /// By default, the time stamp on the event is [Duration.zero]. You can give a
  /// specific time stamp by passing the `timeStamp` argument.
  PointerAddedEvent addPointer({
    Duration timeStamp = Duration.zero,
    Offset? location,
  }) {
    _location = location ?? _location;
    return PointerAddedEvent(
      timeStamp: timeStamp,
      kind: kind,
      device: _device,
      position: _location ?? Offset.zero,
    );
  }

  /// Create a [PointerRemovedEvent] with the [PointerDeviceKind] the pointer
  /// was created with.
  ///
  /// By default, the time stamp on the event is [Duration.zero]. You can give a
  /// specific time stamp by passing the `timeStamp` argument.
  PointerRemovedEvent removePointer({
    Duration timeStamp = Duration.zero,
    Offset? location,
  }) {
    _location = location ?? _location;
    return PointerRemovedEvent(
      timeStamp: timeStamp,
      kind: kind,
      device: _device,
      pointer: pointer,
      position: _location ?? Offset.zero,
    );
  }

  /// Create a [PointerHoverEvent] to the given location.
  ///
  /// By default, the time stamp on the event is [Duration.zero]. You can give a
  /// specific time stamp by passing the `timeStamp` argument.
  ///
  /// [isDown] must be false, since hover events can't be sent when the pointer
  /// is up.
  PointerHoverEvent hover(
    Offset newLocation, {
    Duration timeStamp = Duration.zero,
  }) {
    assert(
        !isDown,
        'Hover events can only be generated when the pointer is up. To '
        'simulate movement when the pointer is down, use move() instead.');
    final Offset delta = location != null ? newLocation - location! : Offset.zero;
    _location = newLocation;
    return PointerHoverEvent(
      timeStamp: timeStamp,
      kind: kind,
      device: _device,
      pointer: pointer,
      position: newLocation,
      delta: delta,
    );
  }

  /// Create a [PointerScrollEvent] (e.g., scroll wheel scroll; not finger-drag
  /// scroll) with the given delta.
  ///
  /// By default, the time stamp on the event is [Duration.zero]. You can give a
  /// specific time stamp by passing the `timeStamp` argument.
  PointerScrollEvent scroll(
    Offset scrollDelta, {
    Duration timeStamp = Duration.zero,
  }) {
    assert(kind != PointerDeviceKind.touch, "Touch pointers can't generate pointer signal events");
    assert(location != null);
    return PointerScrollEvent(
      timeStamp: timeStamp,
      kind: kind,
      device: _device,
      position: location!,
      scrollDelta: scrollDelta,
    );
  }

  /// Create a [PointerScrollInertiaCancelEvent] (e.g., user resting their finger on the trackpad).
  ///
  /// By default, the time stamp on the event is [Duration.zero]. You can give a
  /// specific time stamp by passing the `timeStamp` argument.
  PointerScrollInertiaCancelEvent scrollInertiaCancel({
    Duration timeStamp = Duration.zero,
  }) {
    assert(kind != PointerDeviceKind.touch, "Touch pointers can't generate pointer signal events");
    assert(location != null);
    return PointerScrollInertiaCancelEvent(
      timeStamp: timeStamp,
      kind: kind,
      device: _device,
      position: location!
    );
  }

  /// Create a [PointerScaleEvent] (e.g., legacy pinch-to-zoom).
  ///
  /// By default, the time stamp on the event is [Duration.zero]. You can give a
  /// specific time stamp by passing the `timeStamp` argument.
  PointerScaleEvent scale(
    double scale, {
    Duration timeStamp = Duration.zero,
  }) {
    assert(kind != PointerDeviceKind.touch, "Touch pointers can't generate pointer signal events");
    assert(location != null);
    return PointerScaleEvent(
      timeStamp: timeStamp,
      kind: kind,
      device: _device,
      position: location!,
      scale: scale,
    );
  }

  /// Create a [PointerPanZoomStartEvent] (e.g., trackpad scroll; not scroll wheel
  /// or finger-drag scroll) with the given delta.
  ///
  /// By default, the time stamp on the event is [Duration.zero]. You can give a
  /// specific time stamp by passing the `timeStamp` argument.
  PointerPanZoomStartEvent panZoomStart(
    Offset location, {
    Duration timeStamp = Duration.zero
  }) {
    assert(!isPanZoomActive);
    assert(kind == PointerDeviceKind.trackpad);
    _location = location;
    _pan = Offset.zero;
    _isPanZoomActive = true;
    return PointerPanZoomStartEvent(
      timeStamp: timeStamp,
      device: _device,
      pointer: pointer,
      position: location,
    );
  }

  /// Create a [PointerPanZoomUpdateEvent] to update the active pan/zoom sequence
  /// on this pointer with updated pan, scale, and/or rotation values.
  ///
  /// [rotation] is in units of radians.
  ///
  /// By default, the time stamp on the event is [Duration.zero]. You can give a
  /// specific time stamp by passing the `timeStamp` argument.
  PointerPanZoomUpdateEvent panZoomUpdate(
    Offset location, {
    Offset pan = Offset.zero,
    double scale = 1,
    double rotation = 0,
    Duration timeStamp = Duration.zero,
  }) {
    assert(isPanZoomActive);
    assert(kind == PointerDeviceKind.trackpad);
    _location = location;
    final Offset panDelta = pan - _pan!;
    _pan = pan;
    return PointerPanZoomUpdateEvent(
      timeStamp: timeStamp,
      device: _device,
      pointer: pointer,
      position: location,
      pan: pan,
      panDelta: panDelta,
      scale: scale,
      rotation: rotation,
    );
  }

  /// Create a [PointerPanZoomEndEvent] to end the active pan/zoom sequence
  /// on this pointer.
  ///
  /// By default, the time stamp on the event is [Duration.zero]. You can give a
  /// specific time stamp by passing the `timeStamp` argument.
  PointerPanZoomEndEvent panZoomEnd({
    Duration timeStamp = Duration.zero
  }) {
    assert(isPanZoomActive);
    assert(kind == PointerDeviceKind.trackpad);
    _isPanZoomActive = false;
    _pan = null;
    return PointerPanZoomEndEvent(
      timeStamp: timeStamp,
      device: _device,
      pointer: pointer,
      position: location!,
    );
  }
}

/// Signature for a callback that can dispatch events and returns a future that
/// completes when the event dispatch is complete.
typedef EventDispatcher = Future<void> Function(PointerEvent event);

/// Signature for callbacks that perform hit-testing at a given location.
typedef HitTester = HitTestResult Function(Offset location);

/// A class for performing gestures in tests.
///
/// The simplest way to create a [TestGesture] is to call
/// [WidgetTester.startGesture].
class TestGesture {
  /// Create a [TestGesture] without dispatching any events from it.
  /// The [TestGesture] can then be manipulated to perform future actions.
  ///
  /// By default, the pointer identifier used is 1. This can be overridden by
  /// providing the `pointer` argument.
  ///
  /// A function to use for hit testing must be provided via the `hitTester`
  /// argument, and a function to use for dispatching events must be provided
  /// via the `dispatcher` argument.
  ///
  /// The device `kind` defaults to [PointerDeviceKind.touch], but move events
  /// when the pointer is "up" require a kind other than
  /// [PointerDeviceKind.touch], like [PointerDeviceKind.mouse], for example,
  /// because touch devices can't produce movement events when they are "up".
  ///
  /// None of the arguments may be null. The `dispatcher` and `hitTester`
  /// arguments are required.
  TestGesture({
    required EventDispatcher dispatcher,
    int pointer = 1,
    PointerDeviceKind kind = PointerDeviceKind.touch,
    int? device,
    int buttons = kPrimaryButton,
  }) : _dispatcher = dispatcher,
       _pointer = TestPointer(pointer, kind, device, buttons);

  /// Dispatch a pointer down event at the given `downLocation`, caching the
  /// hit test result.
  Future<void> down(Offset downLocation, { Duration timeStamp = Duration.zero }) async {
    assert(_pointer.kind != PointerDeviceKind.trackpad, 'Trackpads are expected to send panZoomStart events, not down events.');
    return TestAsyncUtils.guard<void>(() async {
      return _dispatcher(_pointer.down(downLocation, timeStamp: timeStamp));
    });
  }

  /// Dispatch a pointer down event at the given `downLocation`, caching the
  /// hit test result with a custom down event.
  Future<void> downWithCustomEvent(Offset downLocation, PointerDownEvent event) async {
    assert(_pointer.kind != PointerDeviceKind.trackpad, 'Trackpads are expected to send panZoomStart events, not down events');
    _pointer.setDownInfo(event, downLocation);
    return TestAsyncUtils.guard<void>(() async {
      return _dispatcher(event);
    });
  }

  final EventDispatcher _dispatcher;
  final TestPointer _pointer;

  /// In a test, send a move event that moves the pointer by the given offset.
  @visibleForTesting
  Future<void> updateWithCustomEvent(PointerEvent event, { Duration timeStamp = Duration.zero }) {
    _pointer.setDownInfo(event, event.position);
    return TestAsyncUtils.guard<void>(() {
      return _dispatcher(event);
    });
  }

  /// In a test, send a pointer add event for this pointer.
  Future<void> addPointer({ Duration timeStamp = Duration.zero, Offset? location }) {
    return TestAsyncUtils.guard<void>(() {
      return _dispatcher(_pointer.addPointer(timeStamp: timeStamp, location: location ?? _pointer.location));
    });
  }

  /// In a test, send a pointer remove event for this pointer.
  Future<void> removePointer({ Duration timeStamp = Duration.zero, Offset? location }) {
    return TestAsyncUtils.guard<void>(() {
      return _dispatcher(_pointer.removePointer(timeStamp: timeStamp, location: location ?? _pointer.location));
    });
  }

  /// Send a move event moving the pointer by the given offset.
  ///
  /// If the pointer is down, then a move event is dispatched. If the pointer is
  /// up, then a hover event is dispatched.
  ///
  /// See also:
  ///  * [WidgetController.drag], a method to simulate a drag.
  ///  * [WidgetController.timedDrag], a method to simulate the drag of a given widget in a given duration.
  ///    It sends move events at a given frequency and it is useful when there are listeners involved.
  ///  * [WidgetController.fling], a method to simulate a fling.
  Future<void> moveBy(Offset offset, { Duration timeStamp = Duration.zero }) {
    assert(_pointer.location != null);
    if (_pointer.isPanZoomActive) {
      return panZoomUpdate(
        _pointer.location!,
        pan: (_pointer.pan ?? Offset.zero) + offset,
        timeStamp: timeStamp
      );
    } else {
      return moveTo(_pointer.location! + offset, timeStamp: timeStamp);
    }
  }

  /// Send a move event moving the pointer to the given location.
  ///
  /// If the pointer is down, then a move event is dispatched. If the pointer is
  /// up, then a hover event is dispatched.
  ///
  /// See also:
  ///  * [WidgetController.drag], a method to simulate a drag.
  ///  * [WidgetController.timedDrag], a method to simulate the drag of a given widget in a given duration.
  ///    It sends move events at a given frequency and it is useful when there are listeners involved.
  ///  * [WidgetController.fling], a method to simulate a fling.
  Future<void> moveTo(Offset location, { Duration timeStamp = Duration.zero }) {
    assert(_pointer.kind != PointerDeviceKind.trackpad);
    return TestAsyncUtils.guard<void>(() {
      if (_pointer._isDown) {
        return _dispatcher(_pointer.move(location, timeStamp: timeStamp));
      } else {
        return _dispatcher(_pointer.hover(location, timeStamp: timeStamp));
      }
    });
  }

  /// End the gesture by releasing the pointer. For trackpad pointers this
  /// will send a panZoomEnd event instead of an up event.
  Future<void> up({ Duration timeStamp = Duration.zero }) {
    return TestAsyncUtils.guard<void>(() async {
      if (_pointer.kind == PointerDeviceKind.trackpad) {
        assert(_pointer._isPanZoomActive);
        await _dispatcher(_pointer.panZoomEnd(timeStamp: timeStamp));
        assert(!_pointer._isPanZoomActive);
      } else {
        assert(_pointer._isDown);
        await _dispatcher(_pointer.up(timeStamp: timeStamp));
        assert(!_pointer._isDown);
      }
    });
  }

  /// End the gesture by canceling the pointer (as would happen if the
  /// system showed a modal dialog on top of the Flutter application,
  /// for instance).
  Future<void> cancel({ Duration timeStamp = Duration.zero }) {
    assert(_pointer.kind != PointerDeviceKind.trackpad, 'Trackpads do not send cancel events.');
    return TestAsyncUtils.guard<void>(() async {
      assert(_pointer._isDown);
      await _dispatcher(_pointer.cancel(timeStamp: timeStamp));
      assert(!_pointer._isDown);
    });
  }

  /// Dispatch a pointer pan zoom start event at the given `location`, caching the
  /// hit test result.
  Future<void> panZoomStart(Offset location, { Duration timeStamp = Duration.zero }) async {
    assert(_pointer.kind == PointerDeviceKind.trackpad, 'Only trackpads can send PointerPanZoom events.');
    return TestAsyncUtils.guard<void>(() async {
      return _dispatcher(_pointer.panZoomStart(location, timeStamp: timeStamp));
    });
  }

  /// Dispatch a pointer pan zoom update event at the given `location`, caching the
  /// hit test result.
  Future<void> panZoomUpdate(Offset location, {
    Offset pan = Offset.zero,
    double scale = 1,
    double rotation = 0,
    Duration timeStamp = Duration.zero
  }) async {
    assert(_pointer.kind == PointerDeviceKind.trackpad, 'Only trackpads can send PointerPanZoom events.');
    return TestAsyncUtils.guard<void>(() async {
      return _dispatcher(_pointer.panZoomUpdate(location,
        pan: pan,
        scale: scale,
        rotation: rotation,
        timeStamp: timeStamp
      ));
    });
  }

  /// Dispatch a pointer pan zoom end event, caching the hit test result.
  Future<void> panZoomEnd({
    Duration timeStamp = Duration.zero
  }) async {
    assert(_pointer.kind == PointerDeviceKind.trackpad, 'Only trackpads can send PointerPanZoom events.');
    return TestAsyncUtils.guard<void>(() async {
      return _dispatcher(_pointer.panZoomEnd(
        timeStamp: timeStamp
      ));
    });
  }
}

/// A record of input [PointerEvent] list with the timeStamp of when it is
/// injected.
///
/// The [timeDelay] is used to indicate the time when the event packet should
/// be sent.
///
/// This is a simulation of how the framework is receiving input events from
/// the engine. See [GestureBinding] and [PointerDataPacket].
class PointerEventRecord {
  /// Creates a pack of [PointerEvent]s.
  PointerEventRecord(this.timeDelay, this.events);

  /// The time delay of when the event record should be sent.
  ///
  /// This value is used as the time delay relative to the start of
  /// [WidgetTester.handlePointerEventRecord] call.
  final Duration timeDelay;

  /// The event list of the record.
  ///
  /// This can be considered as a simulation of the events expanded from the
  /// [PointerDataPacket].
  ///
  /// See [PointerEventConverter.expand].
  final List<PointerEvent> events;
}
