/*
 * Copyright (C) 1997-2001 Id Software, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
 * USA.
 *
 * =======================================================================
 *
 * ABI between client and refresher
 *
 * =======================================================================
 */

#ifndef CL_REF_H
#define CL_REF_H

#include "../../common/header/common.h"

#define	MAX_DLIGHTS		32
#define	MAX_ENTITIES	128
#define	MAX_PARTICLES	4096
#define	MAX_LIGHTSTYLES	256

#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		0x68
#define SHELL_BG_COLOR		0x78

#define SHELL_DOUBLE_COLOR		0xDF
#define	SHELL_HALF_DAM_COLOR	0x90
#define SHELL_CYAN_COLOR		0x72

#define SHELL_WHITE_COLOR	0xD7

#define ENTITY_FLAGS	68
#define	API_VERSION		3

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;
} entity_t;

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

typedef struct {
	vec3_t	origin;
	int		color;
	float	alpha;
} particle_t;

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

typedef struct {
	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_particles;
	particle_t	*particles;
} refdef_t;

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

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

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

	/* 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	(*BeginRegistration)(char *map);
	struct model_s *(*RegisterModel)(char *name);
	struct image_s *(*RegisterSkin)(char *name);
	struct image_s *(*RegisterPic)(char *name);
	void	(*SetSky)(char *name, float rotate, vec3_t axis);
	void	(*EndRegistration)(void);

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

	/* 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);

	void	(*AppActivate)(qboolean activate);

} refexport_t;

/*
 * these are the functions imported by the refresh module
 */
typedef struct {
	void	(*Sys_Error)(int err_level, char *str, ...);
	void	(*Sys_Mkdir)(char *path);
	void	(*Sys_FreeLibrary)(void *handle);
	void	*(*Sys_LoadLibrary)(const char *path, const char *sym, void **handle);
	void	*(*Sys_GetProcAddress)(void *handle, const char *sym);

	void	(*Cmd_AddCommand)(char *name, void(*cmd)(void));
	void	(*Cmd_RemoveCommand)(char *name);
	int		(*Cmd_Argc)(void);
	char	*(*Cmd_Argv)(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)(char *name, void **buf);
	void	(*FS_FreeFile)(void *buf);

	/* The gamedir is the ./baseq2 directory (read only) and the
	   ~/.quake2/baseq2 directory for write operations. The later
	   overrides the first */
	char	*(*FS_Gamedir)(void);

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

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

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

#endif
