#include "StdAfx.h"
#include "MakeSkillScript.h"

#include "FileLoader.h"
#include "Tokenizer.h"

cMakeSkillScript* cMakeSkillScript::mpMakeSkillScript = NULL;


cMakeSkillScript::cMakeSkillScript(void)
{
	/// 싱글톤
	if( !mpMakeSkillScript )
	{
		mpMakeSkillScript = this;
	}

}

cMakeSkillScript::~cMakeSkillScript(void)
{
	cPHashMap::cIterator begin = mGroupMap.Begin();
	cPHashMap::cIterator end = mGroupMap.End();

	for( ; begin != end ; ++begin )
	{
		cPAry* pLongAry = (cPAry*)(*begin).mSecond;
		for( unsigned long i = 0 ; pLongAry->GetSize() > i ; ++i )
		{
			sRecipeGroupInfo* pInfo = (sRecipeGroupInfo*)(*pLongAry)[i];
			SAFE_DELETE( pInfo );
		}
		pLongAry->Clear();

		SAFE_DELETE( pLongAry );
	}
	mGroupMap.Clear();

	begin = mMakeSkillMap.Begin();
	end = mMakeSkillMap.End();
	for( ; begin != end ; ++begin )
	{
		sMakeSkillScript* pMake = (sMakeSkillScript*)(*begin).mSecond;
		cPAry* pAry = pMake->mpMaterial;
		if( pAry != NULL )
		{
			for( unsigned long i = 0 ; i < pAry->GetSize() ; ++i )
			{
				sMaterialScript* pMaterial = (sMaterialScript*)(*pAry)[i];
				SAFE_DELETE( pMaterial );
			}
		}
		SAFE_DELETE( pAry );
		SAFE_DELETE( pMake );
	}
	mMakeSkillMap.Clear();
}


bool cMakeSkillScript::Init()
{
	/// 스킬 스크립트 로드
	if( !MakeSkillScriptLoad() )
	{
		assert(NULL);
		return false;
	}

	return true;

}


bool cMakeSkillScript::MakeSkillScriptLoad()
{
	cFileLoader loader;
	cString pathName = "./script/resource/item_mixed.txt";

	if( loader.Open( pathName, true ) == false )
	{
		assert( 0 && "failed to load item_mixed.txt" );
		return false;
	}

	cTokenizer tokenizer( loader.GetBufferPtr(), loader.GetSize(), " \t\r\n", pathName.Cstr() );
	cString str;

	/// mix 확인
	if( tokenizer.GetNext( &str ) == false )
		return false;

	sMakeSkillScript* pMakeScript = NULL;
	sMaterialScript* pMaterialScript = NULL;
	cPAry* pGroupAry;

	while( tokenizer.IsEnd() == false )
	{
		if( str.CompareNoCase( "mix" ) != 0 )
			return true;

		pMakeScript = new sMakeSkillScript;

		/// 전문기술
		if( tokenizer.GetNext( &str ) == false )
			return false;
		pMakeScript->mMakeSkill = (unsigned char)str.ToInt();

		/// 레시피
		if( tokenizer.GetNext( &str ) == false )
			return false;
		pMakeScript->mRecipeIdx = str.ToInt();

		/// 분류타입
		if( tokenizer.GetNext( &str ) == false )
			return false;
		pMakeScript->mType = str.ToInt();

		/// 레시피그룹
		if( tokenizer.GetNext( &str ) == false )
			return false;
		pMakeScript->mGroupIdx = (unsigned char)str.ToInt();

		/// 습득 그룹을 기준으로 관련된 레시피 정보들을 기록해두는 참조hash map
		if( pMakeScript->mGroupIdx != 0 )
		{
			pGroupAry = (cPAry*)mGroupMap.GetAt( pMakeScript->mGroupIdx );
			if( pGroupAry == NULL )
			{
				pGroupAry = new cPAry;
				if( mGroupMap.Insert( pMakeScript->mGroupIdx, pGroupAry ) == false )
					return false;
			}

			sRecipeGroupInfo* pGroupInfo = new sRecipeGroupInfo;
			pGroupInfo->mRecipeIdx = pMakeScript->mRecipeIdx;
			pGroupInfo->mMakeSkill = pMakeScript->mMakeSkill;
			pGroupAry->PushBack( pGroupInfo );
		}

		for( int i = 0 ; i < MAKESKILL_MAKE_ITEM_CNT ; ++i )
		{
			/// 완성된 아이템
			if( tokenizer.GetNext( &str ) == false )
				return false;
			pMakeScript->mMakeItemIdx[i] = str.ToInt();

			/// 완성된 수량
			if( tokenizer.GetNext( &str ) == false )
				return false;
			pMakeScript->mMakeCnt[i] = (unsigned char)str.ToInt();

			/// 선택 확률(비율)
			if( tokenizer.GetNext( &str ) == false )
				return false;
			pMakeScript->mMakeRate[i] = (unsigned char)str.ToInt();
		}

		/// 조합시간
		if( tokenizer.GetNext( &str ) == false )
			return false;
		pMakeScript->mMakeTime = str.ToInt();

		/// 재조합시간
		if( tokenizer.GetNext( &str ) == false )
			return false;
		pMakeScript->mNextMakeTime = str.ToInt();

		if( pMakeScript->mpMaterial != NULL )
			return false;

		cPAry* pMaterialAry = new cPAry;
		pMakeScript->mpMaterial = pMaterialAry;

		bool materialTrue = true;
		while( materialTrue )
		{
			/// mix 확인
			if( tokenizer.GetNext( &str ) == false )
				break;

			if( str.CompareNoCase( "mix" ) == 0 )
				break;
			
			pMaterialScript = new sMaterialScript;

			/// 재료 아이템
			pMaterialScript->mItemIdx = str.ToInt();

			/// 보유수량
			if( tokenizer.GetNext( &str ) == false )
				return false;
			pMaterialScript->mItemCnt = (unsigned char)str.ToInt();

			pMaterialAry->PushBack( pMaterialScript );
		}
	    
		if( mMakeSkillMap.Insert( pMakeScript->mRecipeIdx, pMakeScript ) == false )
			return false;
	}

	return true;
}


sMakeSkillScript* cMakeSkillScript::GetMakeSkill( unsigned long recipeIdx )
{
	return (sMakeSkillScript*)mMakeSkillMap.GetAt( recipeIdx );
}


tArray<void*>* cMakeSkillScript::GetRecipeGroup( unsigned long groupIdx )
{
	return (cPAry*)mGroupMap.GetAt( groupIdx );
}