/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   200X/X/X - 2014/01/24
/// 
/// @brief  DirectX ライトオブジェクト
/// 
/// ****************************************************************************

#pragma once

#include "CPL_DX_Kernel.h"

namespace CPL {
namespace DX {
namespace Object {


/// @cond
namespace zzz_ {

// _____________________________________________________________________________
/// @brief ライトカラー
///
// *****************************************************************************
class LightColor
{
protected:
  DX::ColorType m_color;

public:
  LightColor() : m_color(1.0f,1.0f,1.0f,1.0f) {}
  LightColor( DX::ColorType const& in_color ) : m_color(in_color) {}

  void                 SetColor( DX::ColorType const& in_color ){ m_color = in_color; }
  void                 GetColer( DX::ColorType& out_color ){ out_color = m_color; }
  DX::ColorType const* GetColor() const { return &m_color; }
  float                GetColorR() const { return m_color.r; }
  float                GetColorG() const { return m_color.g; }
  float                GetColorB() const { return m_color.b; }
  float                GetColorA() const { return m_color.a; }
};


// _____________________________________________________________________________
/// @brief ライト法線
///
// *****************************************************************************
class LightNormal
{
protected:
  DX::Vector3 m_normal;

public:
  LightNormal() : m_normal(0.0f, 1.0f, 0.0f) {}
  LightNormal( DX::Vector3 const& in_normal ) : m_normal(in_normal) {}

  void               SetNormal( DX::Vector3 const& in_normal ){ m_normal = in_normal; }
  void               GetNormal( DX::Vector3& out_normal ){ out_normal = m_normal; }
  DX::Vector3 const* GetNormal() const { return &m_normal; }
  float              GetNormalX() const { return m_normal.x; }
  float              GetNormalY() const { return m_normal.y; }
  float              GetNormalZ() const { return m_normal.z; }
};


// _____________________________________________________________________________
/// @brief ライトパワー
///
// *****************************************************************************
class LightPower {
protected:
  float m_power;

public:
  LightPower() : m_power( 1.0f ) {}
  LightPower( float in_power ) : m_power( in_power ) {}

  void  SetPower( float in_power ){ m_power = in_power; }
  float GetPower() const { return m_power; }
  void  GetPower( float& out_power ){ out_power = m_power; }
};


// _____________________________________________________________________________
/// @brief ライト座標
///
// *****************************************************************************
class LightPosition {
protected:
  DX::Vector3 m_position;

public:
  LightPosition() : m_position(0.0f, 0.0f, 0.0f) {}
  LightPosition( DX::Vector3 const in_pos ) : m_position(in_pos) {}

  void               SetPosition( DX::Vector3 const& in_position ){ m_position = in_position; }
  void               GetPosition( DX::Vector3& out_position ){ out_position = m_position; }
  DX::Vector3 const* GetPosition() const { return &m_position; }
  float              GetPositionX() const { return m_position.x; }
  float              GetPositionY() const { return m_position.y; }
  float              GetPositionZ() const { return m_position.z; }
};


} // namespace zzz_
/// @endcond


// _____________________________________________________________________________
/// @brief 平方光ライトオブジェクト
///
// *****************************************************************************
class DirectionalLight
  : public zzz_::LightColor
  , public zzz_::LightNormal
  , public zzz_::LightPower
{
public:
  DirectionalLight(){}
  DirectionalLight(
        DX::ColorType const& in_color,
        DX::Vector3 const&   in_normal,
        float                in_power )
    : zzz_::LightColor( in_color ),
      zzz_::LightNormal( in_normal ),
      zzz_::LightPower( in_power )
  {}
};


// _____________________________________________________________________________
/// @brief 点光源ライトオブジェクト
///
// *****************************************************************************
class PointLight
  : public zzz_::LightColor
  , public zzz_::LightPosition
  , public zzz_::LightPower
{
public:
  PointLight(
        DX::ColorType const& in_color,
        DX::Vector3 const& in_position,
        float in_power )
    : zzz_::LightColor( in_color ),
      zzz_::LightPosition( in_position ),
      zzz_::LightPower( in_power )
  {}
};


// _____________________________________________________________________________
/// @brief スポットライトオブジェクト
///
// *****************************************************************************
class SpotLight
  : public zzz_::LightColor
  , public zzz_::LightPosition
  , public zzz_::LightPower
{
protected:
  float m_theta, m_phi;
public:
  SpotLight()
    : m_theta( toRAD(30) )
    , m_phi( toRAD(45) )
  {}
  SpotLight
  ( DX::ColorType const& in_color
  , DX::Vector3 const&   in_pos
  , float                in_power
  , float                in_theta
  , float                in_phi )
    : zzz_::LightColor( in_color )
    , zzz_::LightPosition( in_pos )
    , zzz_::LightPower( in_power )
    , m_theta( in_theta )
    , m_phi( in_phi )
  {}

  void  SetTheta( float in_theta ){ m_theta = in_theta; }
  void  SetPhi  ( float in_phi   ){ m_phi   = in_phi; }
  float GetTheta() const { return m_theta; }
  float GetPhi  () const { return m_phi; }
  void  GetTheta( float& out_theta ) const { out_theta = m_theta; }
  void  GetPhi  ( float& out_phi   ) const { out_phi   = m_phi;   }
};


} // namespace Object
} // namespace DX
} // namespace CPL
