#pragma once
#if !defined(IGINTERFACE_H_INC)
#define IGINTERFACE_H_INC


#if !defined(G_ICARUS_H_INC)
	#include "../newgame/g_icarus.h"
#endif

class CICARUSGameInterface
{

/************************************************************************************************
 *	CICARUSGameInterface:											                            *
 *															                                    *
 *	Contains member functions which correspond to function pointers in Q3_Interface.cpp.        *
 *								                                                                *
 *																							    *
 *                                                                                              *
 ************************************************************************************************/


public:

			CICARUSGameInterface(void) {};
			~CICARUSGameInterface(void){};

static void		DebugPrint( int level, const char *format, ... );
static CSequencer	*GetEntitySequencerByName( const char *name );
static DWORD		GetTime( void );
static void		Lerp2Pos( int taskID, int entID, vec3_t origin, vec3_t angles, float duration );
static void		Lerp2Angles( int taskID, int entID, vec3_t angles, float duration );
static bool		PlaySound( int taskID, int entID, const char *name, const char *channel );
static void		TaskIDSet( CEntity *ent, taskID_t taskType, int taskID );
static void		TaskIDComplete( CEntity *ent, taskID_t taskType );
static void		TaskIDClear( int *taskID );
static bool		TaskIDPending( CEntity *ent, taskID_t taskType );
static void		Remove( int entID, int parentID, const char *name );
static bool		GetTag( int entID, const char *name, int lookup, vec3_t info, int parentID );
static int		GetFloat( int entID, int type, const char *name, float *value );
static int		GetVector( int entID, int type, const char *name, vec3_t value );
static int		GetString( int entID, int type, const char *name, const char **value );
static int		Evaluate( int p1Type, const char *p1, int p2Type, const char *p2, int operatorType );
static void		DeclareVariable( int type, const char *name );
static void		FreeVariable( const char *name );
static void		Set( int taskID, int entID, const char *type_name, const char *data );
static void		Use( int entID, int parentID, const char *target );
static void		Play( int taskID, int entID, const char *type, const char *name );
static void		*Malloc( int size, int tag );
static void		Free( void *memory );
static void		Cam_Enable( void );
static void		Cam_Disable( void );
static void		Cam_Zoom( float fov, float duration );
static void		Cam_Move( vec3_t origin, float duration );
static void		Cam_Pan( vec3_t angles, vec3_t dir, float duration );
static void		Cam_Roll( float angle, float duration );
static void		Cam_Track( const char *name, float speed, float initLerp, int taskID );
static void		Cam_Follow( const char *name, float speed, float initLerp );
static void		Cam_Distance( float dist, float initLerp );
static void		Cam_Shake( float intensity, int duration );
static void		Cam_Fade( float sr, float sg, float sb, float sa, float dr, float dg, float db, float da, float duration );
static void		Cam_Path( const char *name, int taskID, bool trans=false);
static int		GetBoltID( const char *boltname);
static int		GetHitID( const char *name);
static int		GetScript( const char *name, void **buf );
static int	    ICARUS_LinkEntity( int entID, CSequencer *sequencer, CTaskManager *taskManager );
static int		AddToPendingAnims(int t)
{
	CICARUSGameInterface::GetPendingAnims().push_back(t);
	return 0;
}
static int		ClosePendingAnims();

static vector<int> &GetPendingAnims(void) 
{ 
	static	vector<int>			mPendingAnims;
	return(mPendingAnims); 
}


static string	&GetCurPackage();
};

//external functions
bool	TAG_GetOrigin( const char *name, const char *instance, vec3_t origin );
bool	TAG_GetAngles( const char *name, const char *instance, vec3_t angles );

void	IG_SetPrintToken( int entID, const char *data );
void	IG_SetStringPackage( int entID, const char *data );

//NOTENOTE: The enums and tables in this file will obviously complain if they are included multiple times, don't do that

typedef enum //# setType_e
{
	//# #sep Parm strings
	SET_PARM1 = 0,//## %s="" # Set entity parm1
	SET_PARM2,//## %s="" # Set entity parm2
	SET_PARM3,//## %s="" # Set entity parm3
	SET_PARM4,//## %s="" # Set entity parm4
	SET_PARM5,//## %s="" # Set entity parm5
	SET_PARM6,//## %s="" # Set entity parm6
	SET_PARM7,//## %s="" # Set entity parm7
	SET_PARM8,//## %s="" # Set entity parm8

	//# #Console commands, subtitle commands
	SET_DISCONNECT, //## #send disconnect
	SET_MAINMENU, //## #go to main menu
	SET_CONSOLE_COMMAND, //## %s="NULL" # Issue this command to the console
	SET_CVAR, //## %s="CVAR_NAME VALUE" # Change this CVAR_NAME to the following VALUE
	SET_STRING_PACKAGE, //## %s="NULL" # Name of the string package for tokens
	SET_PRINT_TOKEN, //## %s="NULL" # Name of token to print out as subtitle
	SET_MUSIC_PERCENTAGE, //## %f="0.0" # Set the music to be this percetage of what it currently is (e.g. .5 will turn it down 1/2 of current volume)
	SET_HUD_MAIN, //## %s="NULL" # name of Hud to set 
	SET_HUD_WEAPONS, //## %s="NULL" # name of Hud to set 
	SET_PLAYERHEALTH_OLD, //## #call this if you want to set the player health to g_playerHealthOld
	SET_PLAYERARMOR_OLD, //## #call this if you want to set the player armor to g_playerArmorOld
	SET_SAVE_PLAYERHEALTH, //## #call this if you want to save the player health to g_playerHealthOld
	SET_SAVE_PLAYERARMOR, //## #call this if you want to savethe player armor to g_playerArmorOld

	SET_WORLD_DEATH_PAUSE, //## #call this to freeze the world, intended for death scripts (ideal after fading out)


	// NOTE!!! If you add any other SET_xxxxxxSCRIPT types, make sure you update the 'case' statements in 
	//	ICARUS_InterrogateScript() (game/g_ICARUS.cpp), or the script-precacher won't find them.
	//# #sep Scripts and other file paths
	//SET_SPAWNSCRIPT,//## %s="NULL" !!"Q:\quake\baseEF\real_scripts\!!#*.txt" # Script to run when spawned //0 - do not change these, these are equal to BSET_SPAWN, etc
	//SET_USE_SCRIPT,//## %s !!"S:\base\scripts\!!#*.txt" # Script to run when used		
	SET_PLAYER_USE_SCRIPT,//## %s !!"S:\base\scripts\!!#*.txt" # Script to run when player uses		
	SET_DEATH_SCRIPT,//## %s !!"S:\base\scripts\!!#*.txt" # Script to run when used	
	SET_PAIN_SCRIPT,//## %s !!"S:\base\scripts\!!#*.txt" # Script to run when used	
	SET_SPAWN_SCRIPT,//## %s !!"S:\base\scripts\!!#*.txt" # Script to run when used	
	SET_VIEW_SCRIPT,//## %s="NULL" !!"S:\base\scripts\!!#*.txt" # Script to run when NPC sees enemy	
	SET_ANY_VIEW_SCRIPT,//## %s="NULL" !!"S:\base\scripts\!!#*.txt" # Script to run when NPC sees any NPC or player
	SET_PLAYER_VIEW_SCRIPT,//## %s="NULL" !!"S:\base\scripts\!!#*.txt" # Script to run when NPC sees player
	SET_HEAR_SCRIPT,//## %s="NULL" !!"S:\base\scripts\!!#*.txt" # Script to run when NPC hears any enemy or player
	SET_KO_SCRIPT,//## %s="NULL" !!"S:\base\scripts\!!#*.txt" # Script to run when NPC is knocked out
	SET_CONTACT_SCRIPT,//## %s="NULL" !!"S:\base\scripts\!!#*.txt" # Script to run when NPC sees enemy or evidence of enemy
	SET_WORLD_HEAR_SCRIPT,//## %s="NULL" !!"S:\base\scripts\!!#*.txt" # Script to run first time player sound is above 0.7
	SET_PLAYER_CAM_DEATH,//## %t="BOOL_TYPES" # turn the player death camera (roff for dropping player to ground) OFF or ON (defaults ON)

	//# #sep Standard strings	
	SET_NAME,//## %s="NULL" # Set/change your targetname
	SET_CAMERA_GROUP,//## %s="NULL" # Set/change your cameraGroup for camera FOLLOW commands
	SET_FACE_TARGET, //## %s="NULL" # Set/change your face target (NOT supported for npc's)
	SET_ENEMY, //## %s="NULL" # Set/change your enemy
	SET_HITLOC, //## %t="HITLOC" # Set/change your hit location (for shooting other NPC's and players)
	SET_FAKEGUN, //## %s="NULL" # Set/change targetname of fake gun (for using SET_HEALTH to kill NPCs)
	SET_PLAYER_VIEW, //## %t="BOOL_TYPES" # attach camera to brush model child (on/off)
	SET_VIEW_PARENT, //## %s="NULL" # Set targetname of brush model for SET_PLAYER_VIEW command
	SET_VIEW_CHILD, //## %s="NULL" # Set targetname of brush model child for SET_PLAYER_VIEW command
	SET_INVIEW_WPN, //## %t="BOOL_TYPES" # toggle inview weapon model (on/off)
	SET_ADD_WPN, //## %s="NULL" # add a weapon to the player's inventory
	SET_REMOVE_WPN, //## %s="NULL" # remove a weapon from the player's inventory

	//# #sep booleans
	SET_NOCLIP, //## %t="BOOL_TYPES" # turn noclip on/off
	SET_IGNOREPAIN, //## %t="BOOL_TYPES" # npc will ignore being in pain
	SET_SOUNDBLOCK, //## %t="BOOL_TYPES" # npc will not play any sounds
	SET_INVINCIBLE, //## %t="BOOL_TYPES" # npc will ignore being in pain
	SET_STATIONARY, //## %t="BOOL_TYPES" # turn npc stationary mode on(1) or off(0)
	SET_FORCE_SCRIPT, //## %t="BOOL_TYPES" # turn force script mode on(1) or off(0)
	SET_HIDE, //## %t="BOOL_TYPES" # turn npc hide mode on(1) or off(0)
	SET_ENABLE, //## %t="BOOL_TYPES" # enable/disable affected device (not for NPCs!!!)	
	SET_EMPLACED, //## %s="NULL" # force this entity onto emplaced weapon with targetname, NULL turns off
	SET_RELEASE_ONCONTACT, //## %t="BOOL_TYPES_REL" # npc will be released from script when he sees or is shot by some enemy
	SET_GOAL_RELEASE, //## %t="GOAL_REL" # GO: ignore enemies when in goal, PAUSE: default combat AI for a little while, STOP: default combat AI until enemies gone, default is PAUSE, set pause time with SET_GOAL_PAUSE
	SET_GOAL_PAUSE, //## %f="5000" # For PAUSE mode in goals, NPCs will stop for this many ms and fight bad guys
	SET_NAVIGATION,	//## %t="BOOL_TYPES" # turn navpoint usage on(1) or off(0)
	SET_TASK_FLUSH, //## %t="BOOL_TYPES" # set to ON to flush all pending script tasks
	SET_ROFF_TRANSLATED, //## %t="BOOL_TYPES" # set to ON and when the camera is roffed it will play it translated
	SET_PLAYERALWAYS_HURT, //## %t="BOOL_TYPES" # turn ON ability for player to always hurt this npc, regardless of invicible setting
	SET_SUIT, //## %t="BOOL_TYPES" # turn on/off the biohazard suit fullscreen effect	

	SET_MORELIGHT, //## %t="BOOL_TYPES" # turn ON to give this npc a minlight effect

	//# #sep vectors
	SET_ORIGIN,//## %v="0.0 0.0 0.0" # Set origin explicitly or with TAG
	SET_ANGLES,//## %v="0.0 0.0 0.0" # Set angles explicitly or with TAG
	SET_MOVE_BY, //## %v="0.0 0.0 0.0" %f="0.0" # Move by vector x,y,z for time t
	SET_MOVE, //## %v="0.0 0.0 0.0" %f="0.0" %f="0.0" # Move in direction x,y,z for d distance and t time

	//# #sep floats
	SET_WAIT,		//## %f="0.0" # Change an entity's wait field
	SET_VIEWDIST,	//## %f="0.0" # Change an NPC's viewing distance
	SET_GOALDIST,	//## %f="0.0" # Change a acceptable goal reached distance (set on commanders)	
	SET_RESET_ALL_VIEWDIST, //## %f="1000.0" # Set all NPC's view distances to this value
	SET_ACCURACY,	//## %f="1.0" # Accuracy of NPC
	SET_DAMAGE,		//## %f="1.0" # Damage of NPC

	//# #sep ints
	SET_HEALTH,//## %d="0" # Change health
	SET_HEALTHNOANIM,//## %d="0" # Change health but don't play animation for it
	SET_SAVEHEALTH,//## # Saves the health out to prepare for level load, cvar name: health_icarusname
	SET_LOADHEALTH,//## # Loads the health from a previous level, cvar name: health_icarusname
	SET_MAXSHOTS, //## %d="0" # Shots the entity can take before starting to ignore pain, use -1 to not use maxshots
		

	//# #sep Animation tables (turn overrides off/on)

	SET_ANIM_SEQUENCER, //## %t="BOOL_TYPES" # turns Animation Sequencer on/off

	SET_ANIM, //## %s="NULL" # plays an animation this many times (use string provided from SklView)

	SET_ANIM_PAIN, //## %t="HITLOC" # When killing/hurting a guy in a script, you can set his death/pain animation here
	
	SET_ANIM_OFF, //## %t="SKEL" # turn animations on this skel off (back to default)

	//SET_ANIM_ALL_OFF, //## %t="BOOL_TYPES" # turn all animations on all skelements off (back to default)

	SET_ANIM_FLUSH, //## %t="BOOL_TYPES" # flush all animations (returns all to stationary)

	SET_ANIM_LOOP,//## %t="BOOL_TYPES"

	SET_ANIM_EYES, //## %t="BOOL_TYPES" # set to OFF to stop blinking (use only in special cases- see Ben)

	//# #sep Animation tables (override specifics)

	SET_MOOD,//## %t="MOOD"

	SET_STANCE,//## %t="STANCE"

	SET_HAND_SIGNAL,//## %t="HANDSIGNAL"

	//# #sep Task/Goal tables

	//in-bhc tables

	SET_TASK,//## %t="TASK_TYPES" # Set/change your current task

	SET_GOAL,//## %t="GOAL_TYPES" # Set/change your team goal (for TeamCommander NPCs)	

	SET_GOALFLUSH,	//## %t="BOOL_TYPES" # Set to on(1) to flush goals.  Set to off(0) to again accept goals.	

	SET_NAVGOAL,//## %s="NULL" # Set/change your navgoal

	SET_NAVGOAL2,//## %s="NULL" # Set/change your 2nd navgoal (mostly for designer assisted Patrols)
	
	SET_NAVGOAL3,//## %s="NULL" # Set/change your 3rd navgoal (mostly for designer assisted Patrols)

	SET_AREAGOAL,//## %s="NULL" # Set/change your area goal

	SET_AREAGOAL2,//## %s="NULL" # Set/change your secondary area goal (mostly for flank area goal)

	SET_VECGOAL,//## %s="NULL" # Set an arbitrary point on the map (x,y,z) to go to.

	SET_ENTGOAL,//## %s="NULL" # Set to go to an entity the map.	

	SET_ENTGOAL2,//## %s="NULL" # Backup ent goal
	
	SET_ENTGOAL3,//## %s="NULL" # Backup ent goal

	SET_ENTGOAL4,//## %s="NULL" # Backup ent goal

	SET_INVENTORY_ACTION,//## %t="INVENTORY_ACTION" # Set the type of action to do on the inventory task

	SET_TASK_SPEED, //## %t="SPEED" # Set the speed to use in a specified SET_TASK (e.g. walk)

	SET_TASK_PAUSE, //## %f="1000" # Set the pause time between navpoints (only supports soldiers/sargeants w/out partners)

	SET_ATTACK, //## %t="BOOL_TYPES" # Set to on(1) to attack (same as SET_TASK ATTACK), off(0) to stop attacking

	SET_TEAM, //## %t="TEAM_TYPES" # Set this NPC or Player to the given team.

	SET_BLOCK_RETRY, //## %f="0" # Set the number of blocks needed before a replan on MoveToEnt- 0 for never replan

	//# #sep Face Angles tables
	SET_LOOK_TARGET,//## %s="NULL" # Set/change your current look target (look at this entity)

	SET_LOOK_POINT, //## %v="0.0 0.0 0.0" # Set/change your current look target to be this point in space

	SET_LOOK_ANGLE, //## %f="0.0" # Set/change your current look target by this degree (e.g. look over 10 degrees)

	SET_LOOK_TYPE, //## %t="LOOK_TYPES" # Use this to set the type of looktarget, lookpoint or lookangle you want.

	SET_LOOK_OFF, //## %t="LOOK_TYPES" # Use this to turn off a looking command for the given type	

	SET_LOOK_PARENT, //## %t="BOOL_TYPES" # Turn on/off parent activation of joint commands (once set, this stays on entity until set again. Default is ON)

	SET_LOOK_ROOT, //## %t="BOOL_TYPES" # Turn on/off root activation of joint commands (once set, this stays on entity until set again. Default is ON)

	SET_AIM,//## # Aim Gun at Current Focus

	SET_SEARCH, //## %v="30.0 50.0 0.0" # Set/change your search angles

	SET_SEARCH_OFF, //## #turn off SEARCH
	
	SET_TALK_TO,//## %s="NULL" # Set/change your current talking to target (turn towards this entity to talk to it)

	SET_TALK_TO_NOROOT,//## %s="NULL" # THIS IS NO LONGER VALID! use TALK_TO instead and set SET_LOOK_ROOT OFF

	SET_SCOTT_MCNUTT, //## %t="MOOD" # Switch Scott McNutt Off or On (use with caution)

	SET_SPECIAL_USE, //## %s="NULL" # Set to targetname to use (must be inside Affect of some NPC)

	SET_VIOLENCE_USE, //## %s="NULL" # Set to targetname to use (this is a use that will only happen if the violence lock is not on)

	SET_CAMERA_NOHUD,  //## %t="BOOL_TYPES" # Set to true to not allow enabling of camera to letterbox screen

	//# #sep Defunct or Not yet implemented tables (don't use these)
	SET_WEAPON,//## %t="WEAPON_NAMES" # Change/Stow/Drop weapon (FUTURE USE)
	
	SET_ANGLE_OVERRIDE, //## %t="BOOL_TYPES" # Turn angle overrides on/off (NO LONGER NEEDED!)
	
	SET_TOUCH, //## %s="NULL" # Touch this entity

	SET_GOALMODE,//## %t="GOAL_MODES" # Set/change your team goal mode (for TeamCommander NPCs)

	//# #eol
	SET_
} setType_t;	


// this enum isn't used directly by the game, it's mainly for BehavEd to scan for...
//
typedef enum //# playType_e
{
	//# #sep Types of file to play
	PLAY_ROFF = 0,//## %s !!"S:\base\!!scripts\*.rof" # Play a ROFF (not Translated)

	PLAY_ROFF_TRANSLATED = 0,//## %s !!"S:\base\!!scripts\*.rof" # Play a ROFF (Translated)
		

	//# #eol
	PLAY_NUMBEROF

} playType_t;


#define stringIDExpand(str, strEnum)	str, strEnum, ENUM2STRING(strEnum)

#endif // IGINTERFACE_H_INC