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