//	Darkstar Engine  (c) UnderWorld Interactive Studio (all coding by Svarog    2007-2008)
//
//      Данный файл является частью Darkstar Engine. Любое использование кода файла
//      без согласия компании, является нарушением закона об авторском праве (в слу-
//      чае если не оговорено обратное).
//
//      Имя файла: spot_light.inl
//      Краткое описание: spot light
//

namespace gs
{
	inline SpotLight::SpotLight()
	{
		diffuse_color = specular_color = math::Vect3(1, 1, 1);
		ambient_color = math::Vect3(0, 0, 0);
		falloff = 1;
		range = 0;
		volume.setRadius(range);
		attenuation = 0;
		phi = theta = 0;
		light_state = DRSL_OFF;
		cos_phi2 = cos_theta2 = cos_theta2_cos_phi2 = 0;
		position = math::vect3_zero;
		volume.setPosition(position);
		orientation = math::Quat(0, 0, 0, 1);
	};

	inline SpotLight::SpotLight(const DRSLIGHTSTATE& light_state, const math::Vect3& position, 
		const math::Quat& orientation, const float range, 
		const float phi, const float theta, const math::Vect3& diffuse_color, 
		const math::Vect3& specular_color, const math::Vect3& ambient_color, 
		const float falloff, const float attenuation)
	{
		this->light_state = light_state;
		this->ambient_color = ambient_color;
		this->diffuse_color = diffuse_color;
		this->specular_color = specular_color;
		this->phi = phi;
		this->theta = theta;
		this->falloff = falloff;
		this->attenuation = attenuation;
		this->range = range;
		volume.setRadius(range);
		this->position = position;
		volume.setPosition(position);
		this->orientation = orientation;
		_recalc();
	};

	inline SpotLight::~SpotLight()
	{

	};

	inline void SpotLight::_recalc()
	{
		cos_phi2 = cosf(phi/2);
		cos_theta2 = cosf(theta/2);
		cos_theta2_cos_phi2 = cos_theta2 - cos_phi2;
	};

	inline void SpotLight::setLightState(const DRSLIGHTSTATE& new_light_state)
	{
		light_state = new_light_state;
	};

	inline const DRSLIGHTSTATE& SpotLight::getLightState() const
	{
		return light_state;
	};

	inline void SpotLight::toggleLightState() 
	{
		light_state = static_cast<DRSLIGHTSTATE>(1-static_cast<int>(light_state));
	};

	inline void SpotLight::setDiffuseColor(const math::Vect3& new_color)
	{
		diffuse_color = new_color;
	};

	inline const math::Vect3& SpotLight::getDiffuseColor() const
	{
		return diffuse_color;
	};

	inline void SpotLight::setSpecularColor(const math::Vect3& new_color)
	{
		specular_color = new_color;
	};

	inline const math::Vect3& SpotLight::getSpecularColor() const
	{
		return specular_color;
	};

	inline void SpotLight::setAmbientColor(const math::Vect3& new_color)
	{
		ambient_color = new_color;
	};

	inline const math::Vect3& SpotLight::getAmbientColor() const
	{
		return ambient_color;
	};

	inline void SpotLight::setRange(const float new_range)
	{
		range = new_range;
		volume.setRadius(new_range);
	};

	inline const float SpotLight::getRange() const
	{
		return range;
	};

	inline void SpotLight::setAttenuation(const float new_attenuation)
	{
		attenuation = new_attenuation;
	};

	inline const float SpotLight::getAttenuation() const
	{
		return attenuation;
	};

	inline void SpotLight::setInnerAngle(const float new_theta)
	{
		theta = new_theta;
		_recalc();
	};

	inline const float SpotLight::getInnerAngle() const
	{
		return theta;
	};

	inline void SpotLight::setOuterAngle(const float new_phi)
	{
		phi = new_phi;
		_recalc();
	};

	inline const float SpotLight::getOuterAngle() const
	{
		return phi;
	};

	inline void SpotLight::setInnerAndOuterAngle(const float new_theta, const float new_phi)
	{
		phi = new_phi;
		theta = new_theta;
		_recalc();
	};

	inline const float SpotLight::getCosPhi2() const
	{
		return cos_phi2;
	};

	inline const float SpotLight::getCosTheta2() const
	{
		return cos_theta2;
	};

	inline const float SpotLight::getCosTheta2CosPhi2() const
	{
		return cos_theta2_cos_phi2;
	};

	inline void SpotLight::setFalloff(const float new_falloff)
	{
		falloff = new_falloff;
	};

	inline const float SpotLight::getFalloff() const
	{
		return falloff;
	};

	inline const math::Sphere& SpotLight::getVolume() const
	{
		return volume;
	};

	inline void SpotLight::setPosition(const math::Vect3& new_position)
	{
		position = new_position;
		volume.setPosition(position);
	};

	inline const math::Vect3& SpotLight::getPosition() const
	{
		return position;
	};

	inline void SpotLight::setOrientation(const math::Quat& new_orientation)
	{
		orientation = new_orientation;
	};

	inline const math::Quat& SpotLight::getOrientation() const
	{
		return orientation;
	};
};