// Copyright 2015 Google Inc. 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_LAYOUT_RENDER_TREE_ANIMATIONS_H_
#define COBALT_LAYOUT_RENDER_TREE_ANIMATIONS_H_

#include "base/callback.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/time.h"
#include "cobalt/cssom/css_computed_style_data.h"
#include "cobalt/cssom/css_computed_style_declaration.h"
#include "cobalt/web_animations/animation_set.h"
#include "cobalt/web_animations/baked_animation_set.h"

namespace cobalt {
namespace layout {

// This file declares the function AddAnimations(), which is
// a convenience function that can be used by code that creates render tree
// nodes (e.g. layout box tree processing).

// This callback function defines a function that is expected to populate a
// given CSS style object for a render tree node type.
class PopulateBaseStyleForRenderTreeNode {
 public:
  typedef base::Callback<void(
      const scoped_refptr<const cssom::CSSComputedStyleData>&,
      const scoped_refptr<cssom::CSSComputedStyleData>&)> Function;
};

// This callback function defines a function that is expected to apply a given
// CSS style to a render tree node builder object.  A function meeting this
// specification can be passed into AddAnimations() in order to
// transfer animated CSS values into a render tree Node.  A function that
// satisfies this declaration may also be used to setup a render tree node
// that is not animated.
template <typename T>
class ApplyStyleToRenderTreeNode {
 public:
  typedef base::Callback<void(
      const scoped_refptr<const cssom::CSSComputedStyleData>&,
      typename T::Builder*)> Function;
};

// Helper function that applies an animation set to a base style to produce
// an animated style that is then passed into the provided
// ApplyStyleToRenderTreeNode<T>::Function callback function.
template <typename T>
void ApplyAnimation(
    const typename ApplyStyleToRenderTreeNode<T>::Function&
        apply_style_function,
    const web_animations::BakedAnimationSet& animations,
    const scoped_refptr<cssom::CSSComputedStyleData>& base_style,
    typename T::Builder* node_builder, base::TimeDelta time_elapsed) {
  scoped_refptr<cssom::CSSComputedStyleData> animated_style =
      new cssom::CSSComputedStyleData();
  animated_style->AssignFrom(*base_style);
  animations.Apply(time_elapsed, animated_style);
  apply_style_function.Run(animated_style, node_builder);
}

// If animations exist, this function will add an animation which represents
// the animations to the passed in ApplyAnimation.  The animation will
// target the passed in render tree node.
template <typename T>
void AddAnimations(
    const typename PopulateBaseStyleForRenderTreeNode::Function&
        populate_base_style_function,
    const typename ApplyStyleToRenderTreeNode<T>::Function&
        apply_style_function,
    const cssom::CSSComputedStyleDeclaration& css_computed_style_declaration,
    const scoped_refptr<T>& target_node,
    render_tree::animations::AnimateNode::Builder* node_animation_map_builder) {
  DCHECK(!css_computed_style_declaration.animations()->IsEmpty());

  // Populate the base style.
  scoped_refptr<cssom::CSSComputedStyleData> base_style =
      new cssom::CSSComputedStyleData();
  populate_base_style_function.Run(css_computed_style_declaration.data(),
                                   base_style);

  web_animations::BakedAnimationSet baked_animation_set(
      *css_computed_style_declaration.animations());

  node_animation_map_builder->Add(
      target_node, base::Bind(&ApplyAnimation<T>, apply_style_function,
                              baked_animation_set, base_style),
      baked_animation_set.end_time());
}

}  // namespace layout
}  // namespace cobalt

#endif  // COBALT_LAYOUT_RENDER_TREE_ANIMATIONS_H_
