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

*/

//g_gametypes.c
extern cvar_t	*g_warmup_enabled;
extern cvar_t	*g_warmup_timelimit;
extern cvar_t	*g_countdown_time;
extern cvar_t	*g_match_extendedtime;
extern cvar_t	*g_votable_gametypes;
extern cvar_t	*g_gametype; // only for use in function that deal with changing gametype, use game.gametype

// some game settings
cvar_t	*g_allow_falldamage;

// g_gameteams.c
extern cvar_t	*g_teams_teamdamage;

#define G_CHALLENGERS_MIN_JOINTEAM_MAPTIME 9000 // must wait 10 seconds before joining

typedef struct 
{
	void		(*initGametype)(void);
	void		(*newMap)(void);
	void		(*checkRules)(void);
	int			(*respawn)(edict_t *ent);
	void		(*clientbegin)(edict_t *ent);
	char		*(*scoreboardMessage) (edict_t *ent, edict_t *killer);

	//time blocks start funcs
	void		(*warmupMatch)(void);
	void		(*countdownMatch)(void);
	void		(*startMatch)(void);
	void		(*endMatch)(void);

	int			maxPlayersPerTeam;
	qboolean	hasChallengersQueue;

	// default item respwan time
	int ammo_respawn;
	int armor_respawn;
	int weapon_respawn;
	int health_respawn;
	int powerup_respawn;
	int megahealth_respawn;

	// few default settings
	int timelimit;
	int extended_time;
	int scorelimit;
	qboolean lock_teams;
}gametype_t;

extern gametype_t	gametypes[];

typedef struct
{
	int playerIndices[MAX_CLIENTS];
	int numplayers;
	int teamplayerscores;
	int teamscore;
	qboolean locked;
	int invited[MAX_CLIENTS];
}g_teamlist_t;

g_teamlist_t teamlist[GS_MAX_TEAMS];

typedef struct
{
	int		score;
	int		deaths;
	int		kills;
	int		suicides;
	int		teamfrags;
} client_scores_t;

typedef struct matchgame_s
{
	int		state;
	float	starttime;
	float	endtime;
	int		pickableItemsMask;

	qboolean	forceStart;		// force starting the game, when warmup timelimit is up
	qboolean	forceExit;		// just exit, ignore extended time checks
	int			extendedTime;	// are we in extended time period and if so is it first, second or ...

	qboolean		ready[MAX_CLIENTS];
	client_scores_t scores[MAX_CLIENTS];

}matchgame_t;

extern matchgame_t		match;


//scoreboards string
char	scoreboardString[MAX_STRING_CHARS];
#define SCOREBOARD_MSG_MAXSIZE (MAX_STRING_CHARS-8) //I know, I know, doesn't make sense having a bigger string than the maxsize value

//clock
char		clockstring[16];

//
//	matches management
//
qboolean G_Match_Tied( void );
void G_Match_RespawnAllItems( void );
void G_Match_RemoveAllProjectiles( void );
void G_Match_RespawnAllClients( void );
void G_Match_CleanUpPlayerStats( edict_t *ent );
void G_Match_FreeBodyQueue( void );
void G_Match_SetUpNextState( void );

//
//	teams
//
void G_Teams_NewMap( void );
void G_Teams_Init( void );
void G_Teams_UpdateTeamTabMessages( void );
void G_GameType_ClientHealthRule( void );
void G_GameType_BeginPostMatch( void );
qboolean G_Match_GenericCountDownAnnounces( void );

qboolean G_Gametype_hasChallengersQueue( int type );
void G_Teams_ExecuteChallengersQueue( void );
void G_Teams_AdvanceChallengersQueue( void );

#ifdef ARMOR_SYSTEM_OF_THE_DAY
void G_GameType_ClientArmorDecayRule( void );
#endif

// gametype specific functions
void G_Gametype_CTF_CheckRules( void );

void G_Gametype_DM_CheckRules( void );
char *G_Gametype_DM_ScoreboardMessage( edict_t *ent, edict_t *killer );

void G_Gametype_TDM_CheckRules( void );
void G_Gametype_TDM_SetUpMatch( void );
char *G_Gametype_TDM_ScoreboardMessage( edict_t *ent, edict_t *killer );

void G_Gametype_CTF_Init( void );
void G_Gametype_CTF_NewMap( void );
void G_Gametype_CTF_ClientBegin( edict_t *ent );
void G_Gametype_CTF_SetUpMatch( void );
void G_Gametype_CTF_SetUpEndMatch( void );
char *G_Gametype_CTF_ScoreboardMessage( edict_t *ent, edict_t *killer );
int G_Gametype_CTF_CapturedFlagTimer( int team );
int G_Gametype_CTF_FlagStatus( int team );


char *G_Gametype_DUEL_ScoreboardMessage( edict_t *ent, edict_t *killer );
void G_Gametype_DUEL_CheckRules( void );

void G_Gametype_RACE_Init( void );
void G_Gametype_RACE_NewMap( void );
void G_Gametype_RACE_CheckRules( void );
void G_Gametype_RACE_ClientBegin( edict_t *ent );
char *G_Gametype_RACE_ScoreboardMessage( edict_t *ent, edict_t *killer );
void G_Gametype_RACE_SetUpWarmup( void );
void G_Gametype_RACE_SetUpMatch( void );
int G_Gametype_RACE_ClientRespawn( edict_t *self );

void G_Gametype_MIDAIR_CheckRules( void );
char *G_Gametype_MIDAIR_ScoreboardMessage( edict_t *ent, edict_t *killer );
int G_Gametype_MIDAIR_ClientRespawn( edict_t *ent );

extern void G_Match_AutorecordCommand( qboolean activate, qboolean cancel );
