#include "stdafx.h"
#include "ItemMixManager.h"
#include "Protocol.h"
#include "MakeSkill_Common.h"
#include "Application.h"

#include "GameUIManager.h"
#include "ItemMixWindow.h"
#include "ObjectManager.h"
#include "Hero.h"

#include "ChatManager.h"
#include "GameResourceManager.h"
#include "UIMsgboxEvent.h"
#include "MakeSkillScript.h"
#include "ItemManager.h"

cItemMixManager* cItemMixManager::mpSingleton = 0;

cItemMixManager::cItemMixManager()
: mNetLock( false )
, mLockTry( eLOCK_ITEMMIXNONE )
, mContinueCount(0)
, mContinueDescCount(0)
, mContinueSkill(0)
, mContinueRecipe(0)
{
	mpSingleton = this;
}

cItemMixManager::~cItemMixManager()
{
	DeleteKeepSkill1();
	DeleteKeepSkill2();
}

void cItemMixManager::Close()
{
	/// UI 클리어
	cItemMixWindow* win = GAMEUI->GetItemMixWindow();
	if( win )
		win->Clear();

	DeleteKeepSkill1();
	DeleteKeepSkill2();

	mContinueDescCount = 0;
	mContinueCount = 0;
	mContinueSkill = 0;
	mContinueRecipe = 0;
	mNetLock = false;
	mLockTry = eLOCK_ITEMMIXNONE;
}

bool cItemMixManager::AddKeepSkill1( unsigned long recipeIdx, unsigned long restTime )
{
	sKeepRecipe* info = new sKeepRecipe;
	info->mStartTime = THEAPP->GetWorldAccumTime();
	info->mRestTime = restTime;

	if( mKeepSkillMap1.Insert( recipeIdx, info ) == false )
	{
		assert(0);
		return false;
	}
	return true;
}

bool cItemMixManager::AddKeepSkill2( unsigned long recipeIdx, unsigned long restTime )
{
	sKeepRecipe* info = new sKeepRecipe;
	info->mStartTime = THEAPP->GetWorldAccumTime();
	info->mRestTime = restTime;

	if( mKeepSkillMap2.Insert( recipeIdx, info ) == false )
	{
		assert(0);
		return false;
	}
	return true;
}

void cItemMixManager::DeleteKeepSkill1()
{
	cKeepRecipeMap::cIterator i = mKeepSkillMap1.Begin();
	cKeepRecipeMap::cIterator end = mKeepSkillMap1.End();
	for( ; i != end; ++i )
	{
		sKeepRecipe* info = (sKeepRecipe*)(i->mSecond);
		SAFE_DELETE( info );
	}
	mKeepSkillMap1.Clear();
}

void cItemMixManager::DeleteKeepSkill2()
{
	cKeepRecipeMap::cIterator i = mKeepSkillMap2.Begin();
	cKeepRecipeMap::cIterator end = mKeepSkillMap2.End();
	for( ; i != end; ++i )
	{
		sKeepRecipe* info = (sKeepRecipe*)(i->mSecond);
		SAFE_DELETE( info );
	}
	mKeepSkillMap2.Clear();
}

sKeepRecipe* cItemMixManager::GetKeepMixSkill1( unsigned long recipeIdx )
{
	return (sKeepRecipe*)mKeepSkillMap1.GetAt( recipeIdx );
}

sKeepRecipe* cItemMixManager::GetKeepMixSkill2( unsigned long recipeIdx )
{
	return (sKeepRecipe*)mKeepSkillMap2.GetAt( recipeIdx );
}

unsigned long cItemMixManager::GetKeepSkillText( unsigned char index )
{
	unsigned long textIdx = 0;

	switch( index )
	{
	case eMAKESKILL_COOK:		textIdx = 130; break;
	case eMAKESKILL_PAINTCARD:	textIdx = 131; break;
	default: 
		assert(0);			
		return 0;
	}
	return textIdx;
}

unsigned long cItemMixManager::GetTypeText( int index, unsigned long type )
{
	unsigned long textIdx = 0;
	switch( index )
	{
	case eMAKESKILL_COOK:
		{
			switch( type )
			{
			case 1:	textIdx = 2001001; break; /// 끓이기
			case 2: textIdx = 2001002; break; /// 굽기
			case 3: textIdx = 2001003; break; /// 혼합
			case 4: textIdx = 2001004; break; /// 볶기
			case 5: textIdx = 2001005; break; /// 튀기기
			default:
				assert(0);
				break;
			}
		}
		break;
	case eMAKESKILL_PAINTCARD:
		{
			switch( type )
			{
			case 1: textIdx = 2001011; break; /// 착용 카드 그리기
			case 2: textIdx = 2001012; break; /// 장착 카드 그리기
			case 3: textIdx = 2001013; break; /// 타로 카드 그리기
			case 4: textIdx = 2001014; break; /// 강화 카드 그리기
			case 5: textIdx = 2001015; break; /// 변신 카드 그리기
			default:
				assert(0);
				break;
			}
		}
		break;
	}
	return textIdx;
}


bool cItemMixManager::ItemMixUseMakeSkill( unsigned short slot, unsigned long makeSkillIdx )
{
	/// HERO의 전문스킬 슬롯 검사
	sHeroInfo* info = HERO->GetHeroInfo();
	if( info )
	{
		/// 빈 전문기술 공간이 있는지 검사
		if( info->mMakeSkill1 > 0 && info->mMakeSkill2 > 0 ) 
		{
			UIMAN->CreateModal(	eStage_Game,
				eMBEVENT_NONE, 
				GAMERESOURCEMAN->GetGameText( 2802 ),	
				GAMERESOURCEMAN->GetGameText( 301 ),	 // 에러
				eSKIN_OK
				);
			return false;
		}

		/// 동일한 전문기술 존재하는지 검사
		if( info->mMakeSkill1 == makeSkillIdx || info->mMakeSkill2 == makeSkillIdx )
		{
			UIMAN->CreateModal(	eStage_Game,
				eMBEVENT_NONE, 
				GAMERESOURCEMAN->GetGameText( 2803 ),	
				GAMERESOURCEMAN->GetGameText( 301 ),	 // 에러
				eSKIN_OK
				);
			return false;
		}

		/// 조합기술 아이템
		MSG_REQ_MAKESKILL_ADD msg;
		::memset( &msg, 0, sizeof( msg ) );

		msg.Category = NM_MAKESKILL;
		msg.Protocol = NM_MAKESKILL_ADD_REQ;
		msg.mSlotNum = (unsigned short)slot;
		NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
		return true;
	}
	return false;
}

bool cItemMixManager::ItemMixUseRecipe( unsigned short slot, unsigned long recipeIdx )
{
	sHeroInfo* info = HERO->GetHeroInfo();
	if( info )
	{
		sMakeSkillScript* script = MAKESKILLSCRIPT->GetMakeSkill( recipeIdx );
		if( script )
		{
			/// 레시피랑 관련된 전문스킬 익혔는지 검사
			if( !(info->mMakeSkill1 == script->mMakeSkill || info->mMakeSkill2 == script->mMakeSkill) )
			{
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2819 ) );
				return false;
			}
		}
		else 
		{
			assert(0);
			return false;
		}
	}
	else
	{
		assert(0);
		return false;
	}

	/// 동일한 레시피 있는지 검사
	if( GetKeepMixSkill1( recipeIdx ) || GetKeepMixSkill2( recipeIdx ) )
	{
		UIMAN->CreateModal(	eStage_Game,
			eMBEVENT_NONE, 
			GAMERESOURCEMAN->GetGameText( 2804 ),	
			GAMERESOURCEMAN->GetGameText( 301 ),	 // 에러
			eSKIN_OK
			);
		return false;
	}

	/// 레시피 아이템
	MSG_REQ_MAKESKILL_RECIPE_ADD msg;
	::memset( &msg, 0, sizeof( msg ) );

	msg.Category = NM_MAKESKILL;
	msg.Protocol = NM_MAKESKILL_RECIPE_ADD_REQ;
	msg.mSlotNum = (unsigned short)slot;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
	return true;
}

bool cItemMixManager::ItemMixUseRecipeGroup( unsigned short slot, unsigned long recipeGroupIdx )
{
	sHeroInfo* info = HERO->GetHeroInfo();
	if( info == NULL)
	{
		assert(NULL);
		return false;
	}

	tArray<void*>* pRecipeAry = MAKESKILLSCRIPT->GetRecipeGroup( recipeGroupIdx );
	if( pRecipeAry == NULL )
	{
		assert(NULL);
		return false;
	}

	bool isAddRecipe = false;
	bool isKeepMakeSkill = false;
	for( unsigned long i = 0 ; i < pRecipeAry->GetSize() ; ++i )
	{
		sRecipeGroupInfo* pGroupInfo = (sRecipeGroupInfo*)(*pRecipeAry)[i];
		if( pGroupInfo == NULL )
		{
			assert(NULL);
			return false;
		}


		sMakeSkillScript* script = MAKESKILLSCRIPT->GetMakeSkill( pGroupInfo->mRecipeIdx );
		if( script == NULL )
		{
			assert(NULL);
			return false;
		}

		/// 레시피랑 관련된 전문스킬 익혔는지 검사
		if( !(info->mMakeSkill1 == script->mMakeSkill || info->mMakeSkill2 == script->mMakeSkill) )
			continue;

		isKeepMakeSkill = true;

		/// 새로 배워야 할 레시피인지 검사
		if( !(GetKeepMixSkill1( pGroupInfo->mRecipeIdx ) || GetKeepMixSkill2( pGroupInfo->mRecipeIdx )) )
			isAddRecipe = true;
	}

	if( isKeepMakeSkill == false )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2819 ) );
		return false;
	}

	if( isAddRecipe == false )
	{
		UIMAN->CreateModal(	eStage_Game,
			eMBEVENT_NONE, 
			GAMERESOURCEMAN->GetGameText( 2804 ),	
			GAMERESOURCEMAN->GetGameText( 301 ),	 // 에러
			eSKIN_OK
			);
		return false;
	}

	/// 레시피 아이템
	MSG_REQ_MAKESKILL_RECIPE_ADD msg;
	::memset( &msg, 0, sizeof( msg ) );

	msg.Category = NM_MAKESKILL;
	msg.Protocol = NM_MAKESKILL_RECIPE_ADD_REQ;
	msg.mSlotNum = (unsigned short)slot;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
	return true;
}

void cItemMixManager::ItemMixStart( unsigned char index, unsigned long recipeIdx, int count )
{
	if( IsNetLock() )
		return;

	if( index == 0 || recipeIdx == 0 )
		return;

	if( count == 0 )
		return;

	/// 연속진행 걸려있으면 리턴
	if( mContinueDescCount > mContinueCount )
		return;

	sKeepRecipe* recipeCool = 0;
	sHeroInfo* info = HERO->GetHeroInfo();
	if( info )
	{
		if( info->mMakeSkill1 == index )
		{
            recipeCool = GetKeepMixSkill1( recipeIdx );
		}
		else if( info->mMakeSkill2 == index )
		{
			recipeCool = GetKeepMixSkill2( recipeIdx );
		}
		else
		{
			assert(0);
		}
	}

	/// 조합 대기 시간 검사	
	if( recipeCool && recipeCool->mRestTime > 0 )
	{
		unsigned long elapsedTime = THEAPP->GetWorldAccumTime() - recipeCool->mStartTime;
		if( recipeCool->mRestTime > elapsedTime )
		{
			CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2814 ) );
			return;
		}
	}

	/// 연속진행 갯수 저장
	mContinueDescCount = count;
	mContinueCount = 0;

	mContinueSkill = index;
	mContinueRecipe = recipeIdx;

	MSG_REQ_MAKESKILL_ITEMMIX_START msg;
	::memset( &msg, 0, sizeof( msg ) );

	msg.Category = NM_MAKESKILL;
	msg.Protocol = NM_MAKESKILL_ITEMMIX_START_REQ;
	msg.mMakeSkill = index;
	msg.mRecipeIdx = recipeIdx;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	/// 저장
	NetLock( eLOCK_ITEMMIXSTART );
}

void cItemMixManager::ItemMixContinue()
{
	if( mContinueDescCount > mContinueCount )
	{
		if( mContinueRecipe == 0 || mContinueSkill == 0 )
		{
			assert(0);
			return;
		}

		sKeepRecipe* recipeCool = 0;
		sHeroInfo* info = HERO->GetHeroInfo();
		if( info )
		{
			if( info->mMakeSkill1 == mContinueSkill )
			{
				recipeCool = GetKeepMixSkill1( mContinueRecipe );
			}
			else if( info->mMakeSkill2 == mContinueSkill )
			{
				recipeCool = GetKeepMixSkill2( mContinueRecipe );
			}
			else
			{
				assert(0);
			}
		}

		/// 조합 대기 시간 검사	
		if( recipeCool && recipeCool->mRestTime > 0 )
		{
			unsigned long elapsedTime = THEAPP->GetWorldAccumTime() - recipeCool->mStartTime;
			if( recipeCool->mRestTime > elapsedTime )
			{
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2814 ) );
				return;
			}
		}

		MSG_REQ_MAKESKILL_ITEMMIX_START msg;
		::memset( &msg, 0, sizeof( msg ) );

		msg.Category = NM_MAKESKILL;
		msg.Protocol = NM_MAKESKILL_ITEMMIX_START_REQ;
		msg.mMakeSkill = mContinueSkill;
		msg.mRecipeIdx = mContinueRecipe;
		NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

		NetLock( eLOCK_ITEMMIXSTART );
	}
}

void cItemMixManager::ItemMixDelete( unsigned char index )
{
	if( IsNetLock() )
		return;

	if( index == 0 )
		return;

	MSG_REQ_MAKESKILL_DELETE msg;
	::memset( &msg, 0, sizeof( msg ) );

	msg.Category = NM_MAKESKILL;
	msg.Protocol = NM_MAKESKILL_DEL_REQ;
	msg.mMakeSkill = index;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	NetLock( eLOCK_ITEMMIXDELETE );
}

/// 게이지가 끝까지 갔으므로 서버에 결과 요청
void cItemMixManager::ItemMixEndRequest()
{
	if( IsNetLock() )
		return;

	MSGROOT msg;
	::memset( &msg, 0, sizeof( msg ) );
	msg.Category = NM_MAKESKILL;
	msg.Protocol = NM_MAKESKILL_ITEMMIX_END_REQ;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	NetLock( eLOCK_ITEMMIXEND );
}

void cItemMixManager::ItemMixOpen()
{
	if( IsNetLock() )
		return;

	cItemMixWindow* win = GAMEUI->GetItemMixWindow();
	if( !win )
	{
		assert(0);
		return;
	}

	if( win->IsVisible() )
		return;

	/// 보유한 보조기술이 없을시
	sHeroInfo* info = HERO->GetHeroInfo();
	if( info && (info->mMakeSkill1 == 0 && info->mMakeSkill2 == 0) )
	{
		UIMAN->CreateModal(	eStage_Game,
			eMBEVENT_NONE, 
			GAMERESOURCEMAN->GetGameText( 2821 ),	
			GAMERESOURCEMAN->GetGameText( 301 ),	 // 에러
			eSKIN_OK
			);
		return;
	}

	/// 
	win->ShowTop();
}

void cItemMixManager::ItemMixCancel( bool hide )
{
	/// [조합중]일때는 서버에 요청
	if( HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		if( IsNetLock() )
			return;

		MSGROOT msg;
		::memset( &msg, 0, sizeof( msg ) );
		msg.Category = NM_MAKESKILL;
		msg.Protocol = NM_MAKESKILL_ITEMMIX_CANCEL_REQ;
		NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

		HERO->ClearItemMIxEffect();
		HERO->SetStopFlag( eSTOP_NONE );
		HERO->SetState( eOBJECT_STATE_IDLE );
	}

	mContinueDescCount = 0;
	mContinueCount = 0;
	mContinueRecipe = 0;
	mContinueSkill = 0;
	mNetLock = false;

	cItemMixWindow* win = GAMEUI->GetItemMixWindow();
	if( win )
	{
		win->StopGauge();

		if( hide == true )
			win->Hide();
	}
}


void cItemMixManager::NetworkMsgParserLoad( char* msg )
{
	MSGROOT* tempMsg = (MSGROOT*)msg;

	switch( tempMsg->Protocol )
	{
	case NM_MAKESKILL_LIST1_RES:
		{
			/// 요리 레시피 목록
			MSG_RES_MAKESKILL_LIST* pmsg = (MSG_RES_MAKESKILL_LIST*)msg;
			
			sRecipeInfo* recipeInfo = pmsg->mRecipeInfo;
			for( int i = 0; i < pmsg->mCount; ++i, ++recipeInfo )
			{
				AddKeepSkill1( recipeInfo->mRecipeIdx, recipeInfo->mCoolTime );
			}
		}
		break;
	case NM_MAKESKILL_LIST2_RES:
		{
			/// 카드그리기 레시피 목록
			MSG_RES_MAKESKILL_LIST* pmsg = (MSG_RES_MAKESKILL_LIST*)msg;

			sRecipeInfo* recipeInfo = pmsg->mRecipeInfo;
			for( int i = 0; i < pmsg->mCount; ++i, ++recipeInfo )
			{
				AddKeepSkill2( recipeInfo->mRecipeIdx, recipeInfo->mCoolTime );
			}
		}
		break;
	}
}

void cItemMixManager::NetworkMsgParserGame( char* msg )
{
	MSGROOT* tempMsg = (MSGROOT*)msg;

	cStringT str;
	switch( tempMsg->Protocol )
	{
	case NM_MAKESKILL_ADD_RES:
		{
			/// 전문 직업 습득
			MSG_RES_MAKESKILL_ADD* pmsg = (MSG_RES_MAKESKILL_ADD*)msg;

			switch( pmsg->ErrorCode )
			{
			case ERROR_MAKESKILL_SUCCESS:
				{
					/// HERO에 저장
					sHeroInfo* info = HERO->GetHeroInfo();
					if( info )
					{
						if( info->mMakeSkill1 == 0 )
						{
							HERO->SetMixSkillFirst( pmsg->mMakeSkill );
						}
						else if( info->mMakeSkill2 == 0 )
						{
							HERO->SetMixSkillSecond( pmsg->mMakeSkill );
						}
						else
						{
							assert(0);
						}
					}

					/// UI 에 추가
					cItemMixWindow* win = GAMEUI->GetItemMixWindow();
					if( win )
						win->InsertMakeSkill( pmsg->mMakeSkill );

					///
					ITEMMAN->DeleteMixInsertItem();

					unsigned long textIndex = GetKeepSkillText( pmsg->mMakeSkill );
					str.Format( GAMERESOURCEMAN->GetGameText( 2801 ), UIMAN->GetUIText( textIndex ) );
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, (LPCTSTR)str.Cstr() );
				}
				break;
			case ERROR_MAKESKILL_NOTHAVE:
			case ERROR_MAKESKILL_ALREADY:
			case ERROR_MAKESKILL_DBUSED:
			case ERROR_MAKESKILL_ITEM:
			case ERROR_MAKESKILL_STATE:
			case ERROR_MAKESKILL_NOTEMPTY:
			case ERROR_MAKESKILL_SCRIPT:
			case ERROR_MAKESKILL_DBERROR:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2806 ) );
				break;
			}

			ITEMMAN->UnlockItemTry( ITEM_TRY_MIXSKILL );
		}
		break;
	case NM_MAKESKILL_RECIPE_ADD_RES:
		{
			/// 레시피 습득
			MSG_RES_MAKESKILL_RECIPE_ADD* pmsg = (MSG_RES_MAKESKILL_RECIPE_ADD*)msg;

			if( pmsg->ErrorCode == ERROR_MAKESKILL_SUCCESS )
			{
				for( unsigned long i = 0 ; i < pmsg->mCount ; ++i )
				{
					sRecipeGroupInfo* pGroupInfo = &pmsg->mGroupInfo[i];
					sHeroInfo* info = HERO->GetHeroInfo();
					if( info )
					{
						if( info->mMakeSkill1 == pGroupInfo->mMakeSkill )
						{
							AddKeepSkill1( pGroupInfo->mRecipeIdx, 0 );
						}
						else if( info->mMakeSkill2 == pGroupInfo->mMakeSkill )
						{
							AddKeepSkill2( pGroupInfo->mRecipeIdx, 0 );
						}
						else
						{
							assert(0);
						}
					}

					/// UI 갱신
					cItemMixWindow* win = GAMEUI->GetItemMixWindow();
					if( win )
						win->InsertRecipe( pGroupInfo->mMakeSkill, pGroupInfo->mRecipeIdx );

					sMakeSkillScript* script = MAKESKILLSCRIPT->GetMakeSkill( pGroupInfo->mRecipeIdx );
					if( script )
					{
						unsigned long textIndex = GetTypeText( pGroupInfo->mMakeSkill, script->mType );
						str.Format( GAMERESOURCEMAN->GetGameText( 2805 ), GAMERESOURCEMAN->GetItemToolTipText( textIndex ), ITEMMAN->GetItemName( pGroupInfo->mRecipeIdx ) );
						CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, (LPCTSTR)str.Cstr() );
					}
				}

				///
				ITEMMAN->DeleteMixInsertItem();
			}
			else
			{
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2818 ) );
			}
			
			///
			ITEMMAN->UnlockItemTry( ITEM_TRY_MIXSKILL );
		}
		break;
	case NM_MAKESKILL_DEL_RES:
		{
			/// 전문스킬 삭제
			MSG_RES_MAKESKILL_DELETE* pmsg = (MSG_RES_MAKESKILL_DELETE*)msg;
		
			/// 성공
			if( pmsg->ErrorCode == 0 )
			{
				sHeroInfo* info = HERO->GetHeroInfo();
				if( info )
				{
					if( info->mMakeSkill1 == pmsg->mMakeSkill )
					{
						HERO->SetMixSkillFirst( 0 );
						DeleteKeepSkill1();
					}
					else if( info->mMakeSkill2 == pmsg->mMakeSkill )
					{
						HERO->SetMixSkillSecond( 0 );
						DeleteKeepSkill2();
					}
					else
					{
						assert(0);
					}
				}

				/// UI 갱신 
				cItemMixWindow* win = GAMEUI->GetItemMixWindow();
				if( win )
					win->DeleteMakeSkill( pmsg->mMakeSkill );

				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2807 ) );
			}
			else
			{
				/// 실패
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2808 ) );
			}

			NetUnLock( eLOCK_ITEMMIXDELETE );
		}
		break;
	case NM_MAKESKILL_ITEMMIX_START_RES:
		{
			MSG_ERROR* pmsg = (MSG_ERROR*)msg;

			if( pmsg->ErrorCode == ERROR_MAKESKILL_START_SUCCESS )
			{
				HERO->SetStopFlag( eSTOP_ITEMMIX );
				HERO->SetItemMixEffect();

				/// 
				sMakeSkillScript* script = MAKESKILLSCRIPT->GetMakeSkill( mContinueRecipe );
				if( script )
				{
					float speed = 100.0f / ((float)script->mMakeTime*0.001f);
					if( speed > 0.0f )
					{
						cItemMixWindow* win = GAMEUI->GetItemMixWindow();
						if( win )
							win->StartGauge( speed );
					}
				}
			}
			else
			{
				/// 조합시작 오류
				mContinueDescCount = 0;
				mContinueCount = 0;
				mContinueRecipe = 0;
				mContinueSkill = 0;

				cItemMixWindow* win = GAMEUI->GetItemMixWindow();
				if( win )
					win->StopGauge();

				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2813 ) );
			}

			NetUnLock( eLOCK_ITEMMIXSTART );
		}
		break;
	case NM_MAKESKILL_ITEMMIX_END_RES:
		{
			MSG_ERROR* pmsg = (MSG_ERROR*)msg;

			if( pmsg->ErrorCode == ERROR_MAKESKILL_END_SUCCESS )
			{
				HERO->ClearItemMIxEffect();
				HERO->SetStopFlag( eSTOP_NONE );
				HERO->SetState( eOBJECT_STATE_IDLE );

				/// 조합 종료
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2800 ) );

				/// 쿨타임 세팅
				sKeepRecipe* recipeCool = 0;
				sHeroInfo* info = HERO->GetHeroInfo();
				if( info )
				{
					if( info->mMakeSkill1 == mContinueSkill )
					{
						recipeCool = GetKeepMixSkill1( mContinueRecipe );
					}
					else if( info->mMakeSkill2 == mContinueSkill )
					{
						recipeCool = GetKeepMixSkill2( mContinueRecipe );
					}
					else
					{
						assert(0);
					}
				}

				/// 조합 대기 시간 세팅
				sMakeSkillScript* script = MAKESKILLSCRIPT->GetMakeSkill( mContinueRecipe );
				if( recipeCool && script )
				{
					recipeCool->mStartTime = THEAPP->GetWorldAccumTime();
					recipeCool->mRestTime = script->mNextMakeTime;
				}

				if( mContinueDescCount > mContinueCount )
					mContinueCount++;
				else
				{
					mContinueDescCount = 0;
					mContinueCount = 0;
					mContinueRecipe = 0;
					mContinueSkill = 0;
				}

				/// 조합종료시, 조합창 갱신
				cItemMixWindow* win = GAMEUI->GetItemMixWindow();
				if( win )
					win->UpdateMixCool();
			}
			else if( pmsg->ErrorCode == ERROR_MAKESKILL_END_STATE )
			{
				mContinueDescCount = 0;
				mContinueCount = 0;
				mContinueRecipe = 0;
				mContinueSkill = 0;

				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2816 ) );
			}
			else
			{
				mContinueDescCount = 0;
				mContinueCount = 0;
				mContinueRecipe = 0;
				mContinueSkill = 0;

				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2817 ) );
			}

			/// 완료갯수 올리기
			cItemMixWindow* win = GAMEUI->GetItemMixWindow();
			if( win )
			{
				win->SetCompleteCount( mContinueCount );
				win->StopGauge();
			}

			/// 새 락을 걸기위해 먼저 풀어준다
			NetUnLock( eLOCK_ITEMMIXEND );

			/// 재조합
			if( pmsg->ErrorCode == ERROR_MAKESKILL_END_SUCCESS && mContinueDescCount > mContinueCount )
			{
				ItemMixContinue();
			}
		}
		break;
	case NM_MAKESKILL_ITEMMIX_START_SYN:
		{
			/// 다른 유저
			MSG_SYN_MAKESKILL_ITEMMIX_START* pmsg = (MSG_SYN_MAKESKILL_ITEMMIX_START*)msg;

			cPlayer* p = OBJECTMAN->GetPlayer( pmsg->mCharacterIdx );
			if( p != NULL )
			{
				p->SetStopFlag( eSTOP_ITEMMIX );
				p->SetItemMixEffect();
			}
		}
		break;
	case NM_MAKESKILL_ITEMMIX_END_SYN:
		{
			/// 다른유저
			MSG_SYN_MAKESKILL_ITEMMIX_END* pmsg = (MSG_SYN_MAKESKILL_ITEMMIX_END*)msg;

			cPlayer* p = OBJECTMAN->GetPlayer( pmsg->mCharacterIdx );
			if( p != NULL )
			{
				p->ClearItemMIxEffect();
				p->SetStopFlag( eSTOP_NONE );
				p->SetState( eOBJECT_STATE_IDLE );
			}
		}
		break;
	case NM_MAKESKILL_ITEMMIX_CANCEL_SYN:
		{
			MSG_SYN_MAKESKILL_ITEMMIX_CANCEL* pmsg = (MSG_SYN_MAKESKILL_ITEMMIX_CANCEL*)msg;

			cPlayer* p = OBJECTMAN->GetPlayer( pmsg->mCharacterIdx );
			if( p != NULL )
			{
				p->ClearItemMIxEffect();
				p->SetStopFlag( eSTOP_NONE );
				p->SetState( eOBJECT_STATE_IDLE );
			}
		}
		break;
	}
}

void cItemMixManager::NetLock( int lockTry )
{
	switch( lockTry )
	{
	case eLOCK_ITEMMIXDELETE:
		{
			cItemMixWindow* win = GAMEUI->GetItemMixWindow();
			if( win )
				win->NetLock( eLOCK_ITEMMIXDELETE );
		}
		break;
	case eLOCK_ITEMMIXSTART:
		{
			cItemMixWindow* win = GAMEUI->GetItemMixWindow();
			if( win )
				win->NetLock( eLOCK_ITEMMIXSTART );
		}
		break;
	case eLOCK_ITEMMIXEND:
		{
			cItemMixWindow* win = GAMEUI->GetItemMixWindow();
			if( win )
				win->NetLock( eLOCK_ITEMMIXEND );
		}
		break;
	default:
		assert(0);
		return;
	}

	mNetLock = true;
	mLockTry = lockTry;
}

void cItemMixManager::NetUnLock( int lockTry )
{
	if( mNetLock == false )
		return;

	switch( lockTry )
	{
	case eLOCK_ITEMMIXDELETE:
		{
			if( mLockTry == lockTry )
			{
				cItemMixWindow* win = GAMEUI->GetItemMixWindow();
				if( win )
					win->NetUnLock( eLOCK_ITEMMIXDELETE );
			}
			else
			{
				assert(0);
			}
		}
		break;
	case eLOCK_ITEMMIXSTART:
		{
			cItemMixWindow* win = GAMEUI->GetItemMixWindow();
			if( win )
				win->NetUnLock( eLOCK_ITEMMIXSTART );
		}
		break;
	case eLOCK_ITEMMIXEND:
		{
			cItemMixWindow* win = GAMEUI->GetItemMixWindow();
			if( win )
				win->NetUnLock( eLOCK_ITEMMIXEND );
		}
		break;
	default:
		assert(0);
		return;
	}

	mLockTry = eLOCK_ITEMMIXNONE;
	mNetLock = false;
}
