/*****************************************************************************
 * $LastChangedDate: 2011-04-23 21:07:07 -0400 (Sat, 23 Apr 2011) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Light implemented by shaders.
 *//*
 * LEGAL:   COPYRIGHT (C) 2009 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
 *****************************************************************************/

#ifndef SHADER_LIGHT_SHADER_HH
#define SHADER_LIGHT_SHADER_HH 1

#include <vector>
#include "base/singleton.hh"
namespace view { class View; }
using namespace view;
#include "shader/light_base.hh"

namespace shader {

#define GET_SHADER_LIGHT() (ShaderLight::GetInstance())

class ShaderLight_PreDrawViewListener;  // to transform light position

////////////////////////////////////////////////////////////////////////////////
/// @brief Light implemented by shaders.
///
/// Most clients should use the interface of Light class (shader/light.hh).
/// ShaderLight is a private implementation of Light class.
///
/// Provides a traditional OpenGL interface over shaders
/// to shader-emulated light sources, fog, etc.
///
class ShaderLight : public BaseLight
{
PREVENT_COPYING(ShaderLight)
friend class Light;
friend class ShaderLight_PreDrawViewListener;
private:
    ShaderLight( void );
    ~ShaderLight();

private:  // only Light class should use GET_SHADER_LIGHT()
    DEFINE_GetInstance( ShaderLight )  // Singleton

public:

// -- Light interface --

// Lights:
    void        SetLightType( const uint lightNum, const shader::defs::eLightType type );
    void        SetLightPosition( const uint lightNum, const WorldVertex& pos );
    WorldVertex GetLightPosition( const uint lightNum );
    void        SetLightColor( const uint lightNum, const RGBA color );
    void        SetLightBrightness( const fp brightness, const shader::defs::eBrightness setting );
    fp          GetLightBrightness( void );
    void        SetLightBaseAmbient( const RGBA color );

// Fog:
    void        SetFogDensity( const fpx fogDensity, const osg::Fog::Mode fogMode );
    void        SetFogColor( const RGBA fogColor );
    void        SetFogMin( const fp fogMin );

private:
    void        PreDraw( shptr<View> view );

private:
    /// @brief Defines a shader-based light source.
    ///
    struct Light
    {
        Light( void )
        : mType(shader::defs::LIGHT_DIRECTIONAL), mPos(0,0,0)
        { }

        shader::defs::eLightType    mType;      ///< light type
        WorldVertex                 mPos;       ///< light position
    };

private:
    CLASS_VAR ShaderLight*  msInstance;
    shptr<ShaderLight_PreDrawViewListener> mPreDrawViewListener;  ///< reflected to event listeners in app
    fp                      mBrightness;        ///< applied by fragment shader
    std::vector<Light>      mLights;            ///< shader-based ligh sources
};

} // namespace shader

#endif // SHADER_LIGHT_SHADER_HH
