/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkMatrix44.h"
#include "include/core/SkPoint3.h"
#include "include/private/SkM44.h"
#include "tests/Test.h"

static bool nearly_equal_double(double a, double b) {
    const double tolerance = 1e-7;
    double diff = a - b;
    if (diff < 0)
        diff = -diff;
    return diff <= tolerance;
}

static bool nearly_equal_scalar(SkScalar a, SkScalar b) {
    const SkScalar tolerance = SK_Scalar1 / 200000;
    return SkScalarAbs(a - b) <= tolerance;
}

template <typename T> void assert16(skiatest::Reporter* reporter, const T data[],
                                    T m0,  T m1,  T m2,  T m3,
                                    T m4,  T m5,  T m6,  T m7,
                                    T m8,  T m9,  T m10, T m11,
                                    T m12, T m13, T m14, T m15) {
    REPORTER_ASSERT(reporter, data[0] == m0);
    REPORTER_ASSERT(reporter, data[1] == m1);
    REPORTER_ASSERT(reporter, data[2] == m2);
    REPORTER_ASSERT(reporter, data[3] == m3);

    REPORTER_ASSERT(reporter, data[4] == m4);
    REPORTER_ASSERT(reporter, data[5] == m5);
    REPORTER_ASSERT(reporter, data[6] == m6);
    REPORTER_ASSERT(reporter, data[7] == m7);

    REPORTER_ASSERT(reporter, data[8] == m8);
    REPORTER_ASSERT(reporter, data[9] == m9);
    REPORTER_ASSERT(reporter, data[10] == m10);
    REPORTER_ASSERT(reporter, data[11] == m11);

    REPORTER_ASSERT(reporter, data[12] == m12);
    REPORTER_ASSERT(reporter, data[13] == m13);
    REPORTER_ASSERT(reporter, data[14] == m14);
    REPORTER_ASSERT(reporter, data[15] == m15);
}

static bool nearly_equal(const SkMatrix44& a, const SkMatrix44& b) {
    for (int i = 0; i < 4; ++i) {
        for (int j = 0; j < 4; ++j) {
            if (!SkScalarNearlyEqual(a.get(i, j), b.get(i, j))) {
                SkDebugf("not equal %g %g\n", a.get(i, j), b.get(i, j));
                return false;
            }
        }
    }
    return true;
}

static bool is_identity(const SkMatrix44& m) {
    SkMatrix44 identity(SkMatrix44::kIdentity_Constructor);
    return nearly_equal(m, identity);
}

///////////////////////////////////////////////////////////////////////////////
static bool bits_isonly(int value, int mask) {
    return 0 == (value & ~mask);
}

static void test_constructor(skiatest::Reporter* reporter) {
    // Allocate a matrix on the heap
    SkMatrix44* placeholderMatrix = new SkMatrix44;
    std::unique_ptr<SkMatrix44> deleteMe(placeholderMatrix);

    for (int row = 0; row < 4; ++row) {
        for (int col = 0; col < 4; ++col) {
            placeholderMatrix->setDouble(row, col, row * col);
        }
    }

    // Use placement-new syntax to trigger the constructor on top of the heap
    // address we already initialized. This allows us to check that the
    // constructor did avoid initializing the matrix contents.
    SkMatrix44* testMatrix = new(placeholderMatrix) SkMatrix44(SkMatrix44::kUninitialized_Constructor);
    REPORTER_ASSERT(reporter, testMatrix == placeholderMatrix);
    REPORTER_ASSERT(reporter, !testMatrix->isIdentity());
    for (int row = 0; row < 4; ++row) {
        for (int col = 0; col < 4; ++col) {
            REPORTER_ASSERT(reporter, nearly_equal_double(row * col, testMatrix->getDouble(row, col)));
        }
    }

    // Verify that kIdentity_Constructor really does initialize to an identity matrix.
    testMatrix = 0;
    testMatrix = new(placeholderMatrix) SkMatrix44(SkMatrix44::kIdentity_Constructor);
    REPORTER_ASSERT(reporter, testMatrix == placeholderMatrix);
    REPORTER_ASSERT(reporter, testMatrix->isIdentity());
    REPORTER_ASSERT(reporter, *testMatrix == SkMatrix44::I());

    // Verify that that constructing from an SkMatrix initializes everything.
    SkMatrix44 scaleMatrix;
    scaleMatrix.setScale(3, 4, 5);
    REPORTER_ASSERT(reporter, scaleMatrix.isScale());
    testMatrix = new(&scaleMatrix) SkMatrix44(SkMatrix::I());
    REPORTER_ASSERT(reporter, testMatrix->isIdentity());
    REPORTER_ASSERT(reporter, *testMatrix == SkMatrix44::I());
}

static void test_translate(skiatest::Reporter* reporter) {
    SkMatrix44 mat;
    SkMatrix44 inverse;

    mat.setTranslate(0, 0, 0);
    REPORTER_ASSERT(reporter, bits_isonly(mat.getType(), SkMatrix44::kIdentity_Mask));
    mat.setTranslate(1, 2, 3);
    REPORTER_ASSERT(reporter, bits_isonly(mat.getType(), SkMatrix44::kTranslate_Mask));
    REPORTER_ASSERT(reporter, mat.invert(&inverse));
    REPORTER_ASSERT(reporter, bits_isonly(inverse.getType(), SkMatrix44::kTranslate_Mask));

    SkMatrix44 a,b,c;
    a.set3x3(1, 2, 3, 4, 5, 6, 7, 8, 9);
    b.setTranslate(10, 11, 12);

    c.setConcat(a, b);
    mat = a;
    mat.preTranslate(10, 11, 12);
    REPORTER_ASSERT(reporter, mat == c);

    c.setConcat(b, a);
    mat = a;
    mat.postTranslate(10, 11, 12);
    REPORTER_ASSERT(reporter, mat == c);
}

static void test_scale(skiatest::Reporter* reporter) {
    SkMatrix44 mat;
    SkMatrix44 inverse;

    mat.setScale(1, 1, 1);
    REPORTER_ASSERT(reporter, bits_isonly(mat.getType(), SkMatrix44::kIdentity_Mask));
    mat.setScale(1, 2, 3);
    REPORTER_ASSERT(reporter, bits_isonly(mat.getType(), SkMatrix44::kScale_Mask));
    REPORTER_ASSERT(reporter, mat.invert(&inverse));
    REPORTER_ASSERT(reporter, bits_isonly(inverse.getType(), SkMatrix44::kScale_Mask));

    SkMatrix44 a,b,c;
    a.set3x3(1, 2, 3, 4, 5, 6, 7, 8, 9);
    b.setScale(10, 11, 12);

    c.setConcat(a, b);
    mat = a;
    mat.preScale(10, 11, 12);
    REPORTER_ASSERT(reporter, mat == c);

    c.setConcat(b, a);
    mat = a;
    mat.postScale(10, 11, 12);
    REPORTER_ASSERT(reporter, mat == c);
}

static void make_i(SkMatrix44* mat) { mat->setIdentity(); }
static void make_t(SkMatrix44* mat) { mat->setTranslate(1, 2, 3); }
static void make_s(SkMatrix44* mat) { mat->setScale(1, 2, 3); }
static void make_st(SkMatrix44* mat) {
    mat->setScale(1, 2, 3);
    mat->postTranslate(1, 2, 3);
}
static void make_a(SkMatrix44* mat) {
    mat->setRotateDegreesAbout(1, 2, 3, 45);
}
static void make_p(SkMatrix44* mat) {
    SkScalar data[] = {
        1, 2, 3, 4, 5, 6, 7, 8,
        1, 2, 3, 4, 5, 6, 7, 8,
    };
    mat->setRowMajor(data);
}

typedef void (*Make44Proc)(SkMatrix44*);

static const Make44Proc gMakeProcs[] = {
    make_i, make_t, make_s, make_st, make_a, make_p
};

static void test_map2(skiatest::Reporter* reporter, const SkMatrix44& mat) {
    SkScalar src2[] = { 1, 2 };
    SkScalar src4[] = { src2[0], src2[1], 0, 1 };
    SkScalar dstA[4], dstB[4];

    for (int i = 0; i < 4; ++i) {
        dstA[i] = SkScalar(123456789);
        dstB[i] = SkScalar(987654321);
    }

    mat.map2(src2, 1, dstA);
    mat.mapScalars(src4, dstB);

    for (int i = 0; i < 4; ++i) {
        REPORTER_ASSERT(reporter, dstA[i] == dstB[i]);
    }
}

static void test_map2(skiatest::Reporter* reporter) {
    SkMatrix44 mat;

    for (size_t i = 0; i < SK_ARRAY_COUNT(gMakeProcs); ++i) {
        gMakeProcs[i](&mat);
        test_map2(reporter, mat);
    }
}

static void test_gettype(skiatest::Reporter* reporter) {
    SkMatrix44 matrix(SkMatrix44::kIdentity_Constructor);

    REPORTER_ASSERT(reporter, matrix.isIdentity());
    REPORTER_ASSERT(reporter, SkMatrix44::kIdentity_Mask == matrix.getType());

    int expectedMask;

    matrix.set(1, 1, 0);
    expectedMask = SkMatrix44::kScale_Mask;
    REPORTER_ASSERT(reporter, matrix.getType() == expectedMask);

    matrix.set(0, 3, 1);    // translate-x
    expectedMask |= SkMatrix44::kTranslate_Mask;
    REPORTER_ASSERT(reporter, matrix.getType() == expectedMask);

    matrix.set(2, 0, 1);
    expectedMask |= SkMatrix44::kAffine_Mask;
    REPORTER_ASSERT(reporter, matrix.getType() == expectedMask);

    matrix.set(3, 2, 1);
    REPORTER_ASSERT(reporter, matrix.getType() & SkMatrix44::kPerspective_Mask);

    // ensure that negative zero is treated as zero
    SkScalar dx = 0;
    SkScalar dy = 0;
    SkScalar dz = 0;
    matrix.setTranslate(-dx, -dy, -dz);
    REPORTER_ASSERT(reporter, matrix.isIdentity());
    matrix.preTranslate(-dx, -dy, -dz);
    REPORTER_ASSERT(reporter, matrix.isIdentity());
    matrix.postTranslate(-dx, -dy, -dz);
    REPORTER_ASSERT(reporter, matrix.isIdentity());
}

static void test_common_angles(skiatest::Reporter* reporter) {
    SkMatrix44 rot;
    // Test precision of rotation in common cases
    int common_angles[] = { 0, 90, -90, 180, -180, 270, -270, 360, -360 };
    for (int i = 0; i < 9; ++i) {
        rot.setRotateDegreesAbout(0, 0, -1, SkIntToScalar(common_angles[i]));

        SkMatrix rot3x3 = SkMatrix(rot);
        REPORTER_ASSERT(reporter, rot3x3.rectStaysRect());
    }
}

static void test_concat(skiatest::Reporter* reporter) {
    int i;
    SkMatrix44 a,b,c,d;

    a.setTranslate(10, 10, 10);
    b.setScale(2, 2, 2);

    SkScalar src[8] = {
        0, 0, 0, 1,
        1, 1, 1, 1
    };
    SkScalar dst[8];

    c.setConcat(a, b);

    d = a;
    d.preConcat(b);
    REPORTER_ASSERT(reporter, d == c);

    c.mapScalars(src, dst); c.mapScalars(src + 4, dst + 4);
    for (i = 0; i < 3; ++i) {
        REPORTER_ASSERT(reporter, 10 == dst[i]);
        REPORTER_ASSERT(reporter, 12 == dst[i + 4]);
    }

    c.setConcat(b, a);

    d = a;
    d.postConcat(b);
    REPORTER_ASSERT(reporter, d == c);

    c.mapScalars(src, dst); c.mapScalars(src + 4, dst + 4);
    for (i = 0; i < 3; ++i) {
        REPORTER_ASSERT(reporter, 20 == dst[i]);
        REPORTER_ASSERT(reporter, 22 == dst[i + 4]);
    }
}

static void test_determinant(skiatest::Reporter* reporter) {
    SkMatrix44 a(SkMatrix44::kIdentity_Constructor);
    REPORTER_ASSERT(reporter, nearly_equal_double(1, a.determinant()));
    a.set(1, 1, 2);
    REPORTER_ASSERT(reporter, nearly_equal_double(2, a.determinant()));
    SkMatrix44 b;
    REPORTER_ASSERT(reporter, a.invert(&b));
    REPORTER_ASSERT(reporter, nearly_equal_double(0.5, b.determinant()));
    SkMatrix44 c = b = a;
    c.set(0, 1, 4);
    b.set(1, 0, 4);
    REPORTER_ASSERT(reporter,
                    nearly_equal_double(a.determinant(),
                                        b.determinant()));
    SkMatrix44 d = a;
    d.set(0, 0, 8);
    REPORTER_ASSERT(reporter, nearly_equal_double(16, d.determinant()));

    SkMatrix44 e = a;
    e.postConcat(d);
    REPORTER_ASSERT(reporter, nearly_equal_double(32, e.determinant()));
    e.set(0, 0, 0);
    REPORTER_ASSERT(reporter, nearly_equal_double(0, e.determinant()));
}

static void test_invert(skiatest::Reporter* reporter) {
    SkMatrix44 inverse;
    double inverseData[16];

    SkMatrix44 identity(SkMatrix44::kIdentity_Constructor);
    identity.invert(&inverse);
    inverse.asRowMajord(inverseData);
    assert16<double>(reporter, inverseData,
                     1, 0, 0, 0,
                     0, 1, 0, 0,
                     0, 0, 1, 0,
                     0, 0, 0, 1);

    SkMatrix44 translation;
    translation.setTranslate(2, 3, 4);
    translation.invert(&inverse);
    inverse.asRowMajord(inverseData);
    assert16<double>(reporter, inverseData,
                     1, 0, 0, -2,
                     0, 1, 0, -3,
                     0, 0, 1, -4,
                     0, 0, 0, 1);

    SkMatrix44 scale;
    scale.setScale(2, 4, 8);
    scale.invert(&inverse);
    inverse.asRowMajord(inverseData);
    assert16<double>(reporter, inverseData,
                     0.5, 0,    0,     0,
                     0,   0.25, 0,     0,
                     0,   0,    0.125, 0,
                     0,   0,    0,     1);

    SkMatrix44 scaleTranslation;
    scaleTranslation.setScale(32, 128, 1024);
    scaleTranslation.preTranslate(2, 3, 4);
    scaleTranslation.invert(&inverse);
    inverse.asRowMajord(inverseData);
    assert16<double>(reporter, inverseData,
                     0.03125,  0,          0,            -2,
                     0,        0.0078125,  0,            -3,
                     0,        0,          0.0009765625, -4,
                     0,        0,          0,             1);

    SkMatrix44 rotation;
    rotation.setRotateDegreesAbout(0, 0, 1, 90);
    rotation.invert(&inverse);
    SkMatrix44 expected;
    double expectedInverseRotation[16] =
            {0,  1, 0, 0,
             -1, 0, 0, 0,
             0,  0, 1, 0,
             0,  0, 0, 1};
    expected.setRowMajord(expectedInverseRotation);
    REPORTER_ASSERT(reporter, nearly_equal(expected, inverse));

    SkMatrix44 affine;
    affine.setRotateDegreesAbout(0, 0, 1, 90);
    affine.preScale(10, 20, 100);
    affine.preTranslate(2, 3, 4);
    affine.invert(&inverse);
    double expectedInverseAffine[16] =
            {0,    0.1,  0,   -2,
             -0.05, 0,   0,   -3,
             0,     0,  0.01, -4,
             0,     0,   0,   1};
    expected.setRowMajord(expectedInverseAffine);
    REPORTER_ASSERT(reporter, nearly_equal(expected, inverse));

    SkMatrix44 perspective(SkMatrix44::kIdentity_Constructor);
    perspective.setDouble(3, 2, 1.0);
    perspective.invert(&inverse);
    double expectedInversePerspective[16] =
            {1, 0,  0, 0,
             0, 1,  0, 0,
             0, 0,  1, 0,
             0, 0, -1, 1};
    expected.setRowMajord(expectedInversePerspective);
    REPORTER_ASSERT(reporter, nearly_equal(expected, inverse));

    SkMatrix44 affineAndPerspective(SkMatrix44::kIdentity_Constructor);
    affineAndPerspective.setDouble(3, 2, 1.0);
    affineAndPerspective.preScale(10, 20, 100);
    affineAndPerspective.preTranslate(2, 3, 4);
    affineAndPerspective.invert(&inverse);
    double expectedInverseAffineAndPerspective[16] =
            {0.1, 0,    2,   -2,
             0,  0.05,  3,   -3,
             0,   0,   4.01, -4,
             0,   0,   -1,    1};
    expected.setRowMajord(expectedInverseAffineAndPerspective);
    REPORTER_ASSERT(reporter, nearly_equal(expected, inverse));

    SkMatrix44 tinyScale(SkMatrix44::kIdentity_Constructor);
    tinyScale.setDouble(0, 0, 1e-39);
    REPORTER_ASSERT(reporter, tinyScale.getType() == SkMatrix44::kScale_Mask);
    REPORTER_ASSERT(reporter, !tinyScale.invert(nullptr));
    REPORTER_ASSERT(reporter, !tinyScale.invert(&inverse));

    SkMatrix44 tinyScaleTranslate(SkMatrix44::kIdentity_Constructor);
    tinyScaleTranslate.setDouble(0, 0, 1e-38);
    REPORTER_ASSERT(reporter, tinyScaleTranslate.invert(nullptr));
    tinyScaleTranslate.setDouble(0, 3, 10);
    REPORTER_ASSERT(
        reporter, tinyScaleTranslate.getType() ==
                      (SkMatrix44::kScale_Mask | SkMatrix44::kTranslate_Mask));
    REPORTER_ASSERT(reporter, !tinyScaleTranslate.invert(nullptr));
    REPORTER_ASSERT(reporter, !tinyScaleTranslate.invert(&inverse));

    SkMatrix44 tinyScalePerspective(SkMatrix44::kIdentity_Constructor);
    tinyScalePerspective.setDouble(0, 0, 1e-39);
    tinyScalePerspective.setDouble(3, 2, -1);
    REPORTER_ASSERT(reporter, (tinyScalePerspective.getType() &
                               SkMatrix44::kPerspective_Mask) ==
                                  SkMatrix44::kPerspective_Mask);
    REPORTER_ASSERT(reporter, !tinyScalePerspective.invert(nullptr));
    REPORTER_ASSERT(reporter, !tinyScalePerspective.invert(&inverse));
}

static void test_transpose(skiatest::Reporter* reporter) {
    SkMatrix44 a,b;

    int i = 0;
    for (int row = 0; row < 4; ++row) {
        for (int col = 0; col < 4; ++col) {
            a.setDouble(row, col, i);
            b.setDouble(col, row, i++);
        }
    }

    a.transpose();
    REPORTER_ASSERT(reporter, nearly_equal(a, b));
}

static void test_get_set_double(skiatest::Reporter* reporter) {
    SkMatrix44 a;
    for (int row = 0; row < 4; ++row) {
        for (int col = 0; col < 4; ++col) {
            a.setDouble(row, col, 3.141592653589793);
            REPORTER_ASSERT(reporter,
                            nearly_equal_double(3.141592653589793,
                                                a.getDouble(row, col)));
            a.setDouble(row, col, 0);
            REPORTER_ASSERT(reporter,
                            nearly_equal_double(0, a.getDouble(row, col)));
        }
    }
}

static void test_set_3x3(skiatest::Reporter* r) {
    static float vals[9] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, };

    SkMatrix44 mat;
    mat.set3x3RowMajorf(vals);

    REPORTER_ASSERT(r, 1.0f == mat.getFloat(0, 0));
    REPORTER_ASSERT(r, 2.0f == mat.getFloat(0, 1));
    REPORTER_ASSERT(r, 3.0f == mat.getFloat(0, 2));
    REPORTER_ASSERT(r, 4.0f == mat.getFloat(1, 0));
    REPORTER_ASSERT(r, 5.0f == mat.getFloat(1, 1));
    REPORTER_ASSERT(r, 6.0f == mat.getFloat(1, 2));
    REPORTER_ASSERT(r, 7.0f == mat.getFloat(2, 0));
    REPORTER_ASSERT(r, 8.0f == mat.getFloat(2, 1));
    REPORTER_ASSERT(r, 9.0f == mat.getFloat(2, 2));
}

static void test_set_row_col_major(skiatest::Reporter* reporter) {
    SkMatrix44 a,b;

    for (int row = 0; row < 4; ++row) {
        for (int col = 0; col < 4; ++col) {
            a.setDouble(row, col, row * 4 + col);
        }
    }

    double bufferd[16];
    float bufferf[16];
    a.asColMajord(bufferd);
    b.setColMajord(bufferd);
    REPORTER_ASSERT(reporter, nearly_equal(a, b));
    b.setRowMajord(bufferd);
    b.transpose();
    REPORTER_ASSERT(reporter, nearly_equal(a, b));
    a.asColMajorf(bufferf);
    b.setColMajorf(bufferf);
    REPORTER_ASSERT(reporter, nearly_equal(a, b));
    b.setRowMajorf(bufferf);
    b.transpose();
    REPORTER_ASSERT(reporter, nearly_equal(a, b));
}

static void test_3x3_conversion(skiatest::Reporter* reporter) {
    SkScalar values4x4[16] = { 1, 2, 3, 4,
                               5, 6, 7, 8,
                               9, 10, 11, 12,
                               13, 14, 15, 16 };
    SkScalar values3x3[9] = { 1, 2, 4,
                              5, 6, 8,
                              13, 14, 16 };
    SkScalar values4x4flattened[16] = { 1, 2, 0, 4,
                                        5, 6, 0, 8,
                                        0, 0, 1, 0,
                                        13, 14, 0, 16 };
    SkMatrix44 a44;
    a44.setRowMajor(values4x4);

    SkMatrix a33 = SkMatrix(a44);
    SkMatrix expected33;
    for (int i = 0; i < 9; i++) expected33[i] = values3x3[i];
    REPORTER_ASSERT(reporter, expected33 == a33);

    SkMatrix44 a44flattened = a33;
    SkMatrix44 expected44flattened;
    expected44flattened.setRowMajor(values4x4flattened);
    REPORTER_ASSERT(reporter, nearly_equal(a44flattened, expected44flattened));

    // Test that a point with a Z value of 0 is transformed the same way.
    SkScalar vec4[4] = { 2, 4, 0, 8 };
    SkPoint3 vec3 = { 2, 4, 8 };

    SkScalar vec4transformed[4];
    SkPoint3 vec3transformed;
    SkScalar vec4transformed2[4];
    a44.mapScalars(vec4, vec4transformed);
    a33.mapHomogeneousPoints(&vec3transformed, &vec3, 1);
    a44flattened.mapScalars(vec4, vec4transformed2);
    REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[0], vec3transformed.fX));
    REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[1], vec3transformed.fY));
    REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[3], vec3transformed.fZ));
    REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[0], vec4transformed2[0]));
    REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[1], vec4transformed2[1]));
    REPORTER_ASSERT(reporter, !nearly_equal_scalar(vec4transformed[2], vec4transformed2[2]));
    REPORTER_ASSERT(reporter, nearly_equal_scalar(vec4transformed[3], vec4transformed2[3]));
}

static void test_has_perspective(skiatest::Reporter* reporter) {
    SkMatrix44 transform(SkMatrix44::kIdentity_Constructor);

    transform.setDouble(3, 2, -0.1);
    REPORTER_ASSERT(reporter, transform.hasPerspective());

    transform.reset();
    REPORTER_ASSERT(reporter, !transform.hasPerspective());

    transform.setDouble(3, 0, -1.0);
    REPORTER_ASSERT(reporter, transform.hasPerspective());

    transform.reset();
    transform.setDouble(3, 1, -1.0);
    REPORTER_ASSERT(reporter, transform.hasPerspective());

    transform.reset();
    transform.setDouble(3, 2, -0.3);
    REPORTER_ASSERT(reporter, transform.hasPerspective());

    transform.reset();
    transform.setDouble(3, 3, 0.5);
    REPORTER_ASSERT(reporter, transform.hasPerspective());

    transform.reset();
    transform.setDouble(3, 3, 0.0);
    REPORTER_ASSERT(reporter, transform.hasPerspective());
}

static bool is_rectilinear (SkVector4& p1, SkVector4& p2, SkVector4& p3, SkVector4& p4) {
    return (SkScalarNearlyEqual(p1.fData[0], p2.fData[0]) &&
            SkScalarNearlyEqual(p2.fData[1], p3.fData[1]) &&
            SkScalarNearlyEqual(p3.fData[0], p4.fData[0]) &&
            SkScalarNearlyEqual(p4.fData[1], p1.fData[1])) ||
           (SkScalarNearlyEqual(p1.fData[1], p2.fData[1]) &&
            SkScalarNearlyEqual(p2.fData[0], p3.fData[0]) &&
            SkScalarNearlyEqual(p3.fData[1], p4.fData[1]) &&
            SkScalarNearlyEqual(p4.fData[0], p1.fData[0]));
}

static SkVector4 mul_with_persp_divide(const SkMatrix44& transform, const SkVector4& target) {
    SkVector4 result = transform * target;
    if (result.fData[3] != 0.0f && result.fData[3] != SK_Scalar1) {
        float wInverse = SK_Scalar1 / result.fData[3];
        result.set(result.fData[0] * wInverse,
                   result.fData[1] * wInverse,
                   result.fData[2] * wInverse,
                   SK_Scalar1);
    }
    return result;
}

static bool empirically_preserves_2d_axis_alignment(skiatest::Reporter* reporter,
                                                    const SkMatrix44& transform) {
  SkVector4 p1(5.0f, 5.0f, 0.0f);
  SkVector4 p2(10.0f, 5.0f, 0.0f);
  SkVector4 p3(10.0f, 20.0f, 0.0f);
  SkVector4 p4(5.0f, 20.0f, 0.0f);

  REPORTER_ASSERT(reporter, is_rectilinear(p1, p2, p3, p4));

  p1 = mul_with_persp_divide(transform, p1);
  p2 = mul_with_persp_divide(transform, p2);
  p3 = mul_with_persp_divide(transform, p3);
  p4 = mul_with_persp_divide(transform, p4);

  return is_rectilinear(p1, p2, p3, p4);
}

static void test(bool expected, skiatest::Reporter* reporter, const SkMatrix44& transform) {
    if (expected) {
        REPORTER_ASSERT(reporter, empirically_preserves_2d_axis_alignment(reporter, transform));
        REPORTER_ASSERT(reporter, transform.preserves2dAxisAlignment());
    } else {
        REPORTER_ASSERT(reporter, !empirically_preserves_2d_axis_alignment(reporter, transform));
        REPORTER_ASSERT(reporter, !transform.preserves2dAxisAlignment());
    }
}

static void test_preserves_2d_axis_alignment(skiatest::Reporter* reporter) {
  SkMatrix44 transform;
  SkMatrix44 transform2;

  static const struct TestCase {
    SkScalar a; // row 1, column 1
    SkScalar b; // row 1, column 2
    SkScalar c; // row 2, column 1
    SkScalar d; // row 2, column 2
    bool expected;
  } test_cases[] = {
    { 3.f, 0.f,
      0.f, 4.f, true }, // basic case
    { 0.f, 4.f,
      3.f, 0.f, true }, // rotate by 90
    { 0.f, 0.f,
      0.f, 4.f, true }, // degenerate x
    { 3.f, 0.f,
      0.f, 0.f, true }, // degenerate y
    { 0.f, 0.f,
      3.f, 0.f, true }, // degenerate x + rotate by 90
    { 0.f, 4.f,
      0.f, 0.f, true }, // degenerate y + rotate by 90
    { 3.f, 4.f,
      0.f, 0.f, false },
    { 0.f, 0.f,
      3.f, 4.f, false },
    { 0.f, 3.f,
      0.f, 4.f, false },
    { 3.f, 0.f,
      4.f, 0.f, false },
    { 3.f, 4.f,
      5.f, 0.f, false },
    { 3.f, 4.f,
      0.f, 5.f, false },
    { 3.f, 0.f,
      4.f, 5.f, false },
    { 0.f, 3.f,
      4.f, 5.f, false },
    { 2.f, 3.f,
      4.f, 5.f, false },
  };

  for (size_t i = 0; i < sizeof(test_cases)/sizeof(TestCase); ++i) {
    const TestCase& value = test_cases[i];
    transform.setIdentity();
    transform.set(0, 0, value.a);
    transform.set(0, 1, value.b);
    transform.set(1, 0, value.c);
    transform.set(1, 1, value.d);

    test(value.expected, reporter, transform);
  }

  // Try the same test cases again, but this time make sure that other matrix
  // elements (except perspective) have entries, to test that they are ignored.
  for (size_t i = 0; i < sizeof(test_cases)/sizeof(TestCase); ++i) {
    const TestCase& value = test_cases[i];
    transform.setIdentity();
    transform.set(0, 0, value.a);
    transform.set(0, 1, value.b);
    transform.set(1, 0, value.c);
    transform.set(1, 1, value.d);

    transform.set(0, 2, 1.f);
    transform.set(0, 3, 2.f);
    transform.set(1, 2, 3.f);
    transform.set(1, 3, 4.f);
    transform.set(2, 0, 5.f);
    transform.set(2, 1, 6.f);
    transform.set(2, 2, 7.f);
    transform.set(2, 3, 8.f);

    test(value.expected, reporter, transform);
  }

  // Try the same test cases again, but this time add perspective which is
  // always assumed to not-preserve axis alignment.
  for (size_t i = 0; i < sizeof(test_cases)/sizeof(TestCase); ++i) {
    const TestCase& value = test_cases[i];
    transform.setIdentity();
    transform.set(0, 0, value.a);
    transform.set(0, 1, value.b);
    transform.set(1, 0, value.c);
    transform.set(1, 1, value.d);

    transform.set(0, 2, 1.f);
    transform.set(0, 3, 2.f);
    transform.set(1, 2, 3.f);
    transform.set(1, 3, 4.f);
    transform.set(2, 0, 5.f);
    transform.set(2, 1, 6.f);
    transform.set(2, 2, 7.f);
    transform.set(2, 3, 8.f);
    transform.set(3, 0, 9.f);
    transform.set(3, 1, 10.f);
    transform.set(3, 2, 11.f);
    transform.set(3, 3, 12.f);

    test(false, reporter, transform);
  }

  // Try a few more practical situations to check precision
  // Reuse TestCase (a, b, c, d) as (x, y, z, degrees) axis to rotate about.
  TestCase rotation_tests[] = {
    { 0.0, 0.0, 1.0, 90.0, true },
    { 0.0, 0.0, 1.0, 180.0, true },
    { 0.0, 0.0, 1.0, 270.0, true },
    { 0.0, 1.0, 0.0, 90.0, true },
    { 1.0, 0.0, 0.0, 90.0, true },
    { 0.0, 0.0, 1.0, 45.0, false },
    // In 3d these next two are non-preserving, but we're testing in 2d after
    // orthographic projection, where they are.
    { 0.0, 1.0, 0.0, 45.0, true },
    { 1.0, 0.0, 0.0, 45.0, true },
  };

  for (size_t i = 0; i < sizeof(rotation_tests)/sizeof(TestCase); ++i) {
    const TestCase& value = rotation_tests[i];
    transform.setRotateDegreesAbout(value.a, value.b, value.c, value.d);
    test(value.expected, reporter, transform);
  }

  static const struct DoubleRotationCase {
    SkScalar x1;
    SkScalar y1;
    SkScalar z1;
    SkScalar degrees1;
    SkScalar x2;
    SkScalar y2;
    SkScalar z2;
    SkScalar degrees2;
    bool expected;
  } double_rotation_tests[] = {
    { 0.0, 0.0, 1.0, 90.0, 0.0, 1.0, 0.0, 90.0, true },
    { 0.0, 0.0, 1.0, 90.0, 1.0, 0.0, 0.0, 90.0, true },
    { 0.0, 1.0, 0.0, 90.0, 0.0, 0.0, 1.0, 90.0, true },
  };

  for (size_t i = 0; i < sizeof(double_rotation_tests)/sizeof(DoubleRotationCase); ++i) {
    const DoubleRotationCase& value = double_rotation_tests[i];
    transform.setRotateDegreesAbout(value.x1, value.y1, value.z1, value.degrees1);
    transform2.setRotateDegreesAbout(value.x2, value.y2, value.z2, value.degrees2);
    transform.postConcat(transform2);
    test(value.expected, reporter, transform);
  }

  // Perspective cases.
  transform.setIdentity();
  transform.setDouble(3, 2, -0.1); // Perspective depth 10
  transform2.setRotateDegreesAbout(0.0, 1.0, 0.0, 45.0);
  transform.preConcat(transform2);
  test(false, reporter, transform);

  transform.setIdentity();
  transform.setDouble(3, 2, -0.1); // Perspective depth 10
  transform2.setRotateDegreesAbout(0.0, 0.0, 1.0, 90.0);
  transform.preConcat(transform2);
  test(true, reporter, transform);
}

// just want to exercise the various converters for Scalar
static void test_toint(skiatest::Reporter* reporter) {
    SkMatrix44 mat;
    mat.setScale(3, 3, 3);

    SkScalar sum = SkScalarFloorToScalar(mat.get(0, 0)) +
                   SkScalarRoundToScalar(mat.get(1, 0)) +
                   SkScalarCeilToScalar(mat.get(2, 0));
    int isum =     SkScalarFloorToInt(mat.get(0, 1)) +
                   SkScalarRoundToInt(mat.get(1, 2)) +
                   SkScalarCeilToInt(mat.get(2, 3));
    REPORTER_ASSERT(reporter, sum >= 0);
    REPORTER_ASSERT(reporter, isum >= 0);
    REPORTER_ASSERT(reporter, static_cast<SkScalar>(isum) == SkIntToScalar(isum));
}

DEF_TEST(Matrix44, reporter) {
    SkMatrix44 mat;
    SkMatrix44 inverse;
    SkMatrix44 iden1;
    SkMatrix44 iden2;
    SkMatrix44 rot;

    mat.setTranslate(1, 1, 1);
    mat.invert(&inverse);
    iden1.setConcat(mat, inverse);
    REPORTER_ASSERT(reporter, is_identity(iden1));

    mat.setScale(2, 2, 2);
    mat.invert(&inverse);
    iden1.setConcat(mat, inverse);
    REPORTER_ASSERT(reporter, is_identity(iden1));

    mat.setScale(SK_Scalar1/2, SK_Scalar1/2, SK_Scalar1/2);
    mat.invert(&inverse);
    iden1.setConcat(mat, inverse);
    REPORTER_ASSERT(reporter, is_identity(iden1));

    mat.setScale(3, 3, 3);
    rot.setRotateDegreesAbout(0, 0, -1, 90);
    mat.postConcat(rot);
    REPORTER_ASSERT(reporter, mat.invert(nullptr));
    mat.invert(&inverse);
    iden1.setConcat(mat, inverse);
    REPORTER_ASSERT(reporter, is_identity(iden1));
    iden2.setConcat(inverse, mat);
    REPORTER_ASSERT(reporter, is_identity(iden2));

    // test tiny-valued matrix inverse
    mat.reset();
    auto v = 1.0e-12f;
    mat.setScale(v,v,v);
    rot.setRotateDegreesAbout(0, 0, -1, 90);
    mat.postConcat(rot);
    mat.postTranslate(v,v,v);
    REPORTER_ASSERT(reporter, mat.invert(nullptr));
    mat.invert(&inverse);
    iden1.setConcat(mat, inverse);
    REPORTER_ASSERT(reporter, is_identity(iden1));

    // test mixed-valued matrix inverse
    mat.reset();
    mat.setScale(1.0e-2f, 3.0f, 1.0e+2f);
    rot.setRotateDegreesAbout(0, 0, -1, 90);
    mat.postConcat(rot);
    mat.postTranslate(1.0e+2f, 3.0f, 1.0e-2f);
    REPORTER_ASSERT(reporter, mat.invert(nullptr));
    mat.invert(&inverse);
    iden1.setConcat(mat, inverse);
    REPORTER_ASSERT(reporter, is_identity(iden1));

    // test degenerate matrix
    mat.reset();
    mat.set3x3(1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    REPORTER_ASSERT(reporter, !mat.invert(nullptr));

    // test rol/col Major getters
    {
        mat.setTranslate(2, 3, 4);
        float dataf[16];
        double datad[16];

        mat.asColMajorf(dataf);
        assert16<float>(reporter, dataf,
                 1, 0, 0, 0,
                 0, 1, 0, 0,
                 0, 0, 1, 0,
                 2, 3, 4, 1);
        mat.asColMajord(datad);
        assert16<double>(reporter, datad, 1, 0, 0, 0,
                        0, 1, 0, 0,
                        0, 0, 1, 0,
                        2, 3, 4, 1);
        mat.asRowMajorf(dataf);
        assert16<float>(reporter, dataf, 1, 0, 0, 2,
                        0, 1, 0, 3,
                        0, 0, 1, 4,
                        0, 0, 0, 1);
        mat.asRowMajord(datad);
        assert16<double>(reporter, datad, 1, 0, 0, 2,
                        0, 1, 0, 3,
                        0, 0, 1, 4,
                        0, 0, 0, 1);
    }

    test_concat(reporter);

    if (false) { // avoid bit rot, suppress warning (working on making this pass)
        test_common_angles(reporter);
    }

    test_constructor(reporter);
    test_gettype(reporter);
    test_determinant(reporter);
    test_invert(reporter);
    test_transpose(reporter);
    test_get_set_double(reporter);
    test_set_row_col_major(reporter);
    test_set_3x3(reporter);
    test_translate(reporter);
    test_scale(reporter);
    test_map2(reporter);
    test_3x3_conversion(reporter);
    test_has_perspective(reporter);
    test_preserves_2d_axis_alignment(reporter);
    test_toint(reporter);
}

static bool eq(const SkMatrix44& a, const SkM44& b, float tol) {
    float fa[16], fb[16];
    a.asColMajorf(fa);
    b.getColMajor(fb);
    for (int i = 0; i < 16; ++i) {
        if (!SkScalarNearlyEqual(fa[i], fb[i], tol)) {
            return false;
        }
    }
    return true;
}

static bool eq(const SkM44& a, const SkM44& b, float tol) {
    float fa[16], fb[16];
    a.getColMajor(fa);
    b.getColMajor(fb);
    for (int i = 0; i < 16; ++i) {
        if (!SkScalarNearlyEqual(fa[i], fb[i], tol)) {
            return false;
        }
    }
    return true;
}

DEF_TEST(M44, reporter) {
    SkM44 m, im;
    SkMatrix44 m44, im44;

    REPORTER_ASSERT(reporter, eq(m44, m, 0));
    REPORTER_ASSERT(reporter, SkM44() == m);
    REPORTER_ASSERT(reporter, m.invert(&im));
    REPORTER_ASSERT(reporter, SkM44() == im);

    m.setTranslate(3, 4, 2);
    m44.setTranslate(3, 4, 2);
    REPORTER_ASSERT(reporter, eq(m44, m, 0));
    REPORTER_ASSERT(reporter, SkM44(1, 0, 0, 3,
                                    0, 1, 0, 4,
                                    0, 0, 1, 2,
                                    0, 0, 0, 1) == m);

    const float f[] = { 1, 0, 0, 2, 3, 1, 2, 5, 0, 5, 3, 0, 0, 1, 0, 2 };
    m.setColMajor(f);
    m44.setColMajorf(f);
    REPORTER_ASSERT(reporter, eq(m44, m, 0));

    {
        SkM44 t = m.transpose();
        REPORTER_ASSERT(reporter, t != m);
        REPORTER_ASSERT(reporter, t.rc(1,0) == m.rc(0,1));
        SkM44 tt = t.transpose();
        REPORTER_ASSERT(reporter, tt == m);
    }

    m.setRowMajor(f);
    m44.setRowMajorf(f);
    REPORTER_ASSERT(reporter, eq(m44, m, 0));

    REPORTER_ASSERT(reporter, m.invert(&im));
    REPORTER_ASSERT(reporter, m44.invert(&im44));
    REPORTER_ASSERT(reporter, eq(im44, im, 0));

    m = m * im;
    // m should be identity now, but our calc is not perfect...
    REPORTER_ASSERT(reporter, eq(SkM44(), m, 0.0000005f));
    REPORTER_ASSERT(reporter, SkM44() != m);
}

DEF_TEST(M44_v3, reporter) {
    SkV3 a = {1, 2, 3},
         b = {1, 2, 2};

    REPORTER_ASSERT(reporter, a.lengthSquared() == 1 + 4 + 9);
    REPORTER_ASSERT(reporter, b.length() == 3);
    REPORTER_ASSERT(reporter, a.dot(b) == 1 + 4 + 6);
    REPORTER_ASSERT(reporter, b.dot(a) == 1 + 4 + 6);
    REPORTER_ASSERT(reporter, (a.cross(b) == SkV3{-2,  1, 0}));
    REPORTER_ASSERT(reporter, (b.cross(a) == SkV3{ 2, -1, 0}));

    SkM44 m = {
        2, 0, 0, 3,
        0, 1, 0, 5,
        0, 0, 3, 1,
        0, 0, 0, 1
    };

    SkV3 c = m * a;
    REPORTER_ASSERT(reporter, (c == SkV3{2, 2, 9}));
    SkV4 d = m.map(4, 3, 2, 1);
    REPORTER_ASSERT(reporter, (d == SkV4{11, 8, 7, 1}));
}

DEF_TEST(M44_v4, reporter) {
    SkM44 m( 1,  2,  3,  4,
             5,  6,  7,  8,
             9, 10, 11, 12,
            13, 14, 15, 16);

    SkV4 r0 = m.row(0),
         r1 = m.row(1),
         r2 = m.row(2),
         r3 = m.row(3);

    REPORTER_ASSERT(reporter, (r0 == SkV4{ 1,  2,  3,  4}));
    REPORTER_ASSERT(reporter, (r1 == SkV4{ 5,  6,  7,  8}));
    REPORTER_ASSERT(reporter, (r2 == SkV4{ 9, 10, 11, 12}));
    REPORTER_ASSERT(reporter, (r3 == SkV4{13, 14, 15, 16}));

    REPORTER_ASSERT(reporter, SkM44::Rows(r0, r1, r2, r3) == m);

    SkV4 c0 = m.col(0),
         c1 = m.col(1),
         c2 = m.col(2),
         c3 = m.col(3);

    REPORTER_ASSERT(reporter, (c0 == SkV4{1, 5,  9, 13}));
    REPORTER_ASSERT(reporter, (c1 == SkV4{2, 6, 10, 14}));
    REPORTER_ASSERT(reporter, (c2 == SkV4{3, 7, 11, 15}));
    REPORTER_ASSERT(reporter, (c3 == SkV4{4, 8, 12, 16}));

    REPORTER_ASSERT(reporter, SkM44::Cols(c0, c1, c2, c3) == m);

    // implement matrix * vector using column vectors
    SkV4 v = {1, 2, 3, 4};
    SkV4 v1 = m * v;
    SkV4 v2 = c0 * v.x + c1 * v.y + c2 * v.z + c3 * v.w;
    REPORTER_ASSERT(reporter, v1 == v2);

    REPORTER_ASSERT(reporter, (c0 + r0 == SkV4{c0.x+r0.x, c0.y+r0.y, c0.z+r0.z, c0.w+r0.w}));
    REPORTER_ASSERT(reporter, (c0 - r0 == SkV4{c0.x-r0.x, c0.y-r0.y, c0.z-r0.z, c0.w-r0.w}));
    REPORTER_ASSERT(reporter, (c0 * r0 == SkV4{c0.x*r0.x, c0.y*r0.y, c0.z*r0.z, c0.w*r0.w}));
}

DEF_TEST(M44_rotate, reporter) {
    const SkV3 x = {1, 0, 0},
               y = {0, 1, 0},
               z = {0, 0, 1};

    // We have radians version of setRotateAbout methods, but even with our best approx
    // for PI, sin(SK_ScalarPI) != 0, so to make the comparisons in the unittest clear,
    // I'm using the variants that explicitly take the sin,cos values.

    struct {
        SkScalar sinAngle, cosAngle;
        SkV3 aboutAxis;
        SkV3 expectedX, expectedY, expectedZ;
    } recs[] = {
        { 0, 1,    x,   x, y, z},    // angle = 0
        { 0, 1,    y,   x, y, z},    // angle = 0
        { 0, 1,    z,   x, y, z},    // angle = 0

        { 0,-1,    x,   x,-y,-z},    // angle = 180
        { 0,-1,    y,  -x, y,-z},    // angle = 180
        { 0,-1,    z,  -x,-y, z},    // angle = 180

        // Skia coordinate system is right-handed

        { 1, 0,    x,   x, z,-y},    // angle = 90
        { 1, 0,    y,  -z, y, x},    // angle = 90
        { 1, 0,    z,   y,-x, z},    // angle = 90

        {-1, 0,    x,   x,-z, y},    // angle = -90
        {-1, 0,    y,   z, y,-x},    // angle = -90
        {-1, 0,    z,  -y, x, z},    // angle = -90
    };

    for (const auto& r : recs) {
        SkM44 m(SkM44::kNaN_Constructor);
        m.setRotateUnitSinCos(r.aboutAxis, r.sinAngle, r.cosAngle);

        auto mx = m * x;
        auto my = m * y;
        auto mz = m * z;
        REPORTER_ASSERT(reporter, mx == r.expectedX);
        REPORTER_ASSERT(reporter, my == r.expectedY);
        REPORTER_ASSERT(reporter, mz == r.expectedZ);

        // flipping the axis-of-rotation should flip the results
        mx = m * -x;
        my = m * -y;
        mz = m * -z;
        REPORTER_ASSERT(reporter, mx == -r.expectedX);
        REPORTER_ASSERT(reporter, my == -r.expectedY);
        REPORTER_ASSERT(reporter, mz == -r.expectedZ);
    }
}
