// Copyright 2019 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/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/gestures.dart';


// The tests in this file are moved from listener_test.dart, which tests several
// deprecated APIs. The file should be removed once these parameters are.

// ignore_for_file: deprecated_member_use_from_same_package
// We have to ignore the lint rule here because we need to use the deprecated
// callbacks in order to test them.

class HoverClient extends StatefulWidget {
  const HoverClient({Key key, this.onHover, this.child}) : super(key: key);

  final ValueChanged<bool> onHover;
  final Widget child;

  @override
  HoverClientState createState() => HoverClientState();
}

class HoverClientState extends State<HoverClient> {
  static int numEntries = 0;
  static int numExits = 0;

  void _onExit(PointerExitEvent details) {
    numExits++;
    if (widget.onHover != null) {
      widget.onHover(false);
    }
  }

  void _onEnter(PointerEnterEvent details) {
    numEntries++;
    if (widget.onHover != null) {
      widget.onHover(true);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Listener(
      onPointerEnter: _onEnter,
      onPointerExit: _onExit,
      child: widget.child,
    );
  }
}

class HoverFeedback extends StatefulWidget {
  const HoverFeedback({Key key}) : super(key: key);

  @override
  _HoverFeedbackState createState() => _HoverFeedbackState();
}

class _HoverFeedbackState extends State<HoverFeedback> {
  bool _hovering = false;

  @override
  Widget build(BuildContext context) {
    return Directionality(
      textDirection: TextDirection.ltr,
      child: HoverClient(
        onHover: (bool hovering) => setState(() => _hovering = hovering),
        child: Text(_hovering ? 'HOVERING' : 'not hovering'),
      ),
    );
  }
}

void main() {
  group('Listener hover detection', () {
    // TODO(tongmu): Remover this group of test after the deprecated callbacks
    // onPointer{Enter,Hover,Exit} are removed. They were kept for compatibility,
    // and the tests have been copied to mouse_region_test.
    // https://github.com/flutter/flutter/issues/36085
    setUp((){
      HoverClientState.numExits = 0;
      HoverClientState.numEntries = 0;
    });

    testWidgets('detects pointer enter', (WidgetTester tester) async {
      PointerEnterEvent enter;
      PointerHoverEvent move;
      PointerExitEvent exit;
      await tester.pumpWidget(Center(
        child: Listener(
          child: Container(
            color: const Color.fromARGB(0xff, 0xff, 0x00, 0x00),
            width: 100.0,
            height: 100.0,
          ),
          onPointerEnter: (PointerEnterEvent details) => enter = details,
          onPointerHover: (PointerHoverEvent details) => move = details,
          onPointerExit: (PointerExitEvent details) => exit = details,
        ),
      ));
      final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
      addTearDown(gesture.removePointer);
      await gesture.moveTo(const Offset(400.0, 300.0));
      await tester.pump();
      expect(move, isNotNull);
      expect(move.position, equals(const Offset(400.0, 300.0)));
      expect(enter, isNotNull);
      expect(enter.position, equals(const Offset(400.0, 300.0)));
      expect(exit, isNull);
    });
    testWidgets('detects pointer exiting', (WidgetTester tester) async {
      PointerEnterEvent enter;
      PointerHoverEvent move;
      PointerExitEvent exit;
      await tester.pumpWidget(Center(
        child: Listener(
          child: Container(
            width: 100.0,
            height: 100.0,
          ),
          onPointerEnter: (PointerEnterEvent details) => enter = details,
          onPointerHover: (PointerHoverEvent details) => move = details,
          onPointerExit: (PointerExitEvent details) => exit = details,
        ),
      ));
      final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
      addTearDown(gesture.removePointer);
      await gesture.moveTo(const Offset(400.0, 300.0));
      await tester.pump();
      move = null;
      enter = null;
      await gesture.moveTo(const Offset(1.0, 1.0));
      await tester.pump();
      expect(move, isNull);
      expect(enter, isNull);
      expect(exit, isNotNull);
      expect(exit.position, equals(const Offset(1.0, 1.0)));
    });
    testWidgets('detects pointer exit when widget disappears', (WidgetTester tester) async {
      PointerEnterEvent enter;
      PointerHoverEvent move;
      PointerExitEvent exit;
      await tester.pumpWidget(Center(
        child: Listener(
          child: Container(
            width: 100.0,
            height: 100.0,
          ),
          onPointerEnter: (PointerEnterEvent details) => enter = details,
          onPointerHover: (PointerHoverEvent details) => move = details,
          onPointerExit: (PointerExitEvent details) => exit = details,
        ),
      ));
      final RenderMouseRegion renderListener = tester.renderObject(find.byType(MouseRegion));
      final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
      addTearDown(gesture.removePointer);
      await gesture.moveTo(const Offset(400.0, 300.0));
      await tester.pump();
      expect(move, isNotNull);
      expect(move.position, equals(const Offset(400.0, 300.0)));
      expect(enter, isNotNull);
      expect(enter.position, equals(const Offset(400.0, 300.0)));
      expect(exit, isNull);
      await tester.pumpWidget(Center(
        child: Container(
          width: 100.0,
          height: 100.0,
        ),
      ));
      expect(exit, isNotNull);
      expect(exit.position, equals(const Offset(400.0, 300.0)));
      expect(tester.binding.mouseTracker.isAnnotationAttached(renderListener.hoverAnnotation), isFalse);
    });
    testWidgets('Hover works with nested listeners', (WidgetTester tester) async {
      final UniqueKey key1 = UniqueKey();
      final UniqueKey key2 = UniqueKey();
      final List<PointerEnterEvent> enter1 = <PointerEnterEvent>[];
      final List<PointerHoverEvent> move1 = <PointerHoverEvent>[];
      final List<PointerExitEvent> exit1 = <PointerExitEvent>[];
      final List<PointerEnterEvent> enter2 = <PointerEnterEvent>[];
      final List<PointerHoverEvent> move2 = <PointerHoverEvent>[];
      final List<PointerExitEvent> exit2 = <PointerExitEvent>[];
      void clearLists() {
        enter1.clear();
        move1.clear();
        exit1.clear();
        enter2.clear();
        move2.clear();
        exit2.clear();
      }

      await tester.pumpWidget(Container());
      final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
      addTearDown(gesture.removePointer);
      await gesture.moveTo(const Offset(400.0, 0.0));
      await tester.pump();
      await tester.pumpWidget(
        Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Listener(
              onPointerEnter: (PointerEnterEvent details) => enter1.add(details),
              onPointerHover: (PointerHoverEvent details) => move1.add(details),
              onPointerExit: (PointerExitEvent details) => exit1.add(details),
              key: key1,
              child: Container(
                width: 200,
                height: 200,
                padding: const EdgeInsets.all(50.0),
                child: Listener(
                  key: key2,
                  onPointerEnter: (PointerEnterEvent details) => enter2.add(details),
                  onPointerHover: (PointerHoverEvent details) => move2.add(details),
                  onPointerExit: (PointerExitEvent details) => exit2.add(details),
                  child: Container(),
                ),
              ),
            ),
          ],
        ),
      );
      final List<RenderObject> listeners = tester.renderObjectList(find.byType(MouseRegion)).toList();
      final RenderMouseRegion renderListener1 = listeners[0];
      final RenderMouseRegion renderListener2 = listeners[1];
      Offset center = tester.getCenter(find.byKey(key2));
      await gesture.moveTo(center);
      await tester.pump();
      expect(move2, isNotEmpty);
      expect(enter2, isNotEmpty);
      expect(exit2, isEmpty);
      expect(move1, isNotEmpty);
      expect(move1.last.position, equals(center));
      expect(enter1, isNotEmpty);
      expect(enter1.last.position, equals(center));
      expect(exit1, isEmpty);
      expect(tester.binding.mouseTracker.isAnnotationAttached(renderListener1.hoverAnnotation), isTrue);
      expect(tester.binding.mouseTracker.isAnnotationAttached(renderListener2.hoverAnnotation), isTrue);
      clearLists();

      // Now make sure that exiting the child only triggers the child exit, not
      // the parent too.
      center = center - const Offset(75.0, 0.0);
      await gesture.moveTo(center);
      await tester.pumpAndSettle();
      expect(move2, isEmpty);
      expect(enter2, isEmpty);
      expect(exit2, isNotEmpty);
      expect(move1, isNotEmpty);
      expect(move1.last.position, equals(center));
      expect(enter1, isEmpty);
      expect(exit1, isEmpty);
      expect(tester.binding.mouseTracker.isAnnotationAttached(renderListener1.hoverAnnotation), isTrue);
      expect(tester.binding.mouseTracker.isAnnotationAttached(renderListener2.hoverAnnotation), isTrue);
      clearLists();
    });
    testWidgets('Hover transfers between two listeners', (WidgetTester tester) async {
      final UniqueKey key1 = UniqueKey();
      final UniqueKey key2 = UniqueKey();
      final List<PointerEnterEvent> enter1 = <PointerEnterEvent>[];
      final List<PointerHoverEvent> move1 = <PointerHoverEvent>[];
      final List<PointerExitEvent> exit1 = <PointerExitEvent>[];
      final List<PointerEnterEvent> enter2 = <PointerEnterEvent>[];
      final List<PointerHoverEvent> move2 = <PointerHoverEvent>[];
      final List<PointerExitEvent> exit2 = <PointerExitEvent>[];
      void clearLists() {
        enter1.clear();
        move1.clear();
        exit1.clear();
        enter2.clear();
        move2.clear();
        exit2.clear();
      }

      await tester.pumpWidget(Container());
      final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
      addTearDown(gesture.removePointer);
      await gesture.moveTo(const Offset(400.0, 0.0));
      await tester.pump();
      await tester.pumpWidget(
        Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Listener(
              key: key1,
              child: Container(
                width: 100.0,
                height: 100.0,
              ),
              onPointerEnter: (PointerEnterEvent details) => enter1.add(details),
              onPointerHover: (PointerHoverEvent details) => move1.add(details),
              onPointerExit: (PointerExitEvent details) => exit1.add(details),
            ),
            Listener(
              key: key2,
              child: Container(
                width: 100.0,
                height: 100.0,
              ),
              onPointerEnter: (PointerEnterEvent details) => enter2.add(details),
              onPointerHover: (PointerHoverEvent details) => move2.add(details),
              onPointerExit: (PointerExitEvent details) => exit2.add(details),
            ),
          ],
        ),
      );
      final List<RenderObject> listeners = tester.renderObjectList(find.byType(MouseRegion)).toList();
      final RenderMouseRegion renderListener1 = listeners[0];
      final RenderMouseRegion renderListener2 = listeners[1];
      final Offset center1 = tester.getCenter(find.byKey(key1));
      final Offset center2 = tester.getCenter(find.byKey(key2));
      await gesture.moveTo(center1);
      await tester.pump();
      expect(move1, isNotEmpty);
      expect(move1.last.position, equals(center1));
      expect(enter1, isNotEmpty);
      expect(enter1.last.position, equals(center1));
      expect(exit1, isEmpty);
      expect(move2, isEmpty);
      expect(enter2, isEmpty);
      expect(exit2, isEmpty);
      expect(tester.binding.mouseTracker.isAnnotationAttached(renderListener1.hoverAnnotation), isTrue);
      expect(tester.binding.mouseTracker.isAnnotationAttached(renderListener2.hoverAnnotation), isTrue);
      clearLists();
      await gesture.moveTo(center2);
      await tester.pump();
      expect(move1, isEmpty);
      expect(enter1, isEmpty);
      expect(exit1, isNotEmpty);
      expect(exit1.last.position, equals(center2));
      expect(move2, isNotEmpty);
      expect(move2.last.position, equals(center2));
      expect(enter2, isNotEmpty);
      expect(enter2.last.position, equals(center2));
      expect(exit2, isEmpty);
      expect(tester.binding.mouseTracker.isAnnotationAttached(renderListener1.hoverAnnotation), isTrue);
      expect(tester.binding.mouseTracker.isAnnotationAttached(renderListener2.hoverAnnotation), isTrue);
      clearLists();
      await gesture.moveTo(const Offset(400.0, 450.0));
      await tester.pump();
      expect(move1, isEmpty);
      expect(enter1, isEmpty);
      expect(exit1, isEmpty);
      expect(move2, isEmpty);
      expect(enter2, isEmpty);
      expect(exit2, isNotEmpty);
      expect(exit2.last.position, equals(const Offset(400.0, 450.0)));
      expect(tester.binding.mouseTracker.isAnnotationAttached(renderListener1.hoverAnnotation), isTrue);
      expect(tester.binding.mouseTracker.isAnnotationAttached(renderListener2.hoverAnnotation), isTrue);
      clearLists();
      await tester.pumpWidget(Container());
      expect(move1, isEmpty);
      expect(enter1, isEmpty);
      expect(exit1, isEmpty);
      expect(move2, isEmpty);
      expect(enter2, isEmpty);
      expect(exit2, isEmpty);
      expect(tester.binding.mouseTracker.isAnnotationAttached(renderListener1.hoverAnnotation), isFalse);
      expect(tester.binding.mouseTracker.isAnnotationAttached(renderListener2.hoverAnnotation), isFalse);
    });

    testWidgets('needsCompositing set when parent class needsCompositing is set', (WidgetTester tester) async {
      await tester.pumpWidget(
        Listener(
          onPointerEnter: (PointerEnterEvent _) {},
          child: const Opacity(opacity: 0.5, child: Placeholder()),
        ),
      );

      RenderPointerListener listener = tester.renderObject(find.byType(Listener).first);
      expect(listener.needsCompositing, isTrue);

      await tester.pumpWidget(
        Listener(
          onPointerEnter: (PointerEnterEvent _) {},
          child: const Placeholder(),
        ),
      );

      listener = tester.renderObject(find.byType(Listener).first);
      expect(listener.needsCompositing, isFalse);
    });

    testWidgets('works with transform', (WidgetTester tester) async {
      // Regression test for https://github.com/flutter/flutter/issues/31986.
      final Key key = UniqueKey();
      const double scaleFactor = 2.0;
      const double localWidth = 150.0;
      const double localHeight = 100.0;
      final List<PointerEvent> events = <PointerEvent>[];

      await tester.pumpWidget(
        MaterialApp(
          home: Center(
            child: Transform.scale(
              scale: scaleFactor,
              child: Listener(
                onPointerEnter: (PointerEnterEvent event) {
                  events.add(event);
                },
                onPointerHover: (PointerHoverEvent event) {
                  events.add(event);
                },
                onPointerExit: (PointerExitEvent event) {
                  events.add(event);
                },
                child: Container(
                  key: key,
                  color: Colors.blue,
                  height: localHeight,
                  width: localWidth,
                  child: const Text('Hi'),
                ),
              ),
            ),
          ),
        ),
      );

      final Offset topLeft = tester.getTopLeft(find.byKey(key));
      final Offset topRight = tester.getTopRight(find.byKey(key));
      final Offset bottomLeft = tester.getBottomLeft(find.byKey(key));
      expect(topRight.dx - topLeft.dx, scaleFactor * localWidth);
      expect(bottomLeft.dy - topLeft.dy, scaleFactor * localHeight);

      final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
      await gesture.addPointer();
      addTearDown(gesture.removePointer);
      await gesture.moveTo(topLeft - const Offset(1, 1));
      await tester.pump();
      expect(events, isEmpty);

      await gesture.moveTo(topLeft + const Offset(1, 1));
      await tester.pump();
      expect(events, hasLength(2));
      expect(events.first, isA<PointerEnterEvent>());
      expect(events.last, isA<PointerHoverEvent>());
      events.clear();

      await gesture.moveTo(bottomLeft + const Offset(1, -1));
      await tester.pump();
      expect(events.single, isA<PointerHoverEvent>());
      expect(events.single.delta, const Offset(0.0, scaleFactor * localHeight - 2));
      events.clear();

      await gesture.moveTo(bottomLeft + const Offset(1, 1));
      await tester.pump();
      expect(events.single, isA<PointerExitEvent>());
      events.clear();
    });

    testWidgets('needsCompositing updates correctly and is respected', (WidgetTester tester) async {
      // Pretend that we have a mouse connected.
      final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
      await gesture.addPointer();
      addTearDown(gesture.removePointer);

      await tester.pumpWidget(
        Transform.scale(
          scale: 2.0,
          child: Listener(
            onPointerDown: (PointerDownEvent _) { },
          ),
        ),
      );
      final RenderPointerListener listener = tester.renderObject(find.byType(Listener));
      expect(listener.needsCompositing, isFalse);
      // No TransformLayer for `Transform.scale` is added because composting is
      // not required and therefore the transform is executed on the canvas
      // directly. (One TransformLayer is always present for the root
      // transform.)
      expect(tester.layers.whereType<TransformLayer>(), hasLength(1));

      await tester.pumpWidget(
        Transform.scale(
          scale: 2.0,
          child: Listener(
            onPointerDown: (PointerDownEvent _) { },
            onPointerHover: (PointerHoverEvent _) { },
          ),
        ),
      );
      expect(listener.needsCompositing, isTrue);
      // Compositing is required, therefore a dedicated TransformLayer for
      // `Transform.scale` is added.
      expect(tester.layers.whereType<TransformLayer>(), hasLength(2));

      await tester.pumpWidget(
        Transform.scale(
          scale: 2.0,
          child: Listener(
            onPointerDown: (PointerDownEvent _) { },
          ),
        ),
      );
      expect(listener.needsCompositing, isFalse);
      // TransformLayer for `Transform.scale` is removed again as transform is
      // executed directly on the canvas.
      expect(tester.layers.whereType<TransformLayer>(), hasLength(1));
    });

    testWidgets("Callbacks aren't called during build", (WidgetTester tester) async {
      final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
      await gesture.addPointer();
      addTearDown(gesture.removePointer);

      await tester.pumpWidget(
        const Center(child: HoverFeedback()),
      );

      await gesture.moveTo(tester.getCenter(find.byType(Text)));
      await tester.pumpAndSettle();
      expect(HoverClientState.numEntries, equals(1));
      expect(HoverClientState.numExits, equals(0));
      expect(find.text('HOVERING'), findsOneWidget);

      await tester.pumpWidget(
        Container(),
      );
      await tester.pump();
      expect(HoverClientState.numEntries, equals(1));
      expect(HoverClientState.numExits, equals(1));

      await tester.pumpWidget(
        const Center(child: HoverFeedback()),
      );
      await tester.pump();
      expect(HoverClientState.numEntries, equals(2));
      expect(HoverClientState.numExits, equals(1));
    });

    testWidgets("Listener activate/deactivate don't duplicate annotations", (WidgetTester tester) async {
      final GlobalKey feedbackKey = GlobalKey();
      final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
      await gesture.addPointer();
      addTearDown(gesture.removePointer);

      await tester.pumpWidget(
        Center(child: HoverFeedback(key: feedbackKey)),
      );

      await gesture.moveTo(tester.getCenter(find.byType(Text)));
      await tester.pumpAndSettle();
      expect(HoverClientState.numEntries, equals(1));
      expect(HoverClientState.numExits, equals(0));
      expect(find.text('HOVERING'), findsOneWidget);

      await tester.pumpWidget(
        Center(child: Container(child: HoverFeedback(key: feedbackKey))),
      );
      await tester.pump();
      expect(HoverClientState.numEntries, equals(2));
      expect(HoverClientState.numExits, equals(1));
      await tester.pumpWidget(
        Container(),
      );
      await tester.pump();
      expect(HoverClientState.numEntries, equals(2));
      expect(HoverClientState.numExits, equals(2));
    });

    testWidgets('Exit event when unplugging mouse should have a position', (WidgetTester tester) async {
      final List<PointerEnterEvent> enter = <PointerEnterEvent>[];
      final List<PointerHoverEvent> hover = <PointerHoverEvent>[];
      final List<PointerExitEvent> exit = <PointerExitEvent>[];

      await tester.pumpWidget(
        Center(
          child: Listener(
            onPointerEnter: (PointerEnterEvent e) => enter.add(e),
            onPointerHover: (PointerHoverEvent e) => hover.add(e),
            onPointerExit: (PointerExitEvent e) => exit.add(e),
            child: Container(
              height: 100.0,
              width: 100.0,
            ),
          ),
        ),
      );

      // Plug-in a mouse and move it to the center of the container.
      TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
      await gesture.addPointer();
      addTearDown(() async {
        if (gesture != null)
          return gesture.removePointer();
      });
      await gesture.moveTo(tester.getCenter(find.byType(Container)));
      await tester.pumpAndSettle();

      expect(enter.length, 1);
      expect(enter.single.position, const Offset(400.0, 300.0));
      expect(hover.length, 1);
      expect(hover.single.position, const Offset(400.0, 300.0));
      expect(exit.length, 0);

      enter.clear();
      hover.clear();
      exit.clear();

      // Unplug the mouse.
      await gesture.removePointer();
      gesture = null;
      await tester.pumpAndSettle();

      expect(enter.length, 0);
      expect(hover.length, 0);
      expect(exit.length, 1);
      expect(exit.single.position, const Offset(400.0, 300.0));
      expect(exit.single.delta, const Offset(0.0, 0.0));
    });
  });
}
