// 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:async';

import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('Positioned constructors', (WidgetTester tester) async {
    final Widget child = Container();
    final Positioned a = Positioned(
      left: 101.0,
      right: 201.0,
      top: 301.0,
      bottom: 401.0,
      child: child,
    );
    expect(a.left, 101.0);
    expect(a.right, 201.0);
    expect(a.top, 301.0);
    expect(a.bottom, 401.0);
    expect(a.width, null);
    expect(a.height, null);
    final Positioned b = Positioned.fromRect(
      rect: const Rect.fromLTRB(
        102.0,
        302.0,
        202.0,
        502.0,
      ),
      child: child,
    );
    expect(b.left, 102.0);
    expect(b.right, null);
    expect(b.top, 302.0);
    expect(b.bottom, null);
    expect(b.width, 100.0);
    expect(b.height, 200.0);
    final Positioned c = Positioned.fromRelativeRect(
      rect: const RelativeRect.fromLTRB(
        103.0,
        303.0,
        203.0,
        403.0,
      ),
      child: child,
    );
    expect(c.left, 103.0);
    expect(c.right, 203.0);
    expect(c.top, 303.0);
    expect(c.bottom, 403.0);
    expect(c.width, null);
    expect(c.height, null);
  });

  testWidgets('Can animate position data', (WidgetTester tester) async {
    final RelativeRectTween rect = RelativeRectTween(
      begin: RelativeRect.fromRect(
        const Rect.fromLTRB(10.0, 20.0, 20.0, 30.0),
        const Rect.fromLTRB(0.0, 10.0, 100.0, 110.0),
      ),
      end: RelativeRect.fromRect(
        const Rect.fromLTRB(80.0, 90.0, 90.0, 100.0),
        const Rect.fromLTRB(0.0, 10.0, 100.0, 110.0),
      ),
    );
    final AnimationController controller = AnimationController(
      duration: const Duration(seconds: 10),
      vsync: tester,
    );
    final List<Size> sizes = <Size>[];
    final List<Offset> positions = <Offset>[];
    final GlobalKey key = GlobalKey();

    void recordMetrics() {
      final RenderBox box = key.currentContext!.findRenderObject()! as RenderBox;
      final BoxParentData boxParentData = box.parentData! as BoxParentData;
      sizes.add(box.size);
      positions.add(boxParentData.offset);
    }

    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Center(
          child: SizedBox(
            height: 100.0,
            width: 100.0,
            child: Stack(
              children: <Widget>[
                PositionedTransition(
                  rect: rect.animate(controller),
                  child: Container(
                    key: key,
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    ); // t=0
    recordMetrics();
    final Completer<void> completer = Completer<void>();
    controller.forward().whenComplete(completer.complete);
    expect(completer.isCompleted, isFalse);
    await tester.pump(); // t=0 again
    expect(completer.isCompleted, isFalse);
    recordMetrics();
    await tester.pump(const Duration(seconds: 1)); // t=1
    expect(completer.isCompleted, isFalse);
    recordMetrics();
    await tester.pump(const Duration(seconds: 1)); // t=2
    expect(completer.isCompleted, isFalse);
    recordMetrics();
    await tester.pump(const Duration(seconds: 3)); // t=5
    expect(completer.isCompleted, isFalse);
    recordMetrics();
    await tester.pump(const Duration(seconds: 5)); // t=10
    expect(completer.isCompleted, isFalse);
    recordMetrics();

    expect(sizes, equals(<Size>[const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0), const Size(10.0, 10.0)]));
    expect(positions, equals(<Offset>[const Offset(10.0, 10.0), const Offset(10.0, 10.0), const Offset(17.0, 17.0), const Offset(24.0, 24.0), const Offset(45.0, 45.0), const Offset(80.0, 80.0)]));

    controller.stop(canceled: false);
    await tester.pump();
    expect(completer.isCompleted, isTrue);
  });
}
