/* ====================================================================
* 목    적 :	모드 그래픽 리소스에 대한 로딩 인터페이스 제공 및 보관 메모리 제공
* 작 성 자 :	이법석
* 작 성 일 :	2006.01
* 주의사항 :	쓰레드용 인터페이스는 별도의 용도이므로 임의 사용을 제한한다.
*				이곳에 로드되는 객체및 텍스쳐는 모두 유일하다.
* =================================================================== */
#pragma once

#include "TexturePalette.h"
#include "ModelInstance.h"

class cCallbackStreamPACK;

/// 리소스 관리자
class cResourceManager
{
	static cResourceManager* mpSingleton;

public:
	cResourceManager();
	~cResourceManager();

	enum
	{
		eCHARACTEREFFECT = 0,
		eOBJECTEFFECT,

		/// 파일에 지정된 정보를 그대로 사용한다.
		eFILEEFFECT,
	};

	/// 초기화
	bool Init();

	void Close();

	void Clear();

	/// 종료
	void Exit();

	/// 기본 객체 로드 함수
	bool LoadNIF( const cString& pathName, NiAVObject** nifRoot = 0);
	bool LoadMapNIF( const cString& pathName );

	/// 쓰레드를 이용한 객체 로드(임의 사용을 제한한다)
	void LoadThreadNIF( const char* fileName );

	/// 로드 쓰레드 종료부
	void FinishThread();

	/// 텍스처
	NiTexture* LoadTexture( const cString& pathName, bool useMipMap = true );
	LPDIRECT3DTEXTURE9 LoadD3DTexture( const cString& pathName, bool useMipMap = true, DWORD filter = D3DX_FILTER_LINEAR, DWORD mipFilter = D3DX_FILTER_LINEAR );
	LPDIRECT3DTEXTURE9 GetD3DTexture( const cString& pathName );

	/// 사운드
	NiAudioSource* LoadSound( const cString& fileName );

	/// 쓰레드용 처리부
	void Process();

	/// 로드된 nif파일 객체를 저장공간에 추가한다.
	//terrain_temp
	unsigned int AddObject( NiNode* n, const cString& pathName );

	/// 객체 제거용 인터페이스
	void RemoveObject( const char* objectName );
	void RemoveObject( NiNode* n );
	void RemoveAllObjects();

	void RemoveAllMapTexture();

	/// 객체 참조용 인터페이스
	//	inline unsigned int	GetObjectCount() const { return mObjectArray.GetSize(); }
	//	NiAVObject*			GetObjectAt( unsigned int objcetIdx );
	//	NiAVObject*			GetObjectByName( const char* objectName );

	inline unsigned int	GetObjectCount() const { return mNodeArray.GetSize(); }
	NiNode*				GetObjectAt( unsigned int objcetIdx );
	NiNode*				GetObjectByName( const cString& pathName );
	NiAudioSource*		GetSoundByName( const cString& fileName );

	/// 객체 복사용 인터페이스
	NiNode*				CloneObjectAt( unsigned int objectIdx );
	NiNode*				CloneObjectByName( const cString& pathName );
	NiAudioSource*		CloneSoundByName( const cString& fileName );

	/// kfm 파일 모델
	bool LoadKFM( const cString& pathName );
	unsigned int AddModel( cModelInstance* model, const cString& pathName );
	void RemoveAllModels();
	inline unsigned int GetModelCount() const { return mModelArray.GetSize(); }
	cModelInstance* GetModelAt( unsigned int modelIdx );
	cModelInstance* GetModelByName( const cString& modelName );

	/// 그림자 텍스처
	NiTexture* GetShadowTexture() const;

public:
	/// 단일체를 리턴
	static cResourceManager* GetSingleton();

protected:
	/// 쓰레드 로딩 클래스
	cCallbackStreamPACK* mpStreamPAK;

	/// 크리티컬 섹션
	static NiCriticalSection mObjectListCriticalSection;
	static NiCriticalSection mTexturePaletteCriticalSection;
	static NiCriticalSection mSoundListCriticalSection;

	/// 텍스처 팔레트
	cTexturePalettePtr mTexturePalette;
	cTexturePalettePtr mMapTexturePalette;

	/// 3D 오브젝트
	NiTObjectArray<NiNodePtr> mNodeArray;
	NiTStringPointerMap<unsigned int> mObjectIndexMap;

	/// 맵 오브젝트
	tArray<unsigned int> mMapIndexArray;

	/// 모델
	NiTObjectArray<cModelInstancePtr> mModelArray;
	NiTStringPointerMap<unsigned int> mModelIndexMap;

	/// 사운드
	typedef tPointerHashMap<cString, NiAudioSource*> cSoundMap;
	cSoundMap mSoundMap;

	/// 텍스처
	typedef tHashMap<cString, void*> cD3DTextureMap;
	cD3DTextureMap mD3DTextureMap;

	/// 그림자 텍스처
	NiTexture* mShadowTexture;
};

inline
NiTexture* cResourceManager::GetShadowTexture() const
{
	return mShadowTexture;
}

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

#define RESOURCEMAN	cResourceManager::GetSingleton()
