// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_RENDER_TREE_ANIMATIONS_ANIMATION_LIST_H_
#define COBALT_RENDER_TREE_ANIMATIONS_ANIMATION_LIST_H_

#include <list>

#include "base/bind.h"
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "cobalt/render_tree/movable.h"

namespace cobalt {
namespace render_tree {
namespace animations {

// An animation list is simply that, a list of animations.  Its usefulness over
// a raw std::list or std::vector is that it is a ref counted object and also
// guaranteed to be immutable (and thus, must be created by the associated
// builder object).  The property of being an immutable reference counted object
// allows this object to safely persist while being shared between multiple
// threads.

template <typename T>
class Animation {
 public:
  // An Animation<T>::Function represents a single animation that can be applied
  // on any render_tree::Node object of the specified template type argument.
  //
  // As an example, one could create an animation that linearly interpolates
  // between two color values on a TextNode object by first definining the
  // animation function (assuming ColorRGBA has operator*() defined):
  //
  //   void InterpolateTextColor(
  //       ColorRGBA final_color, base::TimeDelta duration,
  //       TextNode::Builder* text_node, base::TimeDelta time_elapsed) {
  //     if (time_elapsed < duration) {
  //       double progress = time_elapsed.InSecondsF() / duration.InSecondsF();
  //       text_node->color =
  //           text_node->color * (1 - progress) + final_color * progress;
  //     } else {
  //       text_node->color = final_color;
  //     }
  //   }
  //
  // You can then use base::Bind to package this function into a base::Callback
  // that matches the Animation<T>::Function signature:
  //
  //   AnimationList<TextNode>::Builder animation_list_builder;
  //   animation_list_builder.push_back(
  //       base::Bind(&InterpolateTextColor,
  //                  ColorRGBA(0.0f, 1.0f, 0.0f),
  //                  base::TimeDelta::FromSeconds(1)));
  //
  // You can now create an AnimationList object from the AnimationList::Builder
  // and ultimately add that to a AnimateNode::Builder object so that it can be
  // mapped to a specific TextNode that it should be applied to.
  typedef base::Callback<void(typename T::Builder*, base::TimeDelta)> Function;
  typedef base::Callback<void(typename T::Builder*)> TimeIndependentFunction;

  // Helper function to convert from time independent function to a time
  // dependent function.
  static void CallTimeIndependentFunction(
      const TimeIndependentFunction& time_independent_function,
      typename T::Builder* builder, base::TimeDelta time) {
    time_independent_function.Run(builder);
  }
};

// The AnimationListBase is used so that we can acquire a non-template handle
// to an AnimationList, which helps reduce code required in node_animation.h by
// letting us collect animation lists in a single collection, at the cost of
// needing to type cast in a few places.
class AnimationListBase : public base::RefCountedThreadSafe<AnimationListBase> {
 public:
  virtual base::TimeDelta GetExpiry() const = 0;
  virtual base::TimeDelta GetDependsOnTimeExpiry() const = 0;

 protected:
  virtual ~AnimationListBase() {}
  friend class base::RefCountedThreadSafe<AnimationListBase>;
};

// Since animation functions are templated on a specific render tree Node type,
// so must AnimationLists.
template <typename T>
class AnimationList : public AnimationListBase {
 public:
  // The actual data structure used internally to store the list of animations.
  // The decision to use a std::list here instead of say, an std::vector, is
  // because it is anticipated that AnimationLists will commonly have only
  // 1 element in them, since std::list does not make an attempt to reserve
  // capacity in advance, it can save on memory in these instances.
  typedef std::list<typename Animation<T>::Function> InternalList;

  // An object that provides a means to setting up a list before constructing
  // the immutable AnimationList.
  struct Builder {
    DECLARE_AS_MOVABLE(Builder);

    Builder()
        : expiry(base::TimeDelta::Max()),
          depends_on_time_expiry(base::TimeDelta::Max()) {}
    explicit Builder(Moved moved) { animations.swap(moved->animations); }
    explicit Builder(const typename Animation<T>::Function& single_animation,
                     base::TimeDelta expiry)
        : expiry(expiry), depends_on_time_expiry(expiry) {
      animations.push_back(single_animation);
    }
    explicit Builder(
        const typename Animation<T>::TimeIndependentFunction& single_animation,
        base::TimeDelta expiry)
        : expiry(expiry),
          // Since this animation is time independent, we mark its
          // time-dependent expiration to be already expired.
          depends_on_time_expiry(-base::TimeDelta::Max()) {
      // Transform from a time independent function to a time dependent
      // function, since we store all functions as time dependent functions.
      animations.push_back(base::Bind(Animation<T>::CallTimeIndependentFunction,
                                      single_animation));
    }

    InternalList animations;
    // When do the animations expire?  base::TimeDelta::Max() implies that they
    // never expire.
    base::TimeDelta expiry;

    // Similar to |expiry|, but only set for animations that depend on the
    // time parameter passed into their animation callback functions.
    // Optimizations can be performed for animations that don't depend on this.
    base::TimeDelta depends_on_time_expiry;
  };

  explicit AnimationList(typename Builder::Moved builder) : data_(builder) {}
  // Convenience constructor to allow for easy construction of AnimationLists
  // containing a single Animation.  |expiry| indicates the time at which the
  // animation ceases, or base::TimeDelta::Max() if that never occurs.
  explicit AnimationList(
      const typename Animation<T>::Function& single_animation,
      base::TimeDelta expiry)
      : data_(single_animation, expiry) {}
  explicit AnimationList(
      const typename Animation<T>::TimeIndependentFunction& single_animation,
      base::TimeDelta expiry)
      : data_(single_animation, expiry) {}

  const Builder& data() const { return data_; }

  base::TimeDelta GetExpiry() const override { return data_.expiry; }
  base::TimeDelta GetDependsOnTimeExpiry() const override {
    return data_.depends_on_time_expiry;
  }

 private:
  ~AnimationList() override {}

  const Builder data_;

  friend class AnimationListBase;
};

}  // namespace animations
}  // namespace render_tree
}  // namespace cobalt

#endif  // COBALT_RENDER_TREE_ANIMATIONS_ANIMATION_LIST_H_
