/* (c) 1999-2000 Tino Schwarze, see COPYING for details */
/**
 * a class for managing an OpenGL directional light
 *
 * #include "cDirectionLight.hh"
 *
 * -lMesaGL or -lGL
 * -lMesaGLU or -lGLU
 *
 * @see cWorld
 */

#include "cDirectionLight.hh"

/**
 * default constructor
 	*/
cDirectionLight::cDirectionLight (
	cEventDispatcher *disp,
	const char *name)
: 	cLight (disp, name),
	mDirection (0.0, 0.0, 1.0)	// default direction
{
}

/**
 * copy constructor (only if in debugging mode)
 	*/
#if DEBUG
cDirectionLight::cDirectionLight (const cDirectionLight &l)
:	cLight (l),	// use inherited copy constructor
	mDirection (l.mDirection)
{
	ENTER_OBJECT_METHOD ("cDirectionLight::cDirectionLight (const cDirectionLight &)");
}
#endif

/**
 * constructor with initialization of position, state and name
 	* @param dir initial position of light source
	* @param name name of light source (optional)
	*/ 
cDirectionLight::cDirectionLight (
		cEventDispatcher *disp,
		const cVertex &dir, 
		const char *name)
: 	cLight (disp, name),	// no default position
	mDirection (dir)
{
}

/**
 * constructor with initialization of position, state and name
 	* @param dir initial position of light source
	* @param state initial state of light source (default: on)
	* @param name name of light source (optional)
	*/ 
cDirectionLight::cDirectionLight (
		cEventDispatcher *disp,
		const cVertex &dir, 
		const teLightState state,
		const char *name)
: 	cLight (disp, cVertex (), state, name),	// no default position
	mDirection (dir)
{
}

/**
 * constructor with initialization of position, ambient color, state and name
	*/ 
cDirectionLight::cDirectionLight (
		cEventDispatcher *disp,
		const cVertex &dir, 
		const cADSEColor &col,
		const cDirectionLight::teLightState state,
		const char *name)
: 	cLight (disp, cVertex (), col, state, name),
	mDirection (dir)
{
	// light source is not visible by default
	SetVisible (false);
}


/**
 * destructor
 	*/
cDirectionLight::~cDirectionLight ()
{
	ENTER_OBJECT_METHOD("cDirectionLight::~cDirectionLight");
	// nothing to do
}


void cDirectionLight::SetDirection (const cVertex &dir)
{
	mDirection = dir;
	// make sure, we get that direction exactly
	mRotation.SetIdentity ();
}


void cDirectionLight::ActivateLight ()
{
	GLenum light_no = (GLenum)((int) (GL_LIGHT0)+mLightSlot);

	// call inherited ActivateLight (sets light color)
	cLight::ActivateLight ();

	// now we need to overwrite the position again...
	//
	// A light's position has 4 values. if the fourth value
	// is zero, it's treated as a directional light.
	// That's a bit odd...
	GLfloat lightpos[4];

	// rotate direction
	cVertex eff_dir = mRotation*mDirection;

	lightpos[0] = eff_dir.GetX();
	lightpos[1] = eff_dir.GetY();
	lightpos[2] = eff_dir.GetZ();
	lightpos[3] = 0.0;	// directional light!

	glLightfv (light_no,
			GL_POSITION, 
			(GLfloat *)&lightpos);
}

void cDirectionLight::DrawThisObject ()
{
	// do not do anything (directional light cannot be drawn)
}

