/* ==========================================================================
* 파    일 : PartyManager.h
* 목    적 : 
* 작 성 자 : 김가람
* 작 성 일 : 2007-11-05
* 주의사항 :
*===========================================================================*/
#pragma once
#include "Player.h"
#include "Monster.h"
#include "Party.h"
#include "IndexGenerator.h"

const unsigned long PARTY_UPDATETIME = 5000;

class cPartyManager
{
	static cPartyManager*	mpSingleton;

public:
	cPartyManager();
	~cPartyManager();

	///
	bool Init();
	void Process( unsigned long elapsedTime, unsigned long accumTime );
	void Release();

	///
	cParty* AllocParty();
	void FreeParty( cParty* party );

	/// 파티생성
	unsigned long AddParty( unsigned long leaderIdx, unsigned long userIdex );
	bool DeleteParty( unsigned long partyIdx );
	cParty*	GetParty( unsigned int partyIdx );

	/// 파티신청응답시 제대로 된 연결인지 검사하기 위함.
	/// 신청정보 저장 ( 신청받은 유저, 신청한 유저 인덱스 )
	bool AddRequest( unsigned long recvIdx, unsigned long reqIdx );
	void DelRequest( unsigned long recvIdx );
		
	/// 파티 갱신 send
	void SendUpdateParty( cParty* party );

	///
	void SendToPartyHunt( cMonster* monster, cPlayer* hero, unsigned int racegender );	/// 몬스터 사냥 : 파티원 갱신
	void SendToPartyChangeJob( cPlayer* player );

	bool ResPartyList( cPlayer* player, cParty* party );
	bool ResPartyAddOne( unsigned long characterIdx, cParty* party );

	/// 파티원 탈퇴처리 ( 파티탈퇴, 게임종료 )
	void PartyOutPlayer( cPlayer* player );
	void PartyChangeLeader( cPlayer* fromPlayer, unsigned long toUserIdx );
	void PartyChangeDivide( cPlayer* fromPlayer, PARTY_DIVIDE_TYPE type );
	void PartyMapOut( cPlayer* hero );		/// 파티원 맵 아웃( 맵체인지 전 )
	void PartyMapIn( cPlayer* player );		/// 파티원 맵 인 ( 맵체인지 완료 )

	///// 파티 해체 ( 전장용 )
	//void PartyBreak( cPlayer* player );
    
	// 파티를 신청한 유저의 인덱스를 검사.
	unsigned long GetRequest( unsigned long recvIdx );

	/// 다음 유저인덱스 찾기
	unsigned long FindNext( cParty* party, unsigned long userIndex );
    
protected:
	///
	bool ResPartyMsgError( unsigned long connectionIdx, char protocol, long error );

public:
	static cPartyManager* Get();

private:
	/// 파티인덱스 제너레이터
	cIndexGenerator	mPartyIndexGen;
    
	/// 전체파티 풀
	typedef tPool<cParty> cPartyPool;
	cPartyPool mPartyPool;
	
	/// 전체 파티정보 저장
	typedef tPointerHashMap<unsigned long, void*> cPartyMap;
	cPartyMap mPartyMap;

	/// 파티신청정보저장
	typedef tHashMap<unsigned long, unsigned long> cJoinMap;
	cJoinMap mJoinMap;
};

inline cPartyManager* cPartyManager::Get()
{
	return mpSingleton;
}

inline cParty* cPartyManager::AllocParty()
{
	return mPartyPool.Alloc();
}

inline void cPartyManager::FreeParty( cParty* party )
{
	mPartyPool.Free( party );
}

#define PARTYMAN cPartyManager::Get()
