// Copyright 2018 The Chromium 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 '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 sample}
/// 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 (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.
    assert(false, 'TweenSequence.evaluate() could not find a interval for $t');
    return null;
  }

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

/// 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 sample}
  ///
  /// 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>';
}
