// 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 'animation.dart';
import 'tween.dart';

// Examples can assume:
// late AnimationController myAnimationController;

/// Enables creating an [Animation] whose value is defined by a sequence of
/// [Tween]s.
///
/// Each [TweenSequenceItem] has a weight that defines its percentage of the
/// animation's duration. Each tween defines the animation's value during the
/// interval indicated by its weight.
///
/// {@tool snippet}
/// This example defines an animation that uses an easing curve to interpolate
/// between 5.0 and 10.0 during the first 40% of the animation, remains at 10.0
/// for the next 20%, and then returns to 5.0 for the final 40%.
///
/// ```dart
/// final Animation<double> animation = TweenSequence<double>(
///   <TweenSequenceItem<double>>[
///     TweenSequenceItem<double>(
///       tween: Tween<double>(begin: 5.0, end: 10.0)
///         .chain(CurveTween(curve: Curves.ease)),
///       weight: 40.0,
///     ),
///     TweenSequenceItem<double>(
///       tween: ConstantTween<double>(10.0),
///       weight: 20.0,
///     ),
///     TweenSequenceItem<double>(
///       tween: Tween<double>(begin: 10.0, end: 5.0)
///         .chain(CurveTween(curve: Curves.ease)),
///       weight: 40.0,
///     ),
///   ],
/// ).animate(myAnimationController);
/// ```
/// {@end-tool}
class TweenSequence<T> extends Animatable<T> {
  /// Construct a TweenSequence.
  ///
  /// The [items] parameter must be a list of one or more [TweenSequenceItem]s.
  ///
  /// There's a small cost associated with building a `TweenSequence` so it's
  /// best to reuse one, rather than rebuilding it on every frame, when that's
  /// possible.
  TweenSequence(List<TweenSequenceItem<T>> items)
      : assert(items != null),
        assert(items.isNotEmpty) {
    _items.addAll(items);

    double totalWeight = 0.0;
    for (final TweenSequenceItem<T> item in _items)
      totalWeight += item.weight;
    assert(totalWeight > 0.0);

    double start = 0.0;
    for (int i = 0; i < _items.length; i += 1) {
      final double end = i == _items.length - 1 ? 1.0 : start + _items[i].weight / totalWeight;
      _intervals.add(_Interval(start, end));
      start = end;
    }
  }

  final List<TweenSequenceItem<T>> _items = <TweenSequenceItem<T>>[];
  final List<_Interval> _intervals = <_Interval>[];

  T _evaluateAt(double t, int index) {
    final TweenSequenceItem<T> element = _items[index];
    final double tInterval = _intervals[index].value(t);
    return element.tween.transform(tInterval);
  }

  @override
  T transform(double t) {
    assert(t >= 0.0 && t <= 1.0);
    if (t == 1.0)
      return _evaluateAt(t, _items.length - 1);
    for (int index = 0; index < _items.length; index++) {
      if (_intervals[index].contains(t))
        return _evaluateAt(t, index);
    }
    // Should be unreachable.
    throw StateError('TweenSequence.evaluate() could not find an interval for $t');
  }

  @override
  String toString() => 'TweenSequence(${_items.length} items)';
}

/// Enables creating a flipped [Animation] whose value is defined by a sequence
/// of [Tween]s.
///
/// This creates a [TweenSequence] that evaluates to a result that flips the
/// tween both horizontally and vertically.
///
/// This tween sequence assumes that the evaluated result has to be a double
/// between 0.0 and 1.0.
class FlippedTweenSequence extends TweenSequence<double> {
  /// Creates a flipped [TweenSequence].
  ///
  /// The [items] parameter must be a list of one or more [TweenSequenceItem]s.
  ///
  /// There's a small cost associated with building a `TweenSequence` so it's
  /// best to reuse one, rather than rebuilding it on every frame, when that's
  /// possible.
  FlippedTweenSequence(super.items)
    : assert(items != null);

  @override
  double transform(double t) => 1 - super.transform(1 - t);
}

/// A simple holder for one element of a [TweenSequence].
class TweenSequenceItem<T> {
  /// Construct a TweenSequenceItem.
  ///
  /// The [tween] must not be null and [weight] must be greater than 0.0.
  const TweenSequenceItem({
    required this.tween,
    required this.weight,
  }) : assert(tween != null),
       assert(weight != null),
       assert(weight > 0.0);

  /// Defines the value of the [TweenSequence] for the interval within the
  /// animation's duration indicated by [weight] and this item's position
  /// in the list of items.
  ///
  /// {@tool snippet}
  ///
  /// The value of this item can be "curved" by chaining it to a [CurveTween].
  /// For example to create a tween that eases from 0.0 to 10.0:
  ///
  /// ```dart
  /// Tween<double>(begin: 0.0, end: 10.0)
  ///   .chain(CurveTween(curve: Curves.ease))
  /// ```
  /// {@end-tool}
  final Animatable<T> tween;

  /// An arbitrary value that indicates the relative percentage of a
  /// [TweenSequence] animation's duration when [tween] will be used.
  ///
  /// The percentage for an individual item is the item's weight divided by the
  /// sum of all of the items' weights.
  final double weight;
}

class _Interval {
  const _Interval(this.start, this.end) : assert(end > start);

  final double start;
  final double end;

  bool contains(double t) => t >= start && t < end;

  double value(double t) => (t - start) / (end - start);

  @override
  String toString() => '<$start, $end>';
}
