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

/// An internal representation of a child widget subtree that, now or in the past,
/// was set on the [PageTransitionSwitcher.child] field and is now in the process of
/// transitioning.
///
/// The internal representation includes fields that we don't want to expose to
/// the public API (like the controllers).
class _ChildEntry {
  /// Creates a [_ChildEntry].
  ///
  /// The [primaryController], [secondaryController], [transition] and
  /// [widgetChild] parameters must not be null.
  _ChildEntry({
    required this.primaryController,
    required this.secondaryController,
    required this.transition,
    required this.widgetChild,
  });

  /// The animation controller for the child's transition.
  final AnimationController primaryController;

  /// The (curved) animation being used to drive the transition.
  final AnimationController secondaryController;

  /// The currently built transition for this child.
  Widget transition;

  /// The widget's child at the time this entry was created or updated.
  /// Used to rebuild the transition if necessary.
  Widget widgetChild;

  /// Release the resources used by this object.
  ///
  /// The object is no longer usable after this method is called.
  void dispose() {
    primaryController.dispose();
    secondaryController.dispose();
  }

  @override
  String toString() {
    return 'PageTransitionSwitcherEntry#${shortHash(this)}($widgetChild)';
  }
}

/// Signature for builders used to generate custom layouts for
/// [PageTransitionSwitcher].
///
/// The builder should return a widget which contains the given children, laid
/// out as desired. It must not return null. The builder should be able to
/// handle an empty list of `entries`.
typedef PageTransitionSwitcherLayoutBuilder = Widget Function(
  List<Widget> entries,
);

/// Signature for builders used to generate custom transitions for
/// [PageTransitionSwitcher].
///
/// The function should return a widget which wraps the given `child`.
///
/// When a [PageTransitionSwitcher]'s `child` is replaced, the new child's
/// `primaryAnimation` runs forward and the value of its `secondaryAnimation` is
/// usually fixed at 0.0. At the same time, the old child's `secondaryAnimation`
/// runs forward, and the value of its primaryAnimation is usually fixed at 1.0.
///
/// The widget returned by the [PageTransitionSwitcherTransitionBuilder] can
/// incorporate both animations. It will use the primary animation to define how
/// its child appears, and the secondary animation to define how its child
/// disappears.
typedef PageTransitionSwitcherTransitionBuilder = Widget Function(
  Widget child,
  Animation<double> primaryAnimation,
  Animation<double> secondaryAnimation,
);

/// A widget that transitions from an old child to a new child whenever [child]
/// changes using an animation specified by [transitionBuilder].
///
/// This is a variation of an [AnimatedSwitcher], but instead of using the
/// same transition for enter and exit, two separate transitions can be
/// specified, similar to how the enter and exit transitions of a [PageRoute]
/// are defined.
///
/// When a new [child] is specified, the [transitionBuilder] is effectively
/// applied twice, once to the old child and once to the new one. When
/// [reverse] is false, the old child's `secondaryAnimation` runs forward, and
/// the value of its `primaryAnimation` is usually fixed at 1.0. The new child's
/// `primaryAnimation` runs forward and the value of its `secondaryAnimation` is
/// usually fixed at 0.0. The widget returned by the [transitionBuilder] can
/// incorporate both animations. It will use the primary animation to define how
/// its child appears, and the secondary animation to define how its child
/// disappears. This is similar to the transition associated with pushing a new
/// [PageRoute] on top of another.
///
/// When [reverse] is true, the old child's `primaryAnimation` runs in reverse
/// and the value of its `secondaryAnimation` is usually fixed at 0.0. The new
/// child's `secondaryAnimation` runs in reverse and the value of its
/// `primaryAnimation` is usually fixed at 1.0. This is similar to popping a
/// [PageRoute] to reveal another [PageRoute] underneath it.
///
/// This process is the same as the one used by [PageRoute.buildTransitions].
///
/// The following example shows a [transitionBuilder] that slides out the
/// old child to the right (driven by the `secondaryAnimation`) while the new
/// child fades in (driven by the `primaryAnimation`):
///
/// ```dart
/// transitionBuilder: (
///   Widget child,
///   Animation<double> primaryAnimation,
///   Animation<double> secondaryAnimation,
/// ) {
///   return SlideTransition(
///     position: Tween<Offset>(
///       begin: Offset.zero,
///       end: const Offset(1.5, 0.0),
///     ).animate(secondaryAnimation),
///     child: FadeTransition(
///       opacity: Tween<double>(
///         begin: 0.0,
///         end: 1.0,
///       ).animate(primaryAnimation),
///       child: child,
///     ),
///   );
/// },
/// ```
///
/// If the children are swapped fast enough (i.e. before [duration] elapses),
/// more than one old child can exist and be transitioning out while the
/// newest one is transitioning in.
///
/// If the *new* child is the same widget type and key as the *old* child,
/// but with different parameters, then [PageTransitionSwitcher] will *not* do a
/// transition between them, since as far as the framework is concerned, they
/// are the same widget and the existing widget can be updated with the new
/// parameters. To force the transition to occur, set a [Key] on each child
/// widget that you wish to be considered unique (typically a [ValueKey] on the
/// widget data that distinguishes this child from the others). For example,
/// changing the child from `SizedBox(width: 10)` to `SizedBox(width: 100)`
/// would not trigger a transition but changing the child from
/// `SizedBox(width: 10)` to `SizedBox(key: Key('foo'), width: 100)` would.
/// Similarly, changing the child to `Container(width: 10)` would trigger a
/// transition.
///
/// The same key can be used for a new child as was used for an already-outgoing
/// child; the two will not be considered related. For example, if a progress
/// indicator with key A is first shown, then an image with key B, then another
/// progress indicator with key A again, all in rapid succession, then the old
/// progress indicator and the image will be fading out while a new progress
/// indicator is fading in.
///
/// PageTransitionSwitcher uses the [layoutBuilder] property to lay out the
/// old and new child widgets. By default, [defaultLayoutBuilder] is used.
/// See the documentation for [layoutBuilder] for suggestions on how to
/// configure the layout of the incoming and outgoing child widgets if
/// [defaultLayoutBuilder] is not your desired layout.
class PageTransitionSwitcher extends StatefulWidget {
  /// Creates a [PageTransitionSwitcher].
  ///
  /// The [duration], [reverse], and [transitionBuilder] parameters
  /// must not be null.
  const PageTransitionSwitcher({
    Key? key,
    this.duration = const Duration(milliseconds: 300),
    this.reverse = false,
    required this.transitionBuilder,
    this.layoutBuilder = defaultLayoutBuilder,
    this.child,
  }) : super(key: key);

  /// The current child widget to display.
  ///
  /// If there was an old child, it will be transitioned out using the
  /// secondary animation of the [transitionBuilder], while the new child
  /// transitions in using the primary animation of the [transitionBuilder].
  ///
  /// If there was no old child, then this child will transition in using
  /// the primary animation of the [transitionBuilder].
  ///
  /// The child is considered to be "new" if it has a different type or [Key]
  /// (see [Widget.canUpdate]).
  final Widget? child;

  /// The duration of the transition from the old [child] value to the new one.
  ///
  /// This duration is applied to the given [child] when that property is set to
  /// a new child. Changing [duration] will not affect the durations of
  /// transitions already in progress.
  final Duration duration;

  /// Indicates whether the new [child] will visually appear on top of or
  /// underneath the old child.
  ///
  /// When this is false, the new child will transition in on top of the
  /// old child while its primary animation and the secondary
  /// animation of the old child are running forward. This is similar to
  /// the transition associated with pushing a new [PageRoute] on top of
  /// another.
  ///
  /// When this is true, the new child will transition in below the
  /// old child while its secondary animation and the primary
  /// animation of the old child are running in reverse. This is similar to
  /// the transition associated with popping a [PageRoute] to reveal a new
  /// [PageRoute] below it.
  final bool reverse;

  /// A function that wraps a new [child] with a primary and secondary animation
  /// set define how the child appears and disappears.
  ///
  /// This is only called when a new [child] is set (not for each build), or
  /// when a new [transitionBuilder] is set. If a new [transitionBuilder] is
  /// set, then the transition is rebuilt for the current child and all old
  /// children using the new [transitionBuilder]. The function must not return
  /// null.
  ///
  /// The child provided to the transitionBuilder may be null.
  final PageTransitionSwitcherTransitionBuilder transitionBuilder;

  /// A function that wraps all of the children that are transitioning out, and
  /// the [child] that's transitioning in, with a widget that lays all of them
  /// out. This is called every time this widget is built. The function must not
  /// return null.
  ///
  /// The default [PageTransitionSwitcherLayoutBuilder] used is
  /// [defaultLayoutBuilder].
  ///
  /// The following example shows a [layoutBuilder] that places all entries in a
  /// [Stack] that sizes itself to match the largest of the active entries.
  /// All children are aligned on the top left corner of the [Stack].
  ///
  /// ```dart
  /// PageTransitionSwitcher(
  ///   duration: const Duration(milliseconds: 100),
  ///   child: Container(color: Colors.red),
  ///   layoutBuilder: (
  ///     List<Widget> entries,
  ///   ) {
  ///     return Stack(
  ///       children: entries,
  ///       alignment: Alignment.topLeft,
  ///     );
  ///   },
  /// ),
  /// ```
  /// See [PageTransitionSwitcherLayoutBuilder] for more information about
  /// how a layout builder should function.
  final PageTransitionSwitcherLayoutBuilder layoutBuilder;

  /// The default layout builder for [PageTransitionSwitcher].
  ///
  /// This function is the default way for how the new and old child widgets are placed
  /// during the transition between the two widgets. All children are placed in a
  /// [Stack] that sizes itself to match the largest of the child or a previous child.
  /// The children are centered on each other.
  ///
  /// See [PageTransitionSwitcherTransitionBuilder] for more information on the function
  /// signature.
  static Widget defaultLayoutBuilder(List<Widget> entries) {
    return Stack(
      children: entries,
      alignment: Alignment.center,
    );
  }

  @override
  _PageTransitionSwitcherState createState() => _PageTransitionSwitcherState();
}

class _PageTransitionSwitcherState extends State<PageTransitionSwitcher>
    with TickerProviderStateMixin {
  final List<_ChildEntry> _activeEntries = <_ChildEntry>[];
  _ChildEntry? _currentEntry;
  int _childNumber = 0;

  @override
  void initState() {
    super.initState();
    _addEntryForNewChild(shouldAnimate: false);
  }

  @override
  void didUpdateWidget(PageTransitionSwitcher oldWidget) {
    super.didUpdateWidget(oldWidget);

    // If the transition builder changed, then update all of the old
    // transitions.
    if (widget.transitionBuilder != oldWidget.transitionBuilder) {
      _activeEntries.forEach(_updateTransitionForEntry);
    }

    final bool hasNewChild = widget.child != null;
    final bool hasOldChild = _currentEntry != null;
    if (hasNewChild != hasOldChild ||
        hasNewChild &&
            !Widget.canUpdate(widget.child!, _currentEntry!.widgetChild)) {
      // Child has changed, fade current entry out and add new entry.
      _childNumber += 1;
      _addEntryForNewChild(shouldAnimate: true);
    } else if (_currentEntry != null) {
      assert(hasOldChild && hasNewChild);
      assert(Widget.canUpdate(widget.child!, _currentEntry!.widgetChild));
      // Child has been updated. Make sure we update the child widget and
      // transition in _currentEntry even though we're not going to start a new
      // animation, but keep the key from the old transition so that we
      // update the transition instead of replacing it.
      _currentEntry!.widgetChild = widget.child!;
      _updateTransitionForEntry(_currentEntry!); // uses entry.widgetChild
    }
  }

  void _addEntryForNewChild({required bool shouldAnimate}) {
    assert(shouldAnimate || _currentEntry == null);
    if (_currentEntry != null) {
      assert(shouldAnimate);
      if (widget.reverse) {
        _currentEntry!.primaryController.reverse();
      } else {
        _currentEntry!.secondaryController.forward();
      }
      _currentEntry = null;
    }
    if (widget.child == null) {
      return;
    }
    final AnimationController primaryController = AnimationController(
      duration: widget.duration,
      vsync: this,
    );
    final AnimationController secondaryController = AnimationController(
      duration: widget.duration,
      vsync: this,
    );
    if (shouldAnimate) {
      if (widget.reverse) {
        primaryController.value = 1.0;
        secondaryController.value = 1.0;
        secondaryController.reverse();
      } else {
        primaryController.forward();
      }
    } else {
      assert(_activeEntries.isEmpty);
      primaryController.value = 1.0;
    }
    _currentEntry = _newEntry(
      child: widget.child!,
      primaryController: primaryController,
      secondaryController: secondaryController,
      builder: widget.transitionBuilder,
    );
    if (widget.reverse && _activeEntries.isNotEmpty) {
      // Add below old child.
      _activeEntries.insert(_activeEntries.length - 1, _currentEntry!);
    } else {
      // Add on top of old child.
      _activeEntries.add(_currentEntry!);
    }
  }

  _ChildEntry _newEntry({
    required Widget child,
    required PageTransitionSwitcherTransitionBuilder builder,
    required AnimationController primaryController,
    required AnimationController secondaryController,
  }) {
    final Widget transition = builder(
      child,
      primaryController,
      secondaryController,
    );
    final _ChildEntry entry = _ChildEntry(
      widgetChild: child,
      transition: KeyedSubtree.wrap(
        transition,
        _childNumber,
      ),
      primaryController: primaryController,
      secondaryController: secondaryController,
    );
    secondaryController.addStatusListener((AnimationStatus status) {
      if (status == AnimationStatus.completed) {
        assert(mounted);
        assert(_activeEntries.contains(entry));
        setState(() {
          _activeEntries.remove(entry);
          entry.dispose();
        });
      }
    });
    primaryController.addStatusListener((AnimationStatus status) {
      if (status == AnimationStatus.dismissed) {
        assert(mounted);
        assert(_activeEntries.contains(entry));
        setState(() {
          _activeEntries.remove(entry);
          entry.dispose();
        });
      }
    });
    return entry;
  }

  void _updateTransitionForEntry(_ChildEntry entry) {
    final Widget transition = widget.transitionBuilder(
      entry.widgetChild,
      entry.primaryController,
      entry.secondaryController,
    );
    entry.transition = KeyedSubtree(
      key: entry.transition.key,
      child: transition,
    );
  }

  @override
  void dispose() {
    for (final _ChildEntry entry in _activeEntries) {
      entry.dispose();
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return widget.layoutBuilder(_activeEntries
        .map<Widget>((_ChildEntry entry) => entry.transition)
        .toList());
  }
}
