// 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_H_
#define COBALT_WEB_ANIMATIONS_KEYFRAME_H_

#include <map>
#include <string>
#include <utility>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/containers/small_map.h"
#include "base/logging.h"
#include "base/optional.h"
#include "cobalt/cssom/property_definitions.h"
#include "cobalt/cssom/property_value.h"
#include "cobalt/cssom/timing_function.h"
#include "cobalt/script/wrappable.h"

namespace cobalt {
namespace web_animations {

// Individual keyframes are represented by a special kind of Keyframe dictionary
// type whose members map to the properties to be animated.
//   https://www.w3.org/TR/2015/WD-web-animations-1-20150707/#the-keyframe-dictionary
// A Keyframe associates target values for a set of CSS properties to a
// particular normalized offset between 0 and 1.
class Keyframe : public script::Wrappable {
 public:
  // Contains all data associated with a Keyframe.  As an object separate from
  // Keyframe, it can be extracted out of a Keyframe object and copied around
  // externally as needed.
  class Data {
   public:
    Data() : easing_(cssom::TimingFunction::GetLinear()) {}

    explicit Data(double offset)
        : offset_(offset), easing_(cssom::TimingFunction::GetLinear()) {}

    Data(double offset, const scoped_refptr<cssom::TimingFunction>& easing)
        : offset_(offset), easing_(easing) {}

    const base::Optional<double>& offset() const { return offset_; }
    void set_offset(const base::Optional<double>& offset) { offset_ = offset; }

    const scoped_refptr<cssom::TimingFunction>& easing() const {
      return easing_;
    }
    void set_easing(const scoped_refptr<cssom::TimingFunction>& easing) {
      easing_ = easing;
    }

    // A Keyframe is specified to be a dictionary, not an interface, so the
    // property names and values are simply specified as additional key/value
    // entries into the Keyframe dictionary, on top of 'offset' and 'easing'.
    // Here though, we explicitly introduce a map for property names to
    // property values at this keyframe.
    typedef base::small_map<
        std::map<cssom::PropertyKey, scoped_refptr<cssom::PropertyValue> >, 2>
        PropertyValueMap;
    const PropertyValueMap& property_values() const { return property_values_; }

    bool AffectsProperty(cssom::PropertyKey property) const {
      return property_values_.find(property) != property_values_.end();
    }

    void AddPropertyValue(cssom::PropertyKey property,
                          scoped_refptr<cssom::PropertyValue> property_value) {
      property_values_.insert(std::make_pair(property, property_value));
    }

   private:
    base::Optional<double> offset_;
    scoped_refptr<cssom::TimingFunction> easing_;
    PropertyValueMap property_values_;
  };

  Keyframe() {}

  const base::Optional<double>& offset() const { return data_.offset(); }
  void set_offset(const base::Optional<double>& offset) {
    data_.set_offset(offset);
  }

  std::string easing() const {
    NOTIMPLEMENTED();
    return std::string("linear");
  }
  void set_easing(const std::string& easing) { NOTIMPLEMENTED(); }

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

  DEFINE_WRAPPABLE_TYPE(Keyframe);

 private:
  ~Keyframe() override {}

  Data data_;

  DISALLOW_COPY_AND_ASSIGN(Keyframe);
};

}  // namespace web_animations
}  // namespace cobalt

#endif  // COBALT_WEB_ANIMATIONS_KEYFRAME_H_
