// 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_WEB_ANIMATIONS_KEYFRAME_EFFECT_READ_ONLY_H_
#define COBALT_WEB_ANIMATIONS_KEYFRAME_EFFECT_READ_ONLY_H_

#include <set>
#include <vector>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "cobalt/cssom/css_computed_style_data.h"
#include "cobalt/cssom/property_definitions.h"
#include "cobalt/script/wrappable.h"
#include "cobalt/web_animations/animatable.h"
#include "cobalt/web_animations/animation_effect_read_only.h"
#include "cobalt/web_animations/keyframe.h"

namespace cobalt {
namespace web_animations {

// Keyframe effects are represented by the KeyframeEffectReadOnly interface.
//   https://www.w3.org/TR/2015/WD-web-animations-1-20150707/#the-keyframeeffect-interfaces
// This class contains a sequence of keyframes which define an effect.  Each
// keyframe specifies an offset and values for a set of CSS properties.  All
// keyframes are normalized to be between 0 and 1, and the responsibility for
// converting from an Animation's local time to a value between 0 and 1 lies
// within AnimationEffectTimingReadOnly, an object owned by
// AnimationEffectReadOnly, this class's superclass.
class KeyframeEffectReadOnly : public AnimationEffectReadOnly {
 public:
  class Data {
   public:
    explicit Data(const std::vector<Keyframe::Data>& keyframes);
    explicit Data(const std::vector<scoped_refptr<Keyframe> >& keyframes);

    typedef std::vector<Keyframe::Data> KeyframeSequence;
    const KeyframeSequence& keyframes() const { return keyframes_; }

    // Returns true if the given property is referenced by any of this effect's
    // keyframes.
    bool IsPropertyAnimated(cssom::PropertyKey property_name) const;

    // Returns true if the given property is the only property referenced by any
    // of this effect's keyframes.
    bool IsOnlyPropertyAnimated(cssom::PropertyKey property_name) const;

    // Applies the underlying effect to the given input CSS style, animating
    // all properties of the style that are referenced by this effect, and
    // updating the provided CSS style to reflect the output animated style,
    // given the current iteration progress and current_iteration.
    void ApplyAnimation(
        const scoped_refptr<cssom::MutableCSSComputedStyleData>& in_out_style,
        double iteration_progress, double current_iteration) const;

    // Applies this effect to a single property value, accepting the underlying
    // value of that property value as input and returning an animated
    // property value as output.
    scoped_refptr<cssom::PropertyValue> ComputeAnimatedPropertyValue(
        cssom::PropertyKey target_property,
        const scoped_refptr<cssom::PropertyValue>& underlying_value,
        double iteration_progress, double current_iteration) const;

   private:
    void CheckKeyframesSorted() const;
    void PopulatePropertiesAffected();

    // A list of keyframes sorted by offset.
    KeyframeSequence keyframes_;

    // The set of properties that are affected by this animation.
    std::set<cssom::PropertyKey> properties_affected_;
  };

  KeyframeEffectReadOnly(
      const scoped_refptr<AnimationEffectTimingReadOnly>& timing,
      const scoped_refptr<Animatable>& target,
      const std::vector<scoped_refptr<Keyframe> >& frames);
  KeyframeEffectReadOnly(
      const scoped_refptr<AnimationEffectTimingReadOnly>& timing,
      const scoped_refptr<Animatable>& target,
      const std::vector<Keyframe::Data>& frames);

  scoped_refptr<Animatable> target() const { return target_; }

  // Custom, not in any spec.
  const Data& data() const { return data_; }

  DEFINE_WRAPPABLE_TYPE(KeyframeEffectReadOnly);
  void TraceMembers(script::Tracer* tracer) override;

 private:
  ~KeyframeEffectReadOnly() override {}

  scoped_refptr<Animatable> target_;

  Data data_;

  DISALLOW_COPY_AND_ASSIGN(KeyframeEffectReadOnly);
};

}  // namespace web_animations
}  // namespace cobalt

#endif  // COBALT_WEB_ANIMATIONS_KEYFRAME_EFFECT_READ_ONLY_H_
