//--------------------------------------------------------------------------------------
// Copyright (C) 2008 http://shift.delblanco.es
//--------------------------------------------------------------------------------------
// SHIFT Videogame is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
//--------------------------------------------------------------------------------------
/// \file 3DLight.h
/// Clase para manejar las luces 3D de la escena.
/// Fichero con la especificación de los atributos y funciones de las luces 3D
/// que se pueden situar en la escena
//--------------------------------------------------------------------------------------
#pragma once
#ifndef __C3DLigth_H__
#define __C3DLigth_H__

//--------------------------------------------------------------------------------------
// Ficheros de cabecera
//--------------------------------------------------------------------------------------
#include <d3d9.h>

//--------------------------------------------------------------------------------------
/// Clase para manejar las luces 3D de la escena.
//--------------------------------------------------------------------------------------
class C3DLight
{

private:  // Campos miembro

    bool                 m_bInit;               ///< Flag que indica si el objeto está inicializado
    IDirect3DDevice9*    m_pDevice;             ///< Puntero al dispositivo de DirectX

    D3DLIGHT9            m_Light;               ///< Luz
    bool				 m_bModified;			///< Indica si hay que refrescar la luz
    bool                 m_bFallOff;            ///< Indica si se están apagando las luces lentamente
    bool                 m_bFallIn;             ///< Indica si se están encendiendo las luces lentamente
    float                m_FallSpd;             ///< Velocidad del FallOff o FallIn actual
    D3DCOLORVALUE        m_Diffuse_ori;         ///< Luz difusa original
    D3DCOLORVALUE        m_Specular_ori;        ///< Luz especular original
    D3DCOLORVALUE        m_Ambient_ori;         ///< Luz ambiental original

public: // Métodos públicos

    /// Constructor
    C3DLight();
    /// Destructor
    ~C3DLight();

    /// Carga la luz ante un CreateDevice
    bool initialize();
    /// Renderiza la luz ante un FrameRender (no requiere implementación)
    void render()							{}
    /// Actualiza la luz ante un FrameMove
    void update();
    /// Restaura la luz ante un ResetDevice
    void restore();
    /// Libera la luz ante un LostDevice (no requiere implementación)
    void free()								{}
    /// Libera la luz ante un DestroyDevice
    void Release();

    /// Apagar las luces lentamente
    void FallOff(float Spd = 0.0f);
    /// Enciende las luces lentamente
    void FallIn(float Spd = 0.0f);

    /// Funcion observadora del tipo de luz
    D3DLIGHTTYPE getType()                  {return m_Light.Type;}
    /// Funcion observadora de la componente difusa de la luz
    void getDiffuse(D3DCOLORVALUE &vCol)    {vCol = m_Light.Diffuse;} 
    /// Funcion observadora de la componente especular de la luz
    void getSpecular(D3DCOLORVALUE &vCol)   {vCol = m_Light.Specular;} 
    /// Funcion observadora de la componente ambiental de la luz
    void getAmbient(D3DCOLORVALUE &vCol)    {vCol = m_Light.Ambient;} 
    /// Funcion observadora de la posición de la luz
    void getPosition(D3DVECTOR &vPos)       {vPos = m_Light.Position;} 
    /// Funcion observadora de la dirección de la luz
    void getDirection(D3DVECTOR &vDir)      {vDir = m_Light.Direction;} 
    /// Funcion observadora del rango
    float getRange()                        {return m_Light.Range;}
    /// Funcion observadora del decaimiento
    float getFalloff()                      {return m_Light.Falloff;}
    /// Funcion observadora de la atenuación0
    float getAttenuation0()                 {return m_Light.Attenuation0;}
    /// Funcion observadora de la atenuación1
    float getAttenuation1()                 {return m_Light.Attenuation1;}
    /// Funcion observadora de la atenuación2
    float getAttenuation2()                 {return m_Light.Attenuation2;}
    /// Funcion observadora de Theta
    float getTheta()                        {return m_Light.Theta;}
    /// Funcion observadora de Phi
    float getPhi()                          {return m_Light.Phi;}

    /// Establece el tipo de luz
    void setType(D3DLIGHTTYPE v)            {m_Light.Type=v; m_bModified=true;}
    /// Establece la componente difusa de la luz
    void setDiffuse(float r, float g, float b, float a)
        {m_Light.Diffuse.r=r; m_Light.Diffuse.g=g; m_Light.Diffuse.b=b; m_Light.Diffuse.a=a;
		 m_Diffuse_ori.r=r; m_Diffuse_ori.g=g; m_Diffuse_ori.b=b; m_Diffuse_ori.a=a;
         m_bModified=true;} 
    /// Establece la componente especular de la luz
    void setSpecular(float r, float g, float b, float a)
        {m_Light.Specular.r=r; m_Light.Specular.g=g; m_Light.Specular.b=b; m_Light.Specular.a=a;
		 m_Specular_ori.r=r; m_Specular_ori.g=g; m_Specular_ori.b=b; m_Specular_ori.a=a;
         m_bModified=true;} 
    /// Establece la componente ambiental de la luz
    void setAmbient(float r, float g, float b, float a)
        {m_Light.Ambient.r=r; m_Light.Ambient.g=g; m_Light.Ambient.b=b; m_Light.Ambient.a=a;
		 m_Ambient_ori.r=r; m_Ambient_ori.g=g; m_Ambient_ori.b=b; m_Ambient_ori.a=a;
         m_bModified=true;} 
    /// Establece la posición
    void setPosition(D3DVECTOR vPos)        {m_Light.Position=vPos; m_bModified=true;} 
    /// Establece la dirección
    void setDirection(D3DVECTOR vDir)       {m_Light.Direction=vDir; m_bModified=true;} 
    /// Establece el rango
    void setRange(float v)                  {m_Light.Range=v; m_bModified=true;}
    /// Establece el decaimiento de la luz
    void setFalloff(float v)                {m_Light.Falloff=v; m_bModified=true;}
    /// Establece la ateniación0
    void setAttenuation0(float v)           {m_Light.Attenuation0=v; m_bModified=true;}
    /// Establece la ateniación1
    void setAttenuation1(float v)           {m_Light.Attenuation1=v; m_bModified=true;}
    /// Establece la ateniación2
    void setAttenuation2(float v)           {m_Light.Attenuation2=v; m_bModified=true;}
    /// Establece Theta
    void setTheta(float v)                  {m_Light.Theta=v; m_bModified=true;}
    /// Establece Phi
    void setPhi(float v)                    {m_Light.Phi=v; m_bModified=true;}

};

#endif
