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

class MockOnEndFunction {
  int called = 0;

  void handler() {
    called++;
  }
}

const Duration animationDuration = Duration(milliseconds:1000);
const Duration additionalDelay = Duration(milliseconds:1);

void main() {
  late MockOnEndFunction mockOnEndFunction;
  const Key switchKey = Key('switchKey');

  setUp(() {
    mockOnEndFunction = MockOnEndFunction();
  });

  testWidgets('BoxConstraintsTween control test', (WidgetTester tester) async {
    final BoxConstraintsTween tween = BoxConstraintsTween(
      begin: BoxConstraints.tight(const Size(20.0, 50.0)),
      end: BoxConstraints.tight(const Size(10.0, 30.0)),
    );
    final BoxConstraints result = tween.lerp(0.25);
    expect(result.minWidth, 17.5);
    expect(result.maxWidth, 17.5);
    expect(result.minHeight, 45.0);
    expect(result.maxHeight, 45.0);
  });

  testWidgets('DecorationTween control test', (WidgetTester tester) async {
    final DecorationTween tween = DecorationTween(
      begin: const BoxDecoration(color: Color(0xFF00FF00)),
      end: const BoxDecoration(color: Color(0xFFFFFF00)),
    );
    final BoxDecoration result = tween.lerp(0.25) as BoxDecoration;
    expect(result.color, const Color(0xFF3FFF00));
  });

  testWidgets('EdgeInsetsTween control test', (WidgetTester tester) async {
    final EdgeInsetsTween tween = EdgeInsetsTween(
      begin: const EdgeInsets.symmetric(vertical: 50.0),
      end: const EdgeInsets.only(top: 10.0, bottom: 30.0),
    );
    final EdgeInsets result = tween.lerp(0.25);
    expect(result.left, 0.0);
    expect(result.right, 0.0);
    expect(result.top, 40.0);
    expect(result.bottom, 45.0);
  });

  testWidgets('Matrix4Tween control test', (WidgetTester tester) async {
    final Matrix4Tween tween = Matrix4Tween(
      begin: Matrix4.translationValues(10.0, 20.0, 30.0),
      end: Matrix4.translationValues(14.0, 24.0, 34.0),
    );
    final Matrix4 result = tween.lerp(0.25);
    expect(result, equals(Matrix4.translationValues(11.0, 21.0, 31.0)));
  });

  testWidgets('AnimatedContainer onEnd callback test', (WidgetTester tester) async {
    await tester.pumpWidget(wrap(
      child: TestAnimatedWidget(
        callback: mockOnEndFunction.handler,
        switchKey: switchKey,
        state: _TestAnimatedContainerWidgetState(),
      ),
    ));

    final Finder widgetFinder = find.byKey(switchKey);

    await tester.tap(widgetFinder);

    await tester.pump();
    expect(mockOnEndFunction.called, 0);
    await tester.pump(animationDuration);
    expect(mockOnEndFunction.called, 0);
    await tester.pump(additionalDelay);
    expect(mockOnEndFunction.called, 1);

    await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
  });

  testWidgets('AnimatedPadding onEnd callback test', (WidgetTester tester) async {
    await tester.pumpWidget(wrap(
      child: TestAnimatedWidget(
        callback: mockOnEndFunction.handler,
        switchKey: switchKey,
        state: _TestAnimatedPaddingWidgetState(),
      ),
    ));

    final Finder widgetFinder = find.byKey(switchKey);

    await tester.tap(widgetFinder);

    await tester.pump();
    expect(mockOnEndFunction.called, 0);
    await tester.pump(animationDuration);
    expect(mockOnEndFunction.called, 0);
    await tester.pump(additionalDelay);
    expect(mockOnEndFunction.called, 1);

    await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
  });

  testWidgets('AnimatedAlign onEnd callback test', (WidgetTester tester) async {
    await tester.pumpWidget(wrap(
      child: TestAnimatedWidget(
        callback: mockOnEndFunction.handler,
        switchKey: switchKey,
        state: _TestAnimatedAlignWidgetState(),
      ),
    ));

    final Finder widgetFinder = find.byKey(switchKey);

    await tester.tap(widgetFinder);

    await tester.pump();
    expect(mockOnEndFunction.called, 0);
    await tester.pump(animationDuration);
    expect(mockOnEndFunction.called, 0);
    await tester.pump(additionalDelay);
    expect(mockOnEndFunction.called, 1);

    await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
  });

  testWidgets('AnimatedPositioned onEnd callback test', (WidgetTester tester) async {
    await tester.pumpWidget(wrap(
      child: TestAnimatedWidget(
        callback: mockOnEndFunction.handler,
        switchKey: switchKey,
        state: _TestAnimatedPositionedWidgetState(),
      ),
    ));

    final Finder widgetFinder = find.byKey(switchKey);

    await tester.tap(widgetFinder);

    await tester.pump();
    expect(mockOnEndFunction.called, 0);
    await tester.pump(animationDuration);
    expect(mockOnEndFunction.called, 0);
    await tester.pump(additionalDelay);
    expect(mockOnEndFunction.called, 1);

    await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
  });

  testWidgets('AnimatedPositionedDirectional onEnd callback test', (WidgetTester tester) async {
    await tester.pumpWidget(wrap(
      child: TestAnimatedWidget(
        callback: mockOnEndFunction.handler,
        switchKey: switchKey,
        state: _TestAnimatedPositionedDirectionalWidgetState(),
      ),
    ));

    final Finder widgetFinder = find.byKey(switchKey);

    await tester.tap(widgetFinder);

    await tester.pump();
    expect(mockOnEndFunction.called, 0);
    await tester.pump(animationDuration);
    expect(mockOnEndFunction.called, 0);
    await tester.pump(additionalDelay);
    expect(mockOnEndFunction.called, 1);

    await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
  });

   testWidgets('AnimatedSlide onEnd callback test', (WidgetTester tester) async {
    await tester.pumpWidget(wrap(
      child: TestAnimatedWidget(
        callback: mockOnEndFunction.handler,
        switchKey: switchKey,
        state: _TestAnimatedSlideWidgetState(),
      ),
    ));

    final Finder widgetFinder = find.byKey(switchKey);

    await tester.tap(widgetFinder);
    await tester.pump();
    expect(mockOnEndFunction.called, 0);
    await tester.pump(animationDuration);
    expect(mockOnEndFunction.called, 0);
    await tester.pump(additionalDelay);
    expect(mockOnEndFunction.called, 1);

    await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
  });

  testWidgets('AnimatedSlide transition test', (WidgetTester tester) async {
    await tester.pumpWidget(wrap(
      child: TestAnimatedWidget(
        switchKey: switchKey,
        state: _TestAnimatedSlideWidgetState(),
      ),
    ));

    final RebuildCountingState<StatefulWidget> state = tester.widget<TestAnimatedWidget>(
      find.byType(TestAnimatedWidget)
    ).rebuildState!;
    final Finder switchFinder = find.byKey(switchKey);
    final SlideTransition slideWidget = tester.widget<SlideTransition>(
      find.ancestor(
        of: find.byType(Placeholder),
        matching: find.byType(SlideTransition),
      ).first,
    );

    expect(state.builds, equals(1));

    await tester.tap(switchFinder);
    expect(state.builds, equals(1));
    await tester.pump();
    expect(slideWidget.position.value, equals(Offset.zero));
    expect(state.builds, equals(2));

    await tester.pump(const Duration(milliseconds: 500));
    expect(slideWidget.position.value, equals(const Offset(0.5,0.5)));
    expect(state.builds, equals(2));
    await tester.pump(const Duration(milliseconds: 250));
    expect(slideWidget.position.value, equals(const Offset(0.75,0.75)));
    expect(state.builds, equals(2));
    await tester.pump(const Duration(milliseconds: 250));
    expect(slideWidget.position.value, equals(const Offset(1,1)));
    expect(state.builds, equals(2));
  });

  testWidgets('AnimatedScale onEnd callback test', (WidgetTester tester) async {
    await tester.pumpWidget(wrap(
      child: TestAnimatedWidget(
        callback: mockOnEndFunction.handler,
        switchKey: switchKey,
        state: _TestAnimatedScaleWidgetState(),
      ),
    ));

    final Finder widgetFinder = find.byKey(switchKey);

    await tester.tap(widgetFinder);
    await tester.pump();
    expect(mockOnEndFunction.called, 0);
    await tester.pump(animationDuration);
    expect(mockOnEndFunction.called, 0);
    await tester.pump(additionalDelay);
    expect(mockOnEndFunction.called, 1);

    await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
  });

  testWidgets('AnimatedScale transition test', (WidgetTester tester) async {
    await tester.pumpWidget(wrap(
      child: TestAnimatedWidget(
        switchKey: switchKey,
        state: _TestAnimatedScaleWidgetState(),
      ),
    ));

    final RebuildCountingState<StatefulWidget> state = tester.widget<TestAnimatedWidget>(
      find.byType(TestAnimatedWidget)
    ).rebuildState!;
    final Finder switchFinder = find.byKey(switchKey);
    final ScaleTransition scaleWidget = tester.widget<ScaleTransition>(
      find.ancestor(
        of: find.byType(Placeholder),
        matching: find.byType(ScaleTransition),
      ).first,
    );

    expect(state.builds, equals(1));

    await tester.tap(switchFinder);
    expect(state.builds, equals(1));
    await tester.pump();
    expect(scaleWidget.scale.value, equals(1.0));
    expect(state.builds, equals(2));

    await tester.pump(const Duration(milliseconds: 500));
    expect(scaleWidget.scale.value, equals(1.5));
    expect(state.builds, equals(2));
    await tester.pump(const Duration(milliseconds: 250));
    expect(scaleWidget.scale.value, equals(1.75));
    expect(state.builds, equals(2));
    await tester.pump(const Duration(milliseconds: 250));
    expect(scaleWidget.scale.value, equals(2.0));
    expect(state.builds, equals(2));
  });

  testWidgets('AnimatedRotation onEnd callback test', (WidgetTester tester) async {
    await tester.pumpWidget(wrap(
      child: TestAnimatedWidget(
        callback: mockOnEndFunction.handler,
        switchKey: switchKey,
        state: _TestAnimatedRotationWidgetState(),
      ),
    ));

    final Finder widgetFinder = find.byKey(switchKey);

    await tester.tap(widgetFinder);
    await tester.pump();
    expect(mockOnEndFunction.called, 0);
    await tester.pump(animationDuration);
    expect(mockOnEndFunction.called, 0);
    await tester.pump(additionalDelay);
    expect(mockOnEndFunction.called, 1);

    await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
  });

  testWidgets('AnimatedRotation transition test', (WidgetTester tester) async {
    await tester.pumpWidget(wrap(
      child: TestAnimatedWidget(
        switchKey: switchKey,
        state: _TestAnimatedRotationWidgetState(),
      ),
    ));

    final RebuildCountingState<StatefulWidget> state = tester.widget<TestAnimatedWidget>(
        find.byType(TestAnimatedWidget)
    ).rebuildState!;
    final Finder switchFinder = find.byKey(switchKey);
    final RotationTransition rotationWidget = tester.widget<RotationTransition>(
      find.ancestor(
        of: find.byType(Placeholder),
        matching: find.byType(RotationTransition),
      ).first,
    );

    expect(state.builds, equals(1));

    await tester.tap(switchFinder);
    expect(state.builds, equals(1));
    await tester.pump();
    expect(rotationWidget.turns.value, equals(0.0));
    expect(state.builds, equals(2));

    await tester.pump(const Duration(milliseconds: 500));
    expect(rotationWidget.turns.value, equals(0.75));
    expect(state.builds, equals(2));
    await tester.pump(const Duration(milliseconds: 250));
    expect(rotationWidget.turns.value, equals(1.125));
    expect(state.builds, equals(2));
    await tester.pump(const Duration(milliseconds: 250));
    expect(rotationWidget.turns.value, equals(1.5));
    expect(state.builds, equals(2));
  });

  testWidgets('AnimatedOpacity onEnd callback test', (WidgetTester tester) async {
    await tester.pumpWidget(wrap(
      child: TestAnimatedWidget(
        callback: mockOnEndFunction.handler,
        switchKey: switchKey,
        state: _TestAnimatedOpacityWidgetState(),
      ),
    ));

    final Finder widgetFinder = find.byKey(switchKey);

    await tester.tap(widgetFinder);
    await tester.pump();
    expect(mockOnEndFunction.called, 0);
    await tester.pump(animationDuration);
    expect(mockOnEndFunction.called, 0);
    await tester.pump(additionalDelay);
    expect(mockOnEndFunction.called, 1);

    await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
  });

  testWidgets('AnimatedOpacity transition test', (WidgetTester tester) async {
    await tester.pumpWidget(wrap(
      child: TestAnimatedWidget(
        switchKey: switchKey,
        state: _TestAnimatedOpacityWidgetState(),
      ),
    ));

    final RebuildCountingState<StatefulWidget> state = tester.widget<TestAnimatedWidget>(
        find.byType(TestAnimatedWidget)
    ).rebuildState!;
    final Finder switchFinder = find.byKey(switchKey);
    final FadeTransition opacityWidget = tester.widget<FadeTransition>(
      find.ancestor(
        of: find.byType(Placeholder),
        matching: find.byType(FadeTransition),
      ).first,
    );

    expect(state.builds, equals(1));

    await tester.tap(switchFinder);
    expect(state.builds, equals(1));
    await tester.pump();
    expect(opacityWidget.opacity.value, equals(0.0));
    expect(state.builds, equals(2));

    await tester.pump(const Duration(milliseconds: 500));
    expect(opacityWidget.opacity.value, equals(0.5));
    expect(state.builds, equals(2));
    await tester.pump(const Duration(milliseconds: 250));
    expect(opacityWidget.opacity.value, equals(0.75));
    expect(state.builds, equals(2));
    await tester.pump(const Duration(milliseconds: 250));
    expect(opacityWidget.opacity.value, equals(1.0));
    expect(state.builds, equals(2));
  });

  testWidgets('AnimatedFractionallySizedBox onEnd callback test', (WidgetTester tester) async {
    await tester.pumpWidget(wrap(
      child: TestAnimatedWidget(
        callback: mockOnEndFunction.handler,
        switchKey: switchKey,
        state: _TestAnimatedFractionallySizedBoxWidgetState(),
      ),
    ));

    final Finder widgetFinder = find.byKey(switchKey);

    await tester.tap(widgetFinder);
    await tester.pump();
    expect(mockOnEndFunction.called, 0);
    await tester.pump(animationDuration);
    expect(mockOnEndFunction.called, 0);
    await tester.pump(additionalDelay);
    expect(mockOnEndFunction.called, 1);

    await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
  });

  testWidgets('SliverAnimatedOpacity onEnd callback test', (WidgetTester tester) async {
    await tester.pumpWidget(TestAnimatedWidget(
      callback: mockOnEndFunction.handler,
      switchKey: switchKey,
      state: _TestSliverAnimatedOpacityWidgetState(),
    ));

    final Finder widgetFinder = find.byKey(switchKey);

    await tester.tap(widgetFinder);

    await tester.pump();
    expect(mockOnEndFunction.called, 0);
    await tester.pump(animationDuration);
    expect(mockOnEndFunction.called, 0);
    await tester.pump(additionalDelay);
    expect(mockOnEndFunction.called, 1);

    await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
  });

  testWidgets('SliverAnimatedOpacity transition test', (WidgetTester tester) async {
    await tester.pumpWidget(wrap(
      child: TestAnimatedWidget(
        switchKey: switchKey,
        state: _TestSliverAnimatedOpacityWidgetState(),
      ),
    ));

    final RebuildCountingState<StatefulWidget> state = tester.widget<TestAnimatedWidget>(
        find.byType(TestAnimatedWidget)
    ).rebuildState!;
    final Finder switchFinder = find.byKey(switchKey);
    final SliverFadeTransition opacityWidget = tester.widget<SliverFadeTransition>(
      find.ancestor(
        of: find.byType(Placeholder),
        matching: find.byType(SliverFadeTransition),
      ).first,
    );

    expect(state.builds, equals(1));

    await tester.tap(switchFinder);
    expect(state.builds, equals(1));
    await tester.pump();
    expect(opacityWidget.opacity.value, equals(0.0));
    expect(state.builds, equals(2));

    await tester.pump(const Duration(milliseconds: 500));
    expect(opacityWidget.opacity.value, equals(0.5));
    expect(state.builds, equals(2));
    await tester.pump(const Duration(milliseconds: 250));
    expect(opacityWidget.opacity.value, equals(0.75));
    expect(state.builds, equals(2));
    await tester.pump(const Duration(milliseconds: 250));
    expect(opacityWidget.opacity.value, equals(1.0));
    expect(state.builds, equals(2));
  });

  testWidgets('AnimatedDefaultTextStyle onEnd callback test', (WidgetTester tester) async {
    await tester.pumpWidget(wrap(
      child: TestAnimatedWidget(
        callback: mockOnEndFunction.handler,
        switchKey: switchKey,
        state: _TestAnimatedDefaultTextStyleWidgetState(),
      ),
    ));

    final Finder widgetFinder = find.byKey(switchKey);

    await tester.tap(widgetFinder);

    await tester.pump();
    expect(mockOnEndFunction.called, 0);
    await tester.pump(animationDuration);
    expect(mockOnEndFunction.called, 0);
    await tester.pump(additionalDelay);
    expect(mockOnEndFunction.called, 1);

    await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
  });

  testWidgets('AnimatedPhysicalModel onEnd callback test', (WidgetTester tester) async {
    await tester.pumpWidget(wrap(
      child: TestAnimatedWidget(
        callback: mockOnEndFunction.handler,
        switchKey: switchKey,
        state: _TestAnimatedPhysicalModelWidgetState(),
      ),
    ));

    final Finder widgetFinder = find.byKey(switchKey);

    await tester.tap(widgetFinder);

    await tester.pump();
    expect(mockOnEndFunction.called, 0);
    await tester.pump(animationDuration);
    expect(mockOnEndFunction.called, 0);
    await tester.pump(additionalDelay);
    expect(mockOnEndFunction.called, 1);

    await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
  });

  testWidgets('TweenAnimationBuilder onEnd callback test', (WidgetTester tester) async {
    await tester.pumpWidget(wrap(
      child: TestAnimatedWidget(
        callback: mockOnEndFunction.handler,
        switchKey: switchKey,
        state: _TestTweenAnimationBuilderWidgetState(),
      ),
    ));

    final Finder widgetFinder = find.byKey(switchKey);

    await tester.tap(widgetFinder);

    await tester.pump();
    expect(mockOnEndFunction.called, 0);
    await tester.pump(animationDuration);
    expect(mockOnEndFunction.called, 0);
    await tester.pump(additionalDelay);
    expect(mockOnEndFunction.called, 1);

    await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
  });

  testWidgets('AnimatedTheme onEnd callback test', (WidgetTester tester) async {
    await tester.pumpWidget(wrap(
      child: TestAnimatedWidget(
        callback: mockOnEndFunction.handler,
        switchKey: switchKey,
        state: _TestAnimatedThemeWidgetState(),
      ),
    ));

    final Finder widgetFinder = find.byKey(switchKey);

    await tester.tap(widgetFinder);

    await tester.pump();
    expect(mockOnEndFunction.called, 0);
    await tester.pump(animationDuration);
    expect(mockOnEndFunction.called, 0);
    await tester.pump(additionalDelay);
    expect(mockOnEndFunction.called, 1);

    await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
  });

  testWidgets('Ensure CurvedAnimations are disposed on widget change',
      (WidgetTester tester) async {
    final GlobalKey<ImplicitlyAnimatedWidgetState<AnimatedOpacity>> key =
        GlobalKey<ImplicitlyAnimatedWidgetState<AnimatedOpacity>>();
    final ValueNotifier<Curve> curve = ValueNotifier<Curve>(const Interval(0.0, 0.5));
    await tester.pumpWidget(wrap(
      child: ValueListenableBuilder<Curve>(
        valueListenable: curve,
        builder: (_, Curve c, __) => AnimatedOpacity(
            key: key,
            opacity: 1.0,
            duration: const Duration(seconds: 1),
            curve: c,
            child: Container(color: Colors.green)),
      ),
    ));

    final ImplicitlyAnimatedWidgetState<AnimatedOpacity>? firstState = key.currentState;
    final Animation<double>? firstAnimation = firstState?.animation;
    if (firstAnimation == null) {
      fail('animation was null!');
    }

    final CurvedAnimation firstCurvedAnimation =
        firstAnimation as CurvedAnimation;

    expect(firstCurvedAnimation.isDisposed, isFalse);

    curve.value = const Interval(0.0, 0.6);
    await tester.pumpAndSettle();

    final ImplicitlyAnimatedWidgetState<AnimatedOpacity>? secondState = key.currentState;
    final Animation<double>? secondAnimation = secondState?.animation;
    if (secondAnimation == null) {
      fail('animation was null!');
    }

    final CurvedAnimation secondCurvedAnimation = secondAnimation as CurvedAnimation;

    expect(firstState, equals(secondState));
    expect(firstAnimation, isNot(equals(secondAnimation)));

    expect(firstCurvedAnimation.isDisposed, isTrue);
    expect(secondCurvedAnimation.isDisposed, isFalse);

    await tester.pumpWidget(
      wrap(
        child: const Offstage(),
      ),
    );
    await tester.pumpAndSettle();

    expect(secondCurvedAnimation.isDisposed, isTrue);
  });
}

Future<void> tapTest2and3(WidgetTester tester, Finder widgetFinder,
    MockOnEndFunction mockOnEndFunction) async {
  await tester.tap(widgetFinder);

  await tester.pump();
  await tester.pump(animationDuration + additionalDelay);
  expect(mockOnEndFunction.called, 2);

  await tester.tap(widgetFinder);

  await tester.pump();
  await tester.pump(animationDuration + additionalDelay);
  expect(mockOnEndFunction.called, 3);
}

Widget wrap({required Widget child}) {
  return Directionality(
    textDirection: TextDirection.ltr,
    child: Material(
      child: Center(child: child),
    ),
  );
}

abstract class RebuildCountingState<T extends StatefulWidget> extends State<T> {
  int builds = 0;
}

class TestAnimatedWidget extends StatefulWidget {
  const TestAnimatedWidget({
    super.key,
    this.callback,
    required this.switchKey,
    required this.state,
  });
  final VoidCallback? callback;
  final Key switchKey;
  final State<StatefulWidget> state;

  RebuildCountingState<StatefulWidget>? get rebuildState =>
    state is RebuildCountingState<StatefulWidget> ? state as RebuildCountingState<StatefulWidget> : null;

  @override
  State<StatefulWidget> createState() => state; // ignore: no_logic_in_create_state, this test predates the lint
}

abstract class _TestAnimatedWidgetState extends RebuildCountingState<TestAnimatedWidget> {
  bool toggle = false;
  final Widget child = const Placeholder();
  final Duration duration = animationDuration;

  void onChanged(bool v) {
    setState(() {
      toggle = v;
    });
  }

  Widget getAnimatedWidget();

  @override
  Widget build(BuildContext context) {
    builds++;
    final Widget animatedWidget = getAnimatedWidget();

    return Stack(
      children: <Widget>[
        animatedWidget,
        Switch(key: widget.switchKey, value: toggle, onChanged: onChanged),
      ],
    );
  }
}

class _TestAnimatedContainerWidgetState extends _TestAnimatedWidgetState {
  @override
  Widget getAnimatedWidget() {
    return AnimatedContainer(
      duration: duration,
      onEnd: widget.callback,
      width: toggle ? 10 : 20,
      foregroundDecoration: toggle ? const BoxDecoration() : null,
      child: child,
    );
  }
}

class _TestAnimatedPaddingWidgetState extends _TestAnimatedWidgetState {
  @override
  Widget getAnimatedWidget() {
    return AnimatedPadding(
      duration: duration,
      onEnd: widget.callback,
      padding:
      toggle ? const EdgeInsets.all(8.0) : const EdgeInsets.all(16.0),
      child: child,
    );
  }
}

class _TestAnimatedAlignWidgetState extends _TestAnimatedWidgetState {
  @override
  Widget getAnimatedWidget() {
    return AnimatedAlign(
      duration: duration,
      onEnd: widget.callback,
      alignment: toggle ? Alignment.topLeft : Alignment.bottomRight,
      child: child,
    );
  }
}

class _TestAnimatedPositionedWidgetState extends _TestAnimatedWidgetState {
  @override
  Widget getAnimatedWidget() {
    return AnimatedPositioned(
      duration: duration,
      onEnd: widget.callback,
      left: toggle ? 10 : 20,
      child: child,
    );
  }
}

class _TestAnimatedPositionedDirectionalWidgetState extends _TestAnimatedWidgetState {
  @override
  Widget getAnimatedWidget() {
    return AnimatedPositionedDirectional(
      duration: duration,
      onEnd: widget.callback,
      start: toggle ? 10 : 20,
      child: child,
    );
  }
}

class _TestAnimatedSlideWidgetState extends _TestAnimatedWidgetState {
  @override
  Widget getAnimatedWidget() {
    return AnimatedSlide(
      duration: duration,
      onEnd: widget.callback,
      offset: toggle ? const Offset(1,1) : Offset.zero,
      child: child,
    );
  }
}

class _TestAnimatedScaleWidgetState extends _TestAnimatedWidgetState {
  @override
  Widget getAnimatedWidget() {
    return AnimatedScale(
      duration: duration,
      onEnd: widget.callback,
      scale: toggle ? 2.0 : 1.0,
      child: child,
    );
  }
}

class _TestAnimatedRotationWidgetState extends _TestAnimatedWidgetState {
  @override
  Widget getAnimatedWidget() {
    return AnimatedRotation(
      duration: duration,
      onEnd: widget.callback,
      turns: toggle ? 1.5 : 0.0,
      child: child,
    );
  }
}

class _TestAnimatedOpacityWidgetState extends _TestAnimatedWidgetState {
  @override
  Widget getAnimatedWidget() {
    return AnimatedOpacity(
      duration: duration,
      onEnd: widget.callback,
      opacity: toggle ? 1.0 : 0.0,
      child: child,
    );
  }
}

class _TestAnimatedFractionallySizedBoxWidgetState extends _TestAnimatedWidgetState {
  @override
  Widget getAnimatedWidget() {
    return AnimatedFractionallySizedBox(
      duration: duration,
      onEnd: widget.callback,
      heightFactor: toggle ? 0.25 : 0.75,
      widthFactor: toggle ? 0.25 : 0.75,
      child: child,
    );
  }
}

class _TestSliverAnimatedOpacityWidgetState extends _TestAnimatedWidgetState {
  @override
  Widget getAnimatedWidget() {
    return SliverAnimatedOpacity(
      sliver: SliverToBoxAdapter(child: child),
      duration: duration,
      onEnd: widget.callback,
      opacity: toggle ? 1.0 : 0.0,
    );
  }

  @override
  Widget build(BuildContext context) {
    builds++;
    final Widget animatedWidget = getAnimatedWidget();

    return Material(
      child: Directionality(
        textDirection: TextDirection.ltr,
        child: CustomScrollView(
          slivers: <Widget>[
            animatedWidget,
            SliverToBoxAdapter(
              child: Switch(
                key: widget.switchKey,
                value: toggle,
                onChanged: onChanged,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _TestAnimatedDefaultTextStyleWidgetState extends _TestAnimatedWidgetState {
  @override
  Widget getAnimatedWidget() {
    return AnimatedDefaultTextStyle(
      duration: duration,
      onEnd: widget.callback,
      style: toggle
        ? const TextStyle(fontStyle: FontStyle.italic)
        : const TextStyle(fontStyle: FontStyle.normal),
      child: child,
    );
  }
}

class _TestAnimatedPhysicalModelWidgetState extends _TestAnimatedWidgetState {
  @override
  Widget getAnimatedWidget() {
    return AnimatedPhysicalModel(
      duration: duration,
      onEnd: widget.callback,
      color: toggle ? Colors.red : Colors.green,
      elevation: 0,
      shadowColor: Colors.blue,
      shape: BoxShape.rectangle,
      child: child,
    );
  }
}

class _TestTweenAnimationBuilderWidgetState extends _TestAnimatedWidgetState {
  @override
  Widget getAnimatedWidget() {
    return TweenAnimationBuilder<double>(
      tween: toggle ? Tween<double>(begin: 1, end: 2) : Tween<double>(begin: 2, end: 1),
      duration: duration,
      onEnd: widget.callback,
      child: child,
      builder: (BuildContext context, double? size, Widget? child) {
        return SizedBox(
          width: size,
          height: size,
          child: child,
        );
      },
    );
  }
}

class _TestAnimatedThemeWidgetState extends _TestAnimatedWidgetState {
  @override
  Widget getAnimatedWidget() {
    return AnimatedTheme(
      data: toggle ? ThemeData.dark() : ThemeData.light(),
      duration: duration,
      onEnd: widget.callback,
      child: child,
    );
  }
}
