#include "MLRHeaders.hpp"

//#############################################################################
//############################    MLRMovieTexture    ###############################
//#############################################################################

DECLARE_TIMER(static, Texture_Loading);
MLRMovieTexture::ClassData*
	MLRMovieTexture::DefaultData = NULL;

extern DWORD gEnableMovieTextures;

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

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRMovieTexture::TerminateClass()
{
	Unregister_Object(DefaultData);
	delete DefaultData;
	DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRMovieTexture::MLRMovieTexture(MemoryStream *stream, ClassData *class_data):
	MLRTexture(stream, class_data)
{
	Verify(gos_GetCurrentHeap() == TexturePoolHeap);
	Check_Pointer(this);
	Check_Object(stream);

	lastTime = 0.0f;
	sumTimeSlice = 0.0f;

	frameTime = 0.5f;

	imageArray = NULL;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRMovieTexture::MLRMovieTexture(
	MLRTexturePool *tp,
	const char* texName,
	int _nrOfFrames,
	float _frameTime,
	int handle,
	int _hint,
	ClassData *class_data
):
	MLRTexture(tp, texName, -1, handle, _hint, class_data)
{
	Verify(gos_GetCurrentHeap() == TexturePoolHeap);

	lastTime = 0.0f;
	sumTimeSlice = 0.0f;

	if(gEnableMovieTextures!=0)
	{
		nrOfFrames = _nrOfFrames;
	}
	else
	{
		nrOfFrames = 1;
	}

	currentFrame = 0;

	Verify(nrOfFrames<100);

	frameTime = _frameTime;

	imageArray = NULL;

	if(nrOfFrames>0)
	{
		imageArray = new GOSImage * [nrOfFrames];

		char frameName[1024];
		Verify(strlen(texName) < 1000);

		for(int i=0;i<nrOfFrames;i++)
		{
			sprintf(frameName, "%s%02d", texName, i+1);
			imageArray[i] = thePool->GetImage(frameName);
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRMovieTexture::TestInstance() const
{
	Verify((*thePool)[textureHandle]);
	for(int i=0;i<nrOfFrames;i++)
	{
		Check_Object(imageArray[i]);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRMovieTexture::~MLRMovieTexture()
{
	for(int i=0;i<nrOfFrames;i++)
	{
		if(NULL==thePool->GetImage(imageArray[i]->GetName()))
		{
			Unregister_Object(imageArray[i]);
			delete imageArray[i];
		}
	}

	delete [] imageArray;
}

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

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

	return texture;
}

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

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRMovieTexture::RollAFrame()
{
	Check_Object(this);

	static float lastTime = 0.0f;

	if(gEnableMovieTextures==0)
	{
		currentFrame = 0;
	}

	if(lastTime > 0.0f)
	{
		float nowTime = (float)gos_GetElapsedTime();

		if (nowTime > lastTime + frameTime)
		{
			do
			{
				currentFrame++;
				if(currentFrame>=nrOfFrames)
				{
					currentFrame = 0;
				}

				lastTime += frameTime;
			} while (nowTime > lastTime + frameTime);

			lastTime = nowTime;
		}
	}
	else
	{
		lastTime = (float)gos_GetElapsedTime();
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRMovieTexture::RollAFrame(Scalar timeSlice)
{
	Check_Object(this);

	if(gEnableMovieTextures==0)
	{
		currentFrame = 0;
		return;
	}

	if(lastTime > 0.0f)
	{
		float nowTime = (float)gos_GetElapsedTime();

		if (nowTime > lastTime + frameTime)
		{
			do
			{
				currentFrame++;
				if(currentFrame>=nrOfFrames)
				{
					currentFrame = 0;
				}

				lastTime += frameTime;
			} while (nowTime > lastTime + frameTime);

			lastTime = nowTime;
		}
	}
	else
	{
		lastTime = (float)gos_GetElapsedTime();
	}
}


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

	hint |= gosHint_VideoMemory;

	for(int i=0;i<nrOfFrames;i++)
	{
		if (imageArray[i] && !imageArray[i]->IsLoaded())
		{
			Check_Object(imageArray[i]);
			if (!imagePool->LoadImageGOS(imageArray[i], 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);
}
