// ===================================================================
//
// ModelObject.h
// Contains model data
//
// Initial coding by Martin Ruzicka

#ifndef MODEL_OBJECT_H
#define MODEL_OBJECT_H

#include "./math/Mathematics.h"
#include "./openGlSupport/VBOmanager.h"
#include "./openGlSupport/OpenGLwrapper.h"
#include "./material/Material.h" 
#include "./math/Matrix.h"
#include "./illumination/Light.h"
#include "./phong/Phong.h"

using namespace ANALYTICAL_GEOMETRY;
using namespace MATRIX;

typedef GLuint GL_ID;

/// Simple geometric object.
/**
*	Mesh = simple geometric object ( all polygons in 1 mesh group have to use same texture and material )
*   Mesh object does not contain geometry, it has only ptr to geometry 
*	so that models could share the same geometry 
*/
struct MeshObject
{
	VBOids vbo_data;		/**< mesh VBOs */
	Material* material;		/**< mesh materials */
	vector<GL_ID> textures;	/**< mesh textures */
};


/// Class used for polygonal models manipulation.
/**
*	Class used for polygonal models manipulation.
*	Consist of group of Meshes, which constitue together one compact model.
*	Methods for TRS ( translate, rotate, scale ) transformations are also provided.
*/
class Model
{
private:
	Matrix4X4<float> modelMatrix;
	vector<MeshObject> meshes;

public:
	

	Model(  const vector<MeshObject>& meshes);
	//Model(void) {};

	
	void identity(void);

	void setPosition( float posX, float posY, float posZ );

	float& positionX(void);
	float& positionY(void);
	float& positionZ(void);

	void translate( float translateX, float translateY, float translateZ);
	void rotate( float angleX, float angleY, float angleZ);
	void scale( float scaleX, float scaleY, float scaleZ);
	void scale( float scaleXYZ );

	/**< Current model matrix is is multiplied from LEFT by transformMatrix. */
	void transformGlobal( const Matrix4X4<float> &transformMatrix );

	/**< OpenGL like transform ( similar to glMatrixMul() ) */
	void transformLocal( const Matrix4X4<float> &transformMatrix );	

	void setModelMatrix( const Matrix4X4<float>& matrix) ;
	void getModelMatrix(Matrix4X4<float>& matrix) const;

	Matrix4X4<float>& getModelMatrixRef(void);
	vector<MeshObject>& getMeshes(void); 
};


namespace RENDER
{
	void renderModel( Model& model, bool useMaterialColor);
	void renderModelNoModelTransform( Model& model);
	void applyMeshColor( const MeshObject& mesh);
}


#endif