// Copyright 2020 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/renderer/rasterizer/skia/skottie_animation.h"

#include "base/bind.h"

namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace skia {

SkottieAnimation::SkottieAnimation(const char* data, size_t length)
    : last_updated_animation_time_(base::TimeDelta()) {
  skottie::Animation::Builder builder;
  skottie_animation_ = builder.make(data, length);
  animation_size_ = math::Size(skottie_animation_->size().width(),
                               skottie_animation_->size().height());
  json_size_in_bytes_ = builder.getStats().fJsonSize;
}

void SkottieAnimation::SetAnimationTimeInternal(
    base::TimeDelta animate_function_time) {
  // Seeking to a particular frame takes precedence over normal playback.
  // Check whether "seek()" has been called but has yet to occur.
  if (seek_counter_ != properties_.seek_counter) {
    base::TimeDelta current_animation_time;
    if (properties_.seek_value_is_frame) {
      skottie_animation_->seekFrame(properties_.seek_value);
      current_animation_time = base::TimeDelta::FromSecondsD(
          properties_.seek_value / skottie_animation_->fps());
    } else {
      skottie_animation_->seekFrameTime(properties_.seek_value *
                                        skottie_animation_->duration());
      current_animation_time = base::TimeDelta::FromSecondsD(
          properties_.seek_value * skottie_animation_->duration());
    }
    seek_counter_ = properties_.seek_counter;
    is_complete_ = false;
    UpdateAnimationFrameAndAnimateFunctionTimes(current_animation_time,
                                                animate_function_time);
    return;
  }

  // Reset the animation time to the start of the animation if the animation is
  // stopped.
  if (properties_.state == LottieState::kStopped) {
    skottie_animation_->seekFrameTime(0);
    is_complete_ = false;
    UpdateAnimationFrameAndAnimateFunctionTimes(base::TimeDelta(),
                                                animate_function_time);
    return;
  }

  // Do not update the animation time is the animation is paused.
  if (properties_.state == LottieState::kPaused) {
    skottie_animation_->seekFrameTime(
        last_updated_animation_time_.InSecondsF());
    UpdateAnimationFrameAndAnimateFunctionTimes(last_updated_animation_time_,
                                                animate_function_time);
    return;
  }

  base::TimeDelta current_animation_time = last_updated_animation_time_;
  base::TimeDelta time_elapsed =
      animate_function_time - last_updated_animate_function_time_;
  current_animation_time += time_elapsed * properties_.speed;
  base::TimeDelta animation_duration =
      base::TimeDelta::FromSecondsD(skottie_animation_->duration());

  if (properties_.loop) {
    // If the animation mode is "bounce", then the animation should change
    // the direction in which it plays after each loop.
    int new_loop_count = floor(current_animation_time / animation_duration);

    // Check whether the number of loops exceeds the limits set by
    // LottieProperties::count.
    // (Note: LottieProperties::count refers to the number of loops after the
    // animation plays once through.)
    if (properties_.count > 0 && new_loop_count > properties_.count) {
      current_animation_time = animation_duration;
    } else {
      // If the animation should continue playing, check whether the animation
      // has completed and needs to trigger a "loop" and potentially reverse
      // direction.
      if (new_loop_count > total_loops_) {
        if (!properties_.onloop_callback.is_null()) {
          properties_.onloop_callback.Run();
        }
        if (properties_.mode == LottieMode::kBounce) {
          direction_ *= -1;
        }
      }
      current_animation_time = base::TimeDelta::FromSecondsD(
          std::fmod(current_animation_time.InSecondsF(),
                    animation_duration.InSecondsF()));
    }
    total_loops_ = new_loop_count;
  }

  if (direction_ * properties_.direction == -1) {
    current_animation_time = animation_duration - current_animation_time;
  }

  if (!is_complete_ && current_animation_time > animation_duration &&
      !properties_.oncomplete_callback.is_null()) {
    is_complete_ = true;
    properties_.oncomplete_callback.Run();
  }

  skottie_animation_->seekFrameTime(current_animation_time.InSecondsF());
  UpdateAnimationFrameAndAnimateFunctionTimes(current_animation_time,
                                              animate_function_time);
}

void SkottieAnimation::UpdateAnimationFrameAndAnimateFunctionTimes(
    base::TimeDelta current_animation_time,
    base::TimeDelta current_animate_function_time) {
  last_updated_animate_function_time_ = current_animate_function_time;

  if (current_animation_time == last_updated_animation_time_) {
    return;
  }

  // Dispatch a frame event every time a new frame is entered, and if the
  // animation is not complete.
  double frame =
      current_animation_time.InSecondsF() * skottie_animation_->fps();
  double seeker = current_animation_time.InSecondsF() /
                  skottie_animation_->duration() * 100;
  if (!properties_.onenterframe_callback.is_null() && !is_complete_) {
    properties_.onenterframe_callback.Run(frame, seeker);
  }

  last_updated_animation_time_ = current_animation_time;
}

}  // namespace skia
}  // namespace rasterizer
}  // namespace renderer
}  // namespace cobalt
