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

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

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

class BogusCurve extends Curve {
  @override
  double transform(double t) => 100.0;
}

void main() {
  setUp(() {
    WidgetsFlutterBinding.ensureInitialized();
    WidgetsBinding.instance!.resetEpoch();
    ui.window.onBeginFrame = null;
    ui.window.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: 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);
  });

}
