/*
 * Copyright 2020 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/SkM44.h"
#include "include/core/SkMatrix.h"
#include "include/private/base/SkVx.h"

#include "src/core/SkMatrixInvert.h"
#include "src/core/SkMatrixPriv.h"
#include "src/core/SkPathPriv.h"

bool SkM44::operator==(const SkM44& other) const {
    if (this == &other) {
        return true;
    }

    auto a0 = skvx::float4::Load(fMat +  0);
    auto a1 = skvx::float4::Load(fMat +  4);
    auto a2 = skvx::float4::Load(fMat +  8);
    auto a3 = skvx::float4::Load(fMat + 12);

    auto b0 = skvx::float4::Load(other.fMat +  0);
    auto b1 = skvx::float4::Load(other.fMat +  4);
    auto b2 = skvx::float4::Load(other.fMat +  8);
    auto b3 = skvx::float4::Load(other.fMat + 12);

    auto eq = (a0 == b0) & (a1 == b1) & (a2 == b2) & (a3 == b3);
    return (eq[0] & eq[1] & eq[2] & eq[3]) == ~0;
}

static void transpose_arrays(SkScalar dst[], const SkScalar src[]) {
    dst[0]  = src[0]; dst[1]  = src[4]; dst[2]  = src[8];  dst[3]  = src[12];
    dst[4]  = src[1]; dst[5]  = src[5]; dst[6]  = src[9];  dst[7]  = src[13];
    dst[8]  = src[2]; dst[9]  = src[6]; dst[10] = src[10]; dst[11] = src[14];
    dst[12] = src[3]; dst[13] = src[7]; dst[14] = src[11]; dst[15] = src[15];
}

void SkM44::getRowMajor(SkScalar v[]) const {
    transpose_arrays(v, fMat);
}

SkM44& SkM44::setConcat(const SkM44& a, const SkM44& b) {
    auto c0 = skvx::float4::Load(a.fMat +  0);
    auto c1 = skvx::float4::Load(a.fMat +  4);
    auto c2 = skvx::float4::Load(a.fMat +  8);
    auto c3 = skvx::float4::Load(a.fMat + 12);

    auto compute = [&](skvx::float4 r) {
        return c0*r[0] + (c1*r[1] + (c2*r[2] + c3*r[3]));
    };

    auto m0 = compute(skvx::float4::Load(b.fMat +  0));
    auto m1 = compute(skvx::float4::Load(b.fMat +  4));
    auto m2 = compute(skvx::float4::Load(b.fMat +  8));
    auto m3 = compute(skvx::float4::Load(b.fMat + 12));

    m0.store(fMat +  0);
    m1.store(fMat +  4);
    m2.store(fMat +  8);
    m3.store(fMat + 12);
    return *this;
}

SkM44& SkM44::preConcat(const SkMatrix& b) {
    auto c0 = skvx::float4::Load(fMat +  0);
    auto c1 = skvx::float4::Load(fMat +  4);
    auto c3 = skvx::float4::Load(fMat + 12);

    auto compute = [&](float r0, float r1, float r3) {
        return (c0*r0 + (c1*r1 + c3*r3));
    };

    auto m0 = compute(b[0], b[3], b[6]);
    auto m1 = compute(b[1], b[4], b[7]);
    auto m3 = compute(b[2], b[5], b[8]);

    m0.store(fMat +  0);
    m1.store(fMat +  4);
    m3.store(fMat + 12);
    return *this;
}

SkM44& SkM44::preTranslate(SkScalar x, SkScalar y, SkScalar z) {
    auto c0 = skvx::float4::Load(fMat +  0);
    auto c1 = skvx::float4::Load(fMat +  4);
    auto c2 = skvx::float4::Load(fMat +  8);
    auto c3 = skvx::float4::Load(fMat + 12);

    // only need to update the last column
    (c0*x + (c1*y + (c2*z + c3))).store(fMat + 12);
    return *this;
}

SkM44& SkM44::postTranslate(SkScalar x, SkScalar y, SkScalar z) {
    skvx::float4 t = { x, y, z, 0 };
    (t * fMat[ 3] + skvx::float4::Load(fMat +  0)).store(fMat +  0);
    (t * fMat[ 7] + skvx::float4::Load(fMat +  4)).store(fMat +  4);
    (t * fMat[11] + skvx::float4::Load(fMat +  8)).store(fMat +  8);
    (t * fMat[15] + skvx::float4::Load(fMat + 12)).store(fMat + 12);
    return *this;
}

SkM44& SkM44::preScale(SkScalar x, SkScalar y) {
    auto c0 = skvx::float4::Load(fMat +  0);
    auto c1 = skvx::float4::Load(fMat +  4);

    (c0 * x).store(fMat + 0);
    (c1 * y).store(fMat + 4);
    return *this;
}

SkM44& SkM44::preScale(SkScalar x, SkScalar y, SkScalar z) {
    auto c0 = skvx::float4::Load(fMat +  0);
    auto c1 = skvx::float4::Load(fMat +  4);
    auto c2 = skvx::float4::Load(fMat +  8);

    (c0 * x).store(fMat + 0);
    (c1 * y).store(fMat + 4);
    (c2 * z).store(fMat + 8);
    return *this;
}

SkV4 SkM44::map(float x, float y, float z, float w) const {
    auto c0 = skvx::float4::Load(fMat +  0);
    auto c1 = skvx::float4::Load(fMat +  4);
    auto c2 = skvx::float4::Load(fMat +  8);
    auto c3 = skvx::float4::Load(fMat + 12);

    SkV4 v;
    (c0*x + (c1*y + (c2*z + c3*w))).store(&v.x);
    return v;
}

static SkRect map_rect_affine(const SkRect& src, const float mat[16]) {
    // When multiplied against vectors of the form <x,y,x,y>, 'flip' allows a single min()
    // to compute both the min and "negated" max between the xy coordinates. Once finished, another
    // multiplication produces the original max.
    const skvx::float4 flip{1.f, 1.f, -1.f, -1.f};

    // Since z = 0 and it's assumed ther's no perspective, only load the upper 2x2 and (tx,ty) in c3
    auto c0 = skvx::shuffle<0,1,0,1>(skvx::float2::Load(mat + 0)) * flip;
    auto c1 = skvx::shuffle<0,1,0,1>(skvx::float2::Load(mat + 4)) * flip;
    auto c3 = skvx::shuffle<0,1,0,1>(skvx::float2::Load(mat + 12));

    // Compute the min and max of the four transformed corners pre-translation; then translate once
    // at the end.
    auto minMax = c3 + flip * min(min(c0 * src.fLeft  + c1 * src.fTop,
                                      c0 * src.fRight + c1 * src.fTop),
                                  min(c0 * src.fLeft  + c1 * src.fBottom,
                                      c0 * src.fRight + c1 * src.fBottom));

    // minMax holds (min x, min y, max x, max y) so can be copied into an SkRect expecting l,t,r,b
    SkRect r;
    minMax.store(&r);
    return r;
}

static SkRect map_rect_perspective(const SkRect& src, const float mat[16]) {
    // Like map_rect_affine, z = 0 so we can skip the 3rd column, but we do need to compute w's
    // for each corner of the src rect.
    auto c0 = skvx::float4::Load(mat + 0);
    auto c1 = skvx::float4::Load(mat + 4);
    auto c3 = skvx::float4::Load(mat + 12);

    // Unlike map_rect_affine, we do not defer the 4th column since we may need to homogeneous
    // coordinates to clip against the w=0 plane
    auto tl = c0 * src.fLeft  + c1 * src.fTop    + c3;
    auto tr = c0 * src.fRight + c1 * src.fTop    + c3;
    auto bl = c0 * src.fLeft  + c1 * src.fBottom + c3;
    auto br = c0 * src.fRight + c1 * src.fBottom + c3;

    // After clipping to w>0 and projecting to 2d, 'project' employs the same negation trick to
    // compute min and max at the same time.
    const skvx::float4 flip{1.f, 1.f, -1.f, -1.f};
    auto project = [&flip](const skvx::float4& p0, const skvx::float4& p1, const skvx::float4& p2) {
        float w0 = p0[3];
        if (w0 >= SkPathPriv::kW0PlaneDistance) {
            // Unclipped, just divide by w
            return flip * skvx::shuffle<0,1,0,1>(p0) / w0;
        } else {
            auto clip = [&](const skvx::float4& p) {
                float w = p[3];
                if (w >= SkPathPriv::kW0PlaneDistance) {
                    float t = (SkPathPriv::kW0PlaneDistance - w0) / (w - w0);
                    auto c = (t * skvx::shuffle<0,1>(p) + (1.f - t) * skvx::shuffle<0,1>(p0)) /
                                  SkPathPriv::kW0PlaneDistance;

                    return flip * skvx::shuffle<0,1,0,1>(c);
                } else {
                    return skvx::float4(SK_ScalarInfinity);
                }
            };
            // Clip both edges leaving p0, and return the min/max of the two clipped points
            // (since clip returns infinity when both p0 and 2nd vertex have w<0, it'll
            // automatically be ignored).
            return min(clip(p1), clip(p2));
        }
    };

    // Project all 4 corners, and pass in their adjacent vertices for clipping if it has w < 0,
    // then accumulate the min and max xy's.
    auto minMax = flip * min(min(project(tl, tr, bl), project(tr, br, tl)),
                             min(project(br, bl, tr), project(bl, tl, br)));

    SkRect r;
    minMax.store(&r);
    return r;
}

SkRect SkMatrixPriv::MapRect(const SkM44& m, const SkRect& src) {
    const bool hasPerspective =
            m.fMat[3] != 0 || m.fMat[7] != 0 || m.fMat[11] != 0 || m.fMat[15] != 1;
    if (hasPerspective) {
        return map_rect_perspective(src, m.fMat);
    } else {
        return map_rect_affine(src, m.fMat);
    }
}

void SkM44::normalizePerspective() {
    // If the bottom row of the matrix is [0, 0, 0, not_one], we will treat the matrix as if it
    // is in perspective, even though it stills behaves like its affine. If we divide everything
    // by the not_one value, then it will behave the same, but will be treated as affine,
    // and therefore faster (e.g. clients can forward-difference calculations).
    if (fMat[15] != 1 && fMat[15] != 0 && fMat[3] == 0 && fMat[7] == 0 && fMat[11] == 0) {
        double inv = 1.0 / fMat[15];
        (skvx::float4::Load(fMat +  0) * inv).store(fMat +  0);
        (skvx::float4::Load(fMat +  4) * inv).store(fMat +  4);
        (skvx::float4::Load(fMat +  8) * inv).store(fMat +  8);
        (skvx::float4::Load(fMat + 12) * inv).store(fMat + 12);
        fMat[15] = 1.0f;
    }
}

///////////////////////////////////////////////////////////////////////////////

/** We always perform the calculation in doubles, to avoid prematurely losing
    precision along the way. This relies on the compiler automatically
    promoting our SkScalar values to double (if needed).
 */
bool SkM44::invert(SkM44* inverse) const {
    SkScalar tmp[16];
    if (SkInvert4x4Matrix(fMat, tmp) == 0.0f) {
        return false;
    }
    memcpy(inverse->fMat, tmp, sizeof(tmp));
    return true;
}

SkM44 SkM44::transpose() const {
    SkM44 trans(SkM44::kUninitialized_Constructor);
    transpose_arrays(trans.fMat, fMat);
    return trans;
}

SkM44& SkM44::setRotateUnitSinCos(SkV3 axis, SkScalar sinAngle, SkScalar cosAngle) {
    // Taken from "Essential Mathematics for Games and Interactive Applications"
    //             James M. Van Verth and Lars M. Bishop -- third edition
    SkScalar x = axis.x;
    SkScalar y = axis.y;
    SkScalar z = axis.z;
    SkScalar c = cosAngle;
    SkScalar s = sinAngle;
    SkScalar t = 1 - c;

    *this = { t*x*x + c,   t*x*y - s*z, t*x*z + s*y, 0,
              t*x*y + s*z, t*y*y + c,   t*y*z - s*x, 0,
              t*x*z - s*y, t*y*z + s*x, t*z*z + c,   0,
              0,           0,           0,           1 };
    return *this;
}

SkM44& SkM44::setRotate(SkV3 axis, SkScalar radians) {
    SkScalar len = axis.length();
    if (len > 0 && SkScalarIsFinite(len)) {
        this->setRotateUnit(axis * (SK_Scalar1 / len), radians);
    } else {
        this->setIdentity();
    }
    return *this;
}

///////////////////////////////////////////////////////////////////////////////

void SkM44::dump() const {
    SkDebugf("|%g %g %g %g|\n"
             "|%g %g %g %g|\n"
             "|%g %g %g %g|\n"
             "|%g %g %g %g|\n",
             fMat[0], fMat[4], fMat[8],  fMat[12],
             fMat[1], fMat[5], fMat[9],  fMat[13],
             fMat[2], fMat[6], fMat[10], fMat[14],
             fMat[3], fMat[7], fMat[11], fMat[15]);
}

///////////////////////////////////////////////////////////////////////////////

SkM44 SkM44::RectToRect(const SkRect& src, const SkRect& dst) {
        if (src.isEmpty()) {
        return SkM44();
    } else if (dst.isEmpty()) {
        return SkM44::Scale(0.f, 0.f, 0.f);
    }

    float sx = dst.width()  / src.width();
    float sy = dst.height() / src.height();

    float tx = dst.fLeft - sx * src.fLeft;
    float ty = dst.fTop  - sy * src.fTop;

    return SkM44{sx,  0.f, 0.f, tx,
                 0.f, sy,  0.f, ty,
                 0.f, 0.f, 1.f, 0.f,
                 0.f, 0.f, 0.f, 1.f};
}

static SkV3 normalize(SkV3 v) {
    const auto vlen = v.length();

    return SkScalarNearlyZero(vlen) ? v : v * (1.0f / vlen);
}

static SkV4 v4(SkV3 v, SkScalar w) { return {v.x, v.y, v.z, w}; }

SkM44 SkM44::LookAt(const SkV3& eye, const SkV3& center, const SkV3& up) {
    SkV3 f = normalize(center - eye);
    SkV3 u = normalize(up);
    SkV3 s = normalize(f.cross(u));

    SkM44 m(SkM44::kUninitialized_Constructor);
    if (!SkM44::Cols(v4(s, 0), v4(s.cross(f), 0), v4(-f, 0), v4(eye, 1)).invert(&m)) {
        m.setIdentity();
    }
    return m;
}

SkM44 SkM44::Perspective(float near, float far, float angle) {
    SkASSERT(far > near);

    float denomInv = sk_ieee_float_divide(1, far - near);
    float halfAngle = angle * 0.5f;
    SkASSERT(halfAngle != 0);
    float cot = sk_ieee_float_divide(1, sk_float_tan(halfAngle));

    SkM44 m;
    m.setRC(0, 0, cot);
    m.setRC(1, 1, cot);
    m.setRC(2, 2, (far + near) * denomInv);
    m.setRC(2, 3, 2 * far * near * denomInv);
    m.setRC(3, 2, -1);
    return m;
}
