// 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.

#include "cobalt/dom/css_animations_adapter.h"

#include <vector>

#include "cobalt/base/tokens.h"
#include "cobalt/cssom/css_declared_style_data.h"
#include "cobalt/cssom/css_keyframes_rule.h"
#include "cobalt/cssom/property_definitions.h"
#include "cobalt/cssom/timing_function_list_value.h"
#include "cobalt/dom/animation_event.h"
#include "cobalt/dom/dom_animatable.h"
#include "cobalt/web_animations/keyframe.h"
#include "cobalt/web_animations/keyframe_effect_read_only.h"

namespace cobalt {
namespace dom {

CSSAnimationsAdapter::CSSAnimationsAdapter(
    const scoped_refptr<dom::DOMAnimatable>& target)
    : animatable_(target) {}

CSSAnimationsAdapter::~CSSAnimationsAdapter() {
  for (AnimationMap::iterator iter = animation_map_.begin();
       iter != animation_map_.end(); ++iter) {
    delete iter->second;
  }
}

namespace {
// Convert a cssom::Animation::FillMode enum value to a
// web_animations::AnimationEffectTimingReadOnly::FillMode value.
web_animations::AnimationEffectTimingReadOnly::FillMode CSSToWebFillMode(
    cssom::Animation::FillMode css_fill_mode) {
  switch (css_fill_mode) {
    case cssom::Animation::kNone:
      return web_animations::AnimationEffectTimingReadOnly::kNone;
    case cssom::Animation::kForwards:
      return web_animations::AnimationEffectTimingReadOnly::kForwards;
    case cssom::Animation::kBackwards:
      return web_animations::AnimationEffectTimingReadOnly::kBackwards;
    case cssom::Animation::kBoth:
      return web_animations::AnimationEffectTimingReadOnly::kBoth;
  }

  NOTREACHED();
  return web_animations::AnimationEffectTimingReadOnly::kNone;
}

// Convert a cssom::Animation::PlaybackDirection enum value to a
// web_animations::AnimationEffectTimingReadOnly::PlaybackDirection value.
web_animations::AnimationEffectTimingReadOnly::PlaybackDirection
CSSToWebDirection(cssom::Animation::PlaybackDirection css_direction) {
  switch (css_direction) {
    case cssom::Animation::kNormal:
      return web_animations::AnimationEffectTimingReadOnly::kNormal;
    case cssom::Animation::kReverse:
      return web_animations::AnimationEffectTimingReadOnly::kReverse;
    case cssom::Animation::kAlternate:
      return web_animations::AnimationEffectTimingReadOnly::kAlternate;
    case cssom::Animation::kAlternateReverse:
      return web_animations::AnimationEffectTimingReadOnly::kAlternateReverse;
  }

  NOTREACHED();
  return web_animations::AnimationEffectTimingReadOnly::kNormal;
}

scoped_refptr<cssom::TimingFunction> GetTimingFunctionFromKeyframePropertyValue(
    const scoped_refptr<cssom::PropertyValue>& value) {
  // An 'animation-timing-function' specified as a property value in a keyframe
  // means that we should use the first value (since animation-timing-function
  // is a list) as the keyframe's timing function.
  return base::polymorphic_downcast<cssom::TimingFunctionListValue*>(
             value.get())
      ->value()[0];
}

std::vector<web_animations::Keyframe::Data>
ConvertCSSKeyframesToWebAnimationsKeyframes(
    const cssom::CSSKeyframesRule& keyframes,
    const scoped_refptr<cssom::TimingFunction>& default_timing_function) {
  // https://drafts.csswg.org/date/2015-03-02/web-animations-css-integration/#conversion-of-css-keyframes
  const std::vector<cssom::CSSKeyframesRule::KeyframeInfo>&
      sorted_css_keyframes = keyframes.sorted_keyframes();

  // 1. Initialize an empty list keyframeList.
  std::vector<web_animations::Keyframe::Data> keyframe_list;
  if (sorted_css_keyframes.empty()) {
    return keyframe_list;
  }
  keyframe_list.reserve(sorted_css_keyframes.size());

  // 2. For each keyframe in keyframes:
  for (size_t i = 0; i < sorted_css_keyframes.size(); ++i) {
    const cssom::CSSKeyframesRule::KeyframeInfo& keyframe(
        sorted_css_keyframes[i]);

    // 2.1. Create a new dictionary newKeyframe.
    // 2.2. Set newKeyframe's offset to the offset defined by keyframe.
    web_animations::Keyframe::Data new_keyframe(keyframe.offset);
    bool easing_was_set = false;
    // 2.4. For each property defined in keyframe:
    for (cssom::CSSDeclaredStyleData::PropertyValues::const_iterator iter =
             keyframe.style->declared_property_values().begin();
         iter != keyframe.style->declared_property_values().end(); ++iter) {
      // 2.3. If keyframe defines an animation-timing-function, set
      //      newKeyframe's easing to the defined animation-timing-function.
      if (iter->first == cssom::kAnimationTimingFunctionProperty) {
        new_keyframe.set_easing(
            GetTimingFunctionFromKeyframePropertyValue(iter->second));
        easing_was_set = true;
      } else {
        // 2.4.1. Set newKeyframe[property] to the value associated with that
        //        property in keyframe
        new_keyframe.AddPropertyValue(iter->first, iter->second);
      }
    }

    if (!easing_was_set) {
      // If no keyframe-specific easing was specified, use the animation's
      // default easing value for this keyframe.
      new_keyframe.set_easing(default_timing_function);
    }

    // 3. Add newKeyframe to keyframeList.
    keyframe_list.push_back(new_keyframe);
  }

  return keyframe_list;
}
}  // namespace

void CSSAnimationsAdapter::OnAnimationStarted(
    const cssom::Animation& css_animation) {
  // The process for constructing web animations from CSS animations is
  // specified here:
  //   https://drafts.csswg.org/date/2015-03-02/web-animations-css-integration/#css-animations

  // Transfer the CSS Animation timing information into a Web Animations
  // AnimationEffectTimingReadOnly object.
  // https://drafts.csswg.org/date/2015-03-02/web-animations-css-integration/#web-animations-instantiation
  scoped_refptr<web_animations::AnimationEffectTimingReadOnly> timing_input(
      new web_animations::AnimationEffectTimingReadOnly(
          css_animation.delay(), base::TimeDelta(),
          CSSToWebFillMode(css_animation.fill_mode()), 0.0,
          css_animation.iteration_count(), css_animation.duration(),
          CSSToWebDirection(css_animation.direction()),
          cssom::TimingFunction::GetLinear()));

  // Construct the web_animations keyframe data from the CSS Animations keyframe
  // data.
  scoped_refptr<web_animations::KeyframeEffectReadOnly> keyframe_effect(
      new web_animations::KeyframeEffectReadOnly(
          timing_input, animatable_,
          ConvertCSSKeyframesToWebAnimationsKeyframes(
              *css_animation.keyframes(), css_animation.timing_function())));

  // Finally setup and play our animation.
  scoped_refptr<web_animations::Animation> web_animation(
      new web_animations::Animation(keyframe_effect,
                                    animatable_->GetDefaultTimeline()));

  // Setup an event handler on the animation so we can watch for when it enters
  // the after phase, allowing us to then trigger the animation events.
  scoped_ptr<web_animations::Animation::EventHandler> event_handler =
      web_animation->AttachEventHandler(
          base::Bind(&CSSAnimationsAdapter::HandleAnimationEnterAfterPhase,
                     base::Unretained(this), css_animation));

  // Track the animation in our map of all CSS Animations-created animations.
  DCHECK(animation_map_.find(css_animation.name()) == animation_map_.end());

  animation_map_.insert(std::make_pair(
      css_animation.name(),
      new AnimationWithEventHandler(web_animation, event_handler.Pass())));

  web_animation->Play();
}

void CSSAnimationsAdapter::OnAnimationRemoved(
    const cssom::Animation& css_animation) {
  // If a CSS Animation is removed from an element, its corresponding
  // Web Animations animation should be stopped and removed also.
  AnimationMap::iterator found = animation_map_.find(css_animation.name());
  DCHECK(animation_map_.end() != found);

  found->second->animation->Cancel();
  delete found->second;
  animation_map_.erase(found);
}

void CSSAnimationsAdapter::HandleAnimationEnterAfterPhase(
    const cssom::Animation& css_animation) {
  // https://drafts.csswg.org/date/2015-03-02/web-animations-css-integration/#css-animations-events
  animatable_->GetEventTarget()->DispatchEvent(new AnimationEvent(
      base::Tokens::animationend(), css_animation.name(),
      static_cast<float>(css_animation.duration().InMillisecondsF() *
                         css_animation.iteration_count())));
}

}  // namespace dom
}  // namespace cobalt
