// 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 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

import '../scheduler/scheduler_tester.dart';

class BogusCurve extends Curve {
  const BogusCurve();

  @override
  double transform(double t) => 100.0;
}

void main() {
  setUp(() {
    WidgetsFlutterBinding.ensureInitialized();
    WidgetsBinding.instance
      ..resetEpoch()
      ..platformDispatcher.onBeginFrame = null
      ..platformDispatcher.onDrawFrame = null;
  });

  test('toString control test', () {
    expect(kAlwaysCompleteAnimation, hasOneLineDescription);
    expect(kAlwaysDismissedAnimation, hasOneLineDescription);
    expect(const AlwaysStoppedAnimation<double>(0.5), hasOneLineDescription);
    CurvedAnimation curvedAnimation = CurvedAnimation(
      parent: kAlwaysDismissedAnimation,
      curve: Curves.ease,
    );
    expect(curvedAnimation, hasOneLineDescription);
    curvedAnimation.reverseCurve = Curves.elasticOut;
    expect(curvedAnimation, hasOneLineDescription);
    final AnimationController controller = AnimationController(
      duration: const Duration(milliseconds: 500),
      vsync: const TestVSync(),
    );
    controller
      ..value = 0.5
      ..reverse();
    curvedAnimation = CurvedAnimation(
      parent: controller,
      curve: Curves.ease,
      reverseCurve: Curves.elasticOut,
    );
    expect(curvedAnimation, hasOneLineDescription);
    controller.stop();
  });

  test('ProxyAnimation.toString control test', () {
    final ProxyAnimation animation = ProxyAnimation();
    expect(animation.value, 0.0);
    expect(animation.status, AnimationStatus.dismissed);
    expect(animation, hasOneLineDescription);
    animation.parent = kAlwaysDismissedAnimation;
    expect(animation, hasOneLineDescription);
  });

  test('ProxyAnimation set parent generates value changed', () {
    final AnimationController controller = AnimationController(
      vsync: const TestVSync(),
    );
    controller.value = 0.5;
    bool didReceiveCallback = false;
    final ProxyAnimation animation = ProxyAnimation()
      ..addListener(() {
        didReceiveCallback = true;
      });
    expect(didReceiveCallback, isFalse);
    animation.parent = controller;
    expect(didReceiveCallback, isTrue);
    didReceiveCallback = false;
    expect(didReceiveCallback, isFalse);
    controller.value = 0.6;
    expect(didReceiveCallback, isTrue);
  });

  test('ReverseAnimation calls listeners', () {
    final AnimationController controller = AnimationController(
      vsync: const TestVSync(),
    );
    controller.value = 0.5;
    bool didReceiveCallback = false;
    void listener() {
      didReceiveCallback = true;
    }
    final ReverseAnimation animation = ReverseAnimation(controller)
      ..addListener(listener);
    expect(didReceiveCallback, isFalse);
    controller.value = 0.6;
    expect(didReceiveCallback, isTrue);
    didReceiveCallback = false;
    animation.removeListener(listener);
    expect(didReceiveCallback, isFalse);
    controller.value = 0.7;
    expect(didReceiveCallback, isFalse);
    expect(animation, hasOneLineDescription);
  });

  test('TrainHoppingAnimation', () {
    final AnimationController currentTrain = AnimationController(
      vsync: const TestVSync(),
    );
    final AnimationController nextTrain = AnimationController(
      vsync: const TestVSync(),
    );
    currentTrain.value = 0.5;
    nextTrain.value = 0.75;
    bool didSwitchTrains = false;
    final TrainHoppingAnimation animation = TrainHoppingAnimation(
      currentTrain,
      nextTrain,
      onSwitchedTrain: () {
        didSwitchTrains = true;
      },
    );
    expect(didSwitchTrains, isFalse);
    expect(animation.value, 0.5);
    expect(animation, hasOneLineDescription);
    nextTrain.value = 0.25;
    expect(didSwitchTrains, isTrue);
    expect(animation.value, 0.25);
    expect(animation, hasOneLineDescription);
    expect(animation.toString(), contains('no next'));
  });

  test('AnimationMean control test', () {
    final AnimationController left = AnimationController(
      value: 0.5,
      vsync: const TestVSync(),
    );
    final AnimationController right = AnimationController(
      vsync: const TestVSync(),
    );

    final AnimationMean mean = AnimationMean(left: left, right: right);

    expect(mean, hasOneLineDescription);
    expect(mean.value, equals(0.25));

    final List<double> log = <double>[];
    void logValue() {
      log.add(mean.value);
    }

    mean.addListener(logValue);

    right.value = 1.0;

    expect(mean.value, equals(0.75));
    expect(log, equals(<double>[0.75]));
    log.clear();

    mean.removeListener(logValue);

    left.value = 0.0;

    expect(mean.value, equals(0.50));
    expect(log, isEmpty);
  });

  test('AnimationMax control test', () {
    final AnimationController first = AnimationController(
      value: 0.5,
      vsync: const TestVSync(),
    );
    final AnimationController second = AnimationController(
      vsync: const TestVSync(),
    );

    final AnimationMax<double> max = AnimationMax<double>(first, second);

    expect(max, hasOneLineDescription);
    expect(max.value, equals(0.5));

    final List<double> log = <double>[];
    void logValue() {
      log.add(max.value);
    }

    max.addListener(logValue);

    second.value = 1.0;

    expect(max.value, equals(1.0));
    expect(log, equals(<double>[1.0]));
    log.clear();

    max.removeListener(logValue);

    first.value = 0.0;

    expect(max.value, equals(1.0));
    expect(log, isEmpty);
  });

  test('AnimationMin control test', () {
    final AnimationController first = AnimationController(
      value: 0.5,
      vsync: const TestVSync(),
    );
    final AnimationController second = AnimationController(
      vsync: const TestVSync(),
    );

    final AnimationMin<double> min = AnimationMin<double>(first, second);

    expect(min, hasOneLineDescription);
    expect(min.value, equals(0.0));

    final List<double> log = <double>[];
    void logValue() {
      log.add(min.value);
    }

    min.addListener(logValue);

    second.value = 1.0;

    expect(min.value, equals(0.5));
    expect(log, equals(<double>[0.5]));
    log.clear();

    min.removeListener(logValue);

    first.value = 0.25;

    expect(min.value, equals(0.25));
    expect(log, isEmpty);
  });

  test('CurvedAnimation with bogus curve', () {
    final AnimationController controller = AnimationController(
      vsync: const TestVSync(),
    );
    final CurvedAnimation curved = CurvedAnimation(parent: controller, curve: const BogusCurve());
    FlutterError? error;
    try {
      curved.value;
    } on FlutterError catch (e) {
      error = e;
    }
    expect(error, isNotNull);
    expect(
      error!.toStringDeep(),
      // RegExp matcher is required here due to flutter web and flutter mobile generating
      // slightly different floating point numbers
      // in Flutter web 0.0 sometimes just appears as 0. or 0
      matches(RegExp(r'''
FlutterError
   Invalid curve endpoint at \d+(\.\d*)?\.
   Curves must map 0\.0 to near zero and 1\.0 to near one but
   BogusCurve mapped \d+(\.\d*)? to \d+(\.\d*)?, which is near \d+(\.\d*)?\.
''', multiLine: true)),
    );
  });

  test('CurvedAnimation running with different forward and reverse durations.', () {
    final AnimationController controller = AnimationController(
      duration: const Duration(milliseconds: 100),
      reverseDuration: const Duration(milliseconds: 50),
      vsync: const TestVSync(),
    );
    final CurvedAnimation curved = CurvedAnimation(parent: controller, curve: Curves.linear, reverseCurve: Curves.linear);

    controller.forward();
    tick(Duration.zero);
    tick(const Duration(milliseconds: 10));
    expect(curved.value, moreOrLessEquals(0.1));
    tick(const Duration(milliseconds: 20));
    expect(curved.value, moreOrLessEquals(0.2));
    tick(const Duration(milliseconds: 30));
    expect(curved.value, moreOrLessEquals(0.3));
    tick(const Duration(milliseconds: 40));
    expect(curved.value, moreOrLessEquals(0.4));
    tick(const Duration(milliseconds: 50));
    expect(curved.value, moreOrLessEquals(0.5));
    tick(const Duration(milliseconds: 60));
    expect(curved.value, moreOrLessEquals(0.6));
    tick(const Duration(milliseconds: 70));
    expect(curved.value, moreOrLessEquals(0.7));
    tick(const Duration(milliseconds: 80));
    expect(curved.value, moreOrLessEquals(0.8));
    tick(const Duration(milliseconds: 90));
    expect(curved.value, moreOrLessEquals(0.9));
    tick(const Duration(milliseconds: 100));
    expect(curved.value, moreOrLessEquals(1.0));
    controller.reverse();
    tick(const Duration(milliseconds: 110));
    expect(curved.value, moreOrLessEquals(1.0));
    tick(const Duration(milliseconds: 120));
    expect(curved.value, moreOrLessEquals(0.8));
    tick(const Duration(milliseconds: 130));
    expect(curved.value, moreOrLessEquals(0.6));
    tick(const Duration(milliseconds: 140));
    expect(curved.value, moreOrLessEquals(0.4));
    tick(const Duration(milliseconds: 150));
    expect(curved.value, moreOrLessEquals(0.2));
    tick(const Duration(milliseconds: 160));
    expect(curved.value, moreOrLessEquals(0.0));
  });

  test('CurvedAnimation stops listening to parent when disposed.', () async {
    const Interval forwardCurve = Interval(0.0, 0.5);
    const Interval reverseCurve = Interval(0.5, 1.0);

    final AnimationController controller = AnimationController(
      duration: const Duration(milliseconds: 100),
      reverseDuration: const Duration(milliseconds: 100),
      vsync: const TestVSync(),
    );
    final CurvedAnimation curved = CurvedAnimation(
        parent: controller, curve: forwardCurve, reverseCurve: reverseCurve);

    expect(forwardCurve.transform(0.5), 1.0);
    expect(reverseCurve.transform(0.5), 0.0);

    controller.forward(from: 0.5);
    expect(controller.status, equals(AnimationStatus.forward));
    expect(curved.value, equals(1.0));

    controller.value = 1.0;
    expect(controller.status, equals(AnimationStatus.completed));

    controller.reverse(from: 0.5);
    expect(controller.status, equals(AnimationStatus.reverse));
    expect(curved.value, equals(0.0));

    expect(curved.isDisposed, isFalse);
    curved.dispose();
    expect(curved.isDisposed, isTrue);

    controller.value = 0.0;
    expect(controller.status, equals(AnimationStatus.dismissed));

    controller.forward(from: 0.5);
    expect(controller.status, equals(AnimationStatus.forward));
    expect(curved.value, equals(0.0));
  });

  test('ReverseAnimation running with different forward and reverse durations.', () {
    final AnimationController controller = AnimationController(
      duration: const Duration(milliseconds: 100),
      reverseDuration: const Duration(milliseconds: 50),
      vsync: const TestVSync(),
    );
    final ReverseAnimation reversed = ReverseAnimation(
      CurvedAnimation(
        parent: controller,
        curve: Curves.linear,
        reverseCurve: Curves.linear,
      ),
    );

    controller.forward();
    tick(Duration.zero);
    tick(const Duration(milliseconds: 10));
    expect(reversed.value, moreOrLessEquals(0.9));
    tick(const Duration(milliseconds: 20));
    expect(reversed.value, moreOrLessEquals(0.8));
    tick(const Duration(milliseconds: 30));
    expect(reversed.value, moreOrLessEquals(0.7));
    tick(const Duration(milliseconds: 40));
    expect(reversed.value, moreOrLessEquals(0.6));
    tick(const Duration(milliseconds: 50));
    expect(reversed.value, moreOrLessEquals(0.5));
    tick(const Duration(milliseconds: 60));
    expect(reversed.value, moreOrLessEquals(0.4));
    tick(const Duration(milliseconds: 70));
    expect(reversed.value, moreOrLessEquals(0.3));
    tick(const Duration(milliseconds: 80));
    expect(reversed.value, moreOrLessEquals(0.2));
    tick(const Duration(milliseconds: 90));
    expect(reversed.value, moreOrLessEquals(0.1));
    tick(const Duration(milliseconds: 100));
    expect(reversed.value, moreOrLessEquals(0.0));
    controller.reverse();
    tick(const Duration(milliseconds: 110));
    expect(reversed.value, moreOrLessEquals(0.0));
    tick(const Duration(milliseconds: 120));
    expect(reversed.value, moreOrLessEquals(0.2));
    tick(const Duration(milliseconds: 130));
    expect(reversed.value, moreOrLessEquals(0.4));
    tick(const Duration(milliseconds: 140));
    expect(reversed.value, moreOrLessEquals(0.6));
    tick(const Duration(milliseconds: 150));
    expect(reversed.value, moreOrLessEquals(0.8));
    tick(const Duration(milliseconds: 160));
    expect(reversed.value, moreOrLessEquals(1.0));
  });

  test('TweenSequence', () {
    final AnimationController controller = AnimationController(
      vsync: const TestVSync(),
    );

    final Animation<double> animation = TweenSequence<double>(
      <TweenSequenceItem<double>>[
        TweenSequenceItem<double>(
          tween: Tween<double>(begin: 5.0, end: 10.0),
          weight: 4.0,
        ),
        TweenSequenceItem<double>(
          tween: ConstantTween<double>(10.0),
          weight: 2.0,
        ),
        TweenSequenceItem<double>(
          tween: Tween<double>(begin: 10.0, end: 5.0),
          weight: 4.0,
        ),
      ],
    ).animate(controller);

    expect(animation.value, 5.0);

    controller.value = 0.2;
    expect(animation.value, 7.5);

    controller.value = 0.4;
    expect(animation.value, 10.0);

    controller.value = 0.6;
    expect(animation.value, 10.0);

    controller.value = 0.8;
    expect(animation.value, 7.5);

    controller.value = 1.0;
    expect(animation.value, 5.0);
  });

  test('TweenSequence with curves', () {
    final AnimationController controller = AnimationController(
      vsync: const TestVSync(),
    );

    final Animation<double> animation = TweenSequence<double>(
      <TweenSequenceItem<double>>[
        TweenSequenceItem<double>(
          tween: Tween<double>(begin: 5.0, end: 10.0)
            .chain(CurveTween(curve: const Interval(0.5, 1.0))),
          weight: 4.0,
        ),
        TweenSequenceItem<double>(
          tween: ConstantTween<double>(10.0)
            .chain(CurveTween(curve: Curves.linear)), // linear is a no-op
          weight: 2.0,
        ),
        TweenSequenceItem<double>(
          tween: Tween<double>(begin: 10.0, end: 5.0)
            .chain(CurveTween(curve: const Interval(0.0, 0.5))),
          weight: 4.0,
        ),
      ],
    ).animate(controller);

    expect(animation.value, 5.0);

    controller.value = 0.2;
    expect(animation.value, 5.0);

    controller.value = 0.4;
    expect(animation.value, 10.0);

    controller.value = 0.6;
    expect(animation.value, 10.0);

    controller.value = 0.8;
    expect(animation.value, 5.0);

    controller.value = 1.0;
    expect(animation.value, 5.0);
  });

  test('TweenSequence, one tween', () {
    final AnimationController controller = AnimationController(
      vsync: const TestVSync(),
    );

    final Animation<double> animation = TweenSequence<double>(
      <TweenSequenceItem<double>>[
        TweenSequenceItem<double>(
          tween: Tween<double>(begin: 5.0, end: 10.0),
          weight: 1.0,
        ),
      ],
    ).animate(controller);

    expect(animation.value, 5.0);

    controller.value = 0.5;
    expect(animation.value, 7.5);

    controller.value = 1.0;
    expect(animation.value, 10.0);
  });

}
