#include "MLRHeaders.hpp"

//#############################################################################
//###############################    MLRInfiniteLight    ##################################
//#############################################################################

MLRInfiniteLight::ClassData*
	MLRInfiniteLight::DefaultData = NULL;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRInfiniteLight::InitializeClass()
{
	Verify(!DefaultData);
	Verify(gos_GetCurrentHeap() == StaticHeap);
	DefaultData =
		new ClassData(
			MLRInfiniteLightClassID,
			"MidLevelRenderer::MLRInfiniteLight",
			MLRLight::DefaultData
		);
	Register_Object(DefaultData);
}

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

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRInfiniteLight::MLRInfiniteLight(ClassData *class_data) :
	MLRLight(class_data)
{
	Verify(gos_GetCurrentHeap() == LightsHeap);
	lightMask = MLRState::FaceLightingMode|MLRState::VertexLightingMode;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRInfiniteLight::MLRInfiniteLight(
	ClassData *class_data,
	Stuff::MemoryStream *stream,
	int version
) :
	MLRLight(class_data, stream, version)
{
	Check_Object(stream);
	Verify(gos_GetCurrentHeap() == LightsHeap);
	lightMask = MLRState::FaceLightingMode|MLRState::VertexLightingMode;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRInfiniteLight::MLRInfiniteLight(
	ClassData *class_data,
	Stuff::Page *page
) :
	MLRLight(class_data, page)
{
	Check_Object(page);
	Verify(gos_GetCurrentHeap() == LightsHeap);
	lightMask = MLRState::FaceLightingMode|MLRState::VertexLightingMode;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRInfiniteLight::~MLRInfiniteLight()
{
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRInfiniteLight::TestInstance()
{
	Verify(IsDerivedFrom(DefaultData));
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRInfiniteLight::LightVertex(const MLRVertexData& vertexData)
{
	UnitVector3D light_z;

	GetInShapeDirection(light_z);

	//
	//-------------------------------------------------------------------
	// Now we reduce the light level falling on the vertex based upon the
	// cosine of the angle between light and normal
	//-------------------------------------------------------------------
	//

	Scalar cosine = 0.7071f;

	if(vertexData.normal!=NULL)
	{
		cosine = -(light_z * (*vertexData.normal)) * intensity;
	}

	RGBColor light_color(color);

	if (cosine > SMALL)
	{
		light_color.red *= cosine;
		light_color.green *= cosine;
		light_color.blue *= cosine;
		Stuff::RGBAColor *t = const_cast<Stuff::RGBAColor*>(vertexData.color);
		Check_Pointer(t);
		t->red += light_color.red;
		t->green += light_color.green;
		t->blue += light_color.blue;
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRInfiniteLight::LightCenter(RGBAColor& rcol)
{
	UnitVector3D light_z;

	GetInShapeDirection(light_z);

	//
	//-------------------------------------------------------------------
	// Now we reduce the light level falling on the vertex based upon the
	// cosine of the angle between light and normal
	//-------------------------------------------------------------------
	//

	Scalar cosine = 0.7071f;

	RGBColor light_color(color);

	if (cosine > SMALL)
	{
		light_color.red *= cosine;
		light_color.green *= cosine;
		light_color.blue *= cosine;

		rcol.red += light_color.red;
		rcol.green += light_color.green;
		rcol.blue += light_color.blue;
	}
}
