/*****************************************************************************
 * $LastChangedDate: 2011-04-09 21:58:06 -0400 (Sat, 09 Apr 2011) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Base class for particle-systems.
 *//*
 * 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_HH
#define FX_PARTSYS_HH 1

#include "base/timer.hh"

namespace fx {

class FX;

////////////////////////////////////////////////////////////////////////////////
/// @brief Base class for particle-systems.
///
/// Its derivatives are Small/BigParticleSystem.
/// The FX container contains particle-systems in terms of this class.
/// This class provide the common registering of timer-tick functors and expiration.
///
/// Features of ParticleSystem:
/// - can be derived and Tick() extended
/// - derivatives are created/contained by FX container
/// - particle-system ages/expires itself
/// - pulsed by timer-tick
/// - calls Tick() which derivates can override for optional animation of particles
///
class ParticleSystem : public Shared
{
PREVENT_COPYING(ParticleSystem)
friend class FX; friend class shptr<ParticleSystem>;
public:
    /// @brief Derivative particle-systems extend this with more args.
    struct Args
    {
        Args( const Milliseconds lifetime,
              const bool timerEnabled = TimerDefs::TIMER_ENABLED )
        :   mLifetime(lifetime),
            mTimerEnabled(timerEnabled)
        { }

        const Milliseconds  mLifetime;          ///< lifetime of entire particle-system
        const bool          mTimerEnabled;      ///< false for particles that don't need updating
    };

protected:
                    ParticleSystem( const Args& args );
    virtual         ~ParticleSystem();
    virtual void    Tick( const Milliseconds millisecElapsed );
    void            Expire( void );
    bool            IfExpired( void ) { return mZombie; }

private:
    ////////////////////////////////////////////////////////////////////////////
    /// @brief Pulsed by timer-tick to animate particle system.
    ///
    CLASS_TICK_FUNCTOR( ParticleSystem, mParticleSystem )

protected:
    const Milliseconds  mTimeOfDeath;               ///< when to destroy this particle system
    shptr<TickFunctor>  mTickFunctor;               ///< pulses animation of particle system
    bool                mRegisteredTickFunctor;
    bool                mZombie;                    ///< if expired
public:
    DECLARE_TYPESIG(TYPESIG_PARTICLE_SYSTEM);
};

} // namespace fx

#endif // FX_PARTSYS_HH
