#pragma once
#define MLR_MLR_BUMPYWATER_HPP

#include <MLR\MLR.hpp>
#include <MLR\MLR_I_C_DT_TMesh.hpp>

namespace MidLevelRenderer {

	//##########################################################################
	//###### MLRIndexedTriMesh with  color no lighting w/ detail texture  ######
	//##########################################################################


	class MLR_BumpyWater:
		public MLR_I_C_TMesh
	{
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Initialization
	//
	public:
		static void
			InitializeClass();
		static void
			TerminateClass();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Constructors/Destructors
	//
	protected:
		MLR_BumpyWater(
			ClassData *class_data,
			Stuff::MemoryStream *stream,
			int version
		);
		~MLR_BumpyWater();

	public:
		MLR_BumpyWater(ClassData *class_data=MLR_BumpyWater::DefaultData);

		static MLR_BumpyWater*
			Make(
				Stuff::MemoryStream *stream,
				int version
			);

		void
			Save(Stuff::MemoryStream *stream);

		virtual void
			FindFacePlanes();

		int
			FindBackFace(const Point3D& u, const Normal3D& n);

		void
			Copy(
				MLR_Water*
			);

		bool
			Copy(MLR_I_C_DeT_PMesh*);

	public:
		virtual int
			TransformAndClip(Stuff::Matrix4D *, MLRClippingState, GOSVertexPool*, FogData*, DWORD=0xffffffff, bool=false);

		virtual void
			TransformNoClip(Stuff::Matrix4D*, GOSVertexPool*, FogData*, DWORD=0xffffffff, bool=false);

		void
			LightMapLighting(MLRLight*);

		virtual GOSVertex3UV*
			GetGOSVertices3UV(int=0)
				{ Check_Object(this); return gos_vertices3uv; }

		void
			SetTextures(DWORD tBump, DWORD tEnv, DWORD tNorm)
				{ Check_Object(this); textureBump = tBump; textureEnv = tEnv; textureNorm = tNorm; }

		virtual DWORD
			GetTexture2()
				{
					Check_Object(this);
					if(MLRState::GetCanBumpEnvMap()==true)
						return textureBump;
					else if(MLRState::GetCanBumpDotMap()==true)
						return textureNorm;
					else
						return 0;
				}

		virtual DWORD
			GetTexture3()
				{ Check_Object(this); return textureEnv; }

		static void
			SetSunLight(Stuff::UnitVector3D& sl)
				{ sunLight = sl; }

		void
			SetBumpWrapRatio(Scalar br)
				{ Check_Object(this); bumpRatio = br; }

		void
			SetEnvWrapRatio(Scalar er)
				{ Check_Object(this); envRatio = er; }

		void
			SetBumpNormWrapRatio(Scalar bnr)
				{ Check_Object(this); bumpNormRatio = bnr; }

//		virtual int
//			GetNumPasses();

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

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

	protected:
		static Stuff::UnitVector3D sunLight;

		GOSVertex3UV *gos_vertices3uv;

		Scalar bumpRatio, envRatio, bumpNormRatio;

		static Stuff::DynamicArrayOf<Vector2DScalar> *texCoords2;	// Base address of texture coordinate list 
		static Stuff::DynamicArrayOf<Vector2DScalar> *texCoords3;	// Base address of texture coordinate list 
		DWORD textureBump;
		DWORD textureEnv;
		DWORD textureNorm;

		static Stuff::DynamicArrayOf<Vector2DScalar> *clipExtraTexCoords2;	// Max_Number_Vertices_Per_Mesh
		static Stuff::DynamicArrayOf<Vector2DScalar> *clipExtraTexCoords3;	// Max_Number_Vertices_Per_Mesh
	};
}
