#ifndef MATRIX_HELPER_H
#define MATRIX_HELPER_H

//#include <math.h>
//#include <windows.h>
//#include "GL/glut.h"
//#include <vector>
//#include <Inventor/SbLinear.h>


//class Vector3D; 

#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif

/** Matrix datatype. */
typedef float Matrix4x4[16]; 
typedef float Matrix3x3[9]; 


//#include "Vector2D.h"

//using namespace geometry; 

//class Vector3D<XNumber>; 

/**
 * Calculates 1 / tan in rad. 
 * @param a The angle. 
 * @return The coTan of the incoming angle. 
 */
float CoTan(float a); 

/**
 * Sets the identity matrix. 
 * @param m [out] The matrix to be set. 
 */
void SetIdentityMatrix(Matrix4x4 &m); 

/**
 * Sets a zero matrix. 
 * @param m [out] the matrix to be set. 
 */
void SetZeroMatrix(Matrix4x4 &m);

void SetZeroMatrix(Matrix3x3 &m); 

/**
 * Copies a matrix to another. 
 * @param m1 [out] The matrix to be set. 
 * @param m2 The matrix to be copied. 
 */
void SetMatrix(Matrix4x4 &m1, Matrix4x4 m2); 

void SetMatrix(Matrix3x3 &m1, Matrix3x3 m2); 

void SetMatrixEntry(Matrix4x4 &m, float entry, int index); 
void SetMatrixEntry(Matrix4x4 &m, float entry, int row, int col); 

float GetMatrixEntry(Matrix4x4 m, int row, int col); 

/**
 * Sets an OpenGL like rotation matrix. 
 * @param m [out] The matrix generated. 
 * @param angle The angle to be rotated. 
 * @param x The x-part of the rotation. 
 * @param y The y-part of the rotation. 
 * @param z The z-part of the rotation. 
 */
void SetRotationMatrix(Matrix4x4 &m, float angle, float x, float y, float z); 

/**
 * Sets an OpenGL like translation matrix. 
 * @param m [out] The matrix generated. 
 * @param transX Translation on x-axis. 
 * @param transY Translation on y-axis. 
 * @param transZ Translation on z-axis. 
 */
void SetTranslationMatrix(Matrix4x4 &m, float transX, float transY, float transZ); 

/**
 * Sets an OpenGL like non-uniform scale matrix. 
 * @param m [out] The matrix generated. 
 * @param scaleX Scale on x-axis. 
 * @param scaleY Scale on y-axis. 
 * @param scaleZ Scale on z-axis. 
 */
void SetScaleMatrix(Matrix4x4 &m, float scaleX, float scaleY, float scaleZ); 

/**
 * Sets an OpenGL like lookat matrix. 
 * @param output [out] The matrix generated. 
 * @param pos The camera position. 
 * @param at The position looking at. 
 * @param up The up-vector of the camera. 
 */
//void SetLookAtMatrix(Matrix4x4 &output, geometry::Vector3D<float> pos, 
//					 geometry::Vector3D<float> at, geometry::Vector3D<float> up); 
void SetLookAtMatrix(Matrix4x4 &output, float posX, float posY, float posZ, 
					 float atX, float atY, float atZ, float upX, float upY, float upZ); 

/**
 * Sets an OpenGL like perspective matrix. 
 * @param output [out] The matrix generated. 
 * @param fovy The viewing angle. 
 * @param aspect The aspect of the window. 
 * @param nearDist The near plane. 
 * @param farDist The far plane. 
 */
void SetPerspectiveMatrix(Matrix4x4 &output, float fovy, float aspect, float nearDist, float farDist); 

/**
 * Multiplies two matrizes. 
 * @param m1 [in/out] The matrix to be multiplied on first place and to be returned. 
 * @param m2 The matrix to be multiplied on second place. 
 */
void MultMatrix(Matrix4x4 &m1, Matrix4x4 m2); 

/**
 * Prints a matrix. 
 * @param m The matrix to be printed. 
 */
void PrintMatrix(Matrix4x4 m); 

/**
 * Converts a Matrix to a float array. 
 * @param m The matrix to be converted. 
 * @return The matrix as float-array. 
 */
float* ConvertMatrixToArray(Matrix4x4 m);

void GetInverseMatrix(Matrix4x4 &copyMatrix, Matrix4x4 m); 

void GetInverseMatrix(Matrix3x3 &copyMatrix, Matrix4x4 m); 

void GetTransposeMatrix(Matrix4x4 &copyMatrix, Matrix4x4 m); 

//void SetHomographyMatrix(Matrix4x4 &output, float** sourcePoints, float** targetPoints); 
void SetHomographyMatrix(Matrix4x4 &output, float sourcePoints[4][3], float targetPoints[4][3]); 

void SetUnitSquareHomographyMatrix(Matrix3x3 &output, float x1, float x2, float x3, float x4, 
								   float y1, float y2, float y3, float y4); 

void ConcatHomographyMatrizes(Matrix4x4 &output, Matrix3x3 sourceMatrix, Matrix3x3 targetMatrix); 

//float GetDeterminant(Matrix4x4 m);




#endif
