#ifndef AFFINETRANSFORMATIONMATRIX_H
#define AFFINETRANSFORMATIONMATRIX_H

#include "../util/mathUtils.h"
#include "../util/FixedInt.h"
#include <vector>
using namespace std;

//It's an Affine Transformation Matrix! Easy and convenient to combine multiple transformations, and specify the order of transformations

class AffineTransformationMatrix{
 public:
  AffineTransformationMatrix();
  ~AffineTransformationMatrix();

  //sets back to the identity matrix
  void clear();
  vector <FixedInt> & getData();

  //multiply other matrix into this matrix
  //lhs * this
  void multiplyMatrix(AffineTransformationMatrix & lhs);
  void multiplyMatrix(vector<FixedInt> & lhs);

  //multiply this matrix into (x, y, 1) to get the new coordinates after applying the matrix.
  //this * (x,y,1)
  void apply(int & x, int & y);
  void apply(FixedInt & x, FixedInt & y);

  //apply effects
  void scale (FixedInt width, FixedInt height);
  void rotate (FixedInt angle);
  void shift (FixedInt x, FixedInt y);
  void shear (FixedInt horiz, FixedInt vert);

  void orthographicProjection(FixedInt ux, FixedInt uy);

  //get scale and angle and shift
  FixedInt getScaleX();
  FixedInt getScaleY();
  FixedInt getShiftX();
  FixedInt getShiftY();
  FixedInt getAngle();

 private:
  vector <FixedInt> data;

  FixedInt scaleX, scaleY;
  FixedInt ang;
  FixedInt shiftX, shiftY;
};

#endif
