/*****************************************************************************
 * $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 projectiles (missiles, bullets, etc).
 *//*
 * 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 GAME_PROJECTILE_HH
#define GAME_PROJECTILE_HH 1

#include "object/module.hh"
#include "object/dyna.hh"
using namespace object;
#include "physics/module.hh"
using namespace physics;

namespace game {

////////////////////////////////////////////////////////////////////////////////
/// @brief Base class for projectiles (missiles, bullets, etc).
///
/// Lua:
/// ----
/// Lua determines which Actor is the target.
/// Lua interfaces with this C++ class in terms of the Dyna class.
///
/// C++:
/// ----
/// Projectile inherits its matrix and speed from its launcher.
/// Every tick, a guidance method defined by the derivative
/// rotates the Dyna's matrix to guide the projectile.
/// Some derivatives such as Missile may define a target Object
/// and guide its projectile towards, while other derivatives
/// such as Bullet/Bomb are unguided.
///
class Projectile : public Dyna
{
PREVENT_COPYING(Projectile)
typedef Dyna Parent;
public:
                            Projectile( shptr<Graph> graph,
                                        Object&      launcher,
                                        const Speed  speed,
                                        const Meter  maxDistanceGeo,
                                        const Meter  safeDistanceGeo,
                                        const bool   malfunction = false );
    virtual                 ~Projectile();
    virtual const string    GetName( void ) { return string("Projectile"); }

protected:
    virtual WorldVertex     Guide( const fp step1 ) = 0;
    virtual void            Explode( void ) = 0;
    virtual void            HandleCollision( shptr<Object> collider );  // Template Method

private:
    virtual void            Tick( const Milliseconds millisecElapsed );

protected:
    bool                mHit;               ///< if projectile has hit anything
private:
    SpeedKPH            mSpeedKPH;          ///< scalar speed
    const fp            mMaxDistance;       ///< prevent projectile moving infinitely
    const fp            mSafeDistance;      ///< distance when collision-detection will be enabled
    const WorldVertex   mInitialPosition;   ///< initial position of projectile
    Milliseconds        mPrevTick;          ///< previous tick
    bool                mCollidable;        ///< temporarily indestructible while launching
    const bool          mMalfunction;       ///< simulate malfunction
public:
    DECLARE_TYPESIG(TYPESIG_PROJECTILE)
};

} // namespace game

#endif // GAME_PROJECTILE_HH
