// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cc/animation/scroll_offset_animations_impl.h"

#include "cc/animation/animation_host.h"
#include "cc/animation/animation_id_provider.h"
#include "cc/animation/animation_player.h"
#include "cc/animation/animation_timeline.h"
#include "cc/animation/element_animations.h"
#include "cc/animation/timing_function.h"

namespace cc {

ScrollOffsetAnimationsImpl::ScrollOffsetAnimationsImpl(
    AnimationHost* animation_host)
    : animation_host_(animation_host),
      scroll_offset_timeline_(
          AnimationTimeline::Create(AnimationIdProvider::NextTimelineId())),
      scroll_offset_animation_player_(
          AnimationPlayer::Create(AnimationIdProvider::NextPlayerId())) {
  scroll_offset_timeline_->set_is_impl_only(true);
  scroll_offset_animation_player_->set_animation_delegate(this);

  animation_host_->AddAnimationTimeline(scroll_offset_timeline_.get());
  scroll_offset_timeline_->AttachPlayer(scroll_offset_animation_player_.get());
}

ScrollOffsetAnimationsImpl::~ScrollOffsetAnimationsImpl() {
  scroll_offset_timeline_->DetachPlayer(scroll_offset_animation_player_.get());
  animation_host_->RemoveAnimationTimeline(scroll_offset_timeline_.get());
}

void ScrollOffsetAnimationsImpl::ScrollAnimationCreate(
    ElementId element_id,
    const gfx::ScrollOffset& target_offset,
    const gfx::ScrollOffset& current_offset,
    base::TimeDelta delayed_by,
    base::TimeDelta animation_start_offset) {
  std::unique_ptr<ScrollOffsetAnimationCurve> curve =
      ScrollOffsetAnimationCurve::Create(
          target_offset, CubicBezierTimingFunction::CreatePreset(
                             CubicBezierTimingFunction::EaseType::EASE_IN_OUT),
          ScrollOffsetAnimationCurve::DurationBehavior::INVERSE_DELTA);
  curve->SetInitialValue(current_offset, delayed_by);

  std::unique_ptr<Animation> animation = Animation::Create(
      std::move(curve), AnimationIdProvider::NextAnimationId(),
      AnimationIdProvider::NextGroupId(), TargetProperty::SCROLL_OFFSET);
  animation->set_time_offset(animation_start_offset);
  animation->set_is_impl_only(true);

  DCHECK(scroll_offset_animation_player_);
  DCHECK(scroll_offset_animation_player_->animation_timeline());

  ReattachScrollOffsetPlayerIfNeeded(element_id);

  scroll_offset_animation_player_->AddAnimation(std::move(animation));
}

bool ScrollOffsetAnimationsImpl::ScrollAnimationUpdateTarget(
    ElementId element_id,
    const gfx::Vector2dF& scroll_delta,
    const gfx::ScrollOffset& max_scroll_offset,
    base::TimeTicks frame_monotonic_time,
    base::TimeDelta delayed_by) {
  DCHECK(scroll_offset_animation_player_);
  if (!scroll_offset_animation_player_->element_animations())
    return false;

  DCHECK_EQ(element_id, scroll_offset_animation_player_->element_id());

  Animation* animation = scroll_offset_animation_player_->GetAnimation(
      TargetProperty::SCROLL_OFFSET);
  if (!animation) {
    scroll_offset_animation_player_->DetachElement();
    return false;
  }
  if (scroll_delta.IsZero())
    return true;

  ScrollOffsetAnimationCurve* curve =
      animation->curve()->ToScrollOffsetAnimationCurve();

  gfx::ScrollOffset new_target =
      gfx::ScrollOffsetWithDelta(curve->target_value(), scroll_delta);
  new_target.SetToMax(gfx::ScrollOffset());
  new_target.SetToMin(max_scroll_offset);

  // TODO(ymalik): Animation::TrimTimeToCurrentIteration should probably check
  // for run_state == Animation::WAITING_FOR_TARGET_AVAILABILITY.
  base::TimeDelta trimmed =
      animation->run_state() == Animation::WAITING_FOR_TARGET_AVAILABILITY
          ? base::TimeDelta()
          : animation->TrimTimeToCurrentIteration(frame_monotonic_time);

  // Re-target taking the delay into account. Note that if the duration of the
  // animation is 0, trimmed will be 0 and UpdateTarget will be called with
  // t = -delayed_by.
  trimmed -= delayed_by;

  curve->UpdateTarget(trimmed.InSecondsF(), new_target);

  return true;
}

void ScrollOffsetAnimationsImpl::ScrollAnimationApplyAdjustment(
    ElementId element_id,
    const gfx::Vector2dF& adjustment) {
  DCHECK(scroll_offset_animation_player_);
  if (element_id != scroll_offset_animation_player_->element_id())
    return;

  if (!scroll_offset_animation_player_->element_animations())
    return;

  Animation* animation = scroll_offset_animation_player_->GetAnimation(
      TargetProperty::SCROLL_OFFSET);
  if (!animation)
    return;

  std::unique_ptr<ScrollOffsetAnimationCurve> new_curve =
      animation->curve()
          ->ToScrollOffsetAnimationCurve()
          ->CloneToScrollOffsetAnimationCurve();
  new_curve->ApplyAdjustment(adjustment);

  std::unique_ptr<Animation> new_animation = Animation::Create(
      std::move(new_curve), AnimationIdProvider::NextAnimationId(),
      AnimationIdProvider::NextGroupId(), TargetProperty::SCROLL_OFFSET);
  new_animation->set_start_time(animation->start_time());
  new_animation->set_is_impl_only(true);
  new_animation->set_affects_active_elements(false);

  // Abort the old animation.
  ScrollAnimationAbort(/* needs_completion */ false);

  // Start a new one with the adjusment.
  scroll_offset_animation_player_->AddAnimation(std::move(new_animation));
}

void ScrollOffsetAnimationsImpl::ScrollAnimationAbort(bool needs_completion) {
  DCHECK(scroll_offset_animation_player_);
  scroll_offset_animation_player_->AbortAnimations(
      TargetProperty::SCROLL_OFFSET, needs_completion);
}

void ScrollOffsetAnimationsImpl::NotifyAnimationFinished(
    base::TimeTicks monotonic_time,
    int target_property,
    int group) {
  DCHECK_EQ(target_property, TargetProperty::SCROLL_OFFSET);
  DCHECK(animation_host_->mutator_host_client());
  animation_host_->mutator_host_client()->ScrollOffsetAnimationFinished();
}

void ScrollOffsetAnimationsImpl::ReattachScrollOffsetPlayerIfNeeded(
    ElementId element_id) {
  if (scroll_offset_animation_player_->element_id() != element_id) {
    if (scroll_offset_animation_player_->element_id())
      scroll_offset_animation_player_->DetachElement();
    if (element_id)
      scroll_offset_animation_player_->AttachElement(element_id);
  }
}

}  // namespace cc
