#pragma once
namespace M3D
{
class CameraParams;
/**
 * Класс для хранения матриц и проведения над ними операций, аналогичных операциям OpenGL
 * Матрица хранится постолбцово
 * На лету производится создание матрицы нормалей
 * Все операции применяются непосредственно в момент из вызова
 */
class GLMatrix4x4
{
	public:
		GLMatrix4x4();
		/**
		 * Вращение относительно вектора [x;y;z] на угол angle
		 * @param angle угол на который требуется повернуть матрицу
		 * @param x компонента x вектора относительно которого производится поворот
		 * @param y компонента y вектора относительно которого производится поворот
		 * @param z компонента z вектора относительно которого производится поворот
		 */
		void rotate( float angle, float x, float y, float z );
		/**
		 * Создание матрицы перемещения. Текущая матрица домножается на матрицу перемещения
		 * @param x величина перемещения по оси x
		 * @param y величина перемещения по оси y
		 * @param z величина перемещения по оси z
		 */
		void translate( float x, float y, float z );
		/**
		 * Создание матрицы масштабирования. Текущая матрица домножается на матрицу масштабирования
		 * @param x коэффициент масштабирования по оси x
		 * @param y коэффициент масштабирования по оси y
		 * @param z коэффициент масштабирования по оси z
		 */
		void scale( float x, float y, float z );
		/**
		 * Создание матрицы проэкции. Текущая матрица домножается на проэкционную матрицу
		 * @param cam_params параметры камеры
		 */
		void projection( const CameraParams &params );
		/**
		 * Получение матрицы в виде массива с постолбцовым хранением
		 * @return указатель на матрицу
		 */
		const float* get_matrix4x4() const { return _matrix4x4_;}
		/**
		 * Получение матрицы поворота в виде массива с постолбцовым хранением
		 * @return указатель на матрицу
		 */
		const float* get_matrix3x3_rotate() const { return _matrix_3x3_rotate_;}
		/**
		 * Заполнение текущей матрицы нулями
		 */
		void zero();
		/**
		 * Создание единичной матрицы
		 */
		void identity();

		void print();

	private:
		/**
		 * Домножение текущей матрицы на матрицу. Домножение производится слева M=L*M
		 * @param matrix матрица - множитель
		 */
		void operator*=( const GLMatrix4x4 &matrix );
		void mult3x3_4x4( const GLMatrix4x4 &matrix );
		float _matrix4x4_[ 16 ];
		float _matrix_3x3_rotate_[ 16 ];
};
}
