// 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/transform_animation_curve_adapter.h"

#include "cc/base/time_util.h"

namespace ui {

TransformAnimationCurveAdapter::TransformAnimationCurveAdapter(
    gfx::Tween::Type tween_type,
    gfx::Transform initial_value,
    gfx::Transform target_value,
    base::TimeDelta duration)
    : tween_type_(tween_type),
      initial_value_(initial_value),
      target_value_(target_value),
      duration_(duration) {
  gfx::DecomposeTransform(&decomposed_initial_value_, initial_value_);
  gfx::DecomposeTransform(&decomposed_target_value_, target_value_);
}

TransformAnimationCurveAdapter::~TransformAnimationCurveAdapter() {
}

base::TimeDelta TransformAnimationCurveAdapter::Duration() const {
  return duration_;
}

scoped_ptr<cc::AnimationCurve> TransformAnimationCurveAdapter::Clone() const {
  return make_scoped_ptr(new TransformAnimationCurveAdapter(
      tween_type_, initial_value_, target_value_, duration_));
}

gfx::Transform TransformAnimationCurveAdapter::GetValue(
    base::TimeDelta t) const {
  if (t >= duration_)
    return target_value_;
  if (t <= base::TimeDelta())
    return initial_value_;
  double progress = cc::TimeUtil::Divide(t, duration_);

  gfx::DecomposedTransform to_return;
  gfx::BlendDecomposedTransforms(&to_return,
                                 decomposed_target_value_,
                                 decomposed_initial_value_,
                                 gfx::Tween::CalculateValue(tween_type_,
                                                            progress));
  return gfx::ComposeTransform(to_return);
}

bool TransformAnimationCurveAdapter::AnimatedBoundsForBox(
    const gfx::BoxF& box,
    gfx::BoxF* bounds) const {
  // TODO(ajuma): Once cc::TransformOperation::BlendedBoundsForBox supports
  // computing bounds for TransformOperationMatrix, use that to compute
  // the bounds we need here.
  return false;
}

bool TransformAnimationCurveAdapter::AffectsScale() const {
  return !initial_value_.IsIdentityOrTranslation() ||
         !target_value_.IsIdentityOrTranslation();
}

bool TransformAnimationCurveAdapter::IsTranslation() const {
  return initial_value_.IsIdentityOrTranslation() &&
         target_value_.IsIdentityOrTranslation();
}

bool TransformAnimationCurveAdapter::MaximumTargetScale(
    bool forward_direction,
    float* max_scale) const {
  return false;
}

InverseTransformCurveAdapter::InverseTransformCurveAdapter(
    TransformAnimationCurveAdapter base_curve,
    gfx::Transform initial_value,
    base::TimeDelta duration)
    : base_curve_(base_curve),
      initial_value_(initial_value),
      duration_(duration) {
  effective_initial_value_ =
      base_curve_.GetValue(base::TimeDelta()) * initial_value_;
}

InverseTransformCurveAdapter::~InverseTransformCurveAdapter() {
}

base::TimeDelta InverseTransformCurveAdapter::Duration() const {
  return duration_;
}

scoped_ptr<cc::AnimationCurve> InverseTransformCurveAdapter::Clone() const {
  return make_scoped_ptr(
      new InverseTransformCurveAdapter(base_curve_, initial_value_, duration_));
}

gfx::Transform InverseTransformCurveAdapter::GetValue(base::TimeDelta t) const {
  if (t <= base::TimeDelta())
    return initial_value_;

  gfx::Transform base_transform = base_curve_.GetValue(t);
  // Invert base
  gfx::Transform to_return(gfx::Transform::kSkipInitialization);
  bool is_invertible = base_transform.GetInverse(&to_return);
  DCHECK(is_invertible);

  to_return.PreconcatTransform(effective_initial_value_);
  return to_return;
}

bool InverseTransformCurveAdapter::AnimatedBoundsForBox(
    const gfx::BoxF& box,
    gfx::BoxF* bounds) const {
  // TODO(ajuma): Once cc::TransformOperation::BlendedBoundsForBox supports
  // computing bounds for TransformOperationMatrix, use that to compute
  // the bounds we need here.
  return false;
}

bool InverseTransformCurveAdapter::AffectsScale() const {
  return !initial_value_.IsIdentityOrTranslation() ||
         base_curve_.AffectsScale();
}

bool InverseTransformCurveAdapter::IsTranslation() const {
  return initial_value_.IsIdentityOrTranslation() &&
         base_curve_.IsTranslation();
}

bool InverseTransformCurveAdapter::MaximumTargetScale(bool forward_direction,
                                                      float* max_scale) const {
  return false;
}

}  // namespace ui
