/** \file Matrix.h
 * \brief The header file for the 'Matrix' class.
 */

#pragma once

namespace OSkA
{
	/** \brief A simple Matrix class.
	 *
	 * The Matrix class represents a mathematic matrix and provides
	 * different methods required by the library.
	 */
	class Matrix
	{
	public:
		/** \brief Default Constructor
		 */
		Matrix();
		/** \brief Constructor
		 *
		 * \param matrix	The Matrix this Matrix will initialized with
		 */
		Matrix(const Matrix &matrix);
		/** \brief Constructor
		 *
		 * \param values	The values this Matrix will initialized with
		 */
		Matrix(float values[16]);
		/** \brief Constructor
		 *
		 * \param a11	Matrix value.
		 * \param a12	Matrix value.
		 * \param a13	Matrix value.
		 * \param a14	Matrix value.
		 * \param a21	Matrix value.
		 * \param a22	Matrix value.
		 * \param a23	Matrix value.
		 * \param a24	Matrix value.
		 * \param a31	Matrix value.
		 * \param a32	Matrix value.
		 * \param a33	Matrix value.
		 * \param a34	Matrix value.
		 * \param a41	Matrix value.
		 * \param a42	Matrix value.
		 * \param a43	Matrix value.
		 * \param a44	Matrix value.
		 */
		Matrix(float a11, float a12, float a13, float a14, 
				float a21, float a22, float a23, float a24, 
				float a31, float a32, float a33, float a34, 
				float a41, float a42, float a43, float a44);
		/** \brief Destructor
		 */
		~Matrix();

		/** \brief Sets the Matrix to an identity Matrix
		 */
		void SetIdentity();
		/** \brief Sets the translate values
		 *
		 * \param x	translate in x direction
		 * \param y	translate in y direction
		 * \param z	translate in z direction
		 */
		void SetTranslate(float x, float y, float z);
		/** \brief Sets a rotation Matrix with X axis
		 *
		 * \param angle	rotation angle
		 */
		void SetRotateX(float angle);
		/** \brief Sets a rotation Matrix with Y axis
		 *
		 * \param angle	rotation angle
		 */
		void SetRotateY(float angle);
		/** \brief Sets a rotation Matrix with Z axis
		 *
		 * \param angle	rotation angle
		 */
		void SetRotateZ(float angle);
		/** \brief Sets the scale values of the matrix.
		 *
		 * \param x	scale in x direction
		 * \param y	scale in y direction
		 * \param z	scale in z direction
		 */
		void SetScale(float x, float y, float z);

		/** \brief Sets a special transformation Matrix
		 *
		 * \param pos		3 size float array, containing translation values
		 * \param rotAngle	the rotation angle
		 * \param rotAxis	3 size float array, containing the rotation axis
		 * \param scale		3 size float array, containing scale values
		 */
		void SetTransform(float* pos, float rotAngle, float* rotAxis, float* scale);

		void Transpose();

		float GetDeterminant();
		void Invert();
		Matrix* GetInverted();

		/** \brief=operator
		 */
		Matrix& operator=(const Matrix &matrix);
		/** \brief Operator for Matrix/Matrix multiplcation
		 */
		Matrix operator *(const Matrix &matrix)const;
		/** \brief Operator for Matrix/Matrix multiplcation
		 */
		Matrix& operator *=(const Matrix &matrix);
		/** \brief Operator for Matrix/float multiplcation
		 */
		Matrix operator *(const float &factor)const;
		/** \brief Operator for Matrix/float multiplcation
		 */
		Matrix& operator *=(const float &factor);
		/** \brief Operator for Matrix/Matrix addition
		 */
		Matrix operator +(const Matrix &matrix)const;
		/** \brief Operator for Matrix/Matrix addition
		 */
		Matrix& operator +=(const Matrix &matrix);

		/** \brief The matrix data, stored in column order.
		 */
		float mCell[16];
	};
}