#ifndef Matrix_hpp
#define Matrix_hpp

#include "Vector.hpp"

class Matrix {
public:
  union {
    struct {
      double _11, _21, _31, _41;
      double _12, _22, _32, _42;
      double _13, _23, _33, _43;
      double _14, _24, _34, _44;
    } _4x4;
    struct {
      Vector side; double _41;
      Vector up; double _42;
      Vector direction; double _43;
      Vector position; double _44;
    } _vector;
    double _16[16];
  };
  Matrix();
  Matrix& setIdentity();
  Matrix& setXRotation(const double rad);
  Matrix& setYRotation(const double rad);
  Matrix& setZRotation(const double rad);
  Matrix& normalize();
  Matrix& setTranslate(
    const double x = 0.0,
    const double y = 0.0,
    const double z = 0.0
  );
  Matrix& setTranslate(const Vector& v);
  Matrix& setScale(
    const double x = 1.0,
    const double y = 1.0,
    const double z = 1.0
  );
  Matrix& setScale(const Vector& v);
  const Matrix& operator * (const Matrix& m);
  Matrix& operator *= (const Matrix& m);
};

#endif
