/**
* MDL Control
* @version: 03-05-2005
* @author Joseph 'Pcjoe' Florencio
*/
#include "hud.h"
#include "parsemsg.h"
#include "const.h"
#include "cl_util.h"
#include "studio_util.h"
#include "r_studioint.h"
#include "r_efx.h"
#include "pm_defs.h"
#include "pmtrace.h"
#include "event_api.h"
#include "com_model.h"
#include "StudioModelRenderer.h"
#include "GameStudioModelRenderer.h"
#include "mdlcontrol.h"
extern engine_studio_api_t IEngineStudio;

CModelControlManager gModelControl;

/*
* Model Control
*/

// Constructors
CMDLControl::CMDLControl()
{	setIndex(0);
	setBodyPart(0);
	setSequence("");
	setInterpolSequence("");
	setInterpolPercent(0);
	setInterpolFrame(0);
	setFrame(0);
	setPosition(vec3_t(0,0,0));
	setAngle(vec3_t(0,0,0));
	setModel(NULL);
}

// Get Studio Header
studiohdr_t *CMDLControl::getStudioHeader( void )
{	model_s *mdl = getModel();
	studiohdr_t *pStudioHeader = NULL;
	// Game Code
#ifdef CLIENT_DLL
	pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata (mdl);
	
	// FX Tool Code
#else

#endif

	return pStudioHeader;
}

// Get Sequence Descriptor
mstudioseqdesc_t *CMDLControl::getSequenceDesc( int iSeq )
{	studiohdr_t *pStudioHeader = getStudioHeader();
	if(!pStudioHeader)
	{	return NULL;
	}
	if(iSeq < 0 || iSeq > pStudioHeader->numseq)
	{	return NULL;
	}
	return ((mstudioseqdesc_t *)((byte *)pStudioHeader + pStudioHeader->seqindex) + iSeq);
}

int CMDLControl::SequenceLookup( std::string strAnim )
{	studiohdr_t *pStudioHeader = getStudioHeader();
	if(!pStudioHeader)
	{	return -1;
	}
	mstudioseqdesc_t *pseqdesc = (mstudioseqdesc_t *)((byte *)pStudioHeader + pStudioHeader->seqindex);
	for (int i = 0; i < pStudioHeader->numseq; i++) 
	{	if(!stricmp(strAnim.c_str(), pseqdesc->label))
		{	return i;
		}
		pseqdesc++;
	}
	return -1;
}

// FPS Lookup
float CMDLControl::fpsLookup( int iSeq )
{	mstudioseqdesc_t *pseqdesc = getSequenceDesc(iSeq);
	if(!pseqdesc)
	{	return 0;
	}
	return pseqdesc->fps;
}

// Max Frames Lookup
int CMDLControl::numFramesLookup( int iSeq )
{	mstudioseqdesc_t *pseqdesc = getSequenceDesc(iSeq);
	if(!pseqdesc)
	{	return 0;
	}
	return pseqdesc->numframes;
}

// Current Sequence Num
int CMDLControl::getSequenceNum( void )
{	int iSeq = SequenceLookup(getSequence());
	if(iSeq == -1)
	{
		int a = 5;
		a = 2;
	}
	return iSeq;
}

// Interpol Sequence Num
int CMDLControl::getInterpolSequenceNum( void )
{	return SequenceLookup(getInterpolSequence());
}

// Set Model
void CMDLControl::setModel( std::string strName )
{	setModel(IEngineStudio.Mod_ForName(strName.c_str(),0));
}


/*
* Model Control Manager
*/
// Constructor
CModelControlManager::CModelControlManager()
{
}

// Find model control
std::list<CMDLControl>::iterator CModelControlManager::findModelControlIter( int idx )
{	std::list<CMDLControl>::iterator iterSearch;
	ForEachIn(iterSearch, (*getModelControlList()))
	{	if(iterSearch->getIndex() == idx)
		{	return iterSearch;
		}
	}
	/*modified by harSens
	return NULL;
	*/
	return m_ModelControls.end();
}

CMDLControl *CModelControlManager::findModelControl( int idx )
{	std::list<CMDLControl>::iterator iterFind = findModelControlIter(idx);
	/*modified by harSens
	if(iterFind != NULL)
	*/
	if (iterFind!=m_ModelControls.end())
	{	return (&(*iterFind));
	}
	return NULL;
}

// Add model control
CMDLControl *CModelControlManager::addModelControl( int idx )
{	CMDLControl newctrl;
	newctrl.setIndex(idx);
	getModelControlList()->push_front(newctrl);
	return (&(*getModelControlList()->begin()));
}

// Remove model control
void CModelControlManager::removeModelControl( int idx )
{	std::list<CMDLControl>::iterator iterRemove = findModelControlIter(idx);
	/*modified by harSens
	if(iterRemove != NULL)
	*/
	if(iterRemove != m_ModelControls.end())
	{	getModelControlList()->erase(iterRemove);
	}
}