// 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 'dart:math' as math;

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';

void main() {
  testWidgets('Scrollable scaled up', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    await tester.pumpWidget(
      MaterialApp(
        home: Transform.scale(
          scale: 2.0,
          child: Center(
            child: Container(
              width: 200,
              child: ListView.builder(
                controller: controller,
                cacheExtent: 0.0,
                itemBuilder: (BuildContext context, int index) {
                  return Container(
                    height: 100.0,
                    color: index % 2 == 0 ? Colors.blue : Colors.red,
                    child: Text('Tile $index'),
                  );
                },
              ),
            ),
          ),
        ),
      ),
    );
    expect(controller.offset, 0.0);

    await tester.drag(find.byType(ListView), const Offset(0.0, -100.0));
    await tester.pump();
    expect(controller.offset, 50.0); // 100.0 / 2.0

    await tester.drag(find.byType(ListView), const Offset(80.0, -70.0));
    await tester.pump();
    expect(controller.offset, 85.0); // 50.0 + (70.0 / 2)

    await tester.drag(find.byType(ListView), const Offset(100.0, 0.0));
    await tester.pump();
    expect(controller.offset, 85.0);

    await tester.drag(find.byType(ListView), const Offset(0.0, 85.0));
    await tester.pump();
    expect(controller.offset, 42.5); // 85.0 - (85.0 / 2)
  });

  testWidgets('Scrollable scaled down', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    await tester.pumpWidget(
      MaterialApp(
        home: Transform.scale(
          scale: 0.5,
          child: Center(
            child: Container(
              width: 200,
              child: ListView.builder(
                controller: controller,
                cacheExtent: 0.0,
                itemBuilder: (BuildContext context, int index) {
                  return Container(
                    height: 100.0,
                    color: index % 2 == 0 ? Colors.blue : Colors.red,
                    child: Text('Tile $index'),
                  );
                },
              ),
            ),
          ),
        ),
      ),
    );
    expect(controller.offset, 0.0);

    await tester.drag(find.byType(ListView), const Offset(0.0, -100.0));
    await tester.pump();
    expect(controller.offset, 200.0); // 100.0 * 2.0

    await tester.drag(find.byType(ListView), const Offset(80.0, -70.0));
    await tester.pump();
    expect(controller.offset, 340.0); // 200.0 + (70.0 * 2)

    await tester.drag(find.byType(ListView), const Offset(100.0, 0.0));
    await tester.pump();
    expect(controller.offset, 340.0);

    await tester.drag(find.byType(ListView), const Offset(0.0, 170.0));
    await tester.pump();
    expect(controller.offset, 0.0); // 340.0 - (170.0 * 2)
  });

  testWidgets('Scrollable rotated 90 degrees', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    await tester.pumpWidget(
      MaterialApp(
        home: Transform.rotate(
          angle: math.pi / 2,
          child: Center(
            child: Container(
              width: 200,
              child: ListView.builder(
                controller: controller,
                cacheExtent: 0.0,
                itemBuilder: (BuildContext context, int index) {
                  return Container(
                    height: 100.0,
                    color: index % 2 == 0 ? Colors.blue : Colors.red,
                    child: Text('Tile $index'),
                  );
                },
              ),
            ),
          ),
        ),
      ),
    );
    expect(controller.offset, 0.0);

    await tester.drag(find.byType(ListView), const Offset(100.0, 0.0));
    await tester.pump();
    expect(controller.offset, 100.0);

    await tester.drag(find.byType(ListView), const Offset(0.0, -100.0));
    await tester.pump();
    expect(controller.offset, 100.0);

    await tester.drag(find.byType(ListView), const Offset(-70.0, -50.0));
    await tester.pump();
    expect(controller.offset, 30.0); // 100.0 - 70.0
  });

  testWidgets('Perspective transform on scrollable', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    await tester.pumpWidget(
      MaterialApp(
        home: Transform(
          transform: Matrix4.identity()
            ..setEntry(3, 2, 0.001)
            ..rotateX(math.pi / 4),
          child: Center(
            child: Container(
              width: 200,
              child: ListView.builder(
                controller: controller,
                cacheExtent: 0.0,
                itemBuilder: (BuildContext context, int index) {
                  return Container(
                    height: 100.0,
                    color: index % 2 == 0 ? Colors.blue : Colors.red,
                    child: Text('Tile $index'),
                  );
                },
              ),
            ),
          ),
        ),
      ),
    );
    expect(controller.offset, 0.0);

    // We want to test that the point in the ListView that the finger touches
    // on the screen stays under the finger as the finger scrolls the ListView
    // in vertical direction. For this, we pick a point in the ListView (here
    // the center of Tile 5) and calculate its position in the coordinate space
    // of the screen. We then place our finger on that point and drag that
    // point up in vertical direction. After the scroll activity is done,
    // we verify that - in the coordinate space of the screen (!) - the point
    // has moved the same distance as the finger. Due to the perspective
    // transform the point will have moved more distance in the *local*
    // coordinate system of the ListView.

    // Calculate where the center of Tile 5 is located in the coordinate
    // space of the screen. We cannot use `tester.getCenter` because it
    // does not properly remove the perspective component from the transform
    // to give us the place on the screen at which we need to touch the screen
    // to have the center of Tile 5 directly under our finger.
    final RenderBox tile5 = tester.renderObject(find.text('Tile 5'));
    final Offset pointOnScreenStart = MatrixUtils.transformPoint(
      PointerEvent.removePerspectiveTransform(tile5.getTransformTo(null)),
      tile5.size.center(Offset.zero),
    );

    // Place the finger on the tracked point and move the finger upwards for
    // 50 pixels to scroll the ListView (the ListView's scroll offset will
    // move more then 50 pixels due to the perspective transform).
    await tester.dragFrom(pointOnScreenStart, const Offset(0.0, -50.0));
    await tester.pump();

    // Get the new position of the tracked point in the screen's coordinate
    // system.
    final Offset pointOnScreenEnd = MatrixUtils.transformPoint(
      PointerEvent.removePerspectiveTransform(tile5.getTransformTo(null)),
      tile5.size.center(Offset.zero),
    );

    // The tracked point (in the coordinate space of the screen) and the finger
    // should have moved the same vertical distance over the screen.
    expect(
      pointOnScreenStart.dy - pointOnScreenEnd.dy,
      within(distance: 0.00001, from: 50.0),
    );

    // While the point traveled the same distance as the finger in the
    // coordinate space of the screen, the scroll view actually moved far more
    // pixels in its local coordinate system due to the perspective transform.
    expect(controller.offset, greaterThan(100));
  });
}
