// Copyright 2013 The Flutter 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 "flutter/flow/matrix_decomposition.h"

namespace flutter {

static inline SkVector3 SkVector3Combine(const SkVector3& a,
                                         float a_scale,
                                         const SkVector3& b,
                                         float b_scale) {
  return {
      a_scale * a.fX + b_scale * b.fX,  //
      a_scale * a.fY + b_scale * b.fY,  //
      a_scale * a.fZ + b_scale * b.fZ,  //
  };
}

static inline SkVector3 SkVector3Cross(const SkVector3& a, const SkVector3& b) {
  return {
      (a.fY * b.fZ) - (a.fZ * b.fY),  //
      (a.fZ * b.fX) - (a.fX * b.fZ),  //
      (a.fX * b.fY) - (a.fY * b.fX)   //
  };
}

MatrixDecomposition::MatrixDecomposition(const SkMatrix& matrix)
    : MatrixDecomposition(SkMatrix44{matrix}) {}

// Use custom normalize to avoid skia precision loss/normalize() privatization.
static inline void SkVector3Normalize(SkVector3& v) {
  double mag = sqrt(v.fX * v.fX + v.fY * v.fY + v.fZ * v.fZ);
  double scale = 1.0 / mag;
  v.fX *= scale;
  v.fY *= scale;
  v.fZ *= scale;
}

MatrixDecomposition::MatrixDecomposition(SkMatrix44 matrix) : valid_(false) {
  if (matrix.get(3, 3) == 0) {
    return;
  }

  for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
      matrix.set(j, i, matrix.get(j, i) / matrix.get(3, 3));
    }
  }

  SkMatrix44 perpective_matrix = matrix;
  for (int i = 0; i < 3; i++) {
    perpective_matrix.set(3, i, 0.0);
  }

  perpective_matrix.set(3, 3, 1.0);

  if (perpective_matrix.determinant() == 0.0) {
    return;
  }

  if (matrix.get(3, 0) != 0.0 || matrix.get(3, 1) != 0.0 ||
      matrix.get(3, 2) != 0.0) {
    const SkVector4 right_hand_side(matrix.get(3, 0), matrix.get(3, 1),
                                    matrix.get(3, 2), matrix.get(3, 3));

    SkMatrix44 inverted_transposed(
        SkMatrix44::Uninitialized_Constructor::kUninitialized_Constructor);
    if (!perpective_matrix.invert(&inverted_transposed)) {
      return;
    }
    inverted_transposed.transpose();

    perspective_ = inverted_transposed * right_hand_side;

    matrix.set(3, 0, 0);
    matrix.set(3, 1, 0);
    matrix.set(3, 2, 0);
    matrix.set(3, 3, 1);
  }

  translation_ = {matrix.get(0, 3), matrix.get(1, 3), matrix.get(2, 3)};

  matrix.set(0, 3, 0.0);
  matrix.set(1, 3, 0.0);
  matrix.set(2, 3, 0.0);

  SkVector3 row[3];
  for (int i = 0; i < 3; i++) {
    row[i].set(matrix.get(0, i), matrix.get(1, i), matrix.get(2, i));
  }

  scale_.fX = row[0].length();

  SkVector3Normalize(row[0]);

  shear_.fX = row[0].dot(row[1]);
  row[1] = SkVector3Combine(row[1], 1.0, row[0], -shear_.fX);

  scale_.fY = row[1].length();

  SkVector3Normalize(row[1]);

  shear_.fX /= scale_.fY;

  shear_.fY = row[0].dot(row[2]);
  row[2] = SkVector3Combine(row[2], 1.0, row[0], -shear_.fY);
  shear_.fZ = row[1].dot(row[2]);
  row[2] = SkVector3Combine(row[2], 1.0, row[1], -shear_.fZ);

  scale_.fZ = row[2].length();

  SkVector3Normalize(row[2]);

  shear_.fY /= scale_.fZ;
  shear_.fZ /= scale_.fZ;

  if (row[0].dot(SkVector3Cross(row[1], row[2])) < 0) {
    scale_.fX *= -1;
    scale_.fY *= -1;
    scale_.fZ *= -1;

    for (int i = 0; i < 3; i++) {
      row[i].fX *= -1;
      row[i].fY *= -1;
      row[i].fZ *= -1;
    }
  }

  rotation_.set(0.5 * sqrt(fmax(1.0 + row[0].fX - row[1].fY - row[2].fZ, 0.0)),
                0.5 * sqrt(fmax(1.0 - row[0].fX + row[1].fY - row[2].fZ, 0.0)),
                0.5 * sqrt(fmax(1.0 - row[0].fX - row[1].fY + row[2].fZ, 0.0)),
                0.5 * sqrt(fmax(1.0 + row[0].fX + row[1].fY + row[2].fZ, 0.0)));

  if (row[2].fY > row[1].fZ) {
    rotation_.fData[0] = -rotation_.fData[0];
  }
  if (row[0].fZ > row[2].fX) {
    rotation_.fData[1] = -rotation_.fData[1];
  }
  if (row[1].fX > row[0].fY) {
    rotation_.fData[2] = -rotation_.fData[2];
  }

  valid_ = true;
}

MatrixDecomposition::~MatrixDecomposition() = default;

bool MatrixDecomposition::IsValid() const {
  return valid_;
}

}  // namespace flutter
