/*****************************************************************************
 * $LastChangedDate: 2011-04-09 21:58:06 -0400 (Sat, 09 Apr 2011) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Small particle-system.
 *//*
 * LEGAL:   COPYRIGHT (C) 2008 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
 *****************************************************************************/

#ifndef FX_PARTSYS_SMALL_HH
#define FX_PARTSYS_SMALL_HH 1

#include "base/timer.hh"
#include "gfx/module.hh"
#include "gfx/rgba.hh"
using namespace gfx;
#include "fx/partsys.hh"

namespace fx {

class SmallParticleDrawable;

////////////////////////////////////////////////////////////////////////////////
/// @brief Opaque struct that defines a small particle.
///
/// Indeed, OpenGL points can have a 3D position.
///
struct SmallParticle
{
    WorldVertex     mPosition;
};

////////////////////////////////////////////////////////////////////////////////
/// @brief Particle-system for small particles (based on OpenGL points or point-sprites).
///
/// This particle system is very fast but it has deficiencies.
/// Left unimplemented was a mechanism to update particles.
///
/// Texture is specified by stateset.
/// Example:
/// new SmallParticleSystem( SmallParticleSystem::Args( Texture::NewTextureAsStateSet( "smoke.png" ) ) );
///
class SmallParticleSystem : public ParticleSystem
{
PREVENT_COPYING(SmallParticleSystem)
typedef ParticleSystem Parent;
friend class FX; friend class shptr<SmallParticleSystem>;
public:
    /// @brief Args for SmallParticleSystem ctor.
    struct Args : public ParticleSystem::Args
    {
        enum ePointType { POINTS,               // regular OpenGL points
                          POINT_SPRITES };      // textured "point points"
        Args( const Milliseconds    lifetime,                                 // base
              const bool            timerEnabled = TimerDefs::TIMER_ENABLED,  // base
              const ePointType      pointType = POINTS,
              const uint            pointSpriteSize = 64,
              RefPtr<osg::StateSet> stateSet = new osg::StateSet );

        const ePointType        mPointType;         ///< point sprite requires texture
        const uint              mPointSpriteSize;   ///< for point sprites
        RefPtr<osg::StateSet>   mStateSet;          ///< can specify texture
    };

public:
                    SmallParticleSystem( const Args& arg );
                    ~SmallParticleSystem();
    void            AttachParticle( const SmallParticle& smallParticle );
    uint            GetParticleCount( void );
    void            SetColorAll( const RGBA color );

private:
    // OSG components:
    RefPtr<osg::StateSet>       mStateSet;          ///< specifies texture (and any other state)
    RefPtr<osg::Geode>          mGeode;
    RefPtr<osg::Geometry>       mGeom;
    RefPtr<osg::Vec3Array>      mVertexs;
    RefPtr<osg::DrawArrays>     mDrawArray;
public:
    DECLARE_TYPESIG(TYPESIG_SMALL_PARTICLE_SYSTEM)
};

} // namespace fx

#endif // FX_PARTSYS_SMALL_HH
