#pragma once
#define MLR_MLRTEXTURE_HPP

#include <MLR\MLR.hpp>
#include <MLR\GOSImage.hpp>
#include <MLR\GOSImagePool.hpp>

namespace MidLevelRenderer {

	class MLRTexturePool;

	class MLRTexture:
		public Stuff::Plug
	{
		friend class MLRTexturePool;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Initialization
	//
	public:
		static void
			InitializeClass();
		static void
			TerminateClass();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Constructors/Destructors
	//
	protected:
		MLRTexture(Stuff::MemoryStream *stream, ClassData *class_data=MLRTexture::DefaultData);

	public:
		MLRTexture(
			MLRTexturePool *pool,
			const char* name,
			int instance,
			int handle,
			int hint=0,
			ClassData *class_data=MLRTexture::DefaultData
		);

		MLRTexture(
			MLRTexturePool *pool,
			GOSImage* image,
			int handle,
			int hint=0,
			ClassData *class_data=MLRTexture::DefaultData
		);

		MLRTexture(const MLRTexture&, ClassData *class_data=MLRTexture::DefaultData);
		~MLRTexture();

		static MLRTexture*
			Make(Stuff::MemoryStream *stream);

		void
			Save(Stuff::MemoryStream *stream);

		virtual GOSImage*
			GetImage(int *h=NULL) const
				{ Check_Object(this); if(h) { *h = hint; } return image; }

		virtual void
			LoadImageGOS(GOSImagePool *imagePool);

		const char*
			GetTextureName()
				{Check_Object(this); return textureName;}

		int
			GetTextureHandle()
				{Check_Object(this); return textureHandle;}

		int
			GetImageNumber();

		int
			GetInstanceNumber();

		int
			GetTextureInstance()
				{Check_Object(this); return instance;}

		bool
			GetAnimateTexture()
				{Check_Object(this); return (!textureMatrixIsIdentity)&&(textureMatrix!=NULL);}

		void
			SetAnimateTexture(bool yesNo)
				{
					Check_Object(this);
					if(yesNo==true)
					{
						textureMatrixIsIdentity = false;

						if(textureMatrix==NULL)
						{
							textureMatrix = new Stuff::AffineMatrix4D;
							Register_Object(textureMatrix);
							*textureMatrix = Stuff::AffineMatrix4D::Identity;
						}
					}
					else
					{
						textureMatrixIsIdentity = true;
						if(textureMatrix!=NULL)
						{
							Unregister_Object(textureMatrix);
							delete textureMatrix;
						}
					}
				}

		Stuff::AffineMatrix4D*
			GetTextureMatrix()
				{ Check_Object(this); return textureMatrix; }

		void
			SetHint(int h)
				{ Check_Object(this); hint = h; }

		int
			GetHint()
				{ Check_Object(this); return hint; }

		void
			SetProxyNumber(int h)
				{ Check_Object(this); proxyNumber = h; }

		int
			GetProxyNumber()
				{ Check_Object(this); return proxyNumber; }

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Class Data Support
	//
	public:
		static ClassData
			*DefaultData;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Testing
	//
	public:
		void
			TestInstance() const;

	protected:
		Stuff::MString textureName;
		int textureNameHashValue;

		int instance;

		int textureHandle;

		int hint;

		bool textureMatrixIsIdentity;

		Stuff::AffineMatrix4D *textureMatrix;

		GOSImage *image;

		MLRTexturePool *thePool;

		int proxyNumber;
	};

}
