/*
 * ExNihilo 3D Engine
 * 
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * Please read AUTHORS file !!!
 * 
 * $Id: ExCModelMD2.cpp,v 1.11 2002/12/13 11:45:03 data Exp $
 *
 */

#include "ExCModelMD2.h"
//---------------------------------------------------------------
ExCModelMD2::ExCModelMD2(void)
{
Guard(ExCModelMD2::ExCModelMD2(void))
	ExCModel::ExCModel();
	SetName("ExCModelMD2");
	SetType(typeid(this).name());
	m_CurrentFrames=2;
	m_NextFrame=3;
	m_InterpolationPourcentage=0.1f;
	m_Interpolation=m_InterpolationPourcentage;
	m_Transition=false;
	StartAction("IDLE");
	m_speed=10;
	count=0;
	m_SphereRadius=9;
	m_ShowCollisionSphere=false;
	//m_Gravity.SetValue(0.0f,-9.81f,0.0f);
	m_Velocity.SetValue(0.0f,0.0f,0.0f);
	m_CollisionGizmo= new ExCGizmoSphere;
	m_CollisionGizmo->SetVisibleState(false);
	m_CollisionCounter=0;
UnGuard
}
/*
ExCModelMD2::ExCModelMD2(const ExCModelMD2& copy)
{
Guard(ExCModelMD2::ExCModelMD2(const ExCModelMD2& copy))
	m_CurrentFrames=copy.m_CurrentFrames;
	m_NextFrame=copy.m_NextFrame;
	m_InterpolationPourcentage=copy.m_InterpolationPourcentage;
	m_Interpolation=copy.m_Interpolation;
	m_Transition=copy.m_Transition;
	m_speed=copy.m_speed;

	m_VecSkin=copy.m_VecSkin;
	m_VecTexture=copy.m_VecTexture;
	m_VecTriangle=copy.m_VecTriangle;
	m_VecVertex=copy.m_VecVertex;
UnGuard
}*/

ExCModelMD2::~ExCModelMD2(void)
{
Guard(ExCModelMD2::~ExCModelMD2(void))
UnGuard
}

ExCAction ExCModelMD2::InputAction(ExCAction Action)
{
	//std::cout<<"MODEL"<<Action;
	switch(Action.m_Action) 
	{
	case NEXT_FRAME:
			NextFrame();
			break;
		case PREVIOUS_FRAME:
			break;
		case SET_CURENT_FRAME:
			break;
		case START_ACTION:
			StartAction(Action.m_Param);
			break;
		case STOP_ACTION:
			StopAction(Action.m_Param);
			break;
		case TURN_LEFT:
			StartAction("TURN_LEFT");
			break;
		case TURN_RIGHT:
			StartAction("TURN_RIGHT");
		case LOOK_UP:
			StartAction(Action.m_Param);
			break;
		case LOOK_DOWN:
			StartAction(Action.m_Param);
			break;
		case MODEL_SET_POS_X:
			m_Position.SetX(atof(Action.m_Param.data()));
			break;
		case MODEL_SET_POS_Y:
			m_Position.SetY(atof(Action.m_Param.data()));
			break;
		case MODEL_SET_POS_Z:
			m_Position.SetZ(atof(Action.m_Param.data()));
			break;
		case MODEL_SET_ANGLE_X:
            m_Angle.SetX(atof(Action.m_Param.data()));
			break;
		case MODEL_SET_ANGLE_Y:
			m_Angle.SetY(atof(Action.m_Param.data()));
			break;
		case MODEL_SET_ANGLE_Z:
			m_Angle.SetZ(atof(Action.m_Param.data()));
			break;
		case MODEL_START_ROTATE_Y_DOWN:
			StartAction("TURN_RIGHT");
			break;
		case MODEL_STOP_ROTATE_Y_DOWN:
			StopAction("TURN_RIGHT");
			if(!IsAction("RUN")){StartAction("IDLE");}
			break;
		case MODEL_START_ROTATE_Y_UP:
			StartAction("TURN_LEFT");
			break;
		case MODEL_STOP_ROTATE_Y_UP:
			StopAction("TURN_LEFT");
			if(!IsAction("RUN")){StartAction("IDLE");}
			break;
		case MODEL_START_ROTATE_Z_DOWN:
			StartAction("LOOK_UP");
			break;
		case MODEL_STOP_ROTATE_Z_DOWN:
			StopAction("LOOK_UP");
			break;
		case MODEL_START_ROTATE_Z_UP:
			StartAction("LOOK_DOWN");
			break;
		case MODEL_STOP_ROTATE_Z_UP:
			StopAction("LOOK_DOWN");
			break;
		case MODEL_START_ROTATE_X_DOWN:
			StartAction("X_DOWN");
			break;
		case MODEL_STOP_ROTATE_X_DOWN:
			StopAction("X_DOWN");
			break;
		case MODEL_START_ROTATE_X_UP:
			StartAction("X_UP");
			break;
		case MODEL_STOP_ROTATE_X_UP:
			StopAction("X_UP");
			break;
		case MODEL_START_MOVE_FORWARD:
			StartAction("RUN");
			m_Acceleration=m_Acceleration+0.01;
			break;
		case MODEL_STOP_MOVE_FORWARD:
			StopAction("RUN");
			StartAction("IDLE");
			m_Acceleration.SetValue(0.0f,0.0f,0.0f);
			m_Velocity.SetValue(0.0f,0.0f,0.0f);
			break;
		case MODEL_JUMP:
			StartAction("JUMP");
			break;
		case MODEL_SET_ACTION:
            break;
		case MODEL_STOP_ALL:
			m_VecAction.clear();
			m_Velocity.SetValue(0.0f,0.0f,0.0f);
			m_Acceleration.SetValue(0.0f,0.0f,0.0f);
			break;
		case MODEL_SHOW_COLLISION_SPHERE:
			if(m_ShowCollisionSphere){m_ShowCollisionSphere=false;}
			else{m_ShowCollisionSphere=true;}

			break;
		case MODEL_START_STRAFE_LEFT:
			StartAction("STRAFE_LEFT");
			break;
		case MODEL_STOP_STRAFE_LEFT	:
			StopAction("STRAFE_LEFT");
			break;
		case MODEL_START_STRAFE_RIGHT:
			StartAction("STRAFE_RIGHT");
			break;
		case MODEL_STOP_STREFA_RIGHT:
			StopAction("STRAFE_RIGHT");
			break;
	}
	return NOTHING;
}

void ExCModelMD2::Process(std::string Action)
{
Guard(void ExCModelMD2::Process(std::string Action))
	if(m_Angle.GetX()<0)m_Angle.SetX(359);
	if(m_Angle.GetX()>359)m_Angle.SetX(0);
	if(m_Angle.GetY()<0)m_Angle.SetY(359);
	if(m_Angle.GetY()>359)m_Angle.SetY(0);
	if(m_Angle.GetZ()<0)m_Angle.SetZ(359);
	if(m_Angle.GetZ()>359)m_Angle.SetZ(0);
	//process action
	if(Action=="RUN")
	{
		//m_Position=m_Target;
		//return;
		//m_Velocity.SetX(0.01f);
	}
	if(Action=="STRAFE_LEFT")
	{
		float angle;
		angle=m_Angle.GetY()+90;
		if(angle>360)angle=angle-360;
		m_Position=m_Position+ExCVec3D(Cos[(int)angle],0.0f,Sin[(int)angle]);
		return;
	}
	if(Action=="STRAFE_RIGHT")
	{
		float angle;
		angle=m_Angle.GetY()+90;
		if(angle>360)angle=angle-360;
		m_Position=m_Position-ExCVec3D(Cos[(int)angle],0.0f,Sin[(int)angle]);
		return;
	}

	if(Action=="TURN_LEFT"){m_Angle.DecY(2);return;}
	if(Action=="TURN_RIGHT"){m_Angle.IncY(2);return;}
	if(Action=="LOOK_UP"){m_Angle.IncZ(2);return;}
	if(Action=="LOOK_DOWN"){m_Angle.DecZ(2);return;}
	if(Action=="X_UP"){m_Angle.IncX(2);return;}
	if(Action=="X_DOWN"){m_Angle.DecX(2);return;}
	if(Action=="JUMP")
	{
		if(m_CurrentFrames=72)
		{
			StopAction("JUMP");
			if(!IsAction("RUN")){StartAction("IDLE");}
		}
	}
UnGuard
}
void ExCModelMD2::ProcessAllAction(void)
{
Guard(void ExCModelMD2::ProcessAllAction(void))
	for(unsigned int i=0;i< m_VecAction.size();i++)
	{
		Process(m_VecAction.at(i));	
	}
UnGuard
}

void ExCModelMD2::StopAction(std::string	 Action)
{
Guard(void ExCModelMD2::StopAction(std::string	 Action))
	for(m_IVecAction= m_VecAction.begin();m_IVecAction!= m_VecAction.end();m_IVecAction++)
	{
		if(strcmp(m_IVecAction->data(),Action.data())==0)
		{
			m_VecAction.erase(m_IVecAction);
			return;
		}
	}	
UnGuard
}

bool ExCModelMD2::IsAction(std::string Action)
{
Guard(bool ExCModelMD2::IsAction(std::string Action))
	for(m_IVecAction= m_VecAction.begin();m_IVecAction!= m_VecAction.end();m_IVecAction++)
	{
		if(strcmp(m_IVecAction->data(),Action.data())==0)
		{
			return true;
		}
	}
	return false;
UnGuard
}
void ExCModelMD2::StartAction(std::string	 Action)
{
Guard(void ExCModelMD2::StartAction(std::string	 Action))
	m_VecAction.push_back(Action);
	m_CurrentAction=Action;
	if(m_CurrentAction=="RUN")
	{
		m_KeyFrameStartAction=40;
		m_KeyFrameStopAction=46;
	}
	if(m_CurrentAction=="ATTACK")
	{
		m_KeyFrameStartAction=47;
		m_KeyFrameStopAction=60;
	}	
	if(m_CurrentAction=="CROUCH")
	{
		m_KeyFrameStartAction=136;
		m_KeyFrameStopAction=154;
	}	
	if(m_CurrentAction=="JUMP")
	{
		m_KeyFrameStartAction=67;
		m_KeyFrameStopAction=73;
	}	
	if(m_CurrentAction=="IDLE")
	{
		m_KeyFrameStartAction=1;
		m_KeyFrameStopAction=39;
	}
	if(m_CurrentAction=="FULL")
	{
		m_KeyFrameStartAction=113;
		m_KeyFrameStopAction=125;

	}
	if(m_CurrentAction=="TURN_LEFT")
	{
		m_KeyFrameStartAction=41;
		m_KeyFrameStopAction=46;
    }
	if(m_CurrentAction=="TURN_RIGHT")
	{
		m_KeyFrameStartAction=41;
		m_KeyFrameStopAction=46;
	}
	if(m_CurrentAction=="LOOK_UP")
	{
		m_KeyFrameStartAction=1;
		m_KeyFrameStopAction=39;
    }
	if(m_CurrentAction=="LOOK_DOWN")
	{
		m_KeyFrameStartAction=1;
		m_KeyFrameStopAction=39;
	}
	if(m_CurrentAction=="FULL")
	{
		m_KeyFrameStartAction=1;
		m_KeyFrameStopAction=198;
	}
	if(m_CurrentAction=="NONE")
	{
		m_KeyFrameStartAction=1;
		m_KeyFrameStopAction=1;
	}	
	m_Transition=true;
	m_CurrentFrames=m_KeyFrameStartAction;
UnGuard
}



void ExCModelMD2::Draw(void)	    
{
Guard(void ExCModelMD2::Draw(void))
	double CurrentTime;
	if(!m_Visible)return;
	//ExCModel::Draw();
	ExCVec3D VecAB,VecBC,VecCA;
	int FrameToDraw,FrameToInterpol;
	CurrentTime=glutGet(GLUT_ELAPSED_TIME);
	if(CurrentTime>m_LastTime+m_speed)
	{
	
		if(m_Transition)
		{
			m_Interpolation+=m_InterpolationPourcentage;
			if(m_Interpolation>1)//check if we go to next frame
			{
				m_Interpolation=m_InterpolationPourcentage;
				m_CurrentFrames++;
				m_NextFrame=m_CurrentFrames+1;
				if(m_NextFrame>m_KeyFrameStopAction)m_NextFrame=m_KeyFrameStartAction;
				if(m_CurrentFrames>m_KeyFrameStopAction)
				{
					m_CurrentFrames=m_KeyFrameStartAction;
					m_NextFrame=m_CurrentFrames+1;
				}
			}
		}
		m_LastTime=CurrentTime;
	}
	FrameToDraw=m_numVertices*m_CurrentFrames;
	FrameToInterpol=m_numVertices*m_NextFrame;
	ProcessAllAction();
//check if camera can see object
	ExCFrustum Frustrum;
	Frustrum.CalculateFrustum();
	if(!Frustrum.SphereInFrustum(m_Position.GetX(),m_Position.GetY(),m_Position.GetZ(),m_CollisionSphere.m_Radius))
	{
		return;
	}

	TabVertices= new float[m_numTriangles*9];
	for(int i = 0; i < m_numTriangles; i++)
	{
		//----------------
		//Vertex coord
		//----------------
		VecAB.SetX(m_VecVertex.at(m_VecTriangle.at(i).first.GetX()+FrameToDraw).GetX());
		VecAB.SetY(m_VecVertex.at(m_VecTriangle.at(i).first.GetX()+FrameToDraw).GetY());
		VecAB.SetZ(m_VecVertex.at(m_VecTriangle.at(i).first.GetX()+FrameToDraw).GetZ());		

		VecBC.SetX(m_VecVertex.at(m_VecTriangle.at(i).first.GetY()+FrameToDraw).GetX());
		VecBC.SetY(m_VecVertex.at(m_VecTriangle.at(i).first.GetY()+FrameToDraw).GetY());
		VecBC.SetZ(m_VecVertex.at(m_VecTriangle.at(i).first.GetY()+FrameToDraw).GetZ());

		VecCA.SetX(m_VecVertex.at(m_VecTriangle.at(i).first.GetZ()+FrameToDraw).GetX());
		VecCA.SetY(m_VecVertex.at(m_VecTriangle.at(i).first.GetZ()+FrameToDraw).GetY());
		VecCA.SetZ(m_VecVertex.at(m_VecTriangle.at(i).first.GetZ()+FrameToDraw).GetZ());

		//--------------
		//interpolation
		//--------------
		if(m_Transition)
		{
			ExCVec3D VecABN,VecBCN,VecCAN;

			VecABN.SetX(m_VecVertex.at(m_VecTriangle.at(i).first.GetX()+FrameToInterpol).GetX());
			VecABN.SetY(m_VecVertex.at(m_VecTriangle.at(i).first.GetX()+FrameToInterpol).GetY());
			VecABN.SetZ(m_VecVertex.at(m_VecTriangle.at(i).first.GetX()+FrameToInterpol).GetZ());		

			VecBCN.SetX(m_VecVertex.at(m_VecTriangle.at(i).first.GetY()+FrameToInterpol).GetX());
			VecBCN.SetY(m_VecVertex.at(m_VecTriangle.at(i).first.GetY()+FrameToInterpol).GetY());
			VecBCN.SetZ(m_VecVertex.at(m_VecTriangle.at(i).first.GetY()+FrameToInterpol).GetZ());

			VecCAN.SetX(m_VecVertex.at(m_VecTriangle.at(i).first.GetZ()+FrameToInterpol).GetX());
			VecCAN.SetY(m_VecVertex.at(m_VecTriangle.at(i).first.GetZ()+FrameToInterpol).GetY());
			VecCAN.SetZ(m_VecVertex.at(m_VecTriangle.at(i).first.GetZ()+FrameToInterpol).GetZ());

			VecAB=VecAB+((VecABN-VecAB)*m_Interpolation);
			VecBC=VecBC+((VecBCN-VecBC)*m_Interpolation);
			VecCA=VecCA+((VecCAN-VecCA)*m_Interpolation);
		}
		//--------------
		//Build array with new vertex data
		//--------------
			TabVertices[0+i*9]=VecBC.GetX();
			TabVertices[1+i*9]=VecBC.GetY();
			TabVertices[2+i*9]=VecBC.GetZ();
			TabVertices[3+i*9]=VecAB.GetX();
			TabVertices[4+i*9]=VecAB.GetY();
			TabVertices[5+i*9]=VecAB.GetZ();
			TabVertices[6+i*9]=VecCA.GetX();
			TabVertices[7+i*9]=VecCA.GetY();
			TabVertices[8+i*9]=VecCA.GetZ();
	}
	//----------------------------
	//Apply mouvement modification 
	//----------------------------
	glPushMatrix();
	ExCModel::Draw();
	//ShowInfo();
	//--------------
	//Draw Model with array
	//--------------
	glRotatef(-90,1,0,0);

	//m_CollisionSphere.SetPosition(m_Position);
	//if(m_ShowCollisionSphere)m_CollisionSphere.Draw();
	m_CollisionGizmo->SetPosition(m_Position);
	m_CollisionGizmo->Draw();

	
	//stock in vidoe memory
	PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL;
	PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL;
	PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL;

	glBindBufferARB = (PFNGLBINDBUFFERARBPROC)
		wglGetProcAddress("glBindBufferARB");
	glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)
		wglGetProcAddress("glGenBuffersARB");
	glBufferDataARB = (PFNGLBUFFERDATAARBPROC)
		wglGetProcAddress("glBufferDataARB");



	glColor3f(1,1,1);
	/*	glPushMatrix();
			glDisable(GL_LIGHTING);
			ManagerTexture->SetTexture(0,m_Skin);
			glTexCoordPointer(2,GL_FLOAT,0,TabTextures);
			ManagerTexture->SetTexture(1,"Model/OgreDOT3");
			glTexCoordPointer(2,GL_FLOAT,0,TabTextures);
			glEnableClientState(GL_VERTEX_ARRAY);
			GLuint buffer = 0;
			glGenBuffersARB(1, &buffer);
			glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
			glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(TabVertices), TabVertices, GL_STATIC_DRAW_ARB);
			
			glVertexPointer(3,GL_FLOAT,0,TabVertices);
			glDrawArrays( GL_TRIANGLES, 0, m_numTriangles*3 );
			ManagerTexture->ResetMultitexture();
		glPopMatrix();
	*/
	glPushMatrix();
		glDisable(GL_LIGHTING);
		ManagerTexture->SetTexture(0,m_Skin);
	/*	
		// RGB
		glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_EXT);

		glTexEnvf(GL_TEXTURE_ENV,GL_COMBINE_RGB_EXT,GL_MODULATE);
		glTexEnvf(GL_TEXTURE_ENV,GL_SOURCE0_RGB_EXT,GL_TEXTURE);
		glTexEnvf(GL_TEXTURE_ENV,GL_OPERAND0_RGB_EXT,GL_SRC_COLOR);
		glTexEnvf(GL_TEXTURE_ENV,GL_SOURCE1_RGB_EXT,GL_PREVIOUS_EXT);
		glTexEnvf(GL_TEXTURE_ENV,GL_OPERAND1_RGB_EXT,GL_SRC_COLOR);

		// alpha
		glTexEnvf(GL_TEXTURE_ENV,GL_COMBINE_ALPHA_EXT,GL_REPLACE);
		glTexEnvf(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_EXT,GL_TEXTURE);
		glTexEnvf(GL_TEXTURE_ENV,GL_OPERAND0_ALPHA_EXT,GL_SRC_ALPHA);

*/
	//	glTexCoordPointer(2,GL_FLOAT,0,TabTextures);
	//	ManagerTexture->SetTexture(1,"Model/droidDOT3");
/*		// RGB
		glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_EXT);
		glTexEnvf(GL_TEXTURE_ENV,GL_COMBINE_RGB_EXT,GL_REPLACE);
		glTexEnvf(GL_TEXTURE_ENV,GL_SOURCE0_RGB_EXT,GL_PREVIOUS_EXT);
		glTexEnvf(GL_TEXTURE_ENV,GL_OPERAND0_RGB_EXT,GL_SRC_COLOR);

		// alpha
		glTexEnvf(GL_TEXTURE_ENV,GL_COMBINE_ALPHA_EXT,GL_ADD_SIGNED_EXT);
		glTexEnvf(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_EXT,GL_TEXTURE);
		glTexEnvf(GL_TEXTURE_ENV,GL_OPERAND0_ALPHA_EXT,GL_ONE_MINUS_SRC_ALPHA);
		glTexEnvf(GL_TEXTURE_ENV,GL_SOURCE1_ALPHA_EXT,GL_PREVIOUS_EXT);
		glTexEnvf(GL_TEXTURE_ENV,GL_OPERAND1_ALPHA_EXT,GL_SRC_ALPHA);

		glEnable(GL_BLEND);

		// src * srcAlpha + 0
		glBlendFunc(GL_SRC_ALPHA, GL_ZERO);
*/

		glTexCoordPointer(2,GL_FLOAT,0,TabTextures);
        glEnableClientState(GL_VERTEX_ARRAY);
		GLuint buffer = 0;
		glGenBuffersARB(1, &buffer);
		glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
		glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(TabVertices), TabVertices, GL_STATIC_DRAW_ARB);

		glVertexPointer(3,GL_FLOAT,0,TabVertices);
		
		
		glDrawArrays( GL_TRIANGLES, 0, m_numTriangles*3 );

	//	glDisable(GL_BLEND);

		ManagerTexture->ResetMultitexture();
	glPopMatrix();
	//--------------------------------------
	glPopMatrix();
	glDisable(GL_TEXTURE_2D);
	m_OldPosition=m_Position;
	delete TabVertices;	

UnGuard
}




bool ExCModelMD2::Load(std::string FileName)	    
{
Guard(bool ExCModelMD2::Load(std::string FileName))
	int i,j;
	FILE *filePtr;                          // file pointer
    int fileLen;                            // length of model file
    char *buffer;                           // file buffer

    modelHeader_t *modelHeader;             // model header
	frame_t *frame;                              // frame data
	stIndex_t *stPtr;                       // texture data
	 mesh_t *bufIndexPtr;          // index variables
	m_Skin=ExNihilo::ExtracValueFromSring(FileName,"../Data/Modeles/",".md2");
	m_Skin="Model/"+m_Skin;
	
	ManagerTexture->Load(m_Skin);
	
	

    filePtr = fopen(FileName.data(), "rb");
    if (filePtr == NULL) 
	{
		throw ExCExpFileNotFound();
		return false;
	}
     

	 // find length of file
     fseek(filePtr, 0, SEEK_END);
     fileLen = ftell(filePtr);
     fseek(filePtr, 0, SEEK_SET);
     
     // read entire file into buffer
     buffer = new char [fileLen+1];
     fread(buffer, sizeof(char), fileLen, filePtr);

	 modelHeader = (modelHeader_t*)buffer; 

/*	 std::ofstream logscale;
	 std::ofstream logfp;
	 std::ofstream logtranslate;
	 std::ofstream logfile;
	 std::ofstream logHeader;
	 std::ofstream logTextureCoord;
	 
	 logscale.open("logscale.txt",std::ios::out);
	 logfp.open("logfp.txt",std::ios::out);
	 logtranslate.open("logtranslate.txt",std::ios::out);
	 logfile.open("logfile.txt",std::ios::out);
	 logHeader.open("logHeader.txt",std::ios::out);
	 logTextureCoord.open("logTextureCoord.txt",std::ios::out);
*/

	m_magic=modelHeader->ident;
	m_version=modelHeader->version;						// The version number of the file (Must be 8)
	m_skinWidth=modelHeader->skinwidth;					// The skin width in pixels
	m_skinHeight=modelHeader->skinheight;				// The skin height in pixels
	m_frameSize=modelHeader->framesize;					// The size in bytes the frames are
	m_numSkins=modelHeader->numSkins;					// The number of skins associated with the model
	m_numVertices=modelHeader->numXYZ;				// The number of vertices (constant for each frame)
	m_numTexCoords=modelHeader->numST;			// The number of texture coordinates
	m_numTriangles=modelHeader->numTris;			// The number of faces (polygons)
	m_numGlCommands=modelHeader->numGLcmds;			// The number of gl commands
	m_numFrames=modelHeader->numFrames;					// The number of animation frames
	m_offsetSkins=modelHeader->offsetSkins;				// The offset in the file for the skin data
	m_offsetTexCoords=modelHeader->offsetST;		// The offset in the file for the texture data
	m_offsetTriangles=modelHeader->offsetTris;		// The offset in the file for the face data
	m_offsetFrames=modelHeader->offsetFrames;			// The offset in the file for the frames data
	m_offsetGlCommands=modelHeader->offsetGLcmds;	// The offset in the file for the gl commands data
	m_offsetEnd=modelHeader->offsetEnd;					// The end of the file offset
	
/*	std::cout<<"This is used to identify the file: "<<m_magic<<std::endl;
	std::cout<<"The version number of the file (Musbe 8):"<<m_version<<std::endl;
	std::cout<<"The skin width in pixels:"<<m_skinWidth<<std::endl;
	std::cout<<"The skin heighin pixels:"<<m_skinHeight<<std::endl;
	std::cout<<"The size in bytes the frames are:"<<m_frameSize<<std::endl;
	std::cout<<"The number of skins associated with the model:"<<m_numSkins<<std::endl;
	std::cout<<"The number of vertices (constan for each frame):"<<m_numVertices<<std::endl;
	std::cout<<"The number of texture coordinates:"<<m_numTexCoords<<std::endl;
	std::cout<<"The number of faces (polygons):"<<m_numTriangles<<std::endl;
	std::cout<<"The number of gl commands:"<<m_numGlCommands<<std::endl;
	std::cout<<"The number of animation frames:"<<m_numFrames<<std::endl;
	std::cout<<"The offset in the file for the skin data:"<<m_offsetSkins<<std::endl;
	std::cout<<"The offset in the file for the texture data:"<<m_offsetTexCoords<<std::endl;
	std::cout<<"The offset in the file for the face data:"<<m_offsetTriangles<<std::endl;
	std::cout<<"The offset in the file for the frames data:"<<m_offsetFrames<<std::endl;
	std::cout<<"The offset in the file for the gl commands data:"<<m_offsetGlCommands<<std::endl;
	std::cout<<"The end of the file offset:"<<m_offsetEnd<<std::endl;
*/	
	//-----------------------------------------------
	//read all skin
	//-----------------------------------------------
	char mybuff[65];
	std::string BuffSkin;
    fseek(filePtr, m_offsetSkins, SEEK_SET);
	for(i = 0;i<m_numSkins;++i)
	{
		fread(&mybuff,sizeof(char),64, filePtr);
		BuffSkin=mybuff;
		//std::cout<<BuffSkin<<std::endl;
		m_VecSkin.push_back(BuffSkin);
	}
	//-----------------------------------------------
	//read vertex  data 
	//-----------------------------------------------
	 ExCVec3D Vec3D;
	 for (j = 0; j < m_numFrames; j++)
     {
          frame = (frame_t*)&buffer[m_offsetFrames+ m_frameSize * j];
          for (i = 0; i < m_numVertices; i++)
          {
				Vec3D.SetX(frame->scale[0] * frame->fp[i].v[0] + frame->translate[0]);
				Vec3D.SetY(frame->scale[1] * frame->fp[i].v[1] + frame->translate[1]);
				Vec3D.SetZ(frame->scale[2] * frame->fp[i].v[2] + frame->translate[2]);
				Vec3D=Vec3D/3;
				m_VecVertex.push_back(Vec3D);

	/*			logscale<<"X:"<<frame->scale[0]<<" Y:"<<frame->scale[1]<<" Z:"<<frame->scale[2]<<std::endl;
				logfp<<"X:"<<frame->fp[i].v[0]<<" Y:"<<frame->fp[i].v[1]<<" Z:"<<frame->fp[i].v[2]<<std::endl;
				logtranslate<<"X:"<<frame->translate[0]<<" Y:"<<frame->translate[1]<<" Z:"<<frame->translate[2]<<std::endl;
				logfile<<"vec :"<<i<<" "<<Vec3D<<std::endl;*/
          }
		  //logfile<<"------------------------------------------------------------------"<<std::endl;
     }
	//-----------------------------------------------
	//read triangles data 
	//-----------------------------------------------
	fseek(filePtr, m_offsetTriangles, SEEK_SET);
	short AB,BC,CA,TAB,TBC,TCA;
	ExCVec3D VertexNum,TexturNum;
	/*std::ofstream logTri;
	logTri.open("logTri.txt",std::ios::out);
	*/
	    
     // point to triangle indexes in buffer
    bufIndexPtr = (mesh_t*)&buffer[modelHeader->offsetTris]; 
	// create a mesh (triangle) list
     for (j = 0; j < m_numFrames; j++)         
     {
          // for all triangles in each frame
          for(i = 0; i < m_numTriangles; i++)
          {
               AB = bufIndexPtr[i].meshIndex[0];
               BC = bufIndexPtr[i].meshIndex[1];
               CA = bufIndexPtr[i].meshIndex[2];
               TAB = bufIndexPtr[i].stIndex[0];
               TBC = bufIndexPtr[i].stIndex[1];
               TCA = bufIndexPtr[i].stIndex[2];
			
			VertexNum.SetValue(AB,BC,CA);
			TexturNum.SetValue(TAB,TBC,TCA);
			std::pair<ExCVec3D,ExCVec3D> tmp(VertexNum,TexturNum);
			m_VecTriangle.push_back(tmp);
		//	logTri<<"AB:"<<AB<<" BC:"<<BC<<" CA:"<<CA<<std::endl;
		//	logTri<<"TAB:"<<TAB<<" TBC:"<<TBC<<" TCA:"<<TCA<<std::endl;
          }
     }
	//-----------------------------------------------
	//read texture coord  data 
	//-----------------------------------------------
	std::vector<ExCVec2D>		*VecTexture;
	VecTexture= new std::vector<ExCVec2D>;	
	stPtr = (stIndex_t*)&buffer[m_offsetTexCoords];
	for (i = 0; i < m_numTexCoords; i++)
	{
		VecTexture->push_back(ExCVec2D(((float)stPtr[i].s / (float)m_skinWidth),((float)stPtr[i].t / (float)m_skinHeight)));
	}
	//------------------------------
	//Build Texture Array
	//------------------------------
	TabTextures= new float[m_numTriangles*6];
	for(i = 0; i < m_numTriangles; i++)
	{
		TabTextures[0+i*6]=VecTexture->at(m_VecTriangle.at(i).second.GetY()).GetX();
		TabTextures[1+i*6]=VecTexture->at(m_VecTriangle.at(i).second.GetY()).GetY();
		TabTextures[2+i*6]=VecTexture->at(m_VecTriangle.at(i).second.GetX()).GetX();
		TabTextures[3+i*6]=VecTexture->at(m_VecTriangle.at(i).second.GetX()).GetY();
		TabTextures[4+i*6]=VecTexture->at(m_VecTriangle.at(i).second.GetZ()).GetX();
		TabTextures[5+i*6]=VecTexture->at(m_VecTriangle.at(i).second.GetZ()).GetY();
	}
	/*for(i = 0; i < m_numTriangles; i++)
	{
		std::cout<<TabTextures[0+i*6]<<std::endl;
		std::cout<<TabTextures[1+i*6]<<std::endl;
		std::cout<<TabTextures[2+i*6]<<std::endl;
		std::cout<<TabTextures[3+i*6]<<std::endl;
		std::cout<<TabTextures[4+i*6]<<std::endl;
		std::cout<<TabTextures[5+i*6]<<std::endl;
	}
	std::cout<<"i:"<<i<<std::endl;*/
	delete VecTexture;
	delete buffer;
	BuildSphere();
	return true;
UnGuard
}
void ExCModelMD2::BuildSphere(void)	   
{
Guard(void ExCModelMD2::BuildSphere(void))
	//look for sphere radisu
	m_CollisionSphere.m_Radius=m_SphereRadius;
UnGuard
}
void ExCModelMD2::ShowInfo(void)
{
Guard(void ExCModelMD2::ShowInfo(void))
	
	char *CIdName;
	char *CPosition;
	char *CVelocity;
	char *CAcceleration;
	char *CGravity;
	char *CLife;
	char *CAngle;
	char *CTarget;

	CIdName= new char[strlen("Name : Id:")+strlen(GetName().data())+7];
	sprintf(CIdName,"Name :%s Id:%ld",GetName().data(),GetId());
	ExNihilo::WriteToScreen(650,20,CIdName);	

	CPosition= new char[strlen("Position X: Y: Z:")+30];
	sprintf(CPosition,"Position X:%f Y:%f Z:%f",m_Position.GetX(),m_Position.GetY(),m_Position.GetZ());
	ExNihilo::WriteToScreen(650,35,CPosition);

	CVelocity= new char[strlen("Velocity X: Y: Z:")+30];
	sprintf(CVelocity,"Velocity X:%f Y:%f Z:%f",m_Velocity.GetX(),m_Velocity.GetY(),m_Velocity.GetZ());
	ExNihilo::WriteToScreen(650,50,CVelocity);	

	CGravity= new char[strlen("Gravity X: Y: Z:")+30];
	sprintf(CGravity,"Gravity X:%f Y:%f Z:%f",m_Gravity.GetX(),m_Gravity.GetY(),m_Gravity.GetZ());
	ExNihilo::WriteToScreen(650,65,CGravity);	

	CAcceleration= new char[strlen("Acceleration X: Y: Z:")+30];
	sprintf(CAcceleration,"Acceleration X:%f Y:%f Z:%f",m_Acceleration.GetX(),m_Acceleration.GetY(),m_Acceleration.GetZ());
	ExNihilo::WriteToScreen(650,80,CAcceleration);	
	
	CTarget= new char[strlen("Target X: Y: Z:")+30];
	sprintf(CTarget,"Target X:%f Y:%f Z:%f",m_Target.GetX(),m_Target.GetY(),m_Target.GetZ());
	ExNihilo::WriteToScreen(650,95,CTarget);	

	CAngle= new char[strlen("Angle X: Y: Z:")+30];
	sprintf(CAngle,"Angle X:%f Y:%f Z:%f",m_Angle.GetX(),m_Angle.GetY(),m_Angle.GetZ());
	ExNihilo::WriteToScreen(650,110,CAngle);

	CLife= new char[strlen("Life :")+10];
	sprintf(CLife,"Life :%f",m_Life);
	ExNihilo::WriteToScreen(650,125,CLife);	
	
	delete CIdName;
	delete CPosition;
	delete CVelocity;
	delete CAcceleration;
	delete CGravity;
	delete CLife;
	delete CAngle;
	delete CTarget;
UnGuard
} 