// Copyright 2015 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/animation_player.h"

#include "cc/animation/animation_delegate.h"
#include "cc/animation/animation_host.h"
#include "cc/animation/animation_timeline.h"
#include "cc/animation/element_animations.h"
#include "cc/animation/layer_animation_controller.h"

namespace cc {

scoped_refptr<AnimationPlayer> AnimationPlayer::Create(int id) {
  return make_scoped_refptr(new AnimationPlayer(id));
}

AnimationPlayer::AnimationPlayer(int id)
    : animation_host_(),
      animation_timeline_(),
      element_animations_(),
      layer_animation_delegate_(),
      id_(id),
      layer_id_(0) {
  DCHECK(id_);
}

AnimationPlayer::~AnimationPlayer() {
  DCHECK(!animation_timeline_);
  DCHECK(!element_animations_);
  DCHECK(!layer_id_);
}

scoped_refptr<AnimationPlayer> AnimationPlayer::CreateImplInstance() const {
  scoped_refptr<AnimationPlayer> player = AnimationPlayer::Create(id());
  return player;
}

void AnimationPlayer::SetAnimationHost(AnimationHost* animation_host) {
  animation_host_ = animation_host;
}

void AnimationPlayer::SetAnimationTimeline(AnimationTimeline* timeline) {
  if (animation_timeline_ == timeline)
    return;

  // We need to unregister player to manage ElementAnimations and observers
  // properly.
  if (layer_id_ && element_animations_)
    UnregisterPlayer();

  animation_timeline_ = timeline;

  // Register player only if layer AND host attached.
  if (layer_id_ && animation_host_)
    RegisterPlayer();
}

void AnimationPlayer::AttachLayer(int layer_id) {
  DCHECK_EQ(layer_id_, 0);
  DCHECK(layer_id);

  layer_id_ = layer_id;

  // Register player only if layer AND host attached.
  if (animation_host_)
    RegisterPlayer();
}

void AnimationPlayer::DetachLayer() {
  DCHECK(layer_id_);

  if (animation_host_)
    UnregisterPlayer();

  layer_id_ = 0;
}

void AnimationPlayer::RegisterPlayer() {
  DCHECK(layer_id_);
  DCHECK(animation_host_);
  DCHECK(!element_animations_);

  // Create LAC or re-use existing.
  animation_host_->RegisterPlayerForLayer(layer_id_, this);
  // Get local reference to shared LAC.
  BindElementAnimations();
}

void AnimationPlayer::UnregisterPlayer() {
  DCHECK(layer_id_);
  DCHECK(animation_host_);
  DCHECK(element_animations_);

  UnbindElementAnimations();
  // Destroy LAC or release it if it's still needed.
  animation_host_->UnregisterPlayerForLayer(layer_id_, this);
}

void AnimationPlayer::BindElementAnimations() {
  DCHECK(!element_animations_);
  element_animations_ =
      animation_host_->GetElementAnimationsForLayerId(layer_id_);
  DCHECK(element_animations_);

  // Pass all accumulated animations to LAC.
  for (auto it = animations_.begin(); it != animations_.end(); ++it)
    element_animations_->layer_animation_controller()->AddAnimation(
        animations_.take(it));
  if (!animations_.empty())
    SetNeedsCommit();
  animations_.clear();
}

void AnimationPlayer::UnbindElementAnimations() {
  element_animations_ = nullptr;
  DCHECK(animations_.empty());
}

void AnimationPlayer::AddAnimation(scoped_ptr<Animation> animation) {
  DCHECK_IMPLIES(
      animation->target_property() == Animation::SCROLL_OFFSET,
      animation_host_ && animation_host_->SupportsScrollAnimations());

  if (element_animations_) {
    element_animations_->layer_animation_controller()->AddAnimation(
        animation.Pass());
    SetNeedsCommit();
  } else {
    animations_.push_back(animation.Pass());
  }
}

void AnimationPlayer::PauseAnimation(int animation_id, double time_offset) {
  DCHECK(element_animations_);
  element_animations_->layer_animation_controller()->PauseAnimation(
      animation_id, base::TimeDelta::FromSecondsD(time_offset));
  SetNeedsCommit();
}

void AnimationPlayer::RemoveAnimation(int animation_id) {
  if (element_animations_) {
    element_animations_->layer_animation_controller()->RemoveAnimation(
        animation_id);
    SetNeedsCommit();
  } else {
    auto animations_to_remove = animations_.remove_if([animation_id](
        Animation* animation) { return animation->id() == animation_id; });
    animations_.erase(animations_to_remove, animations_.end());
  }
}

void AnimationPlayer::PushPropertiesTo(AnimationPlayer* player_impl) {
  if (!element_animations_) {
    if (player_impl->element_animations())
      player_impl->DetachLayer();
    return;
  }

  DCHECK(layer_id_);
  if (!player_impl->element_animations())
    player_impl->AttachLayer(layer_id_);
}

void AnimationPlayer::NotifyAnimationStarted(
    base::TimeTicks monotonic_time,
    Animation::TargetProperty target_property,
    int group) {
  if (layer_animation_delegate_)
    layer_animation_delegate_->NotifyAnimationStarted(monotonic_time,
                                                      target_property, group);
}

void AnimationPlayer::NotifyAnimationFinished(
    base::TimeTicks monotonic_time,
    Animation::TargetProperty target_property,
    int group) {
  if (layer_animation_delegate_)
    layer_animation_delegate_->NotifyAnimationFinished(monotonic_time,
                                                       target_property, group);
}

void AnimationPlayer::SetNeedsCommit() {
  DCHECK(animation_host_);
  animation_host_->SetNeedsCommit();
}

}  // namespace cc
