/*!
	@file RuTextureAtlas_Aggregate.h

	Copyright (c) 2004-2005 All rights reserved
*/

#ifndef _RUTEXTUREATLAS_AGGREGATE_H_
#define _RUTEXTUREATLAS_AGGREGATE_H_

#include "../../Engine/Texture/RuTextureAtlas_Base.h"

#pragma unmanaged

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

class CRuTextureAtlas_Aggregate : public CRuTextureAtlas_Base
{
	ruRTTI_DECLARE
	ruHEAP_DECLARE
	ruCLASSGUID_DECLARE

protected:
	struct SubAtlasDesc
	{
		CRuTextureAtlas_Base*				m_subAtlas;
		CRuLRUQueue<CRuGUID, INT32>*		m_bindQueue;
	};

	struct TextureDesc
	{
		IRuTexture*							m_texture;											//!< Texture reference
		CRuTextureAtlas_Base*				m_atlas;											//!< Atlas that the texture resides within
		INT32								m_handle;											//!< Slot that the texture resides within
	};

	CRuArrayList<SubAtlasDesc>				m_subAtlases;										//!< List of sub atlases
	CRuArrayList<TextureDesc>				m_boundTextures;									//!< List of bound textures
	CRuStack<INT32>							m_unusedHandles;									//!< Stack of unused handles

	CRuLRUQueue<CRuGUID, INT32>*			m_textureQueue;

public:
											CRuTextureAtlas_Aggregate();
	virtual									~CRuTextureAtlas_Aggregate();

	BOOL									BindSubAtlas(CRuTextureAtlas_Base *subAtlas);
	BOOL									UnbindSubAtlas(CRuTextureAtlas_Base *subAtlas);

	virtual IRuTexture*						GetAtlasTexture();
	virtual IRuTexture*						GetTexture(INT32 textureHandle);
	virtual UINT32							GetTextureWidth(INT32 textureHandle);
	virtual UINT32							GetTextureHeight(INT32 textureHandle);

	virtual BOOL							CanBindIntoAtlas(IRuTexture *texture);
	virtual INT32							BindIntoAtlas(IRuTexture *texture);
	virtual BOOL							UnbindFromAtlas(INT32 textureHandle);
	virtual BOOL							TranslateUV(INT32 textureHandle, REAL u, REAL v, REAL uBias, REAL vBias, REAL &uOut, REAL &vOut);

protected:
//	void									FlushTextureQueue();
//	static BOOL								FlushTextureQueueCallback(const void *key, const void *data, void *userData);
};

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

#pragma managed

#endif
