/*
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.

*/
// client.h -- primary header for client

#include "../qcommon/qcommon.h"
#include "../ref_gl/render.h"
#include "../cgame/cg_public.h"

#include "cin.h"
#include "vid.h"
#include "sound.h"
#include "input.h"
#include "keys.h"
#include "console.h"

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

//
// the client_state_t structure is wiped completely at every
// server map change
//
typedef struct
{
	int			timeoutcount;

	int				timedemo_frames;
	unsigned int	timedemo_start;
	int				timedemo_counts[100];

	qboolean	soundPrepped;		// ambient sounds can start

	int			cmdNum;				// current cmd
	usercmd_t	cmds[CMD_BACKUP];	// each mesage will send several old cmds
	int			cmd_time[CMD_BACKUP];	// time sent, for calculating pings

	frame_t		*curFrame;			// current snap in execution
	int			suppressCount;		// number of messages rate suppressed
	frame_t		frames[UPDATE_BACKUP];

	// the client maintains its own idea of view angles, which are
	// sent to the server each frame.  It is cleared to 0 upon entering each level.
	// the server sends a delta each frame which is added to the locally
	// tracked view angles to account for standing on rotating objects,
	// and teleport direction changes
	vec3_t		viewangles;

	int				serverTimeDelta; // the time difference with the server time, or at least our best guess about it
	unsigned int	serverTime;		// the best match we can guess about current time in the server

	//
	// non-gameserver infornamtion
	cinematics_t cin;

	//
	// server state information
	//
	int			servercount;	// server identification for prespawns
	char		gamedir[MAX_QPATH];
	int			playernum;

	char		servermessage[MAX_QPATH];
	char		configstrings[MAX_CONFIGSTRINGS][MAX_CONFIGSTRING_CHARS];
} client_state_t;

extern	client_state_t	cl;

/*
==================================================================

the client_static_t structure is persistant through an arbitrary number
of server connections

==================================================================
*/

typedef struct download_list_s download_list_t;

struct download_list_s
{
	char			pakname[MAX_OSPATH];
	download_list_t	*next;
};

typedef struct
{
	// both downloads
	char			name[MAX_OSPATH];
	char			tempname[MAX_OSPATH];
	int				size;
	unsigned		checksum;
	double			percent;
	download_list_t	*list;
	// server download
	int				filenum;
	int				offset;
	unsigned int	timeout;
	int				retries;
	// web download
	qboolean		web;
	qboolean		disconnect;
} download_t;

typedef struct
{
	connstate_t	state;				// only set through CL_SetClientState
	keydest_t	key_dest;
	keydest_t	old_key_dest;

	int				framecount;
	unsigned int	realtime;			// always increasing, no clamping, etc
	float			trueframetime;
	float			frametime;			// seconds since last frame

// screen rendering information
	qboolean	cgameActive;
	qboolean	mediaInitialized;

	unsigned int	disable_screen;		// showing loading plaque between levels
										// or changing rendering dlls
										// if time gets > 30 seconds ahead, break it
	int			disable_servercount;	// when we receive a frame and cl.servercount
										// > cls.disable_servercount, clear disable_screen

// connection information
	char		servername[MAX_OSPATH];	// name of server from original connect
	netadr_t	serveraddress;			// address of that server
	int			connect_time;		// for connection retransmits
	int			connect_count;

	netadr_t	rconaddress;		// address where we are sending rcon messages, to ignore other print packets

	qboolean	rejected;			// these are used when the server rejects our connection
	int			rejecttype;
	char		rejectmessage[80];

	int			quakePort;			// a 16 bit value that allows quake servers
									// to work around address translating routers
	netchan_t	netchan;

	char		*statusbar;

	int			challenge;			// from the server to use for connecting

	download_t	download;

// demo recording info must be here, so it isn't cleared on level change
	qboolean	demorecording;
	qboolean	demowaiting;	// don't record until a non-delta message is received
	int			demofile;
	char        demofilename[MAX_OSPATH];

	qboolean	demoplaying;
	int			demoplay_lastsnaptime;
	int			demoplay_framemsecs;
	qboolean	demoavi;
	int			demoavi_frame;

	// these shaders have nothing to do with media
	struct shader_s *whiteShader;
	struct shader_s *consoleShader;

	// system fonts
	struct mufont_s *fontSystemSmall;
	struct mufont_s *fontSystemMedium;
	struct mufont_s *fontSystemBig;

	// these are our reliable messages that go to the server
	int			reliableSequence;			// the last one we put in the list to be sent
	int			reliableSent;				// the last one we sent to the server
	int			reliableAcknowledge;		// the last one the server has executed
	char		reliableCommands[MAX_RELIABLE_COMMANDS][MAX_STRING_CHARS];

	// reliable messages received from server
	int			lastExecutedServerCommand;		// last server command grabbed or executed with CL_GetServerCommand

	// times when we got/sent last valid packets from/to server
	unsigned int lastPacketSentTime;
	unsigned int lastPacketReceivedTime;

#ifdef BATTLEYE
	qboolean	runBattlEye;
	battleye_transmit_t BE;
#endif
} client_static_t;

extern client_static_t	cls;

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

//
// cvars
//
extern	cvar_t	*cl_stereo_separation;
extern	cvar_t	*cl_stereo;

extern	cvar_t	*cl_upspeed;
extern	cvar_t	*cl_forwardspeed;
extern	cvar_t	*cl_sidespeed;

extern	cvar_t	*cl_yawspeed;
extern	cvar_t	*cl_pitchspeed;

extern	cvar_t	*cl_run;

extern	cvar_t	*cl_anglespeedkey;

extern	cvar_t	*cl_compresspackets;
extern	cvar_t	*cl_shownet;

extern	cvar_t	*lookspring;
extern	cvar_t	*lookstrafe;
extern	cvar_t	*sensitivity;

extern	cvar_t	*m_pitch;
extern	cvar_t	*m_yaw;
extern	cvar_t	*m_forward;
extern	cvar_t	*m_side;

extern	cvar_t	*cl_freelook;

extern	cvar_t	*cl_timedemo;
extern	cvar_t	*cl_demoavi_fps;
extern	cvar_t	*cl_demoavi_scissor;

// wsw : debug netcode
extern	cvar_t	*cl_debug_serverCmd;

extern	cvar_t	*cl_downloads;
extern	cvar_t	*cl_downloads_from_web;

// delta from this if not from a previous frame
extern	entity_state_t	cl_baselines[MAX_EDICTS];

#ifdef BATTLEYE
extern	cvar_t	*cl_battleye;
#endif

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


//
// cl_cin.c
//
void CL_PlayCinematic_f( void );
qboolean SCR_DrawCinematic( void );
void SCR_RunCinematic( void );
void SCR_StopCinematic( void );
void SCR_FinishCinematic( void );

//
// cl_main.c
//
void CL_Init( void );
void CL_Quit( void );

void CL_UpdateClientCommandsToServer( msg_t *msg );
void CL_AddReliableCommand( /*const*/ char *cmd );
void CL_Netchan_Transmit( msg_t *msg );

void CL_RequestNextDownload( void );
void CL_StopServerDownload( void );
void CL_CheckDownloadTimeout( void );

void CL_GetClipboardData( char *string, int size );
void CL_SetKeyDest( int key_dest );
void CL_SetOldKeyDest( int key_dest );
void CL_ResetServerCount( void );
void CL_SetClientState( int state );
void CL_ClearState( void );
void CL_ReadPackets( void );

void CL_SendCommand( void );
void CL_Disconnect_f( void );

//
// cl_ents.c
//
int CL_ParseEntityBits( msg_t *msg, unsigned *bits );
void CL_ParseDelta( msg_t *msg, entity_state_t *from, entity_state_t *to, int number, unsigned bits );
void CL_ParseFrame( msg_t *msg );


//
// cl_game.c
//
void CL_GameModule_Init( void );
void CL_GameModule_Shutdown( void );
void CL_GameModule_ServerCommand( void );
void CL_GameModule_InGameMenu( void );
void CL_GameModule_LoadLayout( char *s );
void CL_GameModule_RenderView( float stereo_separation );
void CL_GameModule_NewFrameSnap( frame_t *frame, frame_t *deltaframe );
void CL_GameModule_GlobalSound( vec3_t origin, int entNum, int entChannel, int soundNum, float fvol, float attenuation );
void CL_GameModule_GetEntitySoundOrigin( int entnum, vec3_t origin );
void CL_GameModule_Trace( trace_t *tr, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask );

//
// cl_ui.c
//
void CL_UIModule_Init( void );
void CL_UIModule_Shutdown( void );
void CL_UIModule_Keydown( int key );
void CL_UIModule_CharEvent( int key );
void CL_UIModule_Refresh( qboolean backGround );
void CL_UIModule_DrawConnectScreen( qboolean backGround );
void CL_UIModule_ForceMenuOff( void );
void CL_UIModule_AddToServerList( char *adr, char *info );
void CL_UIModule_MouseMove( int dx, int dy );

//
// cl_serverlist.c
//
void CL_ParseGetInfoResponse( msg_t *msg );
void CL_QueryGetInfoMessage_f( void );
void CL_ParseStatusMessage( msg_t *msg );
void CL_ParseGetServersResponse( msg_t *msg );
void CL_GetServers_f( void );
void CL_PingServer_f( void );

//
// cl_input.c
//
typedef struct
{
	int			down[2];		// key nums holding it down
	unsigned	downtime;		// msec timestamp
	unsigned	msec;			// msec down this frame
	int			state;
} kbutton_t;

extern	kbutton_t	in_mlook, in_klook;
extern 	kbutton_t 	in_strafe;
extern 	kbutton_t 	in_speed;

void CL_InitInput (void);
void CL_ShutdownInput (void);
void CL_UpdateUserCommand( void );
void CL_UserInputFrame( void );
void CL_WritePacket( usercmd_t *cmd ); // jal: move me
void CL_BaseMove( usercmd_t *cmd );
void CL_MouseMove( usercmd_t *cmd, int mx, int my ); // wsw : pb : moved mousemove to cl_input (q3 like)

void IN_CenterView( void );



//
// cl_demo.c
//
void CL_WriteDemoMessage( msg_t *msg );
void CL_DemoCompleted( void );
void CL_PlayDemo_f( void );
void CL_PlayDemoToAvi_f( void );
void CL_ReadDemoPackets( void );
void CL_Stop_f( void );
void CL_Record_f( void );
#ifdef DEMOCAM // -- PLX
void CL_PauseDemo_f( void );
#endif

//
// cl_parse.c
//
extern	char *svc_strings[256];
void CL_ParseServerMessage( msg_t *msg );
void SHOWNET( msg_t *msg, char *s );

void CL_Download_f( void );
void CL_FreeDownloadList( void );
qboolean CL_CheckOrDownloadFile( char *filename );

//
// cl_screen.c
//
#define SMALL_CHAR_WIDTH	8
#define SMALL_CHAR_HEIGHT	16

#define BIG_CHAR_WIDTH		16
#define BIG_CHAR_HEIGHT		16

#define GIANT_CHAR_WIDTH	32
#define GIANT_CHAR_HEIGHT	48

void SCR_InitScreen( void );
void SCR_UpdateScreen( void );
void SCR_BeginLoadingPlaque( void );
void SCR_EndLoadingPlaque( void );
void SCR_DebugGraph( float value, float r, float g, float b );
void SCR_RunConsole( void );
void SCR_RegisterConsoleMedia( void );
void SCR_ShutDownConsoleMedia( void );
struct mufont_s *SCR_RegisterFont( char *name );
size_t SCR_strHeight( struct mufont_s *font );
size_t SCR_strWidth( const char *str, struct mufont_s *font, int maxlen );
size_t SCR_StrlenForWidth( const char *str, struct mufont_s *font, size_t maxwidth );
void SCR_DrawString( int x, int y, int align, const char *str, struct mufont_s *font, vec4_t color );
void SCR_DrawStringLen( int x, int y, int align, const char *str, size_t len, struct mufont_s *font, vec4_t color );
void SCR_DrawRawChar( int x, int y, int num, struct mufont_s *font, vec4_t color );
void SCR_DrawFillRect( int x, int y, int w, int h, vec4_t color );

void CL_InitMedia( void );
void CL_ShutdownMedia( void );
void CL_RestartMedia( void );

void CL_AddNetgraph( void );

extern	float	scr_con_current;
extern	float	scr_conlines;		// lines of console to display

#ifdef BATTLEYE
void CL_AddBattleyeCommandToMessage( msg_t *msg );

//
// cl_battleye.c
//
extern void CL_BE_Start(void);
extern void CL_BE_NewIncomingPacket(void* buf, int len);
#endif
