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

#include "cobalt/dom/css_animations_adapter.h"

#include <memory>
#include <utility>
#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, cssom::AnimationSet* animation_set) {
  // 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.
  std::unique_ptr<web_animations::Animation::EventHandler> event_handler =
      web_animation->AttachEventHandler(
          base::Bind(&CSSAnimationsAdapter::HandleAnimationEnterAfterPhase,
                     base::Unretained(this), animation_set));

  // 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, std::move(event_handler))));

  web_animation->Play();
}

void CSSAnimationsAdapter::OnAnimationEnded(
    const cssom::Animation& css_animation) {
  // An animation has entered the "after phase", so we should correspondingly
  // fire the animationend event.
  //   https://drafts.csswg.org/date/2015-03-02/web-animations-css-integration/#css-animations-events
  // Cobalt assumes that the CSSOM does not change during computed style
  // calculation. Post to dispatch the event asynchronously here to avoid
  // calling event handlers during computed style calculation, which in turn
  // may modify CSSOM and require restart of the computed style calculation.
  animatable_->GetEventTarget()->PostToDispatchEvent(
      FROM_HERE,
      new AnimationEvent(
          base::Tokens::animationend(), css_animation.name(),
          static_cast<float>(css_animation.duration().InMillisecondsF() *
                             css_animation.iteration_count())));
}

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(
    cssom::AnimationSet* animation_set) {
  // The update processing handles signalling when an animation ends.
  DCHECK(animatable_->GetDefaultTimeline()->current_time());
  base::TimeDelta current_time = base::TimeDelta::FromMillisecondsD(
      animatable_->GetDefaultTimeline()->current_time().value_or(0));
  animation_set->Update(current_time, *animatable_->GetComputedStyle(),
                        animatable_->GetKeyframesMap());
}

}  // namespace dom
}  // namespace cobalt
