// Copyright 2018 The Chromium 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 'dart:ui' as ui;

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';

import '../flutter_test_alternative.dart';

typedef HandleEventCallback = void Function(PointerEvent event);

class TestGestureFlutterBinding extends BindingBase with ServicesBinding, SchedulerBinding, GestureBinding {
  HandleEventCallback callback;

  @override
  void handleEvent(PointerEvent event, HitTestEntry entry) {
    super.handleEvent(event, entry);
    if (callback != null) {
      callback(event);
    }
  }
}

TestGestureFlutterBinding _binding = TestGestureFlutterBinding();

void ensureTestGestureBinding() {
  _binding ??= TestGestureFlutterBinding();
  assert(GestureBinding.instance != null);
}

void main() {
  setUp(ensureTestGestureBinding);

  group(MouseTracker, () {
    final List<PointerEnterEvent> enter = <PointerEnterEvent>[];
    final List<PointerHoverEvent> move = <PointerHoverEvent>[];
    final List<PointerExitEvent> exit = <PointerExitEvent>[];
    final MouseTrackerAnnotation annotation = MouseTrackerAnnotation(
      onEnter: (PointerEnterEvent event) => enter.add(event),
      onHover: (PointerHoverEvent event) => move.add(event),
      onExit: (PointerExitEvent event) => exit.add(event),
    );
    // Only respond to some mouse events.
    final MouseTrackerAnnotation partialAnnotation = MouseTrackerAnnotation(
      onEnter: (PointerEnterEvent event) => enter.add(event),
      onHover: (PointerHoverEvent event) => move.add(event),
    );
    bool isInHitRegionOne;
    bool isInHitRegionTwo;
    MouseTracker tracker;

    void clear() {
      enter.clear();
      exit.clear();
      move.clear();
    }

    setUp(() {
      clear();
      isInHitRegionOne = true;
      isInHitRegionTwo = false;
      tracker = MouseTracker(
        GestureBinding.instance.pointerRouter,
            (Offset _) sync* {
          if (isInHitRegionOne)
            yield annotation;
          else if (isInHitRegionTwo)
            yield partialAnnotation;
        },
      );
    });

    test('receives and processes mouse hover events', () {
      final ui.PointerDataPacket packet1 = ui.PointerDataPacket(data: <ui.PointerData>[
        ui.PointerData(
          change: ui.PointerChange.hover,
          physicalX: 0.0 * ui.window.devicePixelRatio,
          physicalY: 0.0 * ui.window.devicePixelRatio,
          kind: PointerDeviceKind.mouse,
        ),
      ]);
      final ui.PointerDataPacket packet2 = ui.PointerDataPacket(data: <ui.PointerData>[
        ui.PointerData(
          change: ui.PointerChange.hover,
          physicalX: 1.0 * ui.window.devicePixelRatio,
          physicalY: 101.0 * ui.window.devicePixelRatio,
          kind: PointerDeviceKind.mouse,
        ),
      ]);
      final ui.PointerDataPacket packet3 = ui.PointerDataPacket(data: <ui.PointerData>[
        ui.PointerData(
          change: ui.PointerChange.remove,
          physicalX: 1.0 * ui.window.devicePixelRatio,
          physicalY: 201.0 * ui.window.devicePixelRatio,
          kind: PointerDeviceKind.mouse,
        ),
      ]);
      final ui.PointerDataPacket packet4 = ui.PointerDataPacket(data: <ui.PointerData>[
        ui.PointerData(
          change: ui.PointerChange.hover,
          physicalX: 1.0 * ui.window.devicePixelRatio,
          physicalY: 301.0 * ui.window.devicePixelRatio,
          kind: PointerDeviceKind.mouse,
        ),
      ]);
      final ui.PointerDataPacket packet5 = ui.PointerDataPacket(data: <ui.PointerData>[
        ui.PointerData(
          change: ui.PointerChange.hover,
          physicalX: 1.0 * ui.window.devicePixelRatio,
          physicalY: 401.0 * ui.window.devicePixelRatio,
          kind: PointerDeviceKind.mouse,
          device: 1,
        ),
      ]);
      tracker.attachAnnotation(annotation);
      isInHitRegionOne = true;
      ui.window.onPointerDataPacket(packet1);
      tracker.collectMousePositions();
      expect(enter.length, equals(1), reason: 'enter contains $enter');
      expect(enter.first.position, equals(const Offset(0.0, 0.0)));
      expect(enter.first.device, equals(0));
      expect(enter.first.runtimeType, equals(PointerEnterEvent));
      expect(exit.length, equals(0), reason: 'exit contains $exit');
      expect(move.length, equals(1), reason: 'move contains $move');
      expect(move.first.position, equals(const Offset(0.0, 0.0)));
      expect(move.first.device, equals(0));
      expect(move.first.runtimeType, equals(PointerHoverEvent));
      clear();

      ui.window.onPointerDataPacket(packet2);
      tracker.collectMousePositions();
      expect(enter.length, equals(0), reason: 'enter contains $enter');
      expect(exit.length, equals(0), reason: 'exit contains $exit');
      expect(move.length, equals(1), reason: 'move contains $move');
      expect(move.first.position, equals(const Offset(1.0, 101.0)));
      expect(move.first.device, equals(0));
      expect(move.first.runtimeType, equals(PointerHoverEvent));
      clear();

      ui.window.onPointerDataPacket(packet3);
      tracker.collectMousePositions();
      expect(enter.length, equals(0), reason: 'enter contains $enter');
      expect(move.length, equals(0), reason: 'move contains $move');
      expect(exit.length, equals(1), reason: 'exit contains $exit');
      expect(exit.first.position, equals(const Offset(1.0, 201.0)));
      expect(exit.first.device, equals(0));
      expect(exit.first.runtimeType, equals(PointerExitEvent));

      clear();
      ui.window.onPointerDataPacket(packet4);
      tracker.collectMousePositions();
      expect(enter.length, equals(1), reason: 'enter contains $enter');
      expect(enter.first.position, equals(const Offset(1.0, 301.0)));
      expect(enter.first.device, equals(0));
      expect(enter.first.runtimeType, equals(PointerEnterEvent));
      expect(exit.length, equals(0), reason: 'exit contains $exit');
      expect(move.length, equals(1), reason: 'move contains $move');
      expect(move.first.position, equals(const Offset(1.0, 301.0)));
      expect(move.first.device, equals(0));
      expect(move.first.runtimeType, equals(PointerHoverEvent));

      // add in a second mouse simultaneously.
      clear();
      ui.window.onPointerDataPacket(packet5);
      tracker.collectMousePositions();
      expect(enter.length, equals(1), reason: 'enter contains $enter');
      expect(enter.first.position, equals(const Offset(1.0, 401.0)));
      expect(enter.first.device, equals(1));
      expect(enter.first.runtimeType, equals(PointerEnterEvent));
      expect(exit.length, equals(0), reason: 'exit contains $exit');
      expect(move.length, equals(2), reason: 'move contains $move');
      expect(move.first.position, equals(const Offset(1.0, 301.0)));
      expect(move.first.device, equals(0));
      expect(move.first.runtimeType, equals(PointerHoverEvent));
      expect(move.last.position, equals(const Offset(1.0, 401.0)));
      expect(move.last.device, equals(1));
      expect(move.last.runtimeType, equals(PointerHoverEvent));
    });
    test('detects exit when annotated layer no longer hit', () {
      final ui.PointerDataPacket packet1 = ui.PointerDataPacket(data: <ui.PointerData>[
        ui.PointerData(
          change: ui.PointerChange.hover,
          physicalX: 0.0 * ui.window.devicePixelRatio,
          physicalY: 0.0 * ui.window.devicePixelRatio,
          kind: PointerDeviceKind.mouse,
        ),
        ui.PointerData(
          change: ui.PointerChange.hover,
          physicalX: 1.0 * ui.window.devicePixelRatio,
          physicalY: 101.0 * ui.window.devicePixelRatio,
          kind: PointerDeviceKind.mouse,
        ),
      ]);
      final ui.PointerDataPacket packet2 = ui.PointerDataPacket(data: <ui.PointerData>[
        ui.PointerData(
          change: ui.PointerChange.hover,
          physicalX: 1.0 * ui.window.devicePixelRatio,
          physicalY: 201.0 * ui.window.devicePixelRatio,
          kind: PointerDeviceKind.mouse,
        ),
      ]);
      isInHitRegionOne = true;
      tracker.attachAnnotation(annotation);

      ui.window.onPointerDataPacket(packet1);
      tracker.collectMousePositions();
      expect(enter.length, equals(1), reason: 'enter contains $enter');
      expect(enter.first.position, equals(const Offset(1.0, 101.0)));
      expect(enter.first.device, equals(0));
      expect(enter.first.runtimeType, equals(PointerEnterEvent));
      expect(move.length, equals(1), reason: 'move contains $move');
      expect(move.first.position, equals(const Offset(1.0, 101.0)));
      expect(move.first.device, equals(0));
      expect(move.first.runtimeType, equals(PointerHoverEvent));
      expect(exit.length, equals(0), reason: 'exit contains $exit');
      // Simulate layer going away by detaching it.
      clear();
      isInHitRegionOne = false;

      ui.window.onPointerDataPacket(packet2);
      tracker.collectMousePositions();
      expect(enter.length, equals(0), reason: 'enter contains $enter');
      expect(move.length, equals(0), reason: 'enter contains $move');
      expect(exit.length, equals(1), reason: 'enter contains $exit');
      expect(exit.first.position, const Offset(1.0, 201.0));
      expect(exit.first.device, equals(0));
      expect(exit.first.runtimeType, equals(PointerExitEvent));

      // Actually detach annotation. Shouldn't receive hit.
      tracker.detachAnnotation(annotation);
      clear();
      isInHitRegionOne = false;

      ui.window.onPointerDataPacket(packet2);
      tracker.collectMousePositions();
      expect(enter.length, equals(0), reason: 'enter contains $enter');
      expect(move.length, equals(0), reason: 'enter contains $move');
      expect(exit.length, equals(0), reason: 'enter contains $exit');
    });

    test("don't flip out if not all mouse events are listened to", () {
      final ui.PointerDataPacket packet = ui.PointerDataPacket(data: <ui.PointerData>[
        ui.PointerData(
          change: ui.PointerChange.hover,
          physicalX: 1.0 * ui.window.devicePixelRatio,
          physicalY: 101.0 * ui.window.devicePixelRatio,
          kind: PointerDeviceKind.mouse,
        ),
      ]);

      isInHitRegionOne = false;
      isInHitRegionTwo = true;
      tracker.attachAnnotation(partialAnnotation);

      ui.window.onPointerDataPacket(packet);
      tracker.collectMousePositions();
      tracker.detachAnnotation(partialAnnotation);
      isInHitRegionTwo = false;
    });
    test('detects exit when mouse goes away', () {
      final ui.PointerDataPacket packet1 = ui.PointerDataPacket(data: <ui.PointerData>[
        ui.PointerData(
          change: ui.PointerChange.hover,
          physicalX: 0.0 * ui.window.devicePixelRatio,
          physicalY: 0.0 * ui.window.devicePixelRatio,
          kind: PointerDeviceKind.mouse,
        ),
        ui.PointerData(
          change: ui.PointerChange.hover,
          physicalX: 1.0 * ui.window.devicePixelRatio,
          physicalY: 101.0 * ui.window.devicePixelRatio,
          kind: PointerDeviceKind.mouse,
        ),
      ]);
      final ui.PointerDataPacket packet2 = ui.PointerDataPacket(data: <ui.PointerData>[
        ui.PointerData(
          change: ui.PointerChange.remove,
          physicalX: 1.0 * ui.window.devicePixelRatio,
          physicalY: 201.0 * ui.window.devicePixelRatio,
          kind: PointerDeviceKind.mouse,
        ),
      ]);
      isInHitRegionOne = true;
      tracker.attachAnnotation(annotation);
      ui.window.onPointerDataPacket(packet1);
      tracker.collectMousePositions();
      ui.window.onPointerDataPacket(packet2);
      tracker.collectMousePositions();
      expect(enter.length, equals(1), reason: 'enter contains $enter');
      expect(enter.first.position, equals(const Offset(1.0, 101.0)));
      expect(enter.first.delta, equals(const Offset(1.0, 101.0)));
      expect(enter.first.device, equals(0));
      expect(enter.first.runtimeType, equals(PointerEnterEvent));
      expect(move.length, equals(1), reason: 'move contains $move');
      expect(move.first.position, equals(const Offset(1.0, 101.0)));
      expect(move.first.delta, equals(const Offset(1.0, 101.0)));
      expect(move.first.device, equals(0));
      expect(move.first.runtimeType, equals(PointerHoverEvent));
      expect(exit.length, equals(1), reason: 'exit contains $exit');
      expect(exit.first.position, equals(const Offset(1.0, 201.0)));
      expect(exit.first.delta, equals(const Offset(0.0, 0.0)));
      expect(exit.first.device, equals(0));
      expect(exit.first.runtimeType, equals(PointerExitEvent));
    });
    test('handles mouse down and move', () {
      final ui.PointerDataPacket packet1 = ui.PointerDataPacket(data: <ui.PointerData>[
        ui.PointerData(
          change: ui.PointerChange.hover,
          physicalX: 0.0 * ui.window.devicePixelRatio,
          physicalY: 0.0 * ui.window.devicePixelRatio,
          kind: PointerDeviceKind.mouse,
        ),
        ui.PointerData(
          change: ui.PointerChange.hover,
          physicalX: 1.0 * ui.window.devicePixelRatio,
          physicalY: 101.0 * ui.window.devicePixelRatio,
          kind: PointerDeviceKind.mouse,
        ),
      ]);
      final ui.PointerDataPacket packet2 = ui.PointerDataPacket(data: <ui.PointerData>[
        ui.PointerData(
          change: ui.PointerChange.down,
          physicalX: 1.0 * ui.window.devicePixelRatio,
          physicalY: 101.0 * ui.window.devicePixelRatio,
          kind: PointerDeviceKind.mouse,
        ),
        ui.PointerData(
          change: ui.PointerChange.move,
          physicalX: 1.0 * ui.window.devicePixelRatio,
          physicalY: 201.0 * ui.window.devicePixelRatio,
          kind: PointerDeviceKind.mouse,
        ),
      ]);
      isInHitRegionOne = true;
      tracker.attachAnnotation(annotation);
      ui.window.onPointerDataPacket(packet1);
      tracker.collectMousePositions();
      ui.window.onPointerDataPacket(packet2);
      tracker.collectMousePositions();
      expect(enter.length, equals(1), reason: 'enter contains $enter');
      expect(enter.first.position, equals(const Offset(1.0, 101.0)));
      expect(enter.first.device, equals(0));
      expect(enter.first.runtimeType, equals(PointerEnterEvent));
      expect(move.length, equals(1), reason: 'move contains $move');
      expect(move.first.position, equals(const Offset(1.0, 101.0)));
      expect(move.first.device, equals(0));
      expect(move.first.runtimeType, equals(PointerHoverEvent));
      expect(exit.length, equals(0), reason: 'exit contains $exit');
    });
  });
}
