#pragma once
#define MLR_MLRPROJECTLIGHT_HPP

#include "MLR.hpp"
#include "MLRInfiniteLightWithFalloff.hpp"

namespace MidLevelRenderer {

	//##########################################################################
	//######################    MLRProjectLight    #############################
	//##########################################################################

	class MLRProjectLight:
		public MLRInfiniteLightWithFalloff
	{
	public:
		static void
			InitializeClass();
		static void
			TerminateClass();

		MLRProjectLight();
		MLRProjectLight(
			Stuff::MemoryStream *stream,
			int version
		);
		MLRProjectLight(Stuff::Page *page);
		~MLRProjectLight();

		void
			Save(Stuff::MemoryStream *stream);
		void
			Write(Stuff::Page *page);

		virtual LightType
			GetLightType() 
				{ Check_Object(this); return ProjectLight; }


	//
	// spotlight spread.  This value is only valid if the light had falloff
	//
		bool
			GetSpreadAngle(Stuff::Radian *angle);
		void
			SetSpreadAngle(const Stuff::Radian &radian);

		void
			SetSpreadAngle(const Stuff::Degree &degree);

		Stuff::Scalar
			GetTanSpreadAngle()
				{ Check_Object(this); return tanSpreadAngle; }

		Stuff::Scalar
			GetCosSpreadAngle()
				{ Check_Object(this); return cosSpreadAngle; }

		virtual void
			LightVertex(const MLRVertexData&);
		virtual void
			LightCenter(RGBAColor&);

		void
			SetLightMap(MLRLightMap *light_map);

		MLRLightMap *
			GetLightMap()
				{Check_Object(this); return lightMap; }

		void
			CreateProjectMatrix();

		virtual
			void SetLightToShapeMatrix(const Stuff::LinearMatrix4D&);

		const Stuff::Matrix4D&
			GetProjectMatrix()
				{ Check_Object(this); return projMatrix; };

		const Stuff::AffineMatrix4D&
			GetInversMatrix()
				{ Check_Object(this); return inverseLightToShape; };

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

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

		void
			InitLineTextureProjection(Stuff::Point3D *lineTestPoints, Stuff::RGBAColor *lineTestColors);

	protected:
		Scalar
			xMin, xMax, yMin, yMax, nnear, ffar, distance;


		MLRLightMap *lightMap;

		Stuff::Radian
			spreadAngle;
		Stuff::Scalar
			tanSpreadAngle,
			cosSpreadAngle;
		Matrix4D
			projMatrix;
		AffineMatrix4D
			inverseLightToShape;
	};

}
