// 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 'package:flutter_test/flutter_test.dart';

import 'gesture_tester.dart';

// Anything longer than [kDoubleTapTimeout] will reset the serial tap count.
final Duration kSerialTapDelay = kDoubleTapTimeout ~/ 2;

void main() {
  setUp(ensureGestureBinding);

  late List<String> events;
  late SerialTapGestureRecognizer serial;

  setUp(() {
    events = <String>[];
    serial = SerialTapGestureRecognizer()
      ..onSerialTapDown = (SerialTapDownDetails details) {
        events.add('down#${details.count}');
      }
      ..onSerialTapCancel = (SerialTapCancelDetails details) {
        events.add('cancel#${details.count}');
      }
      ..onSerialTapUp = (SerialTapUpDetails details) {
        events.add('up#${details.count}');
      };
  });

  // Down/up pair 1: normal tap sequence
  const PointerDownEvent down1 = PointerDownEvent(
    pointer: 1,
    position: Offset(10.0, 10.0),
  );

  const PointerCancelEvent cancel1 = PointerCancelEvent(
    pointer: 1,
  );

  const PointerUpEvent up1 = PointerUpEvent(
    pointer: 1,
    position: Offset(11.0, 9.0),
  );

  // Down/up pair 2: normal tap sequence close to pair 1
  const PointerDownEvent down2 = PointerDownEvent(
    pointer: 2,
    position: Offset(12.0, 12.0),
  );

  const PointerUpEvent up2 = PointerUpEvent(
    pointer: 2,
    position: Offset(13.0, 11.0),
  );

  // Down/up pair 3: normal tap sequence close to pair 1
  const PointerDownEvent down3 = PointerDownEvent(
    pointer: 3,
    position: Offset(12.0, 12.0),
  );

  const PointerUpEvent up3 = PointerUpEvent(
    pointer: 3,
    position: Offset(13.0, 11.0),
  );

  // Down/up pair 4: normal tap sequence far away from pair 1
  const PointerDownEvent down4 = PointerDownEvent(
    pointer: 4,
    position: Offset(130.0, 130.0),
  );

  const PointerUpEvent up4 = PointerUpEvent(
    pointer: 4,
    position: Offset(131.0, 129.0),
  );

  // Down/move/up sequence 5: intervening motion
  const PointerDownEvent down5 = PointerDownEvent(
    pointer: 5,
    position: Offset(10.0, 10.0),
  );

  const PointerMoveEvent move5 = PointerMoveEvent(
    pointer: 5,
    position: Offset(25.0, 25.0),
  );

  const PointerUpEvent up5 = PointerUpEvent(
    pointer: 5,
    position: Offset(25.0, 25.0),
  );

  // Down/up pair 7: normal tap sequence close to pair 1 but on secondary button
  const PointerDownEvent down6 = PointerDownEvent(
    pointer: 6,
    position: Offset(10.0, 10.0),
    buttons: kSecondaryMouseButton,
  );

  const PointerUpEvent up6 = PointerUpEvent(
    pointer: 6,
    position: Offset(11.0, 9.0),
  );

  testGesture('Recognizes serial taps', (GestureTester tester) {
    serial.addPointer(down1);
    tester.closeArena(1);
    tester.route(down1);
    tester.route(up1);
    GestureBinding.instance!.gestureArena.sweep(1);
    expect(events, <String>['down#1', 'up#1']);

    events.clear();
    tester.async.elapse(kSerialTapDelay);
    serial.addPointer(down2);
    tester.closeArena(2);
    tester.route(down2);
    tester.route(up2);
    GestureBinding.instance!.gestureArena.sweep(2);
    expect(events, <String>['down#2', 'up#2']);

    events.clear();
    tester.async.elapse(kSerialTapDelay);
    serial.addPointer(down3);
    tester.closeArena(3);
    tester.route(down3);
    tester.route(up3);
    GestureBinding.instance!.gestureArena.sweep(3);
    expect(events, <String>['down#3', 'up#3']);
  });

  // Because tap gesture will hold off on declaring victory.
  testGesture('Wins over tap gesture below it in the tree', (GestureTester tester) {
    bool recognizedSingleTap = false;
    bool canceledSingleTap = false;
    final TapGestureRecognizer singleTap = TapGestureRecognizer()
      ..onTap = () {
        recognizedSingleTap = true;
      }
      ..onTapCancel = () {
        canceledSingleTap = true;
      };

    singleTap.addPointer(down1);
    serial.addPointer(down1);
    tester.closeArena(1);
    tester.route(down1);
    tester.async.elapse(kPressTimeout); // To register the possible single tap.
    tester.route(up1);
    GestureBinding.instance!.gestureArena.sweep(1);
    expect(events, <String>['down#1', 'up#1']);
    expect(recognizedSingleTap, isFalse);
    expect(canceledSingleTap, isTrue);
  });

  testGesture('Wins over tap gesture above it in the tree', (GestureTester tester) {
    bool recognizedSingleTap = false;
    bool canceledSingleTap = false;
    final TapGestureRecognizer singleTap = TapGestureRecognizer()
      ..onTap = () {
        recognizedSingleTap = true;
      }
      ..onTapCancel = () {
        canceledSingleTap = true;
      };

    serial.addPointer(down1);
    singleTap.addPointer(down1);
    tester.closeArena(1);
    tester.route(down1);
    tester.async.elapse(kPressTimeout); // To register the possible single tap.
    tester.route(up1);
    GestureBinding.instance!.gestureArena.sweep(1);
    expect(events, <String>['down#1', 'up#1']);
    expect(recognizedSingleTap, isFalse);
    expect(canceledSingleTap, isTrue);
  });

  testGesture('Loses to release gesture below it in the tree', (GestureTester tester) {
    bool recognizedRelease = false;
    final ReleaseGestureRecognizer release = ReleaseGestureRecognizer()
      ..onRelease = () {
        recognizedRelease = true;
      };

    release.addPointer(down1);
    serial.addPointer(down1);
    tester.closeArena(1);
    tester.route(down1);
    tester.route(up1);
    GestureBinding.instance!.gestureArena.sweep(1);
    expect(events, <String>['down#1', 'cancel#1']);
    expect(recognizedRelease, isTrue);
  });

  testGesture('Wins over release gesture above it in the tree', (GestureTester tester) {
    bool recognizedRelease = false;
    final ReleaseGestureRecognizer release = ReleaseGestureRecognizer()
      ..onRelease = () {
        recognizedRelease = true;
      };

    serial.addPointer(down1);
    release.addPointer(down1);
    tester.closeArena(1);
    tester.route(down1);
    tester.route(up1);
    GestureBinding.instance!.gestureArena.sweep(1);
    expect(events, <String>['down#1', 'up#1']);
    expect(recognizedRelease, isFalse);
  });

  testGesture('Fires cancel if competing recognizer declares victory', (GestureTester tester) {
    final WinningGestureRecognizer winner = WinningGestureRecognizer();
    winner.addPointer(down1);
    serial.addPointer(down1);
    tester.closeArena(1);
    tester.route(down1);
    tester.route(up1);
    GestureBinding.instance!.gestureArena.sweep(1);
    expect(events, <String>['down#1', 'cancel#1']);
  });

  testGesture('Wins over double-tap recognizer below it in the tree', (GestureTester tester) {
    bool recognizedDoubleTap = false;
    final DoubleTapGestureRecognizer doubleTap = DoubleTapGestureRecognizer()
      ..onDoubleTap = () {
        recognizedDoubleTap = true;
      };

    doubleTap.addPointer(down1);
    serial.addPointer(down1);
    tester.closeArena(1);
    tester.route(down1);
    tester.route(up1);
    GestureBinding.instance!.gestureArena.sweep(1);
    expect(events, <String>['down#1', 'up#1']);
    expect(recognizedDoubleTap, isFalse);

    events.clear();
    tester.async.elapse(kSerialTapDelay);
    doubleTap.addPointer(down2);
    serial.addPointer(down2);
    tester.closeArena(2);
    tester.route(down2);
    tester.route(up2);
    GestureBinding.instance!.gestureArena.sweep(2);
    expect(events, <String>['down#2', 'up#2']);
    expect(recognizedDoubleTap, isFalse);

    events.clear();
    tester.async.elapse(kSerialTapDelay);
    serial.addPointer(down3);
    tester.closeArena(3);
    tester.route(down3);
    tester.route(up3);
    GestureBinding.instance!.gestureArena.sweep(3);
    expect(events, <String>['down#3', 'up#3']);
  });

  testGesture('Wins over double-tap recognizer above it in the tree', (GestureTester tester) {
    bool recognizedDoubleTap = false;
    final DoubleTapGestureRecognizer doubleTap = DoubleTapGestureRecognizer()
      ..onDoubleTap = () {
        recognizedDoubleTap = true;
      };

    serial.addPointer(down1);
    doubleTap.addPointer(down1);
    tester.closeArena(1);
    tester.route(down1);
    tester.route(up1);
    GestureBinding.instance!.gestureArena.sweep(1);
    expect(events, <String>['down#1', 'up#1']);
    expect(recognizedDoubleTap, isFalse);

    events.clear();
    tester.async.elapse(kSerialTapDelay);
    serial.addPointer(down2);
    doubleTap.addPointer(down2);
    tester.closeArena(2);
    tester.route(down2);
    tester.route(up2);
    GestureBinding.instance!.gestureArena.sweep(2);
    expect(events, <String>['down#2', 'up#2']);
    expect(recognizedDoubleTap, isFalse);

    events.clear();
    tester.async.elapse(kSerialTapDelay);
    serial.addPointer(down3);
    doubleTap.addPointer(down3);
    tester.closeArena(3);
    tester.route(down3);
    tester.route(up3);
    GestureBinding.instance!.gestureArena.sweep(3);
    expect(events, <String>['down#3', 'up#3']);
  });

  testGesture('Fires cancel and resets for PointerCancelEvent', (GestureTester tester) {
    serial.addPointer(down1);
    tester.closeArena(1);
    tester.route(down1);
    tester.route(cancel1);
    GestureBinding.instance!.gestureArena.sweep(1);
    expect(events, <String>['down#1', 'cancel#1']);

    events.clear();
    tester.async.elapse(const Duration(milliseconds: 100));
    serial.addPointer(down2);
    tester.closeArena(2);
    tester.route(down2);
    tester.route(up2);
    GestureBinding.instance!.gestureArena.sweep(2);
    expect(events, <String>['down#1', 'up#1']);
  });

  testGesture('Fires cancel and resets when pointer dragged past slop tolerance', (GestureTester tester) {
    serial.addPointer(down5);
    tester.closeArena(5);
    tester.route(down5);
    tester.route(move5);
    tester.route(up5);
    GestureBinding.instance!.gestureArena.sweep(5);
    expect(events, <String>['down#1', 'cancel#1']);

    events.clear();
    tester.async.elapse(const Duration(milliseconds: 1000));
    serial.addPointer(down1);
    tester.closeArena(1);
    tester.route(down1);
    tester.route(up1);
    GestureBinding.instance!.gestureArena.sweep(1);
    expect(events, <String>['down#1', 'up#1']);
  });

  testGesture('Resets if times out in between taps', (GestureTester tester) {
    serial.addPointer(down1);
    tester.closeArena(1);
    tester.route(down1);
    tester.route(up1);
    GestureBinding.instance!.gestureArena.sweep(1);
    expect(events, <String>['down#1', 'up#1']);

    events.clear();
    tester.async.elapse(const Duration(milliseconds: 1000));
    serial.addPointer(down2);
    tester.closeArena(2);
    tester.route(down2);
    tester.route(up2);
    GestureBinding.instance!.gestureArena.sweep(2);
    expect(events, <String>['down#1', 'up#1']);
  });

  testGesture('Resets if taps are far apart', (GestureTester tester) {
    serial.addPointer(down1);
    tester.closeArena(1);
    tester.route(down1);
    tester.route(up1);
    GestureBinding.instance!.gestureArena.sweep(1);
    expect(events, <String>['down#1', 'up#1']);

    events.clear();
    tester.async.elapse(const Duration(milliseconds: 100));
    serial.addPointer(down4);
    tester.closeArena(4);
    tester.route(down4);
    tester.route(up4);
    GestureBinding.instance!.gestureArena.sweep(4);
    expect(events, <String>['down#1', 'up#1']);
  });

  testGesture('Serial taps with different buttons will start a new tap sequence', (GestureTester tester) {
    serial.addPointer(down1);
    tester.closeArena(1);
    tester.route(down1);
    tester.route(up1);
    GestureBinding.instance!.gestureArena.sweep(1);
    expect(events, <String>['down#1', 'up#1']);

    events.clear();
    tester.async.elapse(const Duration(milliseconds: 1000));
    serial.addPointer(down6);
    tester.closeArena(6);
    tester.route(down6);
    tester.route(up6);
    GestureBinding.instance!.gestureArena.sweep(6);
    expect(events, <String>['down#1', 'up#1']);
  });

  testGesture('Interleaving taps cancel first sequence and start second sequence', (GestureTester tester) {
    serial.addPointer(down1);
    tester.closeArena(1);
    tester.route(down1);

    serial.addPointer(down2);
    tester.closeArena(2);
    tester.route(down2);

    tester.route(up1);
    GestureBinding.instance!.gestureArena.sweep(1);
    tester.route(up2);
    GestureBinding.instance!.gestureArena.sweep(2);
    expect(events, <String>['down#1', 'cancel#1', 'down#1', 'up#1']);
  });

  testGesture('Is no-op if no callbacks are specified', (GestureTester tester) {
    serial = SerialTapGestureRecognizer();
    serial.addPointer(down1);
    tester.closeArena(1);
    tester.route(down1);
    expect(serial.isTrackingPointer, isFalse);
    tester.route(up1);
    GestureBinding.instance!.gestureArena.sweep(1);
    expect(events, <String>[]);
  });

  testGesture('Works for non-primary button', (GestureTester tester) {
    serial.addPointer(down6);
    tester.closeArena(6);
    tester.route(down6);
    tester.route(up6);
    GestureBinding.instance!.gestureArena.sweep(6);
    expect(events, <String>['down#1', 'up#1']);
  });
}

class WinningGestureRecognizer extends PrimaryPointerGestureRecognizer {
  @override
  String get debugDescription => 'winner';

  @override
  void handlePrimaryPointer(PointerEvent event) {
    resolve(GestureDisposition.accepted);
  }
}

class ReleaseGestureRecognizer extends PrimaryPointerGestureRecognizer {
  VoidCallback? onRelease;

  @override
  String get debugDescription => 'release';

  @override
  void handlePrimaryPointer(PointerEvent event) {
    if (event is PointerUpEvent) {
      resolve(GestureDisposition.accepted);
      if (onRelease != null) {
        onRelease!();
      }
    }
  }
}
