/* (c) 1999-2000 Tino Schwarze, see COPYING for details */
/**@pkg cObject.cVisibleObject.cInteractiveObject.cLight.cSpotLight*/
/**
 * a class for managing a directional OpenGL light
 *
 * #include "cSpotLight.hh"
 *
 * -lMesaGL or -lGL
 *
 * @see cInteractiveObject
 * @see cLight
 * @pkgdoc cObject.cVisibleObject.cInteractiveObject.cLight.cSpotLight
 */

#ifndef cSpotLight_hh
#define cSpotLight_hh

// include class cLight to derive from
#include "cLight.hh"

// include class cColor representing an RGB(A) color for use
// with OpenGL
#include "cADSEColor.hh"

// include common project macros, definitions and headers
#include "common.hh"

/**
 * A class for an OpenGL directional light.
	* The inherited mRotation quaternion is used (in contrast to cLight)
	* - it modifies the light's direction.
	*/
class cSpotLight 
:	public cLight
{
public:
	/**
	 * default constructor
	 	*/
	cSpotLight (
		cEventDispatcher *disp,
		const char *name = NULL);

#if DEBUG
	/**
	 * copy constructor (inherited)
	 	*/
	cSpotLight (const cSpotLight &);
#endif

	/**
	 * constructor with initialization of position and name
	 	* @param pos initial position of light source
	 	* @param dir initial direction of light source
		* @param state initial state of light source (default: on)
		* @param name name of light source (optional)
	 	*/
	cSpotLight (
		cEventDispatcher *disp,
		const cVertex &pos, 
		const cVertex &dir, 
		const char *name = NULL);

	/**
	 * constructor with initialization of position, state and name
	 	* @param pos initial position of light source
	 	* @param dir initial direction of light source
		* @param state initial state of light source (default: on)
		* @param name name of light source (optional)
	 	*/
	cSpotLight (
		cEventDispatcher *disp,
		const cVertex &pos, 
		const cVertex &dir, 
		const teLightState state = LIGHT_ON, 
		const char *name = NULL);

	/**
	 * constructor with initialization of position, color, state 
	 * and name
	 	* @param dir initial direction of light source
	 	* @param pos initial position of light source
		* @param col color of the light source (cADSEColor object)
		*        (emissive color component is not used)
		* @param state initial state of light source (default: on)
		* @param name name of light source (optional)
	 	*/
	cSpotLight (
		cEventDispatcher *disp,
		const cVertex &pos, 
		const cVertex &dir, 
		const cADSEColor &col,
		const teLightState state = LIGHT_ON, 
		const char *name = NULL);

	/**
	 * destructor
	 	*/
	virtual ~cSpotLight ();

// OPERATIONS
	// note: translating the light is obtained via functions inherited from
	// cVisibleObject (@see cVisibleObject::MoveBy, cVisibleObject::MoveTo)

	/**
	 * set new direction to point to
		* @param dir new direction
		*/
	virtual void SetDirection (const cVertex &dir);

	/**
	 * set new cutoff
	 	* @param angle 0..90 (180 means point light)
		*/
	virtual void SetCutOff (const GLfloat cutoff);
	
	/**
	 * set new light distribution exponent
	 	* @param exponent 0..128 (0 = uniform light distribution)
		*/
	virtual void SetExponent (const GLfloat exponent);
	
    /**
     * event receiver - we listen for switchon/switchoff events
        *
        * @return 0 - event accepted, -1 - event not
        * accepted
        */
    virtual int ReceiveEvent (const cEvent &event);

protected:
	/**
	 * this one performs the actual set up of the light
		*
		* (called by Activate()); separeted to simplify
		* cSpotLight
		*/
	virtual void ActivateLight ();

	/**
	 * A light is a visible object therefore it needs a drawing function
	 	*
		* Not used here - a SpotLight cannot be drawn!
	 	*/
	virtual void DrawThisObject ();

	/**
	 * restore old cutoff/exponent (called by cLight::Deactivate())
	 	*/
	virtual void DeactivateLight ();

    /**
     * we want to get events for altering cutoff/exponent
        */
    virtual void SubscribeToActiveEvents ();

    /**
     * unsubscribe from events if we get deselected
        */
    virtual void UnsubscribeFromActiveEvents ();


	/**
	 * identify an instance of this class if it's got no name
	 	*/
	virtual const char *GetDefaultName () const
	{
		return "cLight";
	}

	/** actual direction */
	cVertex mDirection;

	/** current cutoff */
	GLfloat mCutOff;

	/** current exponent */
	GLfloat mExponent;

	/** saved cutoff */
	GLfloat mOldCutOff;

	/** saved exponent */
	GLfloat mOldExponent;
};

#endif	// ifndef cSpotLight_hh

