// Copyright (c) 2012 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 "ui/compositor/scoped_layer_animation_settings.h"

#include <stddef.h>

#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/layer_animation_sequence.h"
#include "ui/compositor/layer_animator.h"
#include "ui/compositor/layer_observer.h"

namespace ui {

namespace {

const int kScopedLayerAnimationDefaultTransitionDurationMs = 200;

template <typename Trait>
class ScopedLayerAnimationObserver : public ui::ImplicitAnimationObserver,
                                     public ui::LayerObserver {
 public:
  ScopedLayerAnimationObserver(ui::Layer* layer) : layer_(layer) {
    layer_->AddObserver(this);
    Trait::AddRequest(layer_);
  }
  ~ScopedLayerAnimationObserver() override {
    if (layer_)
      layer_->RemoveObserver(this);
  }

  // ui::ImplicitAnimationObserver overrides:
  void OnImplicitAnimationsCompleted() override {
    // If animation finishes before |layer_| is destoyed, we will remove the
    // request applied on the layer and remove |this| from the |layer_|
    // observer list when deleting |this|.
    if (layer_) {
      Trait::RemoveRequest(layer_);
      layer_->GetAnimator()->RemoveAndDestroyOwnedObserver(this);
    }
  }

  // ui::LayerObserver overrides:
  void LayerDestroyed(ui::Layer* layer) override {
    // If the animation is still going past layer destruction then we want the
    // layer to keep the request until the animation has finished. We will defer
    // deleting |this| until the animation finishes.
    layer_->RemoveObserver(this);
    layer_ = nullptr;
  }

 private:
  ui::Layer* layer_;

  DISALLOW_COPY_AND_ASSIGN(ScopedLayerAnimationObserver);
};

struct RenderSurfaceCachingTrait {
  static void AddRequest(ui::Layer* layer) {
    layer->AddCacheRenderSurfaceRequest();
  }
  static void RemoveRequest(ui::Layer* layer) {
    layer->RemoveCacheRenderSurfaceRequest();
  }
};
using ScopedRenderSurfaceCaching =
    ScopedLayerAnimationObserver<RenderSurfaceCachingTrait>;

struct DeferredPaintingTrait {
  static void AddRequest(ui::Layer* layer) { layer->AddDeferredPaintRequest(); }
  static void RemoveRequest(ui::Layer* layer) {
    layer->RemoveDeferredPaintRequest();
  }
};
using ScopedDeferredPainting =
    ScopedLayerAnimationObserver<DeferredPaintingTrait>;

struct TrilinearFilteringTrait {
  static void AddRequest(ui::Layer* layer) {
    layer->AddTrilinearFilteringRequest();
  }
  static void RemoveRequest(ui::Layer* layer) {
    layer->RemoveTrilinearFilteringRequest();
  }
};
using ScopedTrilinearFiltering =
    ScopedLayerAnimationObserver<TrilinearFilteringTrait>;

void AddObserverToSettings(
    ui::ScopedLayerAnimationSettings* settings,
    std::unique_ptr<ui::ImplicitAnimationObserver> observer) {
  settings->AddObserver(observer.get());
  settings->GetAnimator()->AddOwnedObserver(std::move(observer));
}

void AddScopedDeferredPaintingObserverRecursive(
    ui::Layer* layer,
    ui::ScopedLayerAnimationSettings* settings) {
  auto observer = std::make_unique<ScopedDeferredPainting>(layer);
  AddObserverToSettings(settings, std::move(observer));
  for (auto* child : layer->children())
    AddScopedDeferredPaintingObserverRecursive(child, settings);
}

}  // namespace

// ScopedLayerAnimationSettings ------------------------------------------------
ScopedLayerAnimationSettings::ScopedLayerAnimationSettings(
    scoped_refptr<LayerAnimator> animator)
    : animator_(animator),
      old_is_transition_duration_locked_(
          animator->is_transition_duration_locked_),
      old_transition_duration_(animator->GetTransitionDuration()),
      old_tween_type_(animator->tween_type()),
      old_preemption_strategy_(animator->preemption_strategy()) {
  SetTransitionDuration(base::TimeDelta::FromMilliseconds(
      kScopedLayerAnimationDefaultTransitionDurationMs));
}

ScopedLayerAnimationSettings::~ScopedLayerAnimationSettings() {
  animator_->set_animation_metrics_reporter(nullptr);
  animator_->is_transition_duration_locked_ =
      old_is_transition_duration_locked_;
  animator_->SetTransitionDuration(old_transition_duration_);
  animator_->set_tween_type(old_tween_type_);
  animator_->set_preemption_strategy(old_preemption_strategy_);

  for (auto* observer : observers_) {
    // Directly remove |observer| from |LayerAnimator::observers_| rather than
    // calling LayerAnimator::RemoveObserver(), to avoid removing it from the
    // observer list of LayerAnimationSequences that have already been
    // scheduled.
    animator_->observers_.RemoveObserver(observer);
    observer->SetActive(true);
  }
}

void ScopedLayerAnimationSettings::AddObserver(
    ImplicitAnimationObserver* observer) {
  observers_.insert(observer);
  animator_->AddObserver(observer);
}

void ScopedLayerAnimationSettings::SetAnimationMetricsReporter(
    AnimationMetricsReporter* reporter) {
  animator_->set_animation_metrics_reporter(reporter);
}

void ScopedLayerAnimationSettings::SetTransitionDuration(
    base::TimeDelta duration) {
  animator_->SetTransitionDuration(duration);
}

base::TimeDelta ScopedLayerAnimationSettings::GetTransitionDuration() const {
  return animator_->GetTransitionDuration();
}

void ScopedLayerAnimationSettings::LockTransitionDuration() {
  animator_->is_transition_duration_locked_ = true;
}

void ScopedLayerAnimationSettings::SetTweenType(gfx::Tween::Type tween_type) {
  animator_->set_tween_type(tween_type);
}

gfx::Tween::Type ScopedLayerAnimationSettings::GetTweenType() const {
  return animator_->tween_type();
}

void ScopedLayerAnimationSettings::SetPreemptionStrategy(
    LayerAnimator::PreemptionStrategy strategy) {
  animator_->set_preemption_strategy(strategy);
}

LayerAnimator::PreemptionStrategy
ScopedLayerAnimationSettings::GetPreemptionStrategy() const {
  return animator_->preemption_strategy();
}

void ScopedLayerAnimationSettings::CacheRenderSurface() {
  auto observer = std::make_unique<ScopedRenderSurfaceCaching>(
      animator_->delegate()->GetLayer());
  AddObserverToSettings(this, std::move(observer));
}

void ScopedLayerAnimationSettings::DeferPaint() {
  AddScopedDeferredPaintingObserverRecursive(animator_->delegate()->GetLayer(),
                                             this);
}

void ScopedLayerAnimationSettings::TrilinearFiltering() {
  auto observer = std::make_unique<ScopedTrilinearFiltering>(
      animator_->delegate()->GetLayer());
  AddObserverToSettings(this, std::move(observer));
}

}  // namespace ui
