#ifndef MATRIX_H
#define MATRIX_H

#include "math/Quaternion.h"
#include "utils/StringBuffer.h"

class Matrix final {
    Vector4 data[4];

    Matrix& rotate(float degrees, int a, int b);

public:
    Matrix();

    Matrix& unit();

    Matrix& set(int index, const Vector4& v);

    Matrix transpose();

    const float* getValues() const;

    Matrix& operator*=(const Matrix& other);
    Matrix operator*(const Matrix& other) const;
    Vector3 operator*(const Vector3& v) const;

    Matrix& scale(const Vector3& v);
    Matrix& scale(float f);

    Matrix& translate(const Vector3& v);
    Matrix& translateX(float tx);
    Matrix& translateY(float ty);
    Matrix& translateZ(float tz);
    Matrix& translateTo(const Vector3& v);

    Matrix& rotateX(float degrees);
    Matrix& rotateY(float degrees);
    Matrix& rotateZ(float degrees);
    Matrix& rotate(const Quaternion& q);

    template<int L>
    void toString(StringBuffer<L>& s) const {
        s.append('[').append(data[0]).append(", ");
        s.append(data[1]).append(", ");
        s.append(data[2]).append(", ");
        s.append(data[3]).append("]");
    }
};

#endif