#ifndef _ref_h
#define _ref_h

#include "qcommon.h"

#define	RESOURCE_GLOBAL		        0x0001	//	never reload
#define	RESOURCE_EPISODE	        0x0002	//	reload across episodes
#define	RESOURCE_LEVEL		        0x0004	//	reload across levels
#define	RESOURCE_RELOAD		        0x0008	//	always reload when we do any caching
#define	RESOURCE_IGNORE		        0x0010	//	don't do anything special, especially don't change resource flags
#define RESOURCE_INTERFACE          0x0020  //  pics needed for drawing the interface.
#define RESOURCE_INTERFACE_TRANS    0x0040  //  pics needed for drawing the interface that have transparency.
#define RESOURCE_NPC_SKIN	        0x0080  //  skins for Superfly, Mikiko and Hiro loaded on a per-episode basis
#define	RESOURCE_FRAMES		        0x0100	//	set on models when they are loaded only for frame info

#define	MAX_DLIGHTS		32
#define	MAX_ENTITIES	1024
#define	MAX_PARTICLES	4096
//#define	MAX_PARTICLES	2048
#define	MAX_LIGHTSTYLES	256
#define MAX_FLARES		32				//  Shawn:  Added for Daikatana
#define MAX_PVOLUMES	48				//  Shawn:  Added for Daikatana
#define MAX_SURFACES	16				//  Shawn:  Added for Daikatana

#define POWERSUIT_SCALE		4.0F

#define SHELL_RED_COLOR		0xF2
#define SHELL_GREEN_COLOR	0xD0
#define SHELL_BLUE_COLOR	0xF3

#define SHELL_RG_COLOR		0xDC
#define SHELL_RB_COLOR		0x86
#define SHELL_BG_COLOR		0x78

#define SHELL_WHITE_COLOR	0xD7

#define ONEDIV255			0.003921

//  Shawn:  Added for Daikatana
typedef struct
{
	int	key;
	int	current_frame[MAX_SURFACES];			// current uv frame for this entity
	int	flags[MAX_SURFACES];					// animation flags for this enity
} uvaentity_t;

typedef struct entity_s
{
	struct model_s		*model;			// opaque type outside refresh
	float				angles[3];

	/*
	** most recent data
	*/
	float				origin[3];		// also used as RF_BEAM's "from"
	int					frame;			// also used as RF_BEAM's diameter

	/*
	** previous data for lerping
	*/
	float				oldorigin[3];	// also used as RF_BEAM's "to"
	int					oldframe;

	/*
	** misc
	*/
	float	backlerp;				// 0.0 = current, 1.0 = old
	int		skinnum;				// also used as RF_BEAM's palette index

	int		lightstyle;				// for flashing entities
	float	alpha;					// ignore if RF_TRANSLUCENT isn't set

	struct image_s	*skin;			// NULL for inline skin
	int		flags;

	float				render_scale [3];
	float				mins[3], maxs[3];		//  Shawn:  Added for particle volumes
} entity_t;

#define ENTITY_FLAGS  68

typedef struct dlight_s
{
	vec3_t	origin;
	vec3_t	color;
	float	intensity;
} dlight_t;

//  Shawn:  Added for Daikatana
typedef struct flare_s
{
	vec3_t	origin;
	vec3_t	angles;
	vec3_t	color;
	float	intensity;
	float	falloff;
} flare_t;

typedef struct foginfo_s
{
	float	r, g, b;
	int		start, end;
	short	active;
	int		inc;
} foginfo_t;

typedef struct ref_particle_s
{
	vec3_t	origin;
	int		color;
	float	alpha;
	int		type;			//	Nelno:	added for particle effects
	int		rotation_vec;	//	Nelno:	nubmer of rotation vector for this particle
	float	size_scale;		//	Nelno:	size scale for this particle
   float pscale;
} particle_t;

typedef struct lightstyle_s
{
	float		rgb[3];			// 0.0 - 2.0
	float		white;			// highest of rgb
} lightstyle_t;

typedef struct refdef_s
{
	int			x, y, width, height;// in virtual screen coordinates
	float		fov_x, fov_y;
	float		vieworg[3];
	float		viewangles[3];
	float		blend[4];			// rgba 0-1 full screen blend
	float		time;				// time is uesed to auto animate
	int			rdflags;			// RDF_UNDERWATER, etc

	byte		*areabits;			// if not NULL, only areas with set bits will be drawn

	lightstyle_t	*lightstyles;	// [MAX_LIGHTSTYLES]

	int			num_entities;
	entity_t	*entities;

	int			num_dlights;
	dlight_t	*dlights;

	int			num_flares;
	flare_t		*flares;

	int			num_particles;
	particle_t	*particles;

	int			num_comparticles;
	particle_t	*comparticles;

	int			num_uvaentities;
	uvaentity_t	*uvaentities;

	foginfo_t	foginfo;
} refdef_t;



#define	API_VERSION		3

//
// these are the functions exported by the refresh module
//
typedef struct refexport_s
{
	// if api_version is different, the dll cannot be used
	int		api_version;

	// called when the library is loaded
	qboolean	(*Init) ( void *hinstance, void *wndproc );

	// called before the library is unloaded
	void	(*Shutdown)();

	// All data that will be used in a level should be
	// registered before rendering any frames to prevent disk hits,
	// but they can still be registered at a later time
	// if necessary.
	//
	// EndRegistration will free any remaining data that wasn't registered.
	// Any model_s or skin_s pointers from before the BeginRegistration
	// are no longer valid after EndRegistration.
	//
	// Skins and images need to be differentiated, because skins
	// are flood filled to eliminate mip map edge errors, and pics have
	// an implicit "pics/" prepended to the name. (a pic name that starts with a
	// slash will not use the "pics/" prefix or the ".pcx" postfix)
   void  (*PurgeResources)(int type);
	void	(*BeginRegistration) (const char *map);
	struct model_s *(*RegisterModel) (const char *name, int flags);
	struct image_s *(*RegisterSkin) (const char *name, int flags);
	struct image_s *(*RegisterPic) (const char *name, int flags);
	void	(*SetSky) (const char *name, float rotate, vec3_t axis);
	void	(*SetPaletteDir) (const char *name);
	
	void	(*EndRegistration)();

	void	(*RenderFrame) (refdef_t *fd);

	void	(*DrawGetPicSize) (int *w, int *h, const char *name);	// will return 0 0 if not found
	void	(*DrawPic) (int x, int y, const char *name);
	void	(*DrawStretchPic) (int x, int y, int w, int h, const char *name);
	void	(*DrawChar) (int x, int y, int c);
	void	(*DrawTileClear) (int x, int y, int w, int h, const char *name);
	void	(*DrawFill) (int x, int y, int w, int h, int c);
	void	(*DrawFadeScreen)();

	// Draw images for cinematic rendering (which can have a different palette). Note that calls
	void	(*DrawStretchRaw) (int x, int y, int w, int h, int cols, int rows, byte *data);

	/*
	** video mode and refresh state management entry points
	*/
	void	(*CinematicSetPalette)( const unsigned char *palette);	// NULL = game palette
	void	(*BeginFrame)( float camera_separation );
	void	(*EndFrame)();

	void	(*AppActivate)( qboolean activate );

	//	Nelno:	added these for per-level console background and chars
	void	(*SetResourceDir) (char *name);
	void	(*DrawConsolePic) (int x, int y, int w, int h);

	//  Shawn:  added this for getting frame name
	void	(*GetFrameName) (char *modelname, int frameindex, char *framename);

	//	Nelno:	testing hierarchical models
	int		(*VertInfo) (void *mod, int surfIndex, int frameIndex, int vertIndex, vec3_t origin, vec3_t oldorigin, vec3_t angles, vec3_t vert);
	int		(*SurfIndex) (void *mod, char *name);
	int		(*TriVerts) (void *mod, int surfIndex, int frameIndex, int vertIndex, vec3_t origin, 
				vec3_t oldorigin, vec3_t angles, vec3_t v1, vec3_t v2, vec3_t v3);

	//	registers new skins for model
	void	(*RegisterEpisodeSkins) (void *model, int episode, int flags);
} refexport_t;

//
// these are the functions imported by the refresh module
//
typedef struct refimport_s
{
	void	(*Sys_Error) (int err_level, char *str, ...);

	void	(*Cmd_AddCommand) (char *name, void(*cmd)());
	void	(*Cmd_RemoveCommand) (char *name);
	int		(*GetArgc)();
	char	*(*GetArgv) (int i);
	void	(*Cmd_ExecuteText) (int exec_when, char *text);

	void	(*Con_Printf) (int print_level, char *str, ...);

	// files will be memory mapped read only
	// the returned buffer may be part of a larger pak file,
	// or a discrete file from anywhere in the quake search path
	// a -1 return means the file does not exist
	// NULL can be passed for buf to just determine existance
	int		(*FS_LoadFile) (const char *name, void **buf);
	void	(*FS_FreeFile) (void *buf);

	// gamedir will be the current directory that generated
	// files should be stored to, ie: "f:\quake\id1"
	char	*(*FS_Gamedir)();

	cvar_t	*(*Cvar_Get) (const char *name, const char *value, int flags);
	cvar_t	*(*Cvar_Set)(const char *name, const char *value );
	void	 (*Cvar_SetValue)(const char *name, float value );

	qboolean	(*Vid_GetModeInfo)( int *width, int *height, int mode );
	void		(*Vid_MenuInit)();
	void		(*Vid_NewWindow)( int width, int height );

	void		(*CL_ParticleVolume) (int key, int type, vec3_t mins, vec3_t maxs);
	void		(*CL_RemoveParticleVolume) (int key);

	void		(*dk_printxy) (int x, int y, char *fmt, ...);
} refimport_t;


// this is the only function actually exported at the linker level
typedef	refexport_t	(*GetRefAPI_t) (refimport_t);


#endif  //#ifndef _ref_h