#include "MLRHeaders.hpp"

//#############################################################################
//############################    MLRTexture    ###############################
//#############################################################################

DECLARE_TIMER(static, Texture_Loading);

MLRTexture::ClassData*
	MLRTexture::DefaultData = NULL;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRTexture::InitializeClass()
{
	Verify(!DefaultData);
	Verify(gos_GetCurrentHeap() == StaticHeap);
	DefaultData =
		new ClassData(
			MLRTextureClassID,
			"MidLevelRenderer::MLRTexture",
			Plug::DefaultData
		);
	Register_Object(DefaultData);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRTexture::TerminateClass()
{
	Unregister_Object(DefaultData);
	delete DefaultData;
	DefaultData = NULL;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRTexture::MLRTexture(MemoryStream *stream, ClassData *class_data):
	Plug(class_data)
{
	Verify(gos_GetCurrentHeap() == TexturePoolHeap);
	Check_Pointer(this);
	Check_Object(stream);

	hint = 0;
	proxyNumber = 0;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRTexture::MLRTexture(
	MLRTexturePool *tp,
	const char* texName,
	int _instance,
	int handle,
	int _hint,
	ClassData *class_data
):
	Plug(class_data)
{
	Verify(gos_GetCurrentHeap() == TexturePoolHeap);
	thePool = tp;
	textureHandle = handle;

	textureName = texName;

	textureNameHashValue = textureName.GetHashValue();

	instance = _instance;

	textureMatrix = NULL;
	textureMatrixIsIdentity = true;

	if(_instance>-1)
	{
		image = thePool->GetImage(textureName);
	}
	else
	{
		instance = 0;
		image = NULL;
	}

	hint = _hint;
	proxyNumber = 0;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRTexture::MLRTexture(
	MLRTexturePool *tp,
	GOSImage *_image,
	int handle,
	int _hint,
	ClassData *class_data
):
	Plug(class_data)
{
	Verify(gos_GetCurrentHeap() == TexturePoolHeap);
	thePool = tp;
	textureHandle = handle;

	image = _image;

	textureName = image->GetName();

	textureNameHashValue = textureName.GetHashValue();

	instance = 0;

	textureMatrix = NULL;
	textureMatrixIsIdentity = true;

	hint = _hint;
	proxyNumber = 0;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRTexture::TestInstance() const
{
	Verify((*thePool)[textureHandle]);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRTexture::MLRTexture(const MLRTexture& tex, ClassData *class_data):
	Plug(class_data)
{
	Check_Object(&tex);
	Verify(gos_GetCurrentHeap() == TexturePoolHeap);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRTexture::~MLRTexture()
{
	thePool->Remove(this);

	if((image!=NULL) && (NULL==thePool->GetImage(image->GetName())))
	{
		Unregister_Object(image);
		delete image;
		image = NULL;
	}

	if(textureMatrix!=NULL)
	{
		textureMatrixIsIdentity = true;
		Unregister_Object(textureMatrix);
		delete textureMatrix;
		textureMatrix = NULL;
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRTexture*
	MLRTexture::Make(MemoryStream *stream)
{
	Check_Object(stream);

	gos_PushCurrentHeap(TexturePoolHeap);
	MLRTexture *texture = new MLRTexture(stream);
	gos_PopCurrentHeap();

	return texture;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRTexture::Save(MemoryStream *stream)
{
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	MLRTexture::GetImageNumber()
{
	Check_Object(this);
	return ((textureHandle-1) >> (thePool->GetInstanceDepth()));
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	MLRTexture::GetInstanceNumber()
{
	Check_Object(this);
	return ((textureHandle-1) & ~((1<<thePool->GetInstanceDepth())-1));
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRTexture::LoadImageGOS(GOSImagePool *imagePool)
{
	Check_Object(this);
	MLR_RENDER("Load Image");
	Start_Timer(Texture_Loading);

	if (image && !image->IsLoaded())
	{
		Check_Object(image);
		if (!imagePool->LoadImageGOS(image, hint))
		{
#ifdef LAB_ONLY
			SPEWALWAYS(("0","Cannot load texture: %s!", (const char *)(textureName)));
			
#ifdef _ARMOR
			PAUSE(("Cannot load texture: %s!", (const char *)(textureName)));
#endif
#endif

		}
	
	}
	Stop_Timer(Texture_Loading);
}
