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

 */

#include "g_local.h"
#include "g_gametypes.h"

char *G_Gametype_RACE_ScoreboardMessage( void )
{
	char entry[MAX_TOKEN_CHARS];
	size_t len;
	int i;
	edict_t	*e;

	//fixed layout scheme id
	Q_snprintfz( scoreboardString, sizeof( scoreboardString ), "scb \"&races " );
	len = strlen( scoreboardString );

	//players
	for( i = 0; teamlist[TEAM_PLAYERS].playerIndices[i] != -1; i++ )
	{
		e = game.edicts + teamlist[TEAM_PLAYERS].playerIndices[i];
		//player tab entry
		*entry = 0;

		Q_snprintfz( entry, sizeof( entry ), "&p %i %i %i %i ", PLAYERNUM( e ),
		             e->r.client->teamchange.race_record, e->r.client->r.ping > 999 ? 999 : e->r.client->r.ping,
		             e->r.client->resp.race_active ? 1 : 0 );

		if( SCOREBOARD_MSG_MAXSIZE - len > strlen( entry ) )
		{
			Q_strncatz( scoreboardString, entry, sizeof( scoreboardString ) );
			len = strlen( scoreboardString );
		}
	}

	G_ScoreboardMessage_AddSpectators();

	// add closing quote
	if( len < SCOREBOARD_MSG_MAXSIZE )
	{
		Q_strncatz( scoreboardString, "\"", sizeof( scoreboardString ) );
		len = strlen( scoreboardString );
	}

	return scoreboardString;
}

void G_Gametype_RACE_ClientBegin( edict_t *ent )
{
	ClientBeginMultiplayerGame( ent );

	ent->r.clipmask = MASK_SOLID;

	//	memset( &ent->r.client->pers.race, 0, sizeof(racescoring_t) );
}

//=================
//G_Gametype_RACE_CheckRules
//=================
void G_Gametype_RACE_CheckRules( void )
{
	if( match.state >= MATCH_STATE_POSTMATCH )
		return;

	if( game.gametype != GAMETYPE_RACE )
		return;

	if( G_Match_GenericCountDownAnnounces() )
	{                                       // true once a second
	}
}

//=================
//G_Gametype_RACE_SetUpMatch
//=================
void G_Gametype_RACE_SetUpMatch( void )
{
	edict_t *ent;

	// clear stats and scores
	game.race_record = 0;
	memset( game.race_record_checkpoint_times, 0, sizeof( game.race_record_checkpoint_times ) );

	// clear client race records
	for( ent = game.edicts + 1; PLAYERNUM( ent ) < game.maxclients; ent++ )
	{
		if( !ent->r.inuse || ent->s.team == TEAM_SPECTATOR )
			continue;

		ent->r.client->teamchange.race_record = 0;
		memset( ent->r.client->teamchange.race_record_checkpoint_times, 0,
		       sizeof( ent->r.client->teamchange.race_record_checkpoint_times ) );
	}

	G_Match_RespawnAllItems();
	G_Match_RespawnAllClients();
	G_Match_FreeBodyQueue();
	match.pickableItemsMask = GS_Gametype_SpawnableItemMask( game.gametype )|GS_Gametype_DropableItemMask( game.gametype );
	if( g_instagib->integer )
	{
		match.pickableItemsMask &= ~G_INSTAGIB_NEGATE_ITEMMASK;
	}
	match.endtime = 0;
}

//=================
//G_Gametype_RACE_SetUpWarmup
//=================
void G_Gametype_RACE_SetUpWarmup( void )
{
	match.state = MATCH_STATE_PLAYTIME-1;
	G_Match_SetUpNextState();
	match.endtime = 0;
}

//=================
//G_Gametype_RACE_ClientRespawn
//=================
qboolean G_Gametype_RACE_ClientRespawn( edict_t *self )
{
	edict_t *ent;
	qboolean respawned;

	// little hack to not autokill a player that leave the race at the end using F5/F3 (chase+join)
	self->deathTimeStamp = level.time;

	// Cgg: remove any missile the player might have fired
	for( ent = &game.edicts[game.maxclients + 1]; ENTNUM( ent ) < game.numentities; ent++ )
	{
		if( !ent->r.inuse )
			continue;

		if( ent->r.owner == self && ( ent->r.svflags & SVF_PROJECTILE ) )
			G_FreeEdict( ent );
	}
	// !Cgg

	respawned = ClientRespawn( self );
	self->r.client->inventory[AMMO_CELLS] = 0;
	return respawned;
}
