#include "stdafx.h"
#include "StageManager.h"
#include "IntroStage.h"
#include "LoginStage.h"
#include "ServerStage.h"

#include "SelectStage.h"
#include "MakeStage.h"
#include "LoadStage.h"
#include "MapChange.h"
#include "GameStage.h"

#include "SceneManager.h"
#include "ResourceManager.h"
#include "GameResourceManager.h"
#include "WorldManager.h"
#include "ObjectManager.h"
#include "SkillManager.h"
#include "DramaturgyManager.h"
#include "ShortcutManager.h"
#include "UIManager.h"
#include "ItemManager.h"
#include "TarotManager.h"
#include "FilterManager.h"
#include "Application.h"
#include "CoolTimeManager.h"
#include "QuickManager.h"
#include "PartyManager.h"
#include "CameraManager.h"
#include "QuestManager.h"
#include "TriggerManager.h"
#include "CheatManager.h"
#include "PVPManager.h"
#include "TitleManager.h"
#include "LightAgent.h"
#include "GuildManager.h"
#include "TipManager.h"
#include "ItemMixManager.h"

#include "InputSystem.h"
#include "SoundSystem.h"

#include "uicursor.h"

#ifdef _GMTOOL
#include "GMTool.h"
#endif


cStageManager* cStageManager::mpStageManager = NULL;

cStageManager::cStageManager()
{
	mpStageManager = this;

	for( int i = 0; i < eStage_Max; ++i )
		mpStage[i] = NULL;
	mCurStage = eStage_Intro;

    mUserIdx  = 0;
	mLoginIdx = 0;
	mChannelIdx = 0;
	mCurrentMapIdx = 0;

	///
	mpUIManager = NULL;
	mpWorldManager = NULL;
	mpObjectManager = NULL;
	mpGameResourceManager = NULL;
	mpSkillManager = NULL;
	mpDramaturgyManager = NULL;
	mpShortcutManager = NULL;
	mpItemManager = NULL;
	mpTarotManager = NULL;
	mpFilterManager = NULL;
	mpCoolManager = NULL;
	mpQuickManager = NULL;
	mpPartyManager = NULL;
	mpQuestManager = NULL;
	mpTriggerManager = NULL;
	mpCheatManager = NULL;
	mpPvpManager = NULL;
	mpTitleManager = NULL;
	mpGuildManager = NULL;
	mpTipManager = NULL;
	mpItemMixManager = NULL;
	mIOCPCLient = NULL;
}

cStageManager::~cStageManager()
{
	//Exit();
}

bool cStageManager::Init( HWND hWnd, unsigned int /*screenWidth*/, unsigned int /*screenHeight*/ )
{
//	XPG_SET( "Performance Test", 10 );

	/// 스테이지 생성전에 네트워크 및 각종 관리자들을 생성
	/// 네트워크 생성 및 초기화

	/// 070330 네트워크 클래스
	mIOCPCLient = new cIOCPClient( hWnd, WM_SOCKEVENTMSG2 );
	if ( !mIOCPCLient || !mIOCPCLient->Initialize( ) )
		return false;
//	XPG_DO( "cIOCPClient" );

	mpDramaturgyManager = new cDramaturgyManager;
	if( !mpDramaturgyManager )
	{
		SAFE_DELETE(mpDramaturgyManager);
		assert( 0 && "failed to init dramaturgy manager" );
		return false;
	}
//	XPG_DO( "cDramaturgyManager" );

	/// 필터관리자 생성 및 초기화
	mpFilterManager = new cFilterManager;
	if( mpFilterManager == 0 || mpFilterManager->Init() == false )
	{
		return false;
	}
//	XPG_DO( "cFilterManager" );

	mpUIManager = new cUIManager;
	if( !mpUIManager || !mpUIManager->InitSkin("./Script/Interface/List_SkinImage.txt") )
	{
		return false;
	}

	/// 게임 리소스 관리자 생성 및 초기화
	mpGameResourceManager = new cGameResourceManager;
	if( !mpGameResourceManager || !mpGameResourceManager->Init() )
	{
		return false;
	}

//	XPG_DO( "cGameResourceManager" );

	/// UI 관리자 생성 및 초기화
//	XPG_DO( "InitSkin" );

	if( mpUIManager->InitImageFont() == false )
	{
		return false;
	}
//	XPG_DO( "InitImageFont" );

//	if( mpUIManager->InitIcon() == false )
//	{
//		return false;
//	}

	if( mpUIManager->InitNpc() == false )
	{
		return false;
	}
//	XPG_DO( "InitNpc" );

	mpCoolManager = new cCoolTimeManager;
	if( mpCoolManager == 0 || mpCoolManager->Init() == false )
	{
		return false;
	}
//	XPG_DO( "cCoolTimeManager" );

	/// 아이템 관리자 생성 및 초기화
	mpItemManager = new cItemManager;
	if( mpItemManager == 0 )
	{
		return false;
	}
//	XPG_DO( "cItemManager" );

	/// 퀵슬롯 관리자 생성 및 초기화 
	mpQuickManager = new cQuickManager;
	if( mpQuickManager == 0 )
	{
		return false;
	}
//	XPG_DO( "cQuickManager" );

	/// 타롯 관리자 생성 및 초기화 
	mpTarotManager = new cTarotManager;
	if( mpTarotManager == 0 || mpTarotManager->Init() == false )
	{
		return false;
	}
//	XPG_DO( "cTarotManager" );

	/// 070201 웅주, 단축키 관리자 생성
	mpShortcutManager = new cShortcutManager;
	if( !mpShortcutManager )
	{
		return false;
	}
//	XPG_DO( "cShortcutManager" );

	/// 파티관리자 생성 및 초기화
	mpPartyManager = new cPartyManager;
	if( mpPartyManager == 0 || mpPartyManager->Init() == false )
	{
		return false;
	}
//	XPG_DO( "cPartyManager" );

	mpTriggerManager = new cTriggerManager;
	if( mpTriggerManager == 0 || mpTriggerManager->Init() == false )
	{
		return false;
	}
//	XPG_DO( "cTriggerManager" );

	mpQuestManager = new cQuestManager;
	if( mpQuestManager == 0 || mpQuestManager->Init() == false )
	{
		return false;
	}
//	XPG_DO( "cQuestManager" );

	/// 월드 관리자 생성 및 초기화
	mpWorldManager = new cWorldManager;
	if( !mpWorldManager )//|| !mpWorldManager->Init() )
	{
		return false;
	}
//	XPG_DO( "cWorldManager" );

	/// 오브젝트 관리자 생성 및 초기화
	mpObjectManager = new cObjectManager;
	if( !mpObjectManager || !mpObjectManager->Init() )
	{
		return false;
	}
//	XPG_DO( "cObjectManager" );

	/// 스킬 관리자를 생성 및 초기화
	mpSkillManager = new cSkillManager;
	if( !mpSkillManager || !mpSkillManager->Init() )
	{
		return false;
	}
//	XPG_DO( "cSkillManager" );

	/// 치트 관리자를 생성
	mpCheatManager = new cCheatManager;

//	XPG_DO( "cCheatManager" );

	/// PVP 관리자를 생성
	mpPvpManager = new cPVPManager;
	if( !mpPvpManager || !mpPvpManager->Init() )
	{
		return false;
	}

	/// 호칭 관리자 생성
	mpTitleManager = new cTitleManager;
	if( !mpTitleManager )
	{
		return false;
	}

	/// 길드 관리자 생성
	mpGuildManager = new cGuildManager;
	if( !mpGuildManager )
	{
		return false;
	}

	/// 팁 관리자 생성
	mpTipManager = new cTipManager;
	if( !mpTipManager || !mpTipManager->Init() )
	{
		return false;
	}

	/// 아이템 조합 관리자
	mpItemMixManager = new cItemMixManager;
	if( !mpItemMixManager )
	{
		return false;
	}

	/// 각 스테이지 생성
	mCurStage = eStage_Intro;
	mpStage[eStage_Intro] = new cIntroStage;
//	XPG_DO( "cIntroStage" );

	mpStage[eStage_Login] = new cLoginStage;
//	XPG_DO( "cLoginStage" );

  	mpStage[eStage_Server] = new cServerStage;
//	XPG_DO( "cServerStage" );

	mpStage[eStage_Select] = new cSelectStage;
//	XPG_DO( "cSelectStage" );

	mpStage[eStage_Make] = new cMakeStage;
//	XPG_DO( "cMakeStage" );

	mpStage[eStage_Load] = new cLoadStage;
//	XPG_DO( "cLoadStage" );

	mpStage[eStage_MapChange] = new cMapChangeStage;
//	XPG_DO( "cMapChangeStage" );

	mpStage[eStage_Game] = new cGameStage;
//	XPG_DO( "cGameStage" );

	/// 배경음 로드
	SOUNDSYS->LoadBGMList();
//	XPG_DO( "LoadBGMList" );

	/// 각 stage 초기화
	for( int i = 0; i < eStage_Max; ++i )
	{
		mpStage[i]->Init( this );

//		XPG_DO( "stageInit" );
	}

	/// stage open
	mpStage[mCurStage]->InitStage();
//	XPG_DO( "cur InitStage" );


	mpStage[mCurStage]->Open();
//	XPG_DO( "cur Open" );

	return true;
}

void cStageManager::Exit()
{
	/// 생성 역순으로...
	if( mpStage[mCurStage] )
        mpStage[mCurStage]->Close();

	for( int i = 0; i < eStage_Max; ++i )
	{
		SAFE_EXIT_DELETE( mpStage[i] );
	}

	SAFE_DELETE( mpItemMixManager );
	SAFE_DELETE( mpTipManager );
	SAFE_DELETE( mpGuildManager );
	SAFE_DELETE( mpTitleManager );
	SAFE_DELETE( mpPvpManager );
	SAFE_DELETE( mpCheatManager );
	SAFE_DELETE( mpSkillManager );	
	SAFE_EXIT_DELETE( mpObjectManager );
	SAFE_EXIT_DELETE( mpWorldManager );
	SAFE_DELETE( mpQuestManager );
	SAFE_DELETE( mpTriggerManager );
	SAFE_DELETE( mpPartyManager );
	SAFE_DELETE( mpShortcutManager );
	SAFE_DELETE( mpTarotManager );
	SAFE_DELETE( mpQuickManager );
	SAFE_DELETE( mpItemManager );
	SAFE_DELETE( mpCoolManager );
	SAFE_DELETE( mpUIManager );
	SAFE_EXIT_DELETE( mpGameResourceManager );
	SAFE_DELETE( mpFilterManager );
	SAFE_DELETE( mpDramaturgyManager );
	SAFE_DELETE( mIOCPCLient );
}

static char buffer[256] = {0,};
void cStageManager::Process( unsigned long deltaTime, unsigned long accumTime )
{
	SOUNDSYS->ProcessStageBGM( accumTime );

	/// skill
	mpSkillManager->Process( deltaTime, accumTime );

	/// 관리 객체들의 변환
    mpObjectManager->Process( deltaTime, accumTime );

	if( mCurStage == eStage_Login )
		mpStage[eStage_Intro]->Process( deltaTime, accumTime );

	///
	mpStage[mCurStage]->Process( deltaTime, accumTime );

	/// 쿨타임 
	mpCoolManager->Process( accumTime );

	/// 퀘스트
	mpQuestManager->Process( accumTime );

	mpPvpManager->Process( deltaTime, accumTime );

	///
	mpPartyManager->Process( accumTime );

	/// ui
	mpUIManager->Process( deltaTime, accumTime );
}

void cStageManager::ProcessWorld( unsigned long deltaTime, unsigned long accumTime )
{
	/// 바닥과 스카이돔에 대한 처리 ( 별도 랜더링 되어질 객체를 구분한다. )
	if( mCurStage == eStage_Game )
		mpWorldManager->Process( deltaTime, accumTime );
}

void cStageManager::NetworkMsgParser( unsigned long connectionindex, char* pMsg, unsigned long length )
{
	mpStage[mCurStage]->NetworkMsgParser( connectionindex, pMsg, length );
}

void cStageManager::MsgBoxEventParser( unsigned int event, unsigned int result, void* exData )
{
	mpStage[mCurStage]->MsgBoxEventParser( event, result, exData );
}

void cStageManager::ProcessKeyPressed( cKeyboardAgent* pKeyboard )
{
	assert(pKeyboard);
	if( SHORTCUTMAN->ProcessKeyPressed( pKeyboard ) == false )
	{
		mpStage[mCurStage]->ProcessKeyPressed( pKeyboard );
	}
}

void cStageManager::ProcessKeyUpDown( unsigned long time, cKeyboardAgent* pKeyboard )
{
	assert(pKeyboard);
	if( SHORTCUTMAN->ProcessKeyUpDown( pKeyboard ) == false )
	{
		mpStage[mCurStage]->ProcessKeyUpDown( time, pKeyboard );
	}
}

void cStageManager::ProcessMouseEvent( unsigned long time, cMouseAgent* pMouse )
{
	assert(pMouse);
	if( pMouse->LButtonDoubleClick() )
	{
		/// LBtnDoubleClick 이벤트 처리
		mpStage[mCurStage]->ProcessLButtonDClick( pMouse );
	}
	else
	{
		if( pMouse->LButtonDown() )
		{
			/// LBtnClick 이벤트 처리
			mpStage[mCurStage]->ProcessLButtonClick( pMouse );
		}
		else if( pMouse->RButtonUp() )
		{
			mpStage[mCurStage]->ProcessRButtonUp( pMouse );
		}
		else if( pMouse->IsDrag() )
		{
			/// mouse over에 대한 처리
			mpStage[mCurStage]->ProcessMouseover( time, pMouse );
		}
		else
		{
			mpStage[mCurStage]->ProcessMouseover( time, pMouse );
		}
	}
}

void cStageManager::ChangeStage( eSTAGE stage )
{
	if( mCurStage == stage )	return;

	/// 스테이지의 배경 사운드 관리
	ManagedBGM( mCurStage, stage );

	mpStage[mCurStage]->Close();

	/// UI 관련 초기화
	mpUIManager->Reset();

	/// 기존 스테이지에서 사용한 정보를 제거한다.
	INPUTSYS->InputInfoClearAll();

	if( stage != eStage_Game )
	{
		LIGHTAGENT->Close();
		SOUNDSYS->Close();
	}

	if( mCurStage == eStage_Game || stage == eStage_Load )
	{
		WORLDMAN->ClearSkyDome();
		SCENEMAN->Clear();
		RESOURCEMAN->Close();
	}

	mpStage[stage]->InitStage();
	mpStage[stage]->Open();	

	ManagedStageMap( mCurStage, stage );

	mCurStage = stage;

#ifdef _GMTOOL
	if( mCurStage == eStage_Game )
	{
		GMTOOL->SetGMToolVisible( true );
	}
	else 
		GMTOOL->SetGMToolVisible( false );
#endif


	CURSOR->SetCursor( eCURSOR_DEFAULT );
}

void cStageManager::ManagedBGM( eSTAGE curStage, eSTAGE newStage )
{
	switch( newStage )
	{
	case eStage_Login:
		{
			if( curStage != eStage_Server && curStage != eStage_Select )
			{
				/// 배경 사운드 시작
				SOUNDSYS->PlayBGMSound(0);
			}
		}
		break;
	case eStage_Select:
		{
			if( curStage == eStage_Game )
			{
				/// 배경 사운드 시작
				SOUNDSYS->PlayBGMSound(0);
			}
		}
		break;
	case eStage_Load:
	case eStage_MapChange:
	case eStage_Game:
		{
			/// 모든 배경 사운드 종료
			SOUNDSYS->PlayBGMSound( (unsigned int)-1 );
		}
		break;
	default:
		break;
	}
}

void cStageManager::ManagedStageMap( eSTAGE curStage, eSTAGE newStage )
{
	switch( newStage )
	{
	case eStage_Login:
		{
			CAMERAMAN->ChangeCamera( 1 );

			if( curStage != eStage_Select && curStage != eStage_Server )
			{
				SCENEMAN->Clear();
				cLoginStage* p = (cLoginStage*)mpStage[eStage_Login];
				if( p )
					p->CreateLoginMap();
			}
		}
		break;
	case eStage_Select:
		{
			CAMERAMAN->ChangeCamera( 1 );
			if( curStage == eStage_Game  )
			{
				SCENEMAN->Clear();
				cSelectStage* p = (cSelectStage*)mpStage[eStage_Select];
				if( p )
					p->CreateSelectMap( true );
			}
			else
			{
				cSelectStage* p = (cSelectStage*)mpStage[eStage_Select];
				if( p )
					p->CreateSelectMap( false );
			}
		}
		break;
	case eStage_Load:
		{
			CAMERAMAN->ChangeCamera( 0 );
			SCENEMAN->Clear();
			cSelectStage* p = (cSelectStage*)mpStage[eStage_Select];
			if( p )
				p->ClearSelectMap();
		}
		break;
	default:
		break;
	}
}
