// 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:
// 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(
///   <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(List<TweenSequenceItem<double>> items)
    : assert(items != null),
      super(items);

  @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>';
}
