/******************************************************************
  
  Module:  debris.h
  
  Author: Sean Craig
  
  Description: 

    Shards and chucks generated when an object is destroyed. 
  
  Copyright 2005 Sony Online Entertainment.  All rights reserved.
  
*******************************************************************/

#ifndef DEBRIS_H
#define DEBRIS_H

//-------------------------------------------------------- Includes
#include "SyVect3.h"
#include "nameid.h"
#include "SyVector.h"
#include "SySceneTypes.h"
#include "netpacket.h"
//-------------------------------------------------------- Typedefs
//---------------------------------------------- Class Declarations
class Titan;

class cDebrisShardMaster;
class cDebrisMaster;
class cGameObject;
class SyHavokRigidBody;

class cDebrisShard
{
public:
  cDebrisShard(Titan *titan);
  virtual ~cDebrisShard();
  
  virtual void Init(const SyVect3 &loc, const SyVect3& start_vel, const cDebrisShardMaster &master);
  virtual void Update(float time);
  void Explosion(const SyVect3 &loc, float radius, float age, tGameID attachFXID);
  void StartLevitation(const SyVect3 &loc, float radius, int id);
  void EndLevitation(int id);

  void SetGoalLocation(const SyVect3& goalLoc, float duration);
  bool IsMoving() { return mbIsMoving; }
  bool IsUsingGoalLocation() { return mbUseGoalLoc; }
  void SetGravity( float g );
  void SetAlpha(float alpha);

protected:
  virtual void _CollisionTest(const SyVect3 &displacement);
private:
  Titan                    *mpTitan;
  SyActorHandle             mActorHandle;
  int32                     mAttachedSpriteHandle;
  float                     mAttachedSpriteTimer;
#ifdef HAVOK_ENABLED
  SyHavokRigidBody*         mRigidBody;
#endif
  bool                      mbIsMoving;
  int                       mBounces;
  SyVect3                   mLoc;
  SyVect3                   mVelocity;
  float                     mRotSpeed;
  float                     mRotAngle;
  float                     mHeading;
  float                     mRadius;
  float                     mHeight;

  float                     mLastExplosionAge;

  float                     mGravityValue;
  int                       mLevitationID;

  bool                      mbUseGoalLoc;
  SyVect3                   mGoalLoc;
};


class cDebris
{
public:
  cDebris(Titan *titan);
  ~cDebris();

  void Init(cGameObject *obj, const SyVect3& force,const cDebrisMaster &master,float RandomMag);
  void Update(float time);

  bool IsDead();

  void Explosion(const SyVect3 &loc, float radius, float age, tGameID attachFXID);
  void StartLevitation(const SyVect3 &loc, float radius,int id);
  void EndLevitation(int id);

  void SetGoalLocation(const SyVect3& goalLoc, float duration);

  tGameObjectID GetSourceID() { return mSourceID; }
private:
  void _NewShard(cDebrisShardMaster  *master, const SyVect3 &loc, const SyVect3 &force, float RandomMag );

  Titan                    *mpTitan;
  SyVector<cDebrisShard *>  mShards;
  float                     mAge;
  tGameObjectID             mSourceID;
};


class cDebrisShardMaster
{
public:
  cDebrisShardMaster();
  ~cDebrisShardMaster();

  char *                    mModelName;
  int32                     mSpriteTemplateHandle;
  int                       mQuantity;
  float                     mRadius;
  float                     mScale;
  float                     mHeight;
  int32                     mNodeID;
};


class cDebrisMaster
{ 
public:
  cDebrisMaster();
  ~cDebrisMaster();

  
  cNameID                          mID;
  SyVector<cDebrisShardMaster *>   mShardMasters;
  float                            mRadius;

};


class cDebrisSys
{
public:
  cDebrisSys(Titan *pTitan);
  virtual ~cDebrisSys();

  void    Init();
  void    Clear();
  void    Update(float time);
  void    Spawn(cGameObject *obj, const SyVect3 &force,tGameID debrisID,float RandomMag=1.0f);

  bool    Exists(tGameID debrisID);
  void    Explosion(const SyVect3 &loc, float radius, float explosionAge, tGameID attachFXID = ID_NONE);

  int     allocateLevitation(){return mLevitationID++;}; // returns id
  void    StartLevitation(const SyVect3 &loc, float radius, int id); 
  void    EndLevitation(int id);

  void    ReForm(tGameObjectID objID, float duration);
private:
  Titan                       *mpTitan;
  SyVector<cDebris*>           mDebris;
  int                          mLevitationID;
};

//------------------------------------------- Function Declarations

void Debris_RegisterTuningVariables();
//--------------------------------------------------------- Globals
//------------------------------------------------ Inline Functions

#endif
