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



#ifndef SkMatrix44_DEFINED
#define SkMatrix44_DEFINED

#include "SkMatrix.h"
#include "SkScalar.h"

#ifdef SK_MSCALAR_IS_DOUBLE
    typedef double SkMScalar;
    static inline double SkFloatToMScalar(float x) {
        return static_cast<double>(x);
    }
    static inline float SkMScalarToFloat(double x) {
        return static_cast<float>(x);
    }
    static inline double SkDoubleToMScalar(double x) {
        return x;
    }
    static inline double SkMScalarToDouble(double x) {
        return x;
    }
    static const SkMScalar SK_MScalarPI = 3.141592653589793;
#else
    typedef float SkMScalar;
    static inline float SkFloatToMScalar(float x) {
        return x;
    }
    static inline float SkMScalarToFloat(float x) {
        return x;
    }
    static inline float SkDoubleToMScalar(double x) {
        return static_cast<float>(x);
    }
    static inline double SkMScalarToDouble(float x) {
        return static_cast<double>(x);
    }
    static const SkMScalar SK_MScalarPI = 3.14159265f;
#endif

#ifdef SK_SCALAR_IS_FLOAT
    #define SkMScalarToScalar SkMScalarToFloat
    #define SkScalarToMScalar SkFloatToMScalar
#else
    #if SK_MSCALAR_IS_DOUBLE
        // we don't have fixed <-> double macros, use double<->scalar macros
        #define SkMScalarToScalar SkDoubleToScalar
        #define SkScalarToMScalar SkScalarToDouble
    #else
        #define SkMScalarToScalar SkFloatToFixed
        #define SkScalarToMScalar SkFixedToFloat
    #endif
#endif

static const SkMScalar SK_MScalar1 = 1;

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

struct SkVector4 {
    SkScalar fData[4];

    SkVector4() {
        this->set(0, 0, 0, 1);
    }
    SkVector4(const SkVector4& src) {
        memcpy(fData, src.fData, sizeof(fData));
    }
    SkVector4(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
        fData[0] = x;
        fData[1] = y;
        fData[2] = z;
        fData[3] = w;
    }

    SkVector4& operator=(const SkVector4& src) {
        memcpy(fData, src.fData, sizeof(fData));
        return *this;
    }

    bool operator==(const SkVector4& v) {
        return fData[0] == v.fData[0] && fData[1] == v.fData[1] &&
               fData[2] == v.fData[2] && fData[3] == v.fData[3];
    }
    bool operator!=(const SkVector4& v) {
        return !(*this == v);
    }
    bool equals(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
        return fData[0] == x && fData[1] == y &&
               fData[2] == z && fData[3] == w;
    }

    void set(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
        fData[0] = x;
        fData[1] = y;
        fData[2] = z;
        fData[3] = w;
    }
};

class SK_API SkMatrix44 {
public:
    SkMatrix44();
    SkMatrix44(const SkMatrix44&);
    SkMatrix44(const SkMatrix44& a, const SkMatrix44& b);

    SkMatrix44& operator=(const SkMatrix44& src) {
        memcpy(this, &src, sizeof(*this));
        return *this;
    }

    bool operator==(const SkMatrix44& other) const {
        return !memcmp(this, &other, sizeof(*this));
    }
    bool operator!=(const SkMatrix44& other) const {
        return !!memcmp(this, &other, sizeof(*this));
    }

    SkMatrix44(const SkMatrix&);
    SkMatrix44& operator=(const SkMatrix& src);
    operator SkMatrix() const;

    SkMScalar get(int row, int col) const;
    void set(int row, int col, const SkMScalar& value);

    void asColMajorf(float[]) const;
    void asColMajord(double[]) const;
    void asRowMajorf(float[]) const;
    void asRowMajord(double[]) const;

    bool isIdentity() const;
    void setIdentity();
    void reset() { this->setIdentity();}

    void set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02,
                SkMScalar m10, SkMScalar m11, SkMScalar m12,
                SkMScalar m20, SkMScalar m21, SkMScalar m22);

    void setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
    void preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
    void postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);

    void setScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
    void preScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
    void postScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);

    void setScale(SkMScalar scale) {
        this->setScale(scale, scale, scale);
    }
    void preScale(SkMScalar scale) {
        this->preScale(scale, scale, scale);
    }
    void postScale(SkMScalar scale) {
        this->postScale(scale, scale, scale);
    }

    void setRotateDegreesAbout(SkMScalar x, SkMScalar y, SkMScalar z,
                               SkMScalar degrees) {
        this->setRotateAbout(x, y, z, degrees * SK_MScalarPI / 180);
    }

    /** Rotate about the vector [x,y,z]. If that vector is not unit-length,
        it will be automatically resized.
     */
    void setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z,
                        SkMScalar radians);
    /** Rotate about the vector [x,y,z]. Does not check the length of the
        vector, assuming it is unit-length.
     */
    void setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z,
                            SkMScalar radians);

    void setConcat(const SkMatrix44& a, const SkMatrix44& b);
    void preConcat(const SkMatrix44& m) {
        this->setConcat(*this, m);
    }
    void postConcat(const SkMatrix44& m) {
        this->setConcat(m, *this);
    }

    friend SkMatrix44 operator*(const SkMatrix44& a, const SkMatrix44& b) {
        return SkMatrix44(a, b);
    }

    /** If this is invertible, return that in inverse and return true. If it is
        not invertible, return false and ignore the inverse parameter.
     */
    bool invert(SkMatrix44* inverse) const;

    /** Apply the matrix to the src vector, returning the new vector in dst.
        It is legal for src and dst to point to the same memory.
     */
    void map(const SkScalar src[4], SkScalar dst[4]) const;
    void map(SkScalar vec[4]) const {
        this->map(vec, vec);
    }

    friend SkVector4 operator*(const SkMatrix44& m, const SkVector4& src) {
        SkVector4 dst;
        m.map(src.fData, dst.fData);
        return dst;
    }

    void dump() const;

private:
    /*  Stored in the same order as opengl:
         [3][0] = tx
         [3][1] = ty
         [3][2] = tz
     */
    SkMScalar fMat[4][4];

    double determinant() const;
};

#endif
