/*
 * 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/web_animations/baked_animation_set.h"

#include <algorithm>

#include "cobalt/web_animations/animation_effect_read_only.h"

namespace cobalt {
namespace web_animations {

// Extract Data objects from the Animation script objects.
BakedAnimation::BakedAnimation(const Animation& animation)
    : animation_data_(animation.data()),
      effect_timing_data_(animation.effect()->timing()->data()),
      keyframe_data_(base::polymorphic_downcast<const KeyframeEffectReadOnly*>(
                         animation.effect().get())
                         ->data()) {}

void BakedAnimation::Apply(const base::TimeDelta& timeline_time,
                           cssom::CSSComputedStyleData* in_out_style) const {
  // Get the animation's local time from the Animation::Data object.
  base::optional<base::TimeDelta> local_time =
      animation_data_.ComputeLocalTimeFromTimelineTime(timeline_time);

  // Obtain the iteration progress from the AnimationEffectTimingReadOnly::Data
  // object.
  AnimationEffectTimingReadOnly::Data::IterationProgress iteration_progress =
      effect_timing_data_.ComputeIterationProgressFromLocalTime(local_time);

  if (!iteration_progress.iteration_progress) {
    return;
  }

  // Use the iteration progress to animate the CSS style properties using
  // keyframe data stored in KeyframeEffectReadOnly::Data.
  keyframe_data_.ApplyAnimation(in_out_style,
                                *iteration_progress.iteration_progress,
                                *iteration_progress.current_iteration);
}

base::TimeDelta BakedAnimation::end_time() const {
  base::TimeDelta end_time_local =
      effect_timing_data_.time_until_after_phase(base::TimeDelta());

  return *animation_data_.ComputeTimelineTimeFromLocalTime(end_time_local);
}

BakedAnimationSet::BakedAnimationSet(const AnimationSet& animation_set) {
  for (AnimationSet::InternalSet::const_iterator iter =
           animation_set.animations().begin();
       iter != animation_set.animations().end(); ++iter) {
    animations_.push_back(new BakedAnimation(**iter));
  }
}

BakedAnimationSet::BakedAnimationSet(const BakedAnimationSet& rhs) {
  for (AnimationList::const_iterator iter = rhs.animations_.begin();
       iter != rhs.animations_.end(); ++iter) {
    animations_.push_back(new BakedAnimation(**iter));
  }
}

void BakedAnimationSet::Apply(const base::TimeDelta& timeline_time,
                              cssom::CSSComputedStyleData* in_out_style) const {
  // TODO: Follow the proceedure for combining effects.
  //   https://www.w3.org/TR/2015/WD-web-animations-1-20150707/#combining-effects
  for (AnimationList::const_iterator iter = animations_.begin();
       iter != animations_.end(); ++iter) {
    (*iter)->Apply(timeline_time, in_out_style);
  }
}

base::TimeDelta BakedAnimationSet::end_time() const {
  base::TimeDelta max_end_time = -base::TimeDelta::Max();
  for (AnimationList::const_iterator iter = animations_.begin();
       iter != animations_.end(); ++iter) {
    base::TimeDelta animation_end_time = (*iter)->end_time();
    max_end_time = std::max(animation_end_time, max_end_time);
  }
  return max_end_time;
}

}  // namespace web_animations
}  // namespace cobalt
