#pragma once
#include "utils/Vector2.h"

class Matrix2
{
public:
   float v[2][2];

   Matrix2(void){}
   Matrix2(float a, float b, float c, float d)
   {
      v[0][0]=a; v[0][1]=b; v[1][0]=c; v[1][1]=d;
   }
   ~Matrix2(void){}

   const static Matrix2 ZERO;

   const static Matrix2 IDENTITY;

   void operator+=(const Matrix2& m)
   {
      v[0][0]+=m.v[0][0]; v[0][1]+=m.v[0][1]; v[1][0]+=m.v[1][0]; v[1][1]+=m.v[1][1];
   }
   void operator-=(const Matrix2& m)
   {
      v[0][0]-=m.v[0][0]; v[0][1]-=m.v[0][1]; v[1][0]-=m.v[1][0]; v[1][1]-=m.v[1][1];
   }

   Matrix2 operator+(const Matrix2& m) const
   {
      return Matrix2(v[0][0]+m.v[0][0], v[0][1]+m.v[0][1], v[1][0]+m.v[1][0], v[1][1]+m.v[1][1]);
   }
   Matrix2 operator-(const Matrix2& m) const
   {
      return Matrix2(v[0][0]-m.v[0][0], v[0][1]-m.v[0][1], v[1][0]-m.v[1][0], v[1][1]-m.v[1][1]);
   }

   friend Matrix2 operator*(float k, const Matrix2& m)
   {
      return Matrix2(k*m.v[0][0], k*m.v[0][1], k*m.v[1][0], k*m.v[1][1]);
   }

   Matrix2 operator*(const Matrix2& m) const
   {
      return Matrix2(v[0][0]*m.v[0][0]+v[0][1]*m.v[1][0],
         v[0][0]*m.v[0][1]+v[0][1]*m.v[1][1],
         v[1][0]*m.v[0][0]+v[1][1]*m.v[1][0],
         v[1][0]*m.v[0][1]+v[1][1]*m.v[1][1]);
   }
   Vector2 operator*(const Vector2& m) const
   {
      return Vector2(v[0][0]*m.x+v[0][1]*m.y,
         v[1][0]*m.x+v[1][1]*m.y);
   }
   friend Matrix2 operator*(const Vector2& v1, const Vector2& v2);
};

inline Matrix2 operator*(const Vector2& v1, const Vector2& v2)
{
   return Matrix2(v1.x*v2.x, v1.x*v2.y, v1.y*v2.x, v1.y*v2.y);
}