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

import 'gesture_tester.dart';

class TestDrag extends Drag {
}

void main() {
  setUp(ensureGestureBinding);

  testGesture('Should recognize pan', (GestureTester tester) {
    final MultiTapGestureRecognizer tap = MultiTapGestureRecognizer(longTapDelay: kLongPressTimeout);

    final List<String> log = <String>[];

    tap.onTapDown = (int pointer, TapDownDetails details) { log.add('tap-down $pointer'); };
    tap.onTapUp = (int pointer, TapUpDetails details) { log.add('tap-up $pointer'); };
    tap.onTap = (int pointer) { log.add('tap $pointer'); };
    tap.onLongTapDown = (int pointer, TapDownDetails details) { log.add('long-tap-down $pointer'); };
    tap.onTapCancel = (int pointer) { log.add('tap-cancel $pointer'); };


    final TestPointer pointer5 = TestPointer(5);
    final PointerDownEvent down5 = pointer5.down(const Offset(10.0, 10.0));
    tap.addPointer(down5);
    tester.closeArena(5);
    expect(log, <String>['tap-down 5']);
    log.clear();
    tester.route(down5);
    expect(log, isEmpty);

    final TestPointer pointer6 = TestPointer(6);
    final PointerDownEvent down6 = pointer6.down(const Offset(15.0, 15.0));
    tap.addPointer(down6);
    tester.closeArena(6);
    expect(log, <String>['tap-down 6']);
    log.clear();
    tester.route(down6);
    expect(log, isEmpty);

    tester.route(pointer5.move(const Offset(11.0, 12.0)));
    expect(log, isEmpty);

    tester.route(pointer6.move(const Offset(14.0, 13.0)));
    expect(log, isEmpty);

    tester.route(pointer5.up());
    expect(log, <String>[
      'tap-up 5',
      'tap 5',
    ]);
    log.clear();

    tester.async.elapse(kLongPressTimeout + kPressTimeout);
    expect(log, <String>['long-tap-down 6']);
    log.clear();

    tester.route(pointer6.move(const Offset(40.0, 30.0))); // move more than kTouchSlop from 15.0,15.0
    expect(log, <String>['tap-cancel 6']);
    log.clear();

    tester.route(pointer6.up());
    expect(log, isEmpty);

    tap.dispose();
  });

  testGesture('Can filter based on device kind', (GestureTester tester) {
    final MultiTapGestureRecognizer tap =
        MultiTapGestureRecognizer(
          longTapDelay: kLongPressTimeout,
          kind: PointerDeviceKind.touch,
        );

    final List<String> log = <String>[];

    tap.onTapDown = (int pointer, TapDownDetails details) { log.add('tap-down $pointer'); };
    tap.onTapUp = (int pointer, TapUpDetails details) { log.add('tap-up $pointer'); };
    tap.onTap = (int pointer) { log.add('tap $pointer'); };
    tap.onLongTapDown = (int pointer, TapDownDetails details) { log.add('long-tap-down $pointer'); };
    tap.onTapCancel = (int pointer) { log.add('tap-cancel $pointer'); };


    final TestPointer touchPointer5 = TestPointer(5);
    final PointerDownEvent down5 = touchPointer5.down(const Offset(10.0, 10.0));
    tap.addPointer(down5);
    tester.closeArena(5);
    expect(log, <String>['tap-down 5']);
    log.clear();
    tester.route(down5);
    expect(log, isEmpty);

    final TestPointer mousePointer6 = TestPointer(6, PointerDeviceKind.mouse);
    final PointerDownEvent down6 = mousePointer6.down(const Offset(20.0, 20.0));
    tap.addPointer(down6);
    tester.closeArena(6);
    // Mouse down should be ignored by the recognizer.
    expect(log, isEmpty);

    final TestPointer touchPointer7 = TestPointer(7);
    final PointerDownEvent down7 = touchPointer7.down(const Offset(15.0, 15.0));
    tap.addPointer(down7);
    tester.closeArena(7);
    expect(log, <String>['tap-down 7']);
    log.clear();
    tester.route(down7);
    expect(log, isEmpty);

    tester.route(touchPointer5.move(const Offset(11.0, 12.0)));
    expect(log, isEmpty);

    // Move within the [kTouchSlop] range.
    tester.route(mousePointer6.move(const Offset(21.0, 18.0)));
    // Move beyond the slop range.
    tester.route(mousePointer6.move(const Offset(50.0, 40.0)));
    // Neither triggers any event because they originate from a mouse.
    expect(log, isEmpty);

    tester.route(touchPointer7.move(const Offset(14.0, 13.0)));
    expect(log, isEmpty);

    tester.route(touchPointer5.up());
    expect(log, <String>[
      'tap-up 5',
      'tap 5',
    ]);
    log.clear();

    // Mouse up should be ignored.
    tester.route(mousePointer6.up());
    expect(log, isEmpty);

    tester.async.elapse(kLongPressTimeout + kPressTimeout);
    // Only the touch pointer (7) triggers a long-tap, not the mouse pointer (6).
    expect(log, <String>['long-tap-down 7']);
    log.clear();

    tester.route(touchPointer7.move(const Offset(40.0, 30.0))); // move more than kTouchSlop from 15.0,15.0
    expect(log, <String>['tap-cancel 7']);
    log.clear();

    tap.dispose();
  });

  testWidgets('DoubleTapGestureRecognizer asserts when kind and supportedDevices are both set', (WidgetTester tester) async {
    expect(
      () {
        DoubleTapGestureRecognizer(
            kind: PointerDeviceKind.touch,
            supportedDevices: <PointerDeviceKind>{ PointerDeviceKind.touch },
        );
      },
      throwsA(
        isA<AssertionError>().having((AssertionError error) => error.toString(),
        'description', contains('kind == null || supportedDevices == null')),
      ),
    );
  });

  testWidgets('MultiTapGestureRecognizer asserts when kind and supportedDevices are both set', (WidgetTester tester) async {
    expect(
      () {
        MultiTapGestureRecognizer(
            kind: PointerDeviceKind.touch,
            supportedDevices: <PointerDeviceKind>{ PointerDeviceKind.touch },
        );
      },
      throwsA(
        isA<AssertionError>().having((AssertionError error) => error.toString(),
        'description', contains('kind == null || supportedDevices == null')),
      ),
    );
  });
}
