// 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.

// @dart = 2.8

import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

import 'gesture_tester.dart';

void main() {
  setUp(ensureGestureBinding);

  testGesture('A force press can be recognized', (GestureTester tester) {

    // Device specific constants that represent those from the iPhone X
    const double pressureMin = 0;
    const double pressureMax = 6.66;

    // Interpolated Flutter pressure values.
    const double startPressure = 0.4; // = Device pressure of 2.66.
    const double peakPressure = 0.85; // = Device pressure of 5.66.

    int started = 0;
    int peaked = 0;
    int updated = 0;
    int ended = 0;

    Offset startGlobalPosition;

    void onStart(ForcePressDetails details) {
      startGlobalPosition = details.globalPosition;
      started += 1;
    }

    final ForcePressGestureRecognizer force = ForcePressGestureRecognizer(startPressure: startPressure, peakPressure: peakPressure);

    force.onStart = onStart;
    force.onPeak = (ForcePressDetails details) => peaked += 1;
    force.onUpdate = (ForcePressDetails details) => updated += 1;
    force.onEnd = (ForcePressDetails details) => ended += 1;

    const int pointerValue = 1;
    final TestPointer pointer = TestPointer(pointerValue);
    const PointerDownEvent down = PointerDownEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 0, pressureMin: pressureMin, pressureMax: pressureMax);
    pointer.setDownInfo(down, const Offset(10.0, 10.0));
    force.addPointer(down);
    tester.closeArena(pointerValue);

    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);

    // Pressure fed into the test environment simulates the values received directly from the device.
    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 2.5, pressureMin: pressureMin, pressureMax: pressureMax));

    // We have not hit the start pressure, so no events should be true.
    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);

    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 2.8, pressureMin: pressureMin, pressureMax: pressureMax));

    // We have just hit the start pressure so just the start event should be triggered and one update call should have occurred.
    expect(started, 1);
    expect(peaked, 0);
    expect(updated, 1);
    expect(ended, 0);

    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 3.3, pressureMin: pressureMin, pressureMax: pressureMax));
    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 4.0, pressureMin: pressureMin, pressureMax: pressureMax));
    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 5.0, pressureMin: pressureMin, pressureMax: pressureMax));
    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 1.0, pressureMin: pressureMin, pressureMax: pressureMax));

    // We have exceeded the start pressure so update should be greater than 0.
    expect(started, 1);
    expect(updated, 5);
    expect(peaked, 0);
    expect(ended, 0);
    expect(startGlobalPosition, const Offset(10.0, 10.0));

    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 6.0, pressureMin: pressureMin, pressureMax: pressureMax));

    // We have exceeded the peak pressure so peak pressure should be true.
    expect(started, 1);
    expect(updated, 6);
    expect(peaked, 1);
    expect(ended, 0);

    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 3.3, pressureMin: pressureMin, pressureMax: pressureMax));
    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 4.0, pressureMin: pressureMin, pressureMax: pressureMax));
    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 5.0, pressureMin: pressureMin, pressureMax: pressureMax));
    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 1.0, pressureMin: pressureMin, pressureMax: pressureMax));

    // Update is still called.
    expect(started, 1);
    expect(updated, 10);
    expect(peaked, 1);
    expect(ended, 0);

    tester.route(pointer.up());

    // We have ended the gesture so ended should be true.
    expect(started, 1);
    expect(updated, 10);
    expect(peaked, 1);
    expect(ended, 1);
  });

  testGesture('Invalid pressure ranges capabilities are not recognized', (GestureTester tester) {
    void testGestureWithMaxPressure(double pressureMax) {
      int started = 0;
      int peaked = 0;
      int updated = 0;
      int ended = 0;

      final ForcePressGestureRecognizer force = ForcePressGestureRecognizer();

      force.onStart = (ForcePressDetails details) => started += 1;
      force.onPeak = (ForcePressDetails details) => peaked += 1;
      force.onUpdate = (ForcePressDetails details) => updated += 1;
      force.onEnd = (ForcePressDetails details) => ended += 1;

      const int pointerValue = 1;
      final TestPointer pointer = TestPointer(pointerValue);
      final PointerDownEvent down = PointerDownEvent(pointer: pointerValue, position: const Offset(10.0, 10.0), pressure: 0, pressureMin: 0, pressureMax: pressureMax);
      pointer.setDownInfo(down, const Offset(10.0, 10.0));
      force.addPointer(down);
      tester.closeArena(pointerValue);

      expect(started, 0);
      expect(peaked, 0);
      expect(updated, 0);
      expect(ended, 0);

      // Pressure fed into the test environment simulates the values received directly from the device.
      tester.route(PointerMoveEvent(pointer: pointerValue, position: const Offset(10.0, 10.0), pressure: 10, pressureMin: 0, pressureMax: pressureMax));

      // Regardless of current pressure, this recognizer shouldn't participate or
      // trigger any callbacks.
      expect(started, 0);
      expect(peaked, 0);
      expect(updated, 0);
      expect(ended, 0);

      tester.route(pointer.up());

      // There should still be no callbacks.
      expect(started, 0);
      expect(updated, 0);
      expect(peaked, 0);
      expect(ended, 0);
    }

    testGestureWithMaxPressure(0);
    testGestureWithMaxPressure(1);
    testGestureWithMaxPressure(-1);
    testGestureWithMaxPressure(0.5);
  });

  testGesture('If minimum pressure is not reached, start and end callbacks are not called', (GestureTester tester) {
    // Device specific constants that represent those from the iPhone X
    const double pressureMin = 0;
    const double pressureMax = 6.66;

    // Interpolated Flutter pressure values.
    const double startPressure = 0.4; // = Device pressure of 2.66.
    const double peakPressure = 0.85; // = Device pressure of 5.66.

    int started = 0;
    int peaked = 0;
    int updated = 0;
    int ended = 0;

    final ForcePressGestureRecognizer force = ForcePressGestureRecognizer(startPressure: startPressure, peakPressure: peakPressure);

    force.onStart = (_) => started += 1;
    force.onPeak = (_) => peaked += 1;
    force.onUpdate = (_) => updated += 1;
    force.onEnd = (_) => ended += 1;

    const int pointerValue = 1;
    final TestPointer pointer = TestPointer(pointerValue);
    const PointerDownEvent down = PointerDownEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 0, pressureMin: pressureMin, pressureMax: pressureMax);
    pointer.setDownInfo(down, const Offset(10.0, 10.0));
    force.addPointer(down);
    tester.closeArena(1);

    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);

    // Pressure fed into the test environment simulates the values received directly from the device.
    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 2.5, pressureMin: pressureMin, pressureMax: pressureMax));

    // We have not hit the start pressure, so no events should be true.
    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);

    tester.route(pointer.up());

    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);
  });

  testGesture('Should recognize drag and not force touch if there is a drag recognizer', (GestureTester tester) {
    final PanGestureRecognizer drag = PanGestureRecognizer();

    // Device specific constants that represent those from the iPhone X
    const double pressureMin = 0;
    const double pressureMax = 6.66;

    // Interpolated Flutter pressure values.
    const double startPressure = 0.4; // = Device pressure of 2.66.
    const double peakPressure = 0.85; // = Device pressure of 5.66.

    int started = 0;
    int peaked = 0;
    int updated = 0;
    int ended = 0;

    final ForcePressGestureRecognizer force = ForcePressGestureRecognizer(startPressure: startPressure, peakPressure: peakPressure);

    force.onStart = (_) => started += 1;
    force.onPeak = (_) => peaked += 1;
    force.onUpdate = (_) => updated += 1;
    force.onEnd = (_) => ended += 1;

    int didStartPan = 0;
    drag.onStart = (_) => didStartPan += 1;

    const int pointerValue = 1;
    final TestPointer pointer = TestPointer(pointerValue);
    const PointerDownEvent down = PointerDownEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 1.0, pressureMin: pressureMin, pressureMax: pressureMax);
    pointer.setDownInfo(down, const Offset(10.0, 10.0));
    force.addPointer(down);
    drag.addPointer(down);
    tester.closeArena(1);

    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);
    expect(didStartPan, 0);

    tester.route(pointer.move(const Offset(30.0, 30.0))); // moved 20 horizontally and 20 vertically which is 28 total

    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);
    expect(didStartPan, 1);

    // Pressure fed into the test environment simulates the values received directly from the device.
    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 2.5, pressureMin: pressureMin, pressureMax: pressureMax));

    // We have not hit the start pressure, so no events should be true.
    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);
    expect(didStartPan, 1);

    // We don't expect any events from the force press recognizer.
    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 4.0, pressureMin: pressureMin, pressureMax: pressureMax));

    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);
    expect(didStartPan, 1);

    tester.route(pointer.up());

    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);
    expect(didStartPan, 1);
  });

  testGesture('Should not call ended on pointer up if the gesture was never accepted', (GestureTester tester) {
    final PanGestureRecognizer drag = PanGestureRecognizer();

    // Interpolated Flutter pressure values.
    const double startPressure = 0.4; // = Device pressure of 2.66.
    const double peakPressure = 0.85; // = Device pressure of 5.66.

    // Device specific constants that represent those from the iPhone X
    const double pressureMin = 0;
    const double pressureMax = 6.66;

    int started = 0;
    int peaked = 0;
    int updated = 0;
    int ended = 0;

    final ForcePressGestureRecognizer force = ForcePressGestureRecognizer(startPressure: startPressure, peakPressure: peakPressure);

    force.onStart = (_) => started += 1;
    force.onPeak = (_) => peaked += 1;
    force.onUpdate = (_) => updated += 1;
    force.onEnd = (_) => ended += 1;

    int didStartPan = 0;
    drag.onStart = (_) => didStartPan += 1;

    const int pointerValue = 1;
    final TestPointer pointer = TestPointer(pointerValue);
    const PointerDownEvent down = PointerDownEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 1.0, pressureMin: pressureMin, pressureMax: pressureMax);
    pointer.setDownInfo(down, const Offset(10.0, 10.0));
    force.addPointer(down);
    drag.addPointer(down);
    tester.closeArena(1);

    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);
    expect(didStartPan, 0);

    tester.route(pointer.up());

    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);
    expect(didStartPan, 0);
  });

  testGesture('Should call start only once if there is a competing gesture recognizer', (GestureTester tester) {
    final PanGestureRecognizer drag = PanGestureRecognizer();

    // Interpolated Flutter pressure values.
    const double startPressure = 0.4; // = Device pressure of 2.66.
    const double peakPressure = 0.85; // = Device pressure of 5.66.

    // Device specific constants that represent those from the iPhone X
    const double pressureMin = 0;
    const double pressureMax = 6.66;

    int started = 0;
    int peaked = 0;
    int updated = 0;
    int ended = 0;

    final ForcePressGestureRecognizer force = ForcePressGestureRecognizer(startPressure: startPressure, peakPressure: peakPressure);

    force.onStart = (_) => started += 1;
    force.onPeak = (_) => peaked += 1;
    force.onUpdate = (_) => updated += 1;
    force.onEnd = (_) => ended += 1;

    int didStartPan = 0;
    drag.onStart = (_) => didStartPan += 1;

    const int pointerValue = 1;
    final TestPointer pointer = TestPointer(pointerValue);
    const PointerDownEvent down = PointerDownEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 1.0, pressureMin: pressureMin, pressureMax: pressureMax);
    pointer.setDownInfo(down, const Offset(10.0, 10.0));
    force.addPointer(down);
    drag.addPointer(down);
    tester.closeArena(1);

    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);
    expect(didStartPan, 0);

    // Pressure fed into the test environment simulates the values received directly from the device.
    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 3.0, pressureMin: pressureMin, pressureMax: pressureMax));

    // We have not hit the start pressure, so no events should be true.
    expect(started, 1);
    expect(peaked, 0);
    expect(updated, 1);
    expect(ended, 0);
    expect(didStartPan, 0);

    tester.route(pointer.up());

    expect(started, 1);
    expect(peaked, 0);
    expect(updated, 1);
    expect(ended, 1);
    expect(didStartPan, 0);
  });

  testGesture('A force press can be recognized with a custom interpolation function', (GestureTester tester) {

    // Device specific constants that represent those from the iPhone X
    const double pressureMin = 0;
    const double pressureMax = 6.66;

    // Interpolated Flutter pressure values.
    const double startPressure = 0.4; // = Device pressure of 2.66.
    const double peakPressure = 0.85; // = Device pressure of 5.66.

    int started = 0;
    int peaked = 0;
    int updated = 0;
    int ended = 0;

    Offset startGlobalPosition;

    void onStart(ForcePressDetails details) {
      startGlobalPosition = details.globalPosition;
      started += 1;
    }

    double interpolateWithEasing(double min, double max, double t) {
      final double lerp = (t - min) / (max - min);
      return Curves.easeIn.transform(lerp);
    }

    final ForcePressGestureRecognizer force = ForcePressGestureRecognizer(startPressure: startPressure, peakPressure: peakPressure, interpolation: interpolateWithEasing);

    force.onStart = onStart;
    force.onPeak = (ForcePressDetails details) => peaked += 1;
    force.onUpdate = (ForcePressDetails details) => updated += 1;
    force.onEnd = (ForcePressDetails details) => ended += 1;

    const int pointerValue = 1;
    final TestPointer pointer = TestPointer(pointerValue);
    const PointerDownEvent down = PointerDownEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 0, pressureMin: pressureMin, pressureMax: pressureMax);
    pointer.setDownInfo(down, const Offset(10.0, 10.0));
    force.addPointer(down);
    tester.closeArena(pointerValue);

    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);

    // Pressure fed into the test environment simulates the values received directly from the device.
    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 2.5, pressureMin: pressureMin, pressureMax: pressureMax));

    // We have not hit the start pressure, so no events should be true.
    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);

    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 2.8, pressureMin: pressureMin, pressureMax: pressureMax));

    // We have just hit the start pressure so just the start event should be triggered and one update call should have occurred.
    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);

    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 3.3, pressureMin: pressureMin, pressureMax: pressureMax));
    expect(started, 0);

    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 4.0, pressureMin: pressureMin, pressureMax: pressureMax));
    expect(started, 1);

    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 5.0, pressureMin: pressureMin, pressureMax: pressureMax));
    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 1.0, pressureMin: pressureMin, pressureMax: pressureMax));

    // We have exceeded the start pressure so update should be greater than 0.
    expect(started, 1);
    expect(updated, 3);
    expect(peaked, 0);
    expect(ended, 0);
    expect(startGlobalPosition, const Offset(10.0, 10.0));

    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 6.0, pressureMin: pressureMin, pressureMax: pressureMax));

    // We have exceeded the peak pressure so peak pressure should be true.
    expect(started, 1);
    expect(updated, 4);
    expect(peaked, 0);
    expect(ended, 0);

    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 3.3, pressureMin: pressureMin, pressureMax: pressureMax));
    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 4.0, pressureMin: pressureMin, pressureMax: pressureMax));
    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 6.5, pressureMin: pressureMin, pressureMax: pressureMax));
    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 1.0, pressureMin: pressureMin, pressureMax: pressureMax));

    // Update is still called.
    expect(started, 1);
    expect(updated, 8);
    expect(peaked, 1);
    expect(ended, 0);

    tester.route(pointer.up());

    // We have ended the gesture so ended should be true.
    expect(started, 1);
    expect(updated, 8);
    expect(peaked, 1);
    expect(ended, 1);
  });

  testGesture('A pressure outside of the device reported min and max pressure will not give an error', (GestureTester tester) {
    // Device specific constants that represent those from the iPhone X
    const double pressureMin = 0;
    const double pressureMax = 6.66;

    // Interpolated Flutter pressure values.
    const double startPressure = 0.4; // = Device pressure of 2.66.
    const double peakPressure = 0.85; // = Device pressure of 5.66.

    int started = 0;
    int peaked = 0;
    int updated = 0;
    int ended = 0;

    final ForcePressGestureRecognizer force = ForcePressGestureRecognizer(startPressure: startPressure, peakPressure: peakPressure);

    force.onStart = (_) => started += 1;
    force.onPeak = (_) => peaked += 1;
    force.onUpdate = (_) => updated += 1;
    force.onEnd = (_) => ended += 1;

    const int pointerValue = 1;
    final TestPointer pointer = TestPointer(pointerValue);
    const PointerDownEvent down = PointerDownEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 0, pressureMin: pressureMin, pressureMax: pressureMax);
    pointer.setDownInfo(down, const Offset(10.0, 10.0));
    force.addPointer(down);
    tester.closeArena(1);

    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);

    // Pressure fed into the test environment simulates the values received directly from the device.
    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 2.5, pressureMin: pressureMin, pressureMax: pressureMax));

    // We have not hit the start pressure, so no events should be true.
    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);

    // If the case where the pressure is greater than the max pressure were not handled correctly, this move event would throw an error.
    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 8.0, pressureMin: pressureMin, pressureMax: pressureMax));
    tester.route(pointer.up());

    expect(started, 1);
    expect(peaked, 1);
    expect(updated, 1);
    expect(ended, 1);
  });

  testGesture('A pressure of NAN will not give an error', (GestureTester tester) {
    // Device specific constants that represent those from the iPhone X
    const double pressureMin = 0;
    const double pressureMax = 6.66;

    // Interpolated Flutter pressure values.
    const double startPressure = 0.4; // = Device pressure of 2.66.
    const double peakPressure = 0.85; // = Device pressure of 5.66.

    int started = 0;
    int peaked = 0;
    int updated = 0;
    int ended = 0;

    final ForcePressGestureRecognizer force = ForcePressGestureRecognizer(startPressure: startPressure, peakPressure: peakPressure);

    force.onStart = (_) => started += 1;
    force.onPeak = (_) => peaked += 1;
    force.onUpdate = (_) => updated += 1;
    force.onEnd = (_) => ended += 1;

    const int pointerValue = 1;
    final TestPointer pointer = TestPointer(pointerValue);
    const PointerDownEvent down = PointerDownEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 0, pressureMin: pressureMin, pressureMax: pressureMax);
    pointer.setDownInfo(down, const Offset(10.0, 10.0));
    force.addPointer(down);
    tester.closeArena(1);

    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);

    // Pressure fed into the test environment simulates the values received directly from the device.
    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 2.5, pressureMin: pressureMin, pressureMax: pressureMax));

    // We have not hit the start pressure, so no events should be true.
    expect(started, 0);
    expect(peaked, 0);
    expect(updated, 0);
    expect(ended, 0);

    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 6.0, pressureMin: pressureMin, pressureMax: pressureMax));
    expect(peaked, 1);

    tester.route(const PointerMoveEvent(pointer: pointerValue, position: Offset(10.0, 10.0), pressure: 0.0 / 0.0, pressureMin: pressureMin, pressureMax: pressureMax));
    tester.route(pointer.up());

    expect(started, 1);
    expect(peaked, 1);
    expect(updated, 1);
    expect(ended, 1);
  });
}
