// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/math/matrix_interpolation.h"

#include <cmath>

#include "cobalt/math/transform_2d.h"

namespace cobalt {
namespace math {

// All algorithms here are based on the specifications provided by the W3C here:
//   https://www.w3.org/TR/css-transforms/#interpolation-of-2d-matrices
DecomposedMatrix DecomposeMatrix(const math::Matrix3F& matrix) {
  DecomposedMatrix decomposition;

  float col0x = matrix.Get(0, 0);
  float col0y = matrix.Get(1, 0);
  float col1x = matrix.Get(0, 1);
  float col1y = matrix.Get(1, 1);

  decomposition.translation[0] = matrix.Get(0, 2);
  decomposition.translation[1] = matrix.Get(1, 2);

  decomposition.scale[0] = sqrt(col0x * col0x + col0y * col0y);
  decomposition.scale[1] = sqrt(col1x * col1x + col1y * col1y);

  // If determinant is negative, one axis was flipped.
  float determinant = col0x * col1y - col0y * col1x;
  if (determinant < 0) {
    // Flip axis with minimum unit vector dot product.
    if (col0x < col1y) {
      decomposition.scale[0] = -decomposition.scale[0];
    } else {
      decomposition.scale[1] = -decomposition.scale[1];
    }
  }

  // Renormalize matrix to remove scale.
  if ((0.0f != decomposition.scale[0])) {
    col0x *= 1 / decomposition.scale[0];
    col0y *= 1 / decomposition.scale[0];
  }
  if ((0.0f !=  decomposition.scale[1])) {
    col1x *= 1 / decomposition.scale[1];
    col1y *= 1 / decomposition.scale[1];
  }

  // Compute rotation and renormalize matrix.
  decomposition.angle = atan2(col0y, col0x);

  if ((0.0f != decomposition.angle)) {
    // Rotate(-angle) = [ cos(angle),  sin(angle) ]
    //                  [ -sin(angle), cos(angle) ]
    //                = [ col0x,  col0y ]
    //                  [ -col0y, col0x ]
    // Thanks to the normalization above.
    float sin_angle = col0y;
    float cos_angle = col0x;
    float m11 = col0x;
    float m12 = col1x;
    float m21 = col0y;
    float m22 = col1y;
    col0x = cos_angle * m11 + sin_angle * m21;
    col0y = -sin_angle * m11 + cos_angle * m21;
    col1x = cos_angle * m12 + sin_angle * m22;
    col1y = -sin_angle * m12 + cos_angle * m22;
  }

  decomposition.m11 = col0x;
  decomposition.m12 = col1x;
  decomposition.m21 = col0y;
  decomposition.m22 = col1y;

  return decomposition;
}

float Lerp(float a, float b, float progress) {
  return a + (b - a) * progress;
}

namespace {

// Prepare certain attributes of the decomposed matrices for interpolation.
void SanitizeInputsForInterpolation(
    const DecomposedMatrix& a, const DecomposedMatrix& b,
    float* a_scale_sanitized, float* a_angle_sanitized,
    float* b_angle_sanitized) {
  static const float kPi = static_cast<float>(M_PI);

  // If x-axis of one is flipped, and y-axis of the other,
  // convert to an unflipped rotation.
  if ((a.scale[0] < 0 && b.scale[1] < 0) ||
      (a.scale[1] < 0 && b.scale[0] < 0)) {
    a_scale_sanitized[0] = -a.scale[0];
    a_scale_sanitized[1] = -a.scale[1];
    *a_angle_sanitized = a.angle + a.angle < 0 ? kPi : -kPi;
  } else {
    a_scale_sanitized[0] = a.scale[0];
    a_scale_sanitized[1] = a.scale[1];
    *a_angle_sanitized = a.angle;
  }

  // Don’t rotate the long way around.
  *b_angle_sanitized = b.angle;
  float angle_difference = std::abs(*a_angle_sanitized - *b_angle_sanitized);
  if (angle_difference > kPi) {
    float rounded_up_revolutions_difference =
        std::ceil(angle_difference / (2 * kPi));
    if (*a_angle_sanitized > *b_angle_sanitized) {
      *a_angle_sanitized -= 2 * kPi * rounded_up_revolutions_difference;
    } else {
      *b_angle_sanitized -= 2 * kPi * rounded_up_revolutions_difference;
    }
  }
}

}  // namespace

DecomposedMatrix InterpolateMatrixDecompositions(const DecomposedMatrix& a,
                                                 const DecomposedMatrix& b,
                                                 float progress) {
  float a_scale[2];
  float a_angle;
  float b_angle;
  SanitizeInputsForInterpolation(a, b, a_scale, &a_angle, &b_angle);

  // And now we lerp each component individually.
  DecomposedMatrix result;
  result.translation[0] = Lerp(a.translation[0], b.translation[0], progress);
  result.translation[1] = Lerp(a.translation[1], b.translation[1], progress);
  result.scale[0] = Lerp(a_scale[0], b.scale[0], progress);
  result.scale[1] = Lerp(a_scale[1], b.scale[1], progress);
  result.angle = Lerp(a_angle, b_angle, progress);
  result.m11 = Lerp(a.m11, b.m11, progress);
  result.m12 = Lerp(a.m12, b.m12, progress);
  result.m21 = Lerp(a.m21, b.m21, progress);
  result.m22 = Lerp(a.m22, b.m22, progress);
  return result;
}

// Reconstruct a matrix from a given matrix decomposition.
//   https://www.w3.org/TR/css-transforms/#recomposing-to-a-2d-matrix
math::Matrix3F RecomposeMatrix(const DecomposedMatrix& decomposition) {
  math::Matrix3F matrix(math::Matrix3F::Identity());

  matrix(0, 0) = decomposition.m11;
  matrix(0, 1) = decomposition.m12;
  matrix(1, 0) = decomposition.m21;
  matrix(1, 1) = decomposition.m22;

  // Rotate matrix.
  matrix = math::RotateMatrix(-decomposition.angle) * matrix;

  // Scale matrix.
  matrix(0, 0) *= decomposition.scale[0];
  matrix(1, 0) *= decomposition.scale[0];
  matrix(0, 1) *= decomposition.scale[1];
  matrix(1, 1) *= decomposition.scale[1];

  // Translate matrix.  Note that we deviate from the specification here
  // because the specification's "recompose" algorithm is inconsistent with
  // its "decompose" algorithm.  The modification acheives this consistency.
  matrix(0, 2) = decomposition.translation[0];
  matrix(1, 2) = decomposition.translation[1];

  return matrix;
}

math::Matrix3F InterpolateMatrices(const math::Matrix3F& a,
                                   const math::Matrix3F& b, float progress) {
  // The main algorithm here is to decompose each matrix, interpolate the
  // decompositions, and then reconstruct a matrix from the interpolated
  // compositions.
  DecomposedMatrix decomposed_a = DecomposeMatrix(a);
  DecomposedMatrix decomposed_b = DecomposeMatrix(b);

  DecomposedMatrix decomposed_interpolated =
      InterpolateMatrixDecompositions(decomposed_a, decomposed_b, progress);

  return RecomposeMatrix(decomposed_interpolated);
}

}  // namespace math
}  // namespace cobalt
