/* ==========================================================================
* 파    일 : PartyManager.h
* 목    적 : 
* 작 성 자 : 김가람
* 작 성 일 : 2007-11-07
* 주의사항 :
*===========================================================================*/
#pragma once
#include "Player_Common.h"
#include "Party_Common.h"

const unsigned long PARTY_WAIT_TIME = 10000;
const unsigned long PARTY_UPDATETIME = 1000;
const unsigned long PARTY_HPMPUPDATE = 100;
const unsigned long PARTY_BUFFUPDATE = 1000;

const int MAX_PARTY = 6;
const int PARTY_NUM = 5;	/// 자신을 제외한 파티원수

enum ePLAYER_JOB;
class cPartyData
{
public:
	void operator=( unsigned int i );
	void operator=( const cPartyData& other );

public:
	/// 파티유저 인덱스
	unsigned long mIndex;

	/// 유저네임
	cStringT mName;

	/// 레벨
	unsigned char mLevel;

	/// 직업
	ePLAYER_JOB mJob;

	/// HP, MP
	unsigned int mHP;
	unsigned int mMaxHP;
	unsigned int mMP;
	unsigned int mMaxMP;

	/// 맵 번호
	unsigned int mMapNum;

	/// 초기 좌표
	float		mInitX;
	float		mInitY;

	/// 연결될 UI 배열번호
	int			mUIIndex;
};

inline
void cPartyData::operator=( unsigned int i )
{
	if( i <= 0 )
	{
		mIndex	= 0;
		mLevel	= 0;
		mJob	= ePLAYER_NONEJOB;
		mHP		= 0;
		mMaxHP	= 0;
		mMP		= 0;
		mMapNum	= 0;
		mInitX  = 0;
		mInitY  = 0;
		mUIIndex = -1;
		mName.Clear();
	}
	else
	{
		assert(0);
	}
}

inline
void cPartyData::operator=( const cPartyData& other )
{
	mIndex	= other.mIndex;
	mLevel	= other.mLevel;
	mJob	= other.mJob;
	mHP		= other.mHP;
	mMaxHP	= other.mMaxHP;
	mMP		= other.mMP;
	mMapNum	= other.mMapNum;
	mName	= other.mName;
	mInitX  = other.mInitX;
	mInitY  = other.mInitY;
	mUIIndex = other.mUIIndex;
}

/// 네트워크 락
enum 
{
	eLOCK_PARTYADD,
	eLOCK_PARTYOUT,
	eLOCK_PARTYCHANGELEADER,
	eLOCK_PARTYCHANGEDIVIDE,
	eLOCK_PARTYTHROW,
};

/// 파티 매니저
class cPartyManager
{
public:
	static cPartyManager* mpSingleton;

public:
	cPartyManager();
	~cPartyManager();

	bool Init();
	void Close();
	void Process( unsigned long accumTime );
	
	void RequestPartyAdd( LPCTSTR targetName );
	void RequestChangeLeader();
	void RequestChangeLeader( unsigned long playerIdx );

	void RequestPartyOut();
	void RequestChangeDivide( PARTY_DIVIDE_TYPE type );
	void RequestThrow();
	void RequestThrow( unsigned long playerIdx );


	/// 해당 유저가 파티인지 검사
	bool IsHeroParty( unsigned long userIndex );

	void ChangeTabTarget( unsigned long userIdx );

	/// 파티원 타겟팅 
	void ChangeTarget( unsigned long userIndex );

	/// 타겟된 파티 윈도우 변경
	void UpdateTarget( int index );

	LPCTSTR GetSelectName();

	/// 파티원 이름 획득
	LPCTSTR GetUserName( unsigned long userIdx );

	/// 네트워크 메시지
	void NetworkMsgParser( char* msg );

	/// 파티 UI 갱신
	void CreatePartyUI();

	/// 파티 UI show / hide
	void HidePartyUI();
	void ShowPartyUI();

	void UpdateLevelUp( unsigned long userIndex, unsigned char level );
	void UpdateMinimap();
	void UpdateBuffList( unsigned long index );

	bool IsHeroLeader();

public:
	static cPartyManager* GetSingleton();

protected:
	void Clear();

	void UpdatePartyHP( unsigned int i, unsigned long hp, unsigned long maxhp );
	void UpdatePartyMP( unsigned int i, unsigned long mp, unsigned long maxmp );

	/// 파티정보 갱신
	bool CreateParty( MSG_SYN_PARTY_LIST* msgData );
	void DeleteParty();
    
	/// 파티원 추가 & 삭제
	void AddUser( MSG_SYN_PARTY_ADDONE* msgData );
	void DeleteUser( int arrIdx );	
		
	void ChangeLeader();

	/// 유저인덱스로 배열 인덱스 검사
	int FindUser( unsigned long userIdx );
	int FindEmptyUI();

	/// 파티원 UI 좌표 갱신
	void UpdateStateUI();

private:
	/// 파티 분배방식
	PARTY_DIVIDE_TYPE mDivideType;

	unsigned long mPartyIndex;

	/// 파티 레벨
	unsigned char mPartyLevel;

	/// 파티장 유저 인덱스
	unsigned long mLeaderIndex;

	/// 파티원 정보
	cPartyData mParty[PARTY_NUM];

	/// 파티인원수
	int mCount;

	/// 선택된 파티정보
	int mSelectDataIndex;

	///
	unsigned long mLastAccumTime;

	/// HP, MP 갱신 시간
	unsigned long mHPMPAccumTime;

	/// 버프리스트 갱신 시간
	unsigned long mBuffAccumTime;

	/// 파티 신청 타겟 이름
	cStringT	mTempTargetName;
};

inline int cPartyManager::FindUser( unsigned long userIdx )
{
	for( int i = 0; i < mCount; ++i )
	{
		if( mParty[i].mIndex == userIdx )
			return i;
	}
	return -1;
}

inline bool cPartyManager::IsHeroParty( unsigned long userIndex )
{
	return ( FindUser( userIndex ) == -1 ) ? false : true;
}

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

#define PARTYMAN cPartyManager::GetSingleton()
