// Copyright (c) 2011 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/gfx/animation/animation.h"

#include <memory>

#include "base/command_line.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "ui/gfx/animation/animation_container.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/animation/tween.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/switches.h"

namespace gfx {

// static
Animation::RichAnimationRenderMode Animation::rich_animation_rendering_mode_ =
    RichAnimationRenderMode::PLATFORM;

// static
absl::optional<bool> Animation::prefers_reduced_motion_;

Animation::Animation(base::TimeDelta timer_interval)
    : timer_interval_(timer_interval),
      is_animating_(false),
      delegate_(nullptr) {}

Animation::~Animation() {
  // Don't send out notification from the destructor. Chances are the delegate
  // owns us and is being deleted as well.
  if (is_animating_)
    container_->Stop(this);
}

void Animation::Start() {
  if (is_animating_)
    return;

  if (!container_) {
    container_ = base::MakeRefCounted<AnimationContainer>();
    if (delegate_)
      delegate_->AnimationContainerWasSet(container_.get());
  }

  is_animating_ = true;

  container_->Start(this);

  AnimationStarted();
}

void Animation::Stop() {
  if (!is_animating_)
    return;

  is_animating_ = false;

  // Notify the container first as the delegate may delete us.
  container_->Stop(this);

  AnimationStopped();

  if (delegate_) {
    if (ShouldSendCanceledFromStop())
      delegate_->AnimationCanceled(this);
    else
      delegate_->AnimationEnded(this);
  }
}

double Animation::CurrentValueBetween(double start, double target) const {
  return Tween::DoubleValueBetween(GetCurrentValue(), start, target);
}

int Animation::CurrentValueBetween(int start, int target) const {
  return Tween::IntValueBetween(GetCurrentValue(), start, target);
}

gfx::Rect Animation::CurrentValueBetween(const gfx::Rect& start_bounds,
                                         const gfx::Rect& target_bounds) const {
  return Tween::RectValueBetween(
      GetCurrentValue(), start_bounds, target_bounds);
}

void Animation::SetContainer(AnimationContainer* container) {
  if (container == container_.get())
    return;

  if (is_animating_)
    container_->Stop(this);

  if (container)
    container_ = container;
  else
    container_ = new AnimationContainer();

  if (delegate_)
    delegate_->AnimationContainerWasSet(container_.get());

  if (is_animating_)
    container_->Start(this);
}

bool Animation::ShouldRenderRichAnimation() {
  if (rich_animation_rendering_mode_ == RichAnimationRenderMode::PLATFORM)
    return ShouldRenderRichAnimationImpl();
  return rich_animation_rendering_mode_ ==
         RichAnimationRenderMode::FORCE_ENABLED;
}

#if defined(OS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_IOS) || \
    defined(OS_FUCHSIA)
// static
bool Animation::ShouldRenderRichAnimationImpl() {
  return true;
  // Defined in platform specific file for Windows and OSX and Linux.
}

// static
bool Animation::ScrollAnimationsEnabledBySystem() {
  return true;
  // Defined in platform specific files for Windows and OSX and Linux.
}

#if !defined(OS_ANDROID)
// static
void Animation::UpdatePrefersReducedMotion() {
  // prefers_reduced_motion_ should only be modified on the UI thread.
  // TODO(crbug.com/927163): DCHECK this assertion once tests are well-behaved.

  // By default, we assume that animations are enabled, to avoid impacting the
  // experience for users on systems that don't have APIs for reduced motion.
  prefers_reduced_motion_ = false;
}
#endif  // !defined(OS_ANDROID)
#endif  // defined(OS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_IOS)
        // || defined(OS_FUCHSIA)

// static
bool Animation::PrefersReducedMotion() {
  // --force-prefers-reduced-motion must always override
  // |prefers_reduced_motion_|, so check it first.
  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kForcePrefersReducedMotion)) {
    return true;
  }

  if (!prefers_reduced_motion_.has_value())
    UpdatePrefersReducedMotion();
  return prefers_reduced_motion_.value();
}

bool Animation::ShouldSendCanceledFromStop() {
  return false;
}

void Animation::SetStartTime(base::TimeTicks start_time) {
  start_time_ = start_time;
}

base::TimeDelta Animation::GetTimerInterval() const {
  return timer_interval_;
}

}  // namespace gfx
