// 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 '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.isEven ? 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.isEven ? 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.isEven ? 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.isEven ? 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));
  });
}
