// 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(
      alignment: Alignment.center,
      children: entries,
    );
  }

  @override
  State<PageTransitionSwitcher> 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());
  }
}
