/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   200X/X/X - 2014/02/05
/// 
/// @brief  シェーダー共通フラグメント（基底ヘッダー）
/// 
/// ****************************************************************************

#pragma once

#include "CPL_DX_Shader_Base.h"


namespace CPL    {
namespace DX     {
namespace Shader {
namespace CSF    { // Common Shader Fragment
  
// KW == Keyword


#define CPL_DX_CSF_DEFINED_DERIVED_CLASS_for_ID_TEMPLATE(class_name,base_name)\
  template<int ID>\
  class class_name : public base_name {\
  protected:\
    class_name() {}\
  }

#define CPL_DX_CSF_DEFINED_DERIVED_CLASS_for_ID_TEMPLATE_and_ARG_NUM(class_name,base_name)\
  template<int ID>\
  class class_name : public base_name {\
  protected:\
    class_name( int in_num ) : base_name( in_num ) {}\
  }

#define CPL_DX_CSF_DEFINED_DERIVED_CLASS_for_SETUP_CPTYPE_and_ARG_NUM(class_name,base_name,cp_type)\
  class class_name : public base_name {\
  protected:\
    class_name( int in_num ) : base_name( cp_type, in_num ) {}\
  }

#define CPL_DX_CSF_DEFINED_DERIVED_CLASS_N_TYPE( class_name )\
  template<int N>\
  class class_name##N : public class_name {\
  protected:\
    class_name##N() : class_name( N ) {}\
  }
  

// global parameter name
struct KW_G_Material         { static CodeStrings::css16 kw_g_material         ; };
struct KW_G_Texture          { static CodeStrings::css16 kw_g_texture          ; };
struct KW_G_Sampler          { static CodeStrings::css16 kw_g_sampler          ; };
struct KW_G_PixelColor       { static CodeStrings::css16 kw_g_pixel_color      ; };
struct KW_G_AmbientLight     { static CodeStrings::css16 kw_g_ambient_light    ; };
struct KW_G_DirectionalLight { static CodeStrings::css32 kw_g_directional_light; };
struct KW_G_PointLight       { static CodeStrings::css16 kw_g_point_light      ; };
struct KW_G_SpotLight        { static CodeStrings::css16 kw_g_spot_light       ; };
struct KW_G_EyePosition      { static CodeStrings::css16 kw_g_eye_position     ; };
struct KW_G_Matrix           { static CodeStrings::css16 kw_g_matrix           ; };
struct KW_G_MtxProj          { static CodeStrings::css16 kw_g_mtx_proj         ; };
struct KW_G_MtxView          { static CodeStrings::css16 kw_g_mtx_view         ; };
struct KW_G_MtxViewProj      { static CodeStrings::css16 kw_g_mtx_view_proj    ; };
struct KW_G_MtxWorld         { static CodeStrings::css16 kw_g_mtx_world        ; };
struct KW_G_MtxBillboard     { static CodeStrings::css16 kw_g_mtx_billboard    ; };

// input parameter name
struct KW_InPosition   { static CodeStrings::css16 kw_in_position   ; };
struct KW_InPositionT  { static CodeStrings::css16 kw_in_positiont  ; };
struct KW_InBWeight    { static CodeStrings::css16 kw_in_bweight    ; };
struct KW_InBIndex     { static CodeStrings::css16 kw_in_bindex     ; };
struct KW_InNormal     { static CodeStrings::css16 kw_in_normal     ; };
struct KW_InPSize      { static CodeStrings::css16 kw_in_psize      ; };
struct KW_InColor      { static CodeStrings::css16 kw_in_color      ; };
struct KW_InTexCoord   { static CodeStrings::css16 kw_in_texcoord   ; };
struct KW_InTangent    { static CodeStrings::css16 kw_in_tangent    ; };
struct KW_InBiNormal   { static CodeStrings::css16 kw_in_binormal   ; };
struct KW_InSV_Position{ static CodeStrings::css16 kw_in_svposition ; };
struct KW_InVFace      { static CodeStrings::css16 kw_in_vface      ; };
//struct KW_InTarget    { static CodeStrings::css16 kw_in_target     ; };

// output parameter name
struct KW_OutPosition   { static CodeStrings::css16 kw_out_position   ; };
struct KW_OutPSize      { static CodeStrings::css16 kw_out_psize      ; };
struct KW_OutFog        { static CodeStrings::css16 kw_out_fog        ; };
struct KW_OutColor      { static CodeStrings::css16 kw_out_color      ; };
struct KW_OutTexCoord   { static CodeStrings::css16 kw_out_texcoord   ; };
struct KW_OutTessFactor { static CodeStrings::css16 kw_out_tess_factor; };
struct KW_OutTarget     { static CodeStrings::css16 kw_out_target     ; };
struct KW_OutDepth      { static CodeStrings::css16 kw_out_depth      ; };

// local parameter name
struct KW_L_Position { static CodeStrings::css16 kw_l_position; };
struct KW_L_Normal   { static CodeStrings::css16 kw_l_normal  ; };
struct KW_L_Color    { static CodeStrings::css16 kw_l_color   ; };
struct KW_L_Matrix   { static CodeStrings::css16 kw_l_matrix  ; };

// other parameter name
struct KW_Diffuse  { static CodeStrings::css16 kw_diffuse ; };
struct KW_Specular { static CodeStrings::css16 kw_specular; };
struct KW_Emissive { static CodeStrings::css16 kw_emissive; };
struct KW_Position { static CodeStrings::css16 kw_position; };
struct KW_Normal   { static CodeStrings::css16 kw_normal  ; };
struct KW_Power    { static CodeStrings::css16 kw_power   ; };
struct KW_Theta    { static CodeStrings::css16 kw_theta   ; };
struct KW_Phi      { static CodeStrings::css16 kw_phi     ; };


/// @cond
namespace zzz_ {
  // =============================================================================
  // ライトオブジェクト用基底クラス
  // =============================================================================
  class BaseLight
    : virtual public CodeFragment
  {
  protected:
    U32 m_color_type; // 0:vertex color  1:material color
    U32 m_light_num;

    BaseLight( U32 in_light_num )
      : m_color_type( 0 )
      , m_light_num( in_light_num )
    {}

    // カラーモード判定
    int CheckColorMode( CIV_Global const& in_global_param ) const;
  };
} // namespace zzz_
/// @endcond

  //// =============================================================================
  //// 変数宣言用簡易クラス
  //// =============================================================================
  //class VariableBase :
  //  virtual public CodeFragment
  //{
  //protected:
  //  CIVariable m_variable;

  //protected:
  //  VariableBase( CIVariable const& in_variable ) :
  //    m_variable( in_variable )
  //  {}
  //};
  //
  //// =============================================================================
  //// グローバルパラメーター
  //// =============================================================================
  //template<int ID>
  //class GlobalParameter :
  //  public VariableBase
  //{
  //protected:
  //  void On_SetupGlobalParameter( CIV_Global& out_global_param )
  //  {
  //    out_global_param << m_variable;
  //  }

  //  GlobalParameter( CIVariable const& in_variable ) :
  //    VariableBase( in_variable )
  //  {}
  //};

  //// =============================================================================
  //// 入力パラメーター
  //// =============================================================================
  //template<int ID>
  //class InputParameter :
  //  public VariableBase
  //{
  //  void On_SetupInputParameter( CIV_Input& out_input_param )
  //  {
  //    out_input_param << m_variable;
  //  }

  //  InputParameter( CIVariable const& in_variable ) :
  //    VariableBase( in_variable )
  //  {}
  //};


  //// =============================================================================
  //// 出力パラメーター
  //// =============================================================================
  //template<int ID>
  //class OutputParameter :
  //  public VariableBase
  //{
  //  void On_SetupOutputParameter( CIV_Output& out_output_param )
  //  {
  //    out_output_param << m_variable;
  //  }

  //  OutputParameter( CIVariable const& in_variable ) :
  //    VariableBase( in_variable )
  //  {}
  //};


/*
// =============================================================================
// 変数定義フラグメント用基底クラス
// =============================================================================
class VariableBase :
  virtual public CodeFragment
{
protected:
  virtual void
    On_CreateVariable(
      CIVariable& out_param_list,
      char_cptr   in_name ) = 0;
};


// =============================================================================
// マテリアル構造体
// =============================================================================
class StMaterial :
  public VariableBase,
  public KW_Material
{
protected:
  void CreateVariable( CIVariable& out_param_list, char_cptr in_name );
};

// =============================================================================
// マテリアル変数
// =============================================================================
class VaMaterial :
  public VariableBase,
  public KW_

// =============================================================================
// ライトデータ
// =============================================================================
class VaLight :
  public VariableBase,
  public KW_M_Light
{
protected:
  void CreateStructure( CIVariable& out_param_list );
  void CreateVariable ( CIVariable& out_param_list, char_cptr in_name );
};

// =============================================================================
// テクスチャー
// =============================================================================
classVa Texture :
  public VariableBase
{
protected:
  int    m_tex_num;
  CPType m_type;

  void CreateVariable( CIVariable& out_param_list, char_cptr in_name );

private:
  Texture( CPType const& in_type, int in_tex_num ) :
    m_type( in_type ),
    m_tex_num( in_tex_num )
  {}
  friend class Texture1D;
  friend class Texture2D;
  friend class Texture3D;
};

class Texture1D : public Texture {
protected:
  Texture1D( int in_tex_num ) : Texture( cp_Texture1D, in_tex_num ){}
};

class Texture2D : public Texture {
protected:
  Texture2D( int in_tex_num ) : Texture( cp_Texture2D, in_tex_num ){}
};

class Texture3D : public Texture {
protected:
  Texture3D( int in_tex_num ) : Texture( cp_Texture3D, in_tex_num ){}
};


// =============================================================================
// サンプラー
// =============================================================================
class Sampler :
  public VariableBase
{
protected:
  CPType m_type;
  void CreateVariable( CIVariable& out_param_list, char_cptr in_name );

private:
  Sampler( CPType const& in_type ) :
    m_type( in_type )
  {}
  friend class Sampler1D;
  friend class Sampler2D;
  friend class Sampler3D;
};

class Sampler1D : public Sampler {
protected:
  Sampler1D() : Sampler( cp_Sampler1D ) {}
};

class Sampler2D : public Sampler {
protected:
  Sampler2D() : Sampler( cp_Sampler2D ) {}
};

class Sampler3D : public Sampler {
protected:
  Sampler3D() : Sampler( cp_Sampler3D ) {}
};


// =============================================================================
// カラー
// =============================================================================
class Color :
  public VariableBase
{
protected:
  void CreateVariable( CIVariable& out_param_list, char_cptr in_name );

  Color(){}
};
*/



} // namespace CSF
} // namespace Shader
} // namespace DX
} // namespace CPL
