// 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::PreservesAxisAlignment() const {
  return (initial_value_.IsIdentity() ||
          initial_value_.IsScaleOrTranslation()) &&
         (target_value_.IsIdentity() || target_value_.IsScaleOrTranslation());
}

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::PreservesAxisAlignment() const {
  return (initial_value_.IsIdentity() ||
          initial_value_.IsScaleOrTranslation()) &&
         (base_curve_.PreservesAxisAlignment());
}

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

}  // namespace ui
