/******************************************************************
  
  Module:  graphic.h
  
  Author: Sean Craig
  
  Description: Handles rendering of an object.  Could be a static 
  model, an animatted model, or perhaps a particle system. 
  
  Copyright 2005 Sony Online Entertainment.  All rights reserved.
  
*******************************************************************/

#ifndef GRAPHIC_H
#define GRAPHIC_H

//-------------------------------------------------------- Includes
#include "SySceneTypes.h"
#include "SyPropObject.h"
#include "animcontroller.h"
//-------------------------------------------------------- Typedefs
//---------------------------------------------- Class Declarations

class cGameObject;
class SyScene;

class cGraphic : public SyPropObject
{
public:
  cGraphic();
  virtual ~cGraphic(){};

  /* Property Class Support */
  static int           InitPropClass();
  static SyPropObject* Creator();  
  static const int     mCLASSID            =  0xFFFF4001;

  // public interface

  virtual void Init(){};
  virtual void Exit(){};
  virtual void Reload(){}; // during level transition
  virtual void Reset(){};
  virtual void Update(float time){};
  virtual void Prerender(){};
//  virtual void SetAlpha(float alpha){};
//  virtual float GetAlpha() { return 1.0f; };
  virtual bool CheckForDelete(){return false;};
  virtual int RagdollOn() { return 0; }
  virtual int RagdollOff(int immediate) { return 1; }
  virtual void SetStartRagdollVector( const SyVect3 & v ) {}

  virtual void SetDirty() {}

  void SetVisible(bool bVisible);
  bool GetVisible();
  void SetOwner(cGameObject *);
  virtual void NetworkReceiveBroadcast(const char *packet,int size){};
  virtual void          EnterScope(){}; // called when an object enters scope (inside simulation bubble)
  virtual void          ExitScope(){}; // called when an object leaves scope (outside simulation bubble)
  virtual void          SceneClearAndInit(){}; // lets the graphic know that the scene has been cleared.

  virtual SyActorHandle         GetActorHandle(){return SyActorNull;};

  // utility function - just sticking here b/c it seemed like the best spot - BP
  static void SetMeshEmitter(int32 fxSpriteHandle, int32 emitterMeshSpriteHandle, SyScene& scene);
protected:

  cGameObject       *mOwner;
};


class cGraphicActor : public cGraphic
{
public:
  cGraphicActor();
  virtual ~cGraphicActor();


  /* Property Class Support */
  static int            InitPropClass();
  static SyPropObject*  Creator();
  static const int      mCLASSID       =  0xFFFF4002;

  // public interface

  virtual void          SceneClearAndInit();
  virtual void          Reload(); // during level transition
  virtual void          Release();
  virtual void          Init();
//  virtual void          SetAlpha(float alpha);
//  virtual float         GetAlpha();
  virtual void          Prerender();
  virtual int           RagdollOn();
  virtual int           RagdollOff(int immediate);
  void                  SetStartRagdollVector( const SyVect3 & v );

  virtual SyActorHandle         GetActorHandle(){return mActorHandle;};

  void SetActor(const char* modelName, const char* ragdollName, const char* fullPath);

  void AddEffect(int index, tGameID effectID);
  void RemoveEffect(int index, tGameID effectID);
  bool GetIdentNodeLocation(SyRefID identNode, SyVect3* pLoc);
  bool GetIdentNodeTransform(SyRefID identNode, SyMatrix44* pTransform);

protected:
  void RemoveEffect(int index);

  SyActorHandle             mActorHandle;

  static const int MAX_EFFECTS = 2;
  int32                     mBodyAttachFXIndex[MAX_EFFECTS];
  tGameID                   mAttachFXID[MAX_EFFECTS];
};

class SyCamera;
class cGraphicCharacter : public cGraphicActor
{
public:
  cGraphicCharacter();
  virtual ~cGraphicCharacter();

  /* Property Class Support */
  static int            InitPropClass();
  static SyPropObject*  Creator();
  static const int      mCLASSID   =  0xFFFF4003;

  // public interface

  virtual void          Init();
  virtual void          Reset();
  virtual void          Exit();
  virtual void          Update(float time); // once/frame
  virtual void          SetDirty(){mDirty = true;};
  virtual void          Prerender();
  virtual bool          CheckForDelete();

  cAnimCharControllerInput *GetAnimInput(){return mAnimController->GetInput();};
  virtual void          EnterScope(); // called when a character enters scope (inside simulation bubble)
  virtual void          ExitScope(); // called when an object leaves scope (outside simulation bubble)
  const SyVect3 &       GetDisplacement(); // how much root node has moved this frame.

  virtual void          NetworkReceiveBroadcast(const char *packet,int size){mAnimController->NetworkReceiveBroadcast(packet,size);}
  cAnimCharControllerInterface *GetAnimController(){return mAnimController;};

  void                  DrawRing(SyCamera &camera); // for player character

  void AddItemEffect(int equipSlot, tGameID fxID);
  void RemoveItemEffect(int equipSlot, tGameID fxID);

  bool GetEquipSlotTransform(int slot, SyMatrix44* pTransform);

  void RecalculateWeaponAttachments();

protected:

  cAnimCharControllerInterface *mAnimController;
  SyVect3                   mAnimDisplacement;
  bool                      mDirty; // need to recalculate weapon attachments, skins, etc. 

  static const int NUM_ATTACH_SLOTS = 6;
  int32 mItemFXSpriteHandles[NUM_ATTACH_SLOTS];
  tGameID mItemFXIDs[NUM_ATTACH_SLOTS];
  int32   mWpnEmitterMeshSpriteHandle;
  int32   mWpnLeftEmitterMeshSpriteHandle;
};

class cGraphicProp : public cGraphicActor
{
public:
  cGraphicProp();
  virtual ~cGraphicProp();

  /* Property Class Support */
  static int            InitPropClass();
  static SyPropObject*  Creator();
  static const int      mCLASSID        =  0xFFFF4004;

  // public interface

  virtual void          Init();
  virtual void          Reset();
  virtual void          Update(float time); // once/frame

  virtual void          NetworkReceiveBroadcast(const char *packet,int size);
  
  cAnimPropControllerInterface *GetAnimController(){return mAnimController;};

protected:
  cAnimPropControllerInterface *mAnimController;
};

class cGraphicDummy : public cGraphicActor
{
public:
  cGraphicDummy();
  virtual ~cGraphicDummy();

  /* Property Class Support */
  static int            InitPropClass();
  static SyPropObject*  Creator();
  static const int      mCLASSID        =  0xFFFF4005;

  // public interface
  virtual void          Init();

protected:
};

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

void RegPropClasses_Graphic();
int GetAttachSlotFromEquip (int i);
//--------------------------------------------------------- Globals
//------------------------------------------------ Inline Functions

#endif
