#define Quake_DllExport    __declspec( dllexport )
#define DllExport	extern "C"	__declspec( dllexport )
#ifndef	DllExport_Plus
#define DllExport_Plus __declspec(dllexport)
#endif


///////////////////////////////////////////////////////////////////////////////
//	defines
///////////////////////////////////////////////////////////////////////////////

#define	GAME_API_VERSION	1

// edict->svflags

#define	SVF_NOCLIENT			0x00000001	//	don't send entity to clients, even if it has effects
#define	SVF_DEADMONSTER			0x00000002	//	treat as CONTENTS_DEADMONSTER for collision
#define	SVF_MONSTER				0x00000004	//	treat as CONTENTS_MONSTER for collision
#define	SVF_NOSPLASH			0x00000008	//	no default water transition sound
#define	SVF_NOTHUD				0x00000010	//	no default landing sound
#define	SVF_OWNERONLY			0x00000020  //	only owner sees this entity
#define	SVF_DEBUGBREAK			0x00000040	//	for debugging a particular entity in server code
#define	SVF_SHOT				0x00000080	//	don't clip against ents with clipmask == MASK_SHOT

#define	MAX_ENT_CLUSTERS		16

enum svc_ops_enum
{
	SVC_BAD,

	// these ops are known to the game dll
	SVC_MUZZLEFLASH,
	SVC_MUZZLEFLASH2,
	SVC_TEMP_ENTITY,
	SVC_LAYOUT,
	SVC_INVENTORY,

	// the rest are private to the client and server, NOT!
	SVC_NOP,
	SVC_DISCONNECT,
	SVC_RECONNECT,
	SVC_SOUND,					// <see code>
	SVC_PRINT,					// [byte] id [string] null terminated string
	SVC_STUFFTEXT,				// [string] stuffed into client's console buffer, should be \n terminated
	SVC_SERVERDATA,				// [long] protocol ...
	SVC_CONFIGSTRING,			// [short] [string]
	SVC_SPAWNBASELINE,		
	SVC_CENTERPRINT,			// [string] to put in center of the screen
	SVC_DOWNLOAD,				// [short] size [size bytes]
	SVC_PLAYERINFO,				// variable
	SVC_PACKETENTITIES,			// [...]
	SVC_DELTAPACKETENTITIES,	// [...]
	SVC_FRAME,
	SVC_EFFECT_NOTIFY,			//	Shawn:	added for Daikatana
	SVC_SETCLIENTMODELS			//	Nelno:	send down edict numbers for a client body parts
};

///////////////////////////////////////////////////////////////////////////////
//	typedefs
///////////////////////////////////////////////////////////////////////////////

//	edict->solid values

typedef enum
{
	SOLID_NOT,			// no interaction with other objects
	SOLID_TRIGGER,		// only touch when inside, after moving
	SOLID_BBOX,			// touch on edge
	SOLID_BSP			// bsp clip, touch on edge
} solid_t;

#define	SOLID_SLIDEBOX	SOLID_BBOX

// Shawn: added for getting frame information
typedef struct
{
	char	name[16];
	int		flags;
} frameinfo_t;

// link_t is only used for entity area links now
typedef struct link_s
{
	struct link_s	*prev, *next;
} link_t;


typedef struct edict_s edict_t;
typedef struct gclient_s gclient_t;


#ifndef GAME_INCLUDE

typedef struct gclient_s
{
	player_state_t	ps;		// communicated by server to clients
	int				ping;
	// the game dll can add anything it wants after
	// this point in the structure
} gclient_t;

///////////////////////////////////////////////////////////////////////////////
//	THIS IS THE SERVER VERSION OF edict_t.	DLLS SHOULD ALWAYS USE
//	THE LONGER userEntity_t AND NOT edict_t!!!!!!!!!!!!!!!!!!!!!!!
//	WHAT A FRICKIN MESS THIS CRAP IS...
///////////////////////////////////////////////////////////////////////////////

struct edict_s
{
	entity_state_t	s;
	struct gclient_s	*client;
	qboolean	inuse;
	int			linkcount;

	// FIXME: move these fields to a server private sv_entity_t
	link_t		area;				// linked to a division node or leaf
	
	int			num_clusters;		// if -1, use headnode instead
	int			clusternums[MAX_ENT_CLUSTERS];
	int			headnode;			// unused if num_clusters != -1
	int			areanum, areanum2;

	//================================

	int			svflags;			// SVF_NOCLIENT, SVF_DEADMONSTER, SVF_MONSTER, etc
//	vec3_t		mins, maxs;
	vec3_t		absmin, absmax, size;
	solid_t		solid;
	int			clipmask;
	edict_t		*owner;

	// the game dll can add anything it wants after
	// this point in the structure
};

#endif		// GAME_INCLUDE

///////////////////////////////////////////////////////////////////////////////
//	inventory typedefs
///////////////////////////////////////////////////////////////////////////////

typedef void invHandle_t;

typedef void (*weaponUse_t) (struct userInventory_s *ptr, struct edict_s *user);
typedef void *(*weaponCommand_t) (struct userInventory_s *ptr, char *commandStr, void *data);

typedef struct userInventory_s
{
	char    *name;
	weaponUse_t	use;
	weaponCommand_t	command;
	void   *precache;
	void   *dummy2;
	void   *dummy3;
	void   *dummy4;
} userInventory_t;

///////////////////////////////////////////////////////////////////////////////
// functions provided by the main engine
///////////////////////////////////////////////////////////////////////////////

typedef struct
{
	// special messages
	void	(*bprintf) (int printlevel, char *fmt, ...);
	void	(*dprintf) (char *fmt, ...);
	void	(*conprintf) (char *fmt, ...);
	void	(*cprintf) (edict_t *ent, int printlevel, char *fmt, ...);
	void	(*centerprintf) (edict_t *ent, char *fmt, ...);
	void	(*centerprint) (edict_t *ent, float msg_time, char *fmt, ...);
	void	(*sound) (edict_t *ent, int channel, int soundindex, float volume, float attenuation, float timeofs);
	void	(*positioned_sound) (vec3_t origin, edict_t *ent, int channel, int soundinedex, float volume, float attenuation, float timeofs);

	// config strings hold all the index strings, the lightstyles,
	// and misc data like the sky definition and cdtrack.
	// All of the current configstrings are sent to clients when
	// they connect, and changes are sent to all connected clients.
	void	(*configstring) (int num, char *string);

	void	(*error) (char *fmt, ...);

	// new names can only be added during spawning
	// existing names can be looked up at any time
	int		(*modelindex) (char *name);
	int		(*soundindex) (char *name);
	int		(*imageindex) (char *name);

	void	(*setmodel) (edict_t *ent, char *name);

	// collision detection
	trace_t	(*trace) (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passent, int contentmask);
	int		(*pointcontents) (vec3_t point);
	qboolean	(*inPVS) (vec3_t p1, vec3_t p2);
	qboolean	(*inPHS) (vec3_t p1, vec3_t p2);
	void		(*SetAreaPortalState) (int portalnum, qboolean open);
	qboolean	(*AreasConnected) (int area1, int area2);

	// an entity will never be sent to a client or used for collision
	// if it is not passed to linkentity.  If the size, position, or
	// solidity changes, it must be relinked.
	void	(*linkentity) (edict_t *ent);
	void	(*unlinkentity) (edict_t *ent);		// call before removing an interactive edict
	int		(*BoxEdicts) (vec3_t mins, vec3_t maxs, edict_t **list,	int maxcount, int areatype);
	void	(*Pmove) (pmove_t *pmove);		// player movement code common with client prediction

	// network messaging
	void	(*multicast) (vec3_t origin, multicast_t to);
	void	(*unicast) (edict_t *ent, qboolean reliable);
	void	(*WriteChar) (int c);
	void	(*WriteByte) (int c);
	void	(*WriteShort) (int c);
	void	(*WriteLong) (int c);
	void	(*WriteFloat) (float f);
	void	(*WriteString) (char *s);
	void	(*WritePosition) (vec3_t pos);	// some fractional bits
	void	(*WriteDir) (vec3_t pos);		// single byte encoded, very coarse
	void	(*WriteAngle) (float f);

	// managed memory allocation
	void	*(*TagMalloc) (int size, int tag);
	void	(*TagFree) (void *block);
	void	(*FreeTags) (int tag);

	// console variable interaction
	cvar_t	*(*cvar) (char *var_name, char *value, int flags);
	cvar_t	*(*cvar_set) (char *var_name, char *value);
	cvar_t	*(*cvar_forceset) (char *var_name, char *value);

	// ClientCommand and coneole command parameter checking
	int		(*argc) (void);
	char	*(*argv) (int n);
	char	*(*args) (void);

	// add commands to the server console as if they were typed in
	// for map changing, etc
	void	(*AddCommandString) (char *text);

	void	(*DebugGraph) (float value, int color);

	void	(*AddCommand) (char *cmd_name, void *function);

	char	*dk_dlldir;
	char	*dk_gamedir;
	char	*dk_gamename;

	//	for getting the command-line parameters used to start Daikatana
	int		(*Com_Argc) (void);
	char	*(*Com_Argv) (int arg);

	void (*printxy)(int x, int y, char *fmt, ...);
    void (*clearxy)(void);

	void (*dk_GetFrameName) (int modelindex, int frameindex, char *name);

	// inventory create/delete methods
	invHandle_t *(*InventoryNew)(void);
    void         (*InventoryFree)(invHandle_t *ptr);

	// inventory search methods
    struct userInventory_s *(*InventoryFindItem)(invHandle_t *ptr, char *name); 
	struct userInventory_s *(*InventoryFirstItem)(invHandle_t *ptr);
    struct userInventory_s *(*InventoryNextItem)(invHandle_t *ptr);

	// inventory add/delete methods
	int		(*InventoryAddItem)(invHandle_t *ptr, struct userInventory_s *item);
    void	(*InventoryDeleteItem)(invHandle_t *ptr, struct userInventory_s *item);

	// inventory items must be precached so client can get resources early on
	void	(*InventoryPrecache)(char *className, char *iconName, char *modelName);

	char	*sv_prepped_refresh;		//	set to true when precached models have been loaded

	//	for viewmodel debugging command
	void	(*dk_ForceModelLoad) (int modelindex, char *name);
	int		(*Sys_Milliseconds) (void);

	//	for hierarchical model testing
	int		(*VertInfo) (edict_t *ent, int surfIndex, int vertIndex, vec3_t vert);
	int		(*SurfIndex) (int modelIndex, char *surfName);
	int		(*TriVerts) (edict_t *ent, int surfIndex, int vertIndex, vec3_t v1, vec3_t v2, vec3_t v3);

	//	PAK File IO routines
	int		(*FS_FileLength)	(FILE *F);
	void	(*FS_Close)			(FILE *F);
	int		(*FS_Open)			(char *filename, FILE **file);
	void	(*FS_Read)			(void *buffer, int len, FILE *f);
	int		(*FS_LoadFile)		(char *path, void **buffer);
	void	(*FS_FreeFile)		(void *buffer);
	int		(*FS_Seek)			(FILE *f, long offset, int origin);
	long	(*FS_Tell)			(FILE *f);
	int		(*FS_Getc)			(FILE *f);
} game_import_t;

///////////////////////////////////////////////////////////////////////////////
// functions exported by the game subsystem
///////////////////////////////////////////////////////////////////////////////

typedef struct
{
	int			apiversion;

	// each new level entered will cause a call to SpawnEntities
	void		(*SpawnEntities) (char *mapname, char *entstring, char *spawnpoint);

	// Read/Write Game is for storing persistant cross level information
	// about the world state and the clients.
	// WriteGame is called every time a level is exited.
	// ReadGame is called on a loadgame.
	void		(*WriteGame) (char *filename, char autosave);
	void		(*ReadGame) (char *filename);

	// ReadLevel is called after the default map information has been
	// loaded with SpawnEntities, so any stored client spawn spots will
	// be used when the clients reconnect.
	void		(*WriteLevel) (char *filename);
	void		(*ReadLevel) (char *filename);

	qboolean	(*ClientConnect) (edict_t *ent, char *userinfo, qboolean loadgame);
	void		(*ClientBegin) (edict_t *ent, qboolean loadgame);
	void		(*ClientUserinfoChanged) (edict_t *ent, char *userinfo);
	void		(*ClientDisconnect) (edict_t *ent);
	void		(*ClientCommand) (edict_t *ent);
	void		(*ClientThink) (edict_t *ent, usercmd_t *cmd);

	void		(*RunFrame) (void);

	// ServerCommand will be called when an "sv <command>" command is issued on the
	// server console.
	// The game can issue gi.argc() / gi.argv() commands to get the rest
	// of the parameters
	void		(*ServerCommand) (void);

	//
	// global variables shared between game and server
	//

	// The edict array is allocated in the game dll so it
	// can vary in size from one game to another.
	// 
	// The size will be fixed when ge->Init() is called
	struct		edict_s		*edicts;
	int			edict_size;
	int			num_edicts;		// current number, <= max_edicts
	int			max_edicts;

	//	Nelno's additions
	
	void		(*LevelLoad) (void);			//	called each time a new level loads
	void		(*LevelExit) (void);			//	called each time a level ends, before next level is loaded
	void		(*InitDLLs) (void);				//	called after all DLLs have loaded the first time
	void		(*UnloadDLLs) (void);			//	called when all DLLs are unloaded
	void		(*InitChangelevel) (void);		//	called when a "changelevel" command is issued

	void		(*Graphics3) (void);
} game_export_t;
