#include "stdafx.h"
#include "npc.h"

#include "GameResourceManager.h"
#include "SceneManager.h"
#include "NpcSceneNode.h"
#include "EffectSceneNode.h"

#include "NpcScript.h"

#include "Quest_Common.h"

#include "ObjectManager.h"
#include "hero.h"

cNpc::cNpc( unsigned char type )
: cBaseObject( type )
,mpNpcClassInfo(0)
{

	mQuestStatus = eNPCQUEST_NONE;
	mQuestEffect = 0;
	mEffectIdx = (unsigned long)-1;
}

cNpc::~cNpc()
{
	mpNpcClassInfo = 0;

	if( mEffectIdx != (unsigned long)-1 )
	{
		cEffectSceneNode* node = SCENEMAN->GetEffectSceneNode( mEffectIdx );
		if( node )
		{
			assert( node == mQuestEffect );
			node->Remove();
		}
		mQuestEffect = 0;
		mEffectIdx = (unsigned long)-1;
	}
}

bool cNpc::Create( unsigned long objId, unsigned long npcClassIdx, unsigned char questStatus, NiPoint3 sPos, NiMatrix3 sRot, float fScale )
{
	mpNpcClassInfo = NPCSCRIPT->GetNPCList( npcClassIdx );
	if( mpNpcClassInfo == 0 )
	{
		assert(0);
		return false;
	}

	mObjectId = objId;

	const char* strFile = GAMERESOURCEMAN->GetModelFileName( mpNpcClassInfo->mModelIndex );
	cNpcSceneNodeParam param;
	param.mpObject = this;
	param.mTranslate = sPos;
	param.mRotate = sRot;
	param.mScale = fScale;

	cString pathName;
	pathName.Format( "./Data/Npc/%s", strFile );
	param.mPathName = pathName;

	cNpcSceneNode* pSceneNode = SCENEMAN->CreateNPC( param );
	if( !pSceneNode )
	{
		assert(0);
		return false;
	}

	mpObjectSceneNode = pSceneNode;
	mpObjectSceneNode->SetTargetAnimation( NPC_ANI_IDLE1 );

	NiPoint3 sFoot = mpObjectSceneNode->GetObjectFoot();
	NiPoint3 sHead = mpObjectSceneNode->GetObjectHead();
	mStatureValue = (sHead.z - sFoot.z) / mpObjectSceneNode->GetWorldScale();

	mpObjectSceneNode->ShowNameGauge( false );
	mpObjectSceneNode->UpdateNameCardTextValue();

	SetQuestStatus( questStatus );

	return true;
}

void cNpc::Update( unsigned long deltaTime, unsigned long accumTime )
{
	if( mpObjectSceneNode == 0 ) return;

	Interpret( accumTime );

	deltaTime;
}

void cNpc::Interpret( unsigned long time )
{
	cActorManagerForPartition*	pActor = mpObjectSceneNode->GetActorManager();
	if( !pActor ) return;

	unsigned int id = mpObjectSceneNode->GetTargetAnimation();

	/// 현재 애니메이션 종료 시점 획득
	float endTime = pActor->GetNextEventTime( cActorManagerForPartition::TEXT_KEY_EVENT, id, "end" );
	if( endTime == NI_INFINITY )
		return;
	if( endTime == cActorManagerForPartition::INVALID_TIME )
	{
		endTime = mpObjectSceneNode->GetTargetAnimationScaleEndTime() * 0.001f;
	}

	float checkTime = (float)mpObjectSceneNode->GetScaleAccumTime() * 0.001f;
	if( endTime > 0 && endTime <= checkTime )
	{
		if( id != NPC_ANI_IDLE1 )
		{
			mpObjectSceneNode->SetTargetAnimation( NPC_ANI_IDLE1 );
		}
		else
		{
			/// random 하게 보조동작을 보여주는 모드..
			int i = ::rand()%1000;
			if(i > 50)
				mpObjectSceneNode->SetTargetAnimation( NPC_ANI_IDLE2 );
		}
	}
	else if( endTime == cActorManagerForPartition::INVALID_TIME )
	{
		/// INVALID_TIME에 대한 보정
		return;
	}
}

void cNpc::test()
{
	mpObjectSceneNode->SetTargetAnimation( NPC_ANI_ENDSPEECH );
}

void cNpc::SetQuestStatus( unsigned char status )
{
	if( mQuestStatus == status )
		return;

	if( status == eNPCQUEST_NONE )
	{
		if( mEffectIdx != (unsigned long)-1 )
		{
			cEffectSceneNode* node = SCENEMAN->GetEffectSceneNode( mEffectIdx );
			if( node )
			{
				assert( node == mQuestEffect );
				node->Remove();
			}
			mQuestEffect = 0;
			mEffectIdx = (unsigned long)-1;
		}
	}
	else
	{
		cString str;
		switch( status )
		{
		case eNPCQUEST_NEW:		/// 신규가능
			str = "./Data/Effect/Eff_NPC_Quest_01.nif";
			break;
		case eNPCQUEST_PLAYING:	/// 진행중
			str = "./Data/Effect/Eff_NPC_Quest_02.nif";
			break;		
		case eNPCQUEST_COMPLETE:/// 진행완료가능
		case eNPCQUEST_REWARD:	/// 보상가능
			str = "./Data/Effect/Eff_NPC_Quest_03.nif";
			break;
		default:
			assert(0);
			return;
		}

		if( mEffectIdx != (unsigned long)-1 )
		{
			cEffectSceneNode* node = SCENEMAN->GetEffectSceneNode( mEffectIdx );
			if( node )
			{
				assert( node == mQuestEffect );
				node->Remove();
			}
			mQuestEffect = 0;
			mEffectIdx = (unsigned long)-1;
		}

		NiTransform trans;
		trans.MakeIdentity();
		trans.m_Translate = NiPoint3( 0.0f, 0.0f, 55.0f );
		mQuestEffect = mpObjectSceneNode->LinkEffect( eLINK_HEAD, str.Cstr(), &trans, true, false );
		if( mQuestEffect )
			mEffectIdx = mQuestEffect->GetIndexByManger();
	}
	mQuestStatus = status;
}
