#pragma once

#include "../graph/Color.h"

#include "GlInclude.h"


namespace lib_gl
{


//! 光源
class Light
{
public:
	Light(void) :
			m_Ambient  ( 1.0f , 1.0f , 1.0f , 1.0f ) ,
			m_Diffuse  ( 1.0f , 1.0f , 1.0f , 1.0f ) ,
			m_Specular ( 1.0f , 1.0f , 1.0f , 1.0f ) ,
			m_LightIndex( GL_LIGHT0 ) ,
			m_IsDirectional( true )
	{}
	Light( GLenum LightIndex ) :
			m_Ambient  ( 1.0f , 1.0f , 1.0f , 1.0f ) ,
			m_Diffuse  ( 1.0f , 1.0f , 1.0f , 1.0f ) ,
			m_Specular ( 1.0f , 1.0f , 1.0f , 1.0f ) ,
			m_LightIndex( LightIndex ) ,
			m_IsDirectional( true )
	{}

	// 光源の位置の同次座標値を返す
	lm::vector4f GetPos4(void) const;

	void SetGL(void);

	//! OpenGL中での光源インデックスを設定/取得する
	void SetLightIndex( GLenum i_LightIndex ){ m_LightIndex = i_LightIndex; }
	GLenum GetLightIndex(void) const { return m_LightIndex; }

	// 全要素の輝度/アルファ設定
	void SetAllBrightness( float brightness );
	void SetAllBrightness( float brightness , float alpha );
	void SetAlphaAll( float i_alpha );

	void SetAmbientPowerN(float l);
	void SetSpDfPowerN(float l);


public:
	lgr::color4f m_Ambient;
	lgr::color4f m_Diffuse;
	lgr::color4f m_Specular;

	lm::vec3f  m_Position;      //!< 位置、または方向を表す.
	bool       m_IsDirectional; //!< 平行光源ならtrue , 点光源ならfalse

protected:
	GLenum  m_LightIndex; //!< GL_LIGHT0 等の光源のインデックス
};



//! 光源の位置の同次座標値を返す
inline
lm::vector4f Light::GetPos4(void) const
{
	lm::vector4f pos4( m_Position.x , m_Position.y , m_Position.z , 0.0f );
	pos4.w = m_IsDirectional ? 0.0f : 1.0f;
	return pos4;
}

//! 光源設定の適用
inline
void Light::SetGL(void)
{
	glLightfv( m_LightIndex , GL_AMBIENT  , m_Ambient.v()  );
	glLightfv( m_LightIndex , GL_DIFFUSE  , m_Diffuse.v()  );
	glLightfv( m_LightIndex , GL_SPECULAR , m_Specular.v() );

	lm::vector4f pos4 = GetPos4();
	glLightfv( m_LightIndex , GL_POSITION , pos4.v() );
}

//! 全要素の輝度を一定値に設定する
inline
void Light::SetAllBrightness( float brightness )
{
	const float& b = brightness;
	m_Ambient.set( b , b , b , m_Ambient.a() );
	m_Diffuse.set( b , b , b , m_Diffuse.a() );
	m_Specular.set( b , b , b , m_Specular.a() );
}

//! 全要素の輝度とアルファ値を一定値に設定する
inline
void Light::SetAllBrightness( float brightness , float alpha )
{
	const float& b = brightness;
	const float& a = alpha;
	m_Ambient.set( b , b , b , a );
	m_Diffuse.set( b , b , b , a );
	m_Specular.set( b , b , b , a );
}

//! 全要素のアルファ値を一定値に設定する
inline
void Light::SetAlphaAll( float i_alpha )
{
	m_Ambient.a()  = i_alpha;
	m_Diffuse.a()  = i_alpha;
	m_Specular.a() = i_alpha;
}

inline
void Light::SetAmbientPowerN(float l)
{
	m_Ambient.set_neutral(l, 1.0f);
}

inline
void Light::SetSpDfPowerN(float l)
{
	m_Diffuse.set_neutral(l, 1.0f);
	m_Specular.set_neutral(l, 1.0f);
}


}
