#ifndef _RURESOURCEMANAGERD3D_H_
#define _RURESOURCEMANAGERD3D_H_

#include "../../Engine/Base/RuResourceManagerBase.h"

// D3D-specific
#include "../../Direct3D/Engine/RuEngineD3D.h"

#pragma unmanaged

// ************************************************************************************************************************************************************

class cFilePackage;

class CRuResourceManagerD3D : public IRuResourceManager
{
protected:
	class CRuRenderTargetPool
	{
	protected:
		INT32								m_poolSize;							//!< Size of the pool (number of render targets)
		INT32								m_rtSize;							//!< Render target size
		RuSurfaceFormat						m_rtFormat;							//!< Render target surface format

		CRuStack<IRuTexture *>				m_freeRenderTargets;				//!< Stack of free render targets
		CRuArrayList<IRuTexture *>			m_usedRenderTargets;				//!< List of used render targets

	public:
											CRuRenderTargetPool(IRuEngine *engine, INT32 poolSize, INT32 rtSize, RuSurfaceFormat rtFormat);
											~CRuRenderTargetPool();

		BOOL								IsIdenticalPoolType(INT32 rtSize, RuSurfaceFormat rtFormat);
		INT32								GetMatchScore(INT32 rtSize, RuSurfaceFormat rtFormat);

		IRuTexture*							GetRenderTarget();
		BOOL								FreeRenderTarget(IRuTexture *renderTarget);
		BOOL								ResetRenderTargetPool();
	};

	CRuEngineD3D*							m_engine;							// Engine core

	cFilePackage*							m_filePackage;						// File packager Entity

	CRuStringHash<IRuBaseTexture *>*		m_textureHash;						// Texture hash
	CRuStringHash<IRuShader *>*				m_shaderHash;						// Shader hash
	CRuStringHash<CRuAnimation *>*			m_animationHash;					// Animation hash
	CRuStringHash<IRuObject *>*				m_entityHash;						// Entity hash

	CRuArrayList<CRuRenderTargetPool *>		m_renderTargetPools;				//!< List of render target pools

	CRuArrayList<IRuTexture *>				m_gc_Texture;

	CRuThread_CriticalSection*				m_objectCS;							//!< Object-level critical section

public:
											CRuResourceManagerD3D();
	virtual									~CRuResourceManagerD3D();

	// Engine association
	BOOL									SetEngine(CRuEngineD3D *engine);
	virtual IRuEngine*						GetEngine();

	// Manager setup
	virtual void							SetRootDirectory(const char *rootDirectory);

	// Texture management
	virtual BOOL							AddTexture(IRuBaseTexture *texture);
	virtual BOOL							RemoveTexture(IRuBaseTexture *texture);
	virtual BOOL							RemoveTexture(const char *textureName);
	virtual	IRuTexture*						LoadTexture(const char *textureName);
	virtual	IRuTexture*						LoadTexture(const char *textureName, RuSurfaceFormat surfaceFormat);
	virtual IRuTexture*						CreateTexture(const char *textureName, UINT32 width, UINT32 height, RuSurfaceFormat surfaceFormat);
	virtual IRuTexture*						CreateTexture(const char *textureName, UINT32 width, UINT32 height, UINT32 levels, RuSurfaceFormat surfaceFormat);
	virtual IRuVolumeTexture*				CreateVolumeTexture(const char *textureName, UINT32 width, UINT32 height, UINT32 depth, UINT32 levels, RuSurfaceFormat surfaceFormat);
	virtual BOOL							CreateRenderTargetPool(INT32 poolSize, INT32 rtSize, RuSurfaceFormat rtFormat);
	virtual BOOL							ResetRenderTargetPools();
	virtual IRuTexture*						GetPooledRenderTarget(INT32 rtSize, RuSurfaceFormat rtFormat);
	virtual BOOL							FreePooledRenderTarget(IRuTexture *renderTarget);

	// Shader management
	virtual BOOL							AddShader(IRuShader *shader);
	virtual BOOL							RemoveShader(IRuShader *shader);
	virtual BOOL							RemoveShader(const char *shaderName);
	virtual IRuShader*						GetShader(const char *shaderName);
	virtual BOOL							GetShaderList(CRuArrayList<const char *> &shaderListOut);

	// Animation management
	virtual CRuAnimation*					LoadAnimation(const char *animationName);

	// Entity management
	// TODO: Pre-load function, garbage collection of stale entities(clone count = 1), etc
	virtual CRuEntity*						LoadEntity(const char *entityName);

	// Dictionary management
	virtual BOOL							ClearTextureDictionary();
	virtual BOOL							ClearShaderDictionary();
	virtual BOOL							ClearAnimationDictionary();
	virtual BOOL							ClearEntityDictionary();

	// Garbage collection
	virtual BOOL							GarbageCollect();

protected:
	static BOOL								GetShaderListCallback(const void *key, const void *data, void *userData);

	static BOOL								ClearTextureDictionaryCallback(const void *key, const void *data, void *userData);
	static BOOL								ClearShaderDictionaryCallback(const void *key, const void *data, void *userData);
	static BOOL								ClearAnimationDictionaryCallback(const void *key, const void *data, void *userData);
	static BOOL								ClearEntityDictionaryCallback(const void *key, const void *data, void *userData);

	static BOOL								GCTextureDictionaryCallback(const void *key, const void *data, void *userData);
};

// ************************************************************************************************************************************************************

#pragma managed

#endif
