// CharacterInfo.cpp: implementation of the CCharacterInfo class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MapEditor.h"
//#include "AtumApplication.h"
#include "CharacterInfo.h"
#include "SpriteAniData.h"

#include "MainFrm.h"
#include "MapEditor.h"
#include "MapEditorDoc.h"
#include "MapEditorView.h"


//extern CAtumApplication				*g_pD3dApp;

float Random(float max, float min)
{
	float fTerm = max - min;
	if(fTerm == 0 ) return max;
	else if(fTerm < 0 )
	{
		float temp = min;
		min = max;
		max = temp;
		fTerm = max - min;
	}
//	int nTerm = fTerm * 100;
//	int nRnd = rand()%nTerm;
//	fTerm = ((float)nRnd) / 100.0f;
	int nTerm = (int)fTerm;
	if(nTerm == 0)
		return min;
	int nRnd = rand()%nTerm;
	return (float)nRnd + min;
}
//////////////////////////////////////////////////////////////////////
// CEffectInfo
//////////////////////////////////////////////////////////////////////
CEffectInfo::CEffectInfo()
{
	memset((char*)this,0,sizeof(EffectData));
	m_pEffect = NULL;
	m_bRestored = FALSE;
	m_fCurrentTime = 0;
	m_pParent = NULL;
}

CEffectInfo::~CEffectInfo()
{
	if(m_bRestored)
	{
		DeleteDeviceObjects();
	}
}

void CEffectInfo::InitData()
{
	memset((char*)this,0,sizeof(EffectData));
	m_pEffect = NULL;
	m_fCurrentTime = m_fStartTime;
	
}

void CEffectInfo::ParticleStop()
{
	if(m_nEffectType == EFFECT_TYPE_PARTICLE)
	{
		if(m_pEffect)
		{
			((CParticleSystem*)m_pEffect)->EmitterStop();
		}
	}
}

// by dhkwon, 030917
void CEffectInfo::SetTexture(char* strTexture)
{
	switch(m_nEffectType)
	{
	case EFFECT_TYPE_OBJECT:
		{
			if(m_pEffect)
			{
				((CObjectAni*)m_pEffect)->SetTexture(strTexture);
			}
		}
		break;
	case EFFECT_TYPE_SPRITE:
		{
			if(m_pEffect)
			{
				((CSpriteAni*)m_pEffect)->SetTexture(strTexture);
			}
		}
		break;
	case EFFECT_TYPE_PARTICLE:
		{
			if(m_pEffect)
			{
				((CParticleSystem*)m_pEffect)->SetTexture(strTexture);
			}
		}
		break;
	}

}

BOOL CEffectInfo::Tick(float fElapsedTime)
{
	if(!m_pEffect)
		return FALSE;
	if(!m_bRestored)
		return TRUE;
	m_fCurrentTime -= fElapsedTime;
	if(m_fCurrentTime>0)
		return TRUE;
	switch(m_nEffectType)
	{
	case EFFECT_TYPE_OBJECT:
		{
			if(!((CObjectAni*)m_pEffect)->Tick(fElapsedTime))
			{
				((CObjectAni*)m_pEffect)->InvalidateDeviceObjects();
				((CObjectAni*)m_pEffect)->DeleteDeviceObjects();
				SAFE_DELETE(m_pEffect);
				return FALSE;
			}
		}
		break;
	case EFFECT_TYPE_SPRITE:
		{
			if(!((CSpriteAni*)m_pEffect)->Tick(fElapsedTime))
			{
				((CSpriteAni*)m_pEffect)->InvalidateDeviceObjects();
				((CSpriteAni*)m_pEffect)->DeleteDeviceObjects();
				SAFE_DELETE(m_pEffect);
				return FALSE;
			}
		}
		break;
	case EFFECT_TYPE_PARTICLE:
		{
			if(!((CParticleSystem*)m_pEffect)->Tick(fElapsedTime))
			{
				((CParticleSystem*)m_pEffect)->InvalidateDeviceObjects();
				((CParticleSystem*)m_pEffect)->DeleteDeviceObjects();
				SAFE_DELETE(m_pEffect);
				return FALSE;
			}
		}
		break;
	}
	return TRUE;
}

void CEffectInfo::Render()
{

}

HRESULT CEffectInfo::InitDeviceObjects()
{
	CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
	CMapEditorView* pView = (CMapEditorView*)pFrame->GetActiveView();

	if(m_bRestored)
	{
		InvalidateDeviceObjects();
		DeleteDeviceObjects();
	}

	char* pEffect = new char[4096];//임의의 큰 사이즈
	DWORD type = pView->m_pEffectRender->LoadEffect(m_strEffectName, m_nEffectType, pEffect);
//	DbgOut("			Effect loaded[%d]\n",type);
	switch(type)
	{
	case EFFECT_TYPE_OBJECT:
		{
			CObjectAni* pObjEffect = new CObjectAni();
			memcpy( (void*)((char*)pObjEffect+sizeof(Effect)), pEffect, sizeof(ObjectAniData)-sizeof(Effect));
			pObjEffect->m_pParent = this;
			pObjEffect->InitDeviceObjects();
			m_pEffect = (char*)pObjEffect;
		}
		break;
	case EFFECT_TYPE_SPRITE:
		{
			CSpriteAni* pSprEffect = new CSpriteAni();
			memcpy( (void*)((char*)pSprEffect+sizeof(Effect)), pEffect, sizeof(SpriteAniData)-sizeof(Effect));
			pSprEffect->m_pParent = this;
			pSprEffect->InitDeviceObjects();
			m_pEffect = (char*)pSprEffect;
//			DbgOut("Sprite Ani loaded[%s]\n",m_strEffectName);
		}
		break;
	case EFFECT_TYPE_PARTICLE:
		{
			CParticleSystem* pParEffect = new CParticleSystem();
			memcpy( (void*)pParEffect, pEffect, sizeof(ParticleData));
			pParEffect->m_pParent = this;
			pParEffect->InitDeviceObjects();
			m_pEffect = (char*)pParEffect;
//			DbgOut("Particle loaded[%s]\n",m_strEffectName);
		}
		break;

	}
	delete pEffect;
	
	m_fCurrentTime = m_fStartTime;
	
	return S_OK;
}

HRESULT CEffectInfo::RestoreDeviceObjects()
{
	switch(m_nEffectType)
	{
	case EFFECT_TYPE_OBJECT:
		{
			if(m_pEffect)
			{
				((CObjectAni*)m_pEffect)->RestoreDeviceObjects();
			}
		}
		break;
	case EFFECT_TYPE_SPRITE:
		{
			if(m_pEffect)
			{
				((CSpriteAni*)m_pEffect)->RestoreDeviceObjects();
			}
		}
		break;
	case EFFECT_TYPE_PARTICLE:
		{
			if(m_pEffect)
			{
				((CParticleSystem*)m_pEffect)->RestoreDeviceObjects();
			}
		}
		break;
	}
	m_bRestored = TRUE;
	return S_OK;
}

HRESULT CEffectInfo::InvalidateDeviceObjects()
{
	if(!m_bRestored)
	{
		return S_OK;
	}
	switch(m_nEffectType)
	{
	case EFFECT_TYPE_OBJECT:
		{
			if(m_pEffect)
			{
				((CObjectAni*)m_pEffect)->InvalidateDeviceObjects();
			}
		}
		break;
	case EFFECT_TYPE_SPRITE:
		{
			if(m_pEffect)
			{
				((CSpriteAni*)m_pEffect)->InvalidateDeviceObjects();
			}
		}
		break;
	case EFFECT_TYPE_PARTICLE:
		{
			if(m_pEffect)
			{
				((CParticleSystem*)m_pEffect)->InvalidateDeviceObjects();
			}
		}
		break;
	}
	return S_OK;
}

HRESULT CEffectInfo::DeleteDeviceObjects()
{
	if(!m_bRestored)
	{
		return S_OK;
	}
	switch(m_nEffectType)
	{
	case EFFECT_TYPE_OBJECT:
		{
			if(m_pEffect)
			{
				((CObjectAni*)m_pEffect)->DeleteDeviceObjects();
				CObjectAni* p = (CObjectAni*)m_pEffect;
				SAFE_DELETE(p);
				m_pEffect = NULL;
			}
		}
		break;
	case EFFECT_TYPE_SPRITE:
		{
			if(m_pEffect)
			{
				((CSpriteAni*)m_pEffect)->DeleteDeviceObjects();
				CSpriteAni* p = (CSpriteAni*)m_pEffect;
				SAFE_DELETE(p);
				m_pEffect = NULL;
			}
		}
		break;
	case EFFECT_TYPE_PARTICLE:
		{
			if(m_pEffect)
			{
				((CParticleSystem*)m_pEffect)->DeleteDeviceObjects();
				CParticleSystem* p = (CParticleSystem*)m_pEffect;
				SAFE_DELETE(p);
				m_pEffect = NULL;
			}
		}
		break;
	}

	m_bRestored = FALSE;
	return S_OK;
}
//////////////////////////////////////////////////////////////////////
// CBodyConditionInfo
//////////////////////////////////////////////////////////////////////

CBodyConditionInfo::CBodyConditionInfo()
{
	m_pParent = NULL;
	m_fCurrentAnimationTime = 0;
}

CBodyConditionInfo::~CBodyConditionInfo()
{
	vector<CEffectInfo*>::iterator it = m_vecEffect.begin();

	while(it != m_vecEffect.end())
	{
		CEffectInfo* pEffect = *it;
		SAFE_DELETE (pEffect);
		m_vecEffect.erase(it);
	}		

}

void CBodyConditionInfo::InitData()
{
	memset((void*)this,0,sizeof(BodyConditionData));
	vector<CEffectInfo*>::iterator it = m_vecEffect.begin();
	m_fCurrentAnimationTime = 0;
	while(it != m_vecEffect.end())
	{
		CEffectInfo* pEffect = *it;
		m_vecEffect.erase(it);
		SAFE_DELETE (pEffect);
	}
}

BOOL CBodyConditionInfo::Tick(float fElapsedTime)
{
	if(m_bCharacterRendering)
	{
		if(m_fStartAnimationTime != 0 || m_fEndAnimationTime != 0)
		{
			m_fCurrentAnimationTime += fElapsedTime*m_fAnimationVel;
			if(m_fCurrentAnimationTime < m_fStartAnimationTime)
			{
				m_fCurrentAnimationTime = m_fStartAnimationTime;
			} else if( m_fCurrentAnimationTime > m_fEndAnimationTime)
			{
				if(m_bNotAnimationLooping)
				{
					m_fCurrentAnimationTime = m_fEndAnimationTime;
				} else
				{
					m_fCurrentAnimationTime = m_fStartAnimationTime;
				}
			}
		}
	}

	vector<CEffectInfo*>::iterator it = m_vecEffect.begin();
	while(it != m_vecEffect.end())
	{
		if((*it)->Tick(fElapsedTime))
		{
		}
		it ++;
/*		else // by dhkwon 2003.5.28 --> 다음 이펙트의 로드가 일어나지 않음 Loading of next effects will not occur
		{
			m_vecEffect.erase(it);
		}
*/	}
	if(!IsUsing())
	{
		if((m_fStartAnimationTime != 0 || m_fEndAnimationTime != 0) && m_bNotAnimationLooping)
		{
			if( m_fCurrentAnimationTime >= m_fEndAnimationTime)
				return FALSE;
			else
				return TRUE;
		}
		return FALSE;
	}
	return TRUE;
}

BOOL CBodyConditionInfo::EffectStop()
{
	vector<CEffectInfo*>::iterator it = m_vecEffect.begin();
	BOOL re = TRUE;
	while(it != m_vecEffect.end())
	{
		if(!(*it)->m_pEffect)
		{
			it++;
			continue;
		}
		if((*it)->m_nEffectType == EFFECT_TYPE_PARTICLE)
		{
			(*it)->ParticleStop();
			re = FALSE;
		}
		else
		{
			CEffectInfo* p = *it;
			p->InvalidateDeviceObjects();
			p->DeleteDeviceObjects();
			continue;
		}

		it++;
	}
	return re;
}

BOOL CBodyConditionInfo::IsUsing() // EFFECT가 끝났는지 확인 -->Effect check has finished
{
	vector<CEffectInfo*>::iterator it = m_vecEffect.begin();
	int count = 0;
	while(it != m_vecEffect.end())
	{
		if((*it)->m_pEffect == NULL)
		{
			count ++;
		}
		it++;
	}
	if(m_vecEffect.size() == count)
	{
		return FALSE;
	}
	return TRUE;
}

void CBodyConditionInfo::Render()
{
	vector<CEffectInfo*>::iterator it = m_vecEffect.begin();
	while(it != m_vecEffect.end())
	{
		(*it)->Render();
		it ++;
	}

}

HRESULT CBodyConditionInfo::InitDeviceObjects()
{
	m_fCurrentAnimationTime = 0;
	vector<CEffectInfo*>::iterator it = m_vecEffect.begin();
	while(it != m_vecEffect.end())
	{
		(*it)->InitDeviceObjects();
		it ++;
	}
	return S_OK;
}

HRESULT CBodyConditionInfo::RestoreDeviceObjects()
{
	CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
	CMapEditorView* pView = (CMapEditorView*)pFrame->GetActiveView();

	vector<CEffectInfo*>::iterator it = m_vecEffect.begin();
	while(it != m_vecEffect.end())
	{
		(*it)->RestoreDeviceObjects();
		it ++;
	}
/*	if(strlen(m_strSoundFileName))
	{
		D3DXVECTOR3 vPos;
		vPos.x = m_mMatrix._41;
		vPos.y = m_mMatrix._42;
		vPos.z = m_mMatrix._43;
		if(m_pParent->IsUpkeepBodyCondition(m_nBodyCondition))
			g_pD3dApp->PlayD3DSound(m_strSoundFileName,vPos);
		else
			g_pD3dApp->PlayD3DSound(m_strSoundFileName,vPos);
	}
*/	return S_OK;
}

HRESULT CBodyConditionInfo::InvalidateDeviceObjects()
{
	CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
	CMapEditorView* pView = (CMapEditorView*)pFrame->GetActiveView();

	vector<CEffectInfo*>::iterator it = m_vecEffect.begin();
	while(it != m_vecEffect.end())
	{
		(*it)->InvalidateDeviceObjects();
		it ++;
	}
/*	if(strlen(m_strSoundFileName))
	{
		if(m_pParent->IsUpkeepBodyCondition(m_nBodyCondition))
			g_pD3dApp->StopD3DSound(m_strSoundFileName);
	}
*/	return S_OK;
}

HRESULT CBodyConditionInfo::DeleteDeviceObjects()
{
	vector<CEffectInfo*>::iterator it = m_vecEffect.begin();
	while(it != m_vecEffect.end())
	{
		(*it)->DeleteDeviceObjects();
		it ++;
	}
	return S_OK;
}

//////////////////////////////////////////////////////////////////////
// CCharacterInfo
//////////////////////////////////////////////////////////////////////

CCharacterInfo::CCharacterInfo()
{
	memset((char*)this,0,sizeof(CharacterData));
	m_nCurrentBodyCondition = 0;
}

CCharacterInfo::~CCharacterInfo()
{
	map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.begin();

	while(it != m_mapBodyCondition.end())
	{
		CBodyConditionInfo* pBody = it->second;
		SAFE_DELETE (pBody);
		it++;
	}		
	m_mapBodyCondition.clear();
}

void CCharacterInfo::InitData()
{
	memset((void*)this,0,sizeof(CharacterData));
	map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.begin();

	while(it != m_mapBodyCondition.end())
	{
		CBodyConditionInfo* pBody = it->second;
		SAFE_DELETE (pBody);
		it++;
	}		
	m_mapBodyCondition.clear();
	m_vecCurrentBodyCondition.clear();
}

BOOL CCharacterInfo::Tick(float fElapsedTime)
{
	vector<LONGLONG>::iterator itCurrent = m_vecCurrentBodyCondition.begin();
//	LONGLONG hyDeleteBodyCondition = m_nCurrentBodyCondition;	
	while(itCurrent != m_vecCurrentBodyCondition.end())
	{
		LONGLONG hySingleBodyCondition = (*itCurrent);
		if(COMPARE_BODYCON_BIT(m_nCurrentBodyCondition,hySingleBodyCondition))
		{
			map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(hySingleBodyCondition);
			if(it != m_mapBodyCondition.end())
			{
//				(it->second)->Tick(fElapsedTime);
				if(!(it->second)->Tick(fElapsedTime))
				{
//					hyDeleteBodyCondition &= ~hySingleBodyCondition;

					(it->second)->InvalidateDeviceObjects();
					(it->second)->DeleteDeviceObjects();
					m_vecCurrentBodyCondition.erase(itCurrent);
					continue;
				}
			}
		}
		itCurrent++;
	}
/*	if(hyDeleteBodyCondition != m_nCurrentBodyCondition)//2003.6.7. by dhkwon
	{
		ChangeBodyCondition(hyDeleteBodyCondition);
	}
*/
/*	for(int i=0;i<64;i++)
	{
		LONGLONG hySingleBodyCondition = 1;
		hySingleBodyCondition <<= i;
		if(COMPARE_BODYCON_BIT(m_nCurrentBodyCondition,hySingleBodyCondition))
		{
			map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(hySingleBodyCondition);
			if(it != m_mapBodyCondition.end())
			{
				(it->second)->Tick(fElapsedTime);
			}
		}
	}
	map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(m_nCurrentBodyCondition);
	if(it != m_mapBodyCondition.end())
	{
		CBodyConditionInfo* pBody = it->second;
		pBody->Tick(fElapsedTime);
	}
*/	return TRUE;
}

void CCharacterInfo::Render()
{
	vector<LONGLONG>::iterator itCurrent = m_vecCurrentBodyCondition.begin();
	while(itCurrent != m_vecCurrentBodyCondition.end())
	{
		LONGLONG hySingleBodyCondition = (*itCurrent);
		if(COMPARE_BODYCON_BIT(m_nCurrentBodyCondition,hySingleBodyCondition))
		{
			map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(hySingleBodyCondition);
			if(it != m_mapBodyCondition.end())
			{
				(it->second)->Render();
			}
		}
		itCurrent++;
	}
/*	for(int i=0;i<64;i++)
	{
		LONGLONG hySingleBodyCondition = 1;
		hySingleBodyCondition <<= i;
		if(COMPARE_BODYCON_BIT(m_nCurrentBodyCondition,hySingleBodyCondition))
		{
			map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(hySingleBodyCondition);
			if(it != m_mapBodyCondition.end())
			{
				(it->second)->Render();
			}
		}
	}
	map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(m_nCurrentBodyCondition);
	if(it != m_mapBodyCondition.end())
	{
		CBodyConditionInfo* pBody = it->second;
		pBody->Render();
	}
*/
}

// bodycondition이 중간에 바뀌는 경우 : 모든 이펙트를 렌더한다. -->If changes in the middle, all effects are rendered
void CCharacterInfo::ChangeBodyCondition(LONGLONG hyBody)
{
	LONGLONG hyNewBodyCondition = ~m_nCurrentBodyCondition & hyBody;
	LONGLONG hyDeleteBodyCondition = m_nCurrentBodyCondition & ~hyBody;
//	m_nCurrentBodyCondition = hyBody;
	LONGLONG hyBodyCondition = hyBody;
	if(hyDeleteBodyCondition != 0 )
	{
		for(int i=0;i<64;i++)
		{
			LONGLONG hySingleBodyCondition = 1;
			hySingleBodyCondition <<= i;
			if(COMPARE_BODYCON_BIT(hyDeleteBodyCondition,hySingleBodyCondition))
			{
				map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(hySingleBodyCondition);
				if(it == m_mapBodyCondition.end())
				{
	//				hyBodyCondition = ~hySingleBodyCondition;
					continue;
				}
				if(!IsUpkeepBodyCondition(hySingleBodyCondition))// 지속형이 아닐때 -->Continuous-duty type
				{
					hyBodyCondition |= hySingleBodyCondition;
	//				if((it->second)->IsUsing())
	//				{
						continue;// 계속 플레이한다. -->Should continue to play
	//				}
				} 
				else if((it->second)->IsUsing())
				{
					if(!(it->second)->EffectStop())
					{
						hyBodyCondition |= hySingleBodyCondition;
						continue;// 사용중이면 계속 플레이한다. -->If not in use, continues to play
					}
				}

				vector<LONGLONG>::iterator itCurrent = m_vecCurrentBodyCondition.begin();
				while(itCurrent != m_vecCurrentBodyCondition.end())
				{
					if((*itCurrent) == hySingleBodyCondition)
					{
	//					sprintf(message,"[%X] erase[%016I64X]\n",this,(*itCurrent));
	//					DbgOut(message);
						m_vecCurrentBodyCondition.erase(itCurrent);// 2003.6.24. by dhkwon
						(it->second)->InvalidateDeviceObjects();
						(it->second)->DeleteDeviceObjects();
						break;
					}
					itCurrent++;
				}
	//			map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(hySingleBodyCondition);
	/*			if(it != m_mapBodyCondition.end())
				{
					(it->second)->InvalidateDeviceObjects();
					(it->second)->DeleteDeviceObjects();
	//				sprintf(message,"Delete[%016I64X]\n",hySingleBodyCondition);
	//				DbgOut(message);
				}
	*/		}
		}
	}
	if(hyNewBodyCondition != 0)
	{
		for(int i=0;i<64;i++)
		{
			LONGLONG hySingleBodyCondition = 1;
			hySingleBodyCondition <<= i;
			if(COMPARE_BODYCON_BIT(hyNewBodyCondition,hySingleBodyCondition))
			{
#ifdef _DEBUG
				vector<LONGLONG>::iterator itCurrent = m_vecCurrentBodyCondition.begin();
				while(itCurrent != m_vecCurrentBodyCondition.end())
				{
					if(*itCurrent == hySingleBodyCondition)
					{
//						DBGOUT("같은 바디컨디션 세팅:%d\n", hySingleBodyCondition); -->Body condition, such as setting
//						continue;
					}
					itCurrent++;
				}
#endif
				m_vecCurrentBodyCondition.push_back(hySingleBodyCondition);
				map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(hySingleBodyCondition);
				if(it != m_mapBodyCondition.end())
				{
					(it->second)->InitDeviceObjects();
					(it->second)->RestoreDeviceObjects();
	//				sprintf(message,"new[%016I64X]\n",hySingleBodyCondition);
	//				DbgOut(message);
				}
#ifdef _DEBUG
				else
				{
//					DbgOut("존재하지 않는 바디컨디션:%d\n", hySingleBodyCondition); -->Body condition does not exist
				}
#endif
			}
		}
	}
//	sprintf(message,"DeleteBody[%016I64X]\n",hyDeleteBodyCondition);
//	DbgOut(message);
	m_nCurrentBodyCondition = hyBodyCondition;
}


// bodycondition을 처음 받아오는 경우 : 지속형의 이펙트만 보여준다. In support of this type show only update
void CCharacterInfo::SetBodyCondition(LONGLONG hyBody)
{
	m_nCurrentBodyCondition = hyBody;
	m_vecCurrentBodyCondition.clear();
	for(int i=0;i<64;i++)
	{
		LONGLONG hySingleBodyCondition = 1;
		hySingleBodyCondition <<= i;
		if(COMPARE_BODYCON_BIT(m_nCurrentBodyCondition,hySingleBodyCondition))
		{
			m_vecCurrentBodyCondition.push_back(hySingleBodyCondition);
			map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(hySingleBodyCondition);
			if(it != m_mapBodyCondition.end() && IsUpkeepBodyCondition(hySingleBodyCondition))
			{
				(it->second)->InitDeviceObjects();
				(it->second)->RestoreDeviceObjects();
			}
		}
	}
}

BOOL CCharacterInfo::IsUpkeepBodyCondition(LONGLONG hyBody)
{
	if( hyBody == BODYCON_EXPLOSION_MASK)// 폭발
		return FALSE;
	if( hyBody == BODYCON_HIT_MASK)// 타격
		return FALSE;
	if( hyBody == BODYCON_FIRE_MASK)//발사
		return FALSE;
	return TRUE;
}

HRESULT CCharacterInfo::InitDeviceObjects()
{
	vector<LONGLONG>::iterator itCurrent = m_vecCurrentBodyCondition.begin();
	while(itCurrent != m_vecCurrentBodyCondition.end())
	{
		LONGLONG hySingleBodyCondition = (*itCurrent);
		if(COMPARE_BODYCON_BIT(m_nCurrentBodyCondition,hySingleBodyCondition))
		{
			map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(hySingleBodyCondition);
			if(it != m_mapBodyCondition.end() && IsUpkeepBodyCondition(hySingleBodyCondition))
			{
				(it->second)->InitDeviceObjects();
			}
		}
		itCurrent++;
	}
/*	for(int i=0;i<64;i++)
	{
		LONGLONG hySingleBodyCondition = 1;
		hySingleBodyCondition <<= i;
		if(COMPARE_BODYCON_BIT(m_nCurrentBodyCondition,hySingleBodyCondition))
		{
			map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(hySingleBodyCondition);
			if(it != m_mapBodyCondition.end() && IsUpkeepBodyCondition(hySingleBodyCondition))
			{
				(it->second)->InitDeviceObjects();
			}
		}
	}
	map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(m_nCurrentBodyCondition);
	if(it != m_mapBodyCondition.end())
	{
		CBodyConditionInfo* pBody = it->second;
		pBody->InitDeviceObjects();
	}
*/	return S_OK;
}

HRESULT CCharacterInfo::RestoreDeviceObjects()
{
	vector<LONGLONG>::iterator itCurrent = m_vecCurrentBodyCondition.begin();
	while(itCurrent != m_vecCurrentBodyCondition.end())
	{
		LONGLONG hySingleBodyCondition = (*itCurrent);
		if(COMPARE_BODYCON_BIT(m_nCurrentBodyCondition,hySingleBodyCondition))
		{
			map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(hySingleBodyCondition);
			if(it != m_mapBodyCondition.end() && IsUpkeepBodyCondition(hySingleBodyCondition))
			{
				(it->second)->RestoreDeviceObjects();
			}
		}
		itCurrent++;
	}
/*	for(int i=0;i<64;i++)
	{
		LONGLONG hySingleBodyCondition = 1;
		hySingleBodyCondition <<= i;
		if(COMPARE_BODYCON_BIT(m_nCurrentBodyCondition,hySingleBodyCondition))
		{
			map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(hySingleBodyCondition);
			if(it != m_mapBodyCondition.end() && IsUpkeepBodyCondition(hySingleBodyCondition))
			{
				(it->second)->RestoreDeviceObjects();
			}
		}
	}
	map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(m_nCurrentBodyCondition);
	if(it != m_mapBodyCondition.end())
	{
		CBodyConditionInfo* pBody = it->second;
		pBody->RestoreDeviceObjects();
	}
*/	return S_OK;
}

HRESULT CCharacterInfo::InvalidateDeviceObjects()
{
	vector<LONGLONG>::iterator itCurrent = m_vecCurrentBodyCondition.begin();
	while(itCurrent != m_vecCurrentBodyCondition.end())
	{
		LONGLONG hySingleBodyCondition = (*itCurrent);
		if(COMPARE_BODYCON_BIT(m_nCurrentBodyCondition,hySingleBodyCondition))
		{
			map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(hySingleBodyCondition);
			if(it != m_mapBodyCondition.end())
			{
				(it->second)->InvalidateDeviceObjects();
			}
		}
		itCurrent++;
	}
/*	for(int i=0;i<64;i++)
	{
		LONGLONG hySingleBodyCondition = 1;
		hySingleBodyCondition <<= i;
		if(COMPARE_BODYCON_BIT(m_nCurrentBodyCondition,hySingleBodyCondition))
		{
			map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(hySingleBodyCondition);
			if(it != m_mapBodyCondition.end() && IsUpkeepBodyCondition(hySingleBodyCondition))
			{
				(it->second)->InvalidateDeviceObjects();
			}
		}
	}
	map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(m_nCurrentBodyCondition);
	if(it != m_mapBodyCondition.end())
	{
		CBodyConditionInfo* pBody = it->second;
		pBody->InvalidateDeviceObjects();
	}
*/	return S_OK;
}

HRESULT CCharacterInfo::DeleteDeviceObjects()
{
	vector<LONGLONG>::iterator itCurrent = m_vecCurrentBodyCondition.begin();
	while(itCurrent != m_vecCurrentBodyCondition.end())
	{
		LONGLONG hySingleBodyCondition = (*itCurrent);
		if(COMPARE_BODYCON_BIT(m_nCurrentBodyCondition,hySingleBodyCondition))
		{
			map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(hySingleBodyCondition);
			if(it != m_mapBodyCondition.end())
			{
				(it->second)->DeleteDeviceObjects();
			}
		}
		itCurrent++;
	}
/*	for(int i=0;i<64;i++)
	{
		LONGLONG hySingleBodyCondition = 1;
		hySingleBodyCondition <<= i;
		if(COMPARE_BODYCON_BIT(m_nCurrentBodyCondition,hySingleBodyCondition))
		{
			map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(hySingleBodyCondition);
			if(it != m_mapBodyCondition.end() && !IsUpkeepBodyCondition(hySingleBodyCondition))
			{
				(it->second)->DeleteDeviceObjects();
			}
		}
	}
	map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(m_nCurrentBodyCondition);
	if(it != m_mapBodyCondition.end())
	{
		CBodyConditionInfo* pBody = it->second;
		pBody->DeleteDeviceObjects();
	}
*/	return S_OK;
}

BOOL CCharacterInfo::Load(char* strName)
{
	CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
	CMapEditorView* pView = (CMapEditorView*)pFrame->GetActiveView();

	DataHeader* pDataHeader = pView->m_pEffectRender->FindObjectInfo(strName);
	if(!pDataHeader)
	{
		return FALSE;
	}

	char* pData = pDataHeader->m_pData;
	memcpy((void*)this, pData, sizeof(CharacterData));
	pData += sizeof(CharacterData);
	// 바디 컨디션 정보
	for(int i=0;i<m_nBodyConditionNumber;i++)
	{
		CBodyConditionInfo* pBody = new CBodyConditionInfo;
		memcpy((void*)pBody, pData, sizeof(BodyConditionData));
		pData += sizeof(BodyConditionData);
		pBody->m_pParent = this;
		m_mapBodyCondition[pBody->m_nBodyCondition] = pBody;
		// 이펙트 정보
		for(int j=0;j<pBody->m_nEffectNumber;j++)
		{
			CEffectInfo* pEffect = new CEffectInfo;
			memcpy((void*)pEffect, pData, sizeof(EffectData));
			pData += sizeof(EffectData);
			pEffect->m_pParent = pBody;
			pBody->m_vecEffect.push_back(pEffect);
		}
	}
	return TRUE;

}
BOOL CCharacterInfo::IsUsing()
{
	vector<LONGLONG>::iterator it = m_vecCurrentBodyCondition.begin();
	while(it != m_vecCurrentBodyCondition.end())
	{
		if(IsUsing((*it)))
		{
			return TRUE;
		}
		it++;
	}
	return FALSE;

}
BOOL CCharacterInfo::IsUsing(LONGLONG hyBody)
{
	map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(hyBody);

	if(it != m_mapBodyCondition.end())
	{
		if((it->second)->IsUsing())
			return TRUE;
	}
	return FALSE;

}

void CCharacterInfo::SetSingleBodyConditionMatrix(LONGLONG hyBody, D3DXMATRIX m)
{
	map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.find(hyBody);

	if(it != m_mapBodyCondition.end())
	{
		(it->second)->m_mMatrix = m;
	}
	

}

void CCharacterInfo::SetAllBodyConditionMatrix(D3DXMATRIX m)
{
	map<LONGLONG,CBodyConditionInfo*>::iterator it = m_mapBodyCondition.begin();

	while(it != m_mapBodyCondition.end())
	{
		(it->second)->m_mMatrix = m;
		it++;
	}
	

}
