/******************************************************************
  
  Module:  script_pawn.h
  
  Author: Sean Craig
  
  Description: Titan specific code for interfacing with the Pawn 
  scripting language

  
  Copyright 2005 Sony Online Entertainment.  All rights reserved.
  
*******************************************************************/

#ifndef SCRIPT_PAWN_H
#define SCRIPT_PAWN_H

//-------------------------------------------------------- Includes
#include "gameobj.h"
#include "Titan.h"
//-------------------------------------------------------- Typedefs
//---------------------------------------------- Class Declarations

typedef enum
{
  PET_ACTIVATE,  // Character activates an object

  PET_TRIGGER_ENTER,     // Character enters a trigger zone
  PET_TRIGGER_EXIT,      // Character exits a trigger zone

  PET_STARTUP,   // on level load
  PET_COLLIDE,   // Character collides with an object
  PET_HIT,
  PET_DEATH,
  PET_INIT,

  PET_SPELL_CAST,
  PET_SPELL_AREA_ENTER, // object entered spell area 
  PET_SPELL_AREA_EXIT,  // object left spell area

  NUM_EVENT_TYPES

} ePawnEventType;

typedef unsigned int tScriptInstanceID; 

static const tScriptInstanceID ID_COMPLETED = 0;

class cScriptInstance;
struct tagAMX;
typedef tagAMX AMX;

class cScriptInstanceDataProxy : public SyPropObject
{
public:
  cScriptInstanceDataProxy();
  ~cScriptInstanceDataProxy();

  // Reflection Support via SyPropObject
  static int           InitPropClass();
  static SyPropObject* Creator();
  static const SyPropClassID mCLASSID              =  0xBBBB;

  static const SyPropID PropId_ThisID           = 0x0000;
  static const SyPropID PropId_OtherID          = 0x0001;
  static const SyPropID PropId_Data             = 0x0002;
  static const SyPropID PropId_DataSize         = 0x0003;
  static const SyPropID PropId_SleepNotifyType  = 0x0004;
  static const SyPropID PropId_SleepTime        = 0x0005;
  static const SyPropID PropId_SleepingID       = 0x0006;
  static const SyPropID PropId_Cutscene         = 0x0007;
  static const SyPropID PropId_ParentIndex      = 0x0008;
  static const SyPropID PropId_AMX_cip          = 0x0009;
  static const SyPropID PropId_AMX_frm          = 0x000A;
  static const SyPropID PropId_AMX_hea          = 0x000B;
  static const SyPropID PropId_AMX_hlw          = 0x000C;
  static const SyPropID PropId_AMX_stk          = 0x000D;
  static const SyPropID PropId_AMX_stp          = 0x000E;

  tGameObjectID       mThisID;
  tGameObjectID       mOtherID;
  SyArray<uint32>     mData;
  int32               mDataSize;
  int32               mSleepNotifyType;
  float               mSleepTime;
  tGameObjectID       mSleepingID;
  bool                mbCutscene;
  int32               mParentIndex;

  int32               mAMX_cip;
  int32               mAMX_frm;
  int32               mAMX_hea;
  int32               mAMX_hlw;
  int32               mAMX_stk;
  int32               mAMX_stp;
};


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

  void      Clear();
  bool      LoadScript(const char *filename); // currently only one loaded script at a time...

  void      ScriptEvent(ePawnEventType type, tGameObjectID actor, tGameObjectID target);
  //bool      ScriptQuery(ePawnEventType type, tGameObjectID actor, tGameObjectID target,int *result);

  void      Update(float time); // resumes waiting scripts...

  //void      NotifyDestinationReached(tGameObjectID actor); // notify script that an actor has reached his destination.
  //void      NotifyAnimationCompleted(tGameObjectID actor);

  bool      Recompile(); // recompiles current script
  bool      Compile(const char *filename); // recompile named script.

  void      AddClone(cScriptInstance *instance, bool bSetActive);
  Titan *   GetTitan() const {return mpTitan;}

  void      EnableDebugging();
  void      DisableDebugging();
  void      DebugCallback(AMX *amx);
  void      DebugRestore();

  void      Startup(); // call startup script next update
  void      DebugPrint(const char *output);
  void      SetCutsceneEndHandler(const char *skip);
  bool      HasCutsceneEndHandler();

  void      EndCutscene();
  void      SkipCutscene(bool bFadeOut = false);

  void      NetworkReceiveBroadcast(const char *state,int maxlen);
  void      NetworkReceiveMessage(const char *state,int maxlen);

  void      LoadLevelScript(const char* filename, bool bInProgess);
  void      PullScriptData(SyVector<cScriptInstanceDataProxy*>& proxies);
  void      PushScriptData(SyVector<cScriptInstanceDataProxy*>& proxies);

  static int32 ProcessScriptFunction(const SyString &str);


protected:
  friend class cScriptInstance;

  cScriptInstance *GetActive() const {return mActive;}
  cScriptInstance *GetScriptInstance(int index) const;
  int GetCloneIndex(cScriptInstance *pClone) const;
  bool      LoadSourceFile(const char *filename);

  static int32 ProcessScriptFunctionHelper(const SyString &str, SyVector<SyString> &arStrings);

  cScriptInstance *               mSource; // source pawn script (gets cloned)
  cScriptInstance *               mActive; // active pawn script
  cScriptInstance *               mRunning; // running pawn script
  SyVector<cScriptInstance *>     mClones; // clones of active pawn script (because of wait conditions)
  Titan  *                        mpTitan;
  char *                          mFilename; // so i knows what to recompile
  char *                          mpSourceScriptData;

  bool                            mbDebugging; // true if we're debugging
  char *                          mSourceFile; // if debugging
  char *                          mSourceFilename;
  int                             mLastLinenum;
  bool                            mbRun; // skips stepthrough until next time.
  bool                            mbStartup; // need to run the startup script
  SyString                        mDebugOutput;
  
  float                           mRemoteUpdateTimer;

  SyString                        mCutsceneEndHandler; // for handler method of skipping callback
  float                           mCutsceneSkipTime; // for timing fadeout etc.
  bool                            mCutsceneSkipping; 
  bool                            mCutsceneEndFadeIn; 
};

//------------------------------------------- Function Declarations
tGameObjectID Script_GetThisID(AMX *amx);
tGameObjectID Script_GetOtherID(AMX *amx);
Titan *       Script_GetTitan(AMX *amx);
void          Script_SetWaitTime(AMX *amx,int time_msecs);
void          Script_RegisterTuningVariables();

void RegPropClasses_ScriptSys();

//--------------------------------------------------------- Globals
//------------------------------------------------ Inline Functions

#endif
