/*
   Copyright (C) 2007 Will Franklin.

   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 "mm_common.h"

//================
// MM_FreeClient
// Free client memory
//================
void MM_FreeClient( mm_client_t *client )
{
	mm_packet_t *packet, *next;

	if( !client )
		return;

	packet = client->packets;
	while( packet )
	{
		next = packet->next;
		MM_Free( packet->cmd );
		MM_Free( packet );
		packet = next;
	}

	MM_Free( client->address );
	MM_Free( client->nickname );
	MM_Free( client );
}

//================
// MM_FreeMatch
// Free match memory and remove it from linked list
//================
void MM_FreeMatch( mm_match_t *match )
{
	int i;
	mm_ignoreserver_t *ignore, *next;

	if( !match )
		return;

	for( i = 0; i < match->maxclients; i++ )
	{
		if( match->clients[i] )
			MM_FreeClient( match->clients[i] );
	}

	// free ignores
	for( ignore = match->ignores; ignore; )
	{
		next = ignore->next;
		MM_Free( ignore );
		ignore = next;
	}

#ifdef MATCHMAKER
	if( match->prev && match->next )
	{
		match->prev->next = match->next;
		match->next->prev = match->prev;
	}
	// first
	else if( match->next )
	{
		match->next->prev = NULL;
		matchlist->first = match->next;
	}
	// last
	else if( match->prev )
	{
		match->prev->next = NULL;
		//matchlist->last = match->prev;
	}
	else
		matchlist->first = NULL;
#endif

	MM_Free( match );
}

//================
// MM_ClientCount
// returns client count
//================
int MM_ClientCount( const mm_match_t *match )
{
	int i, count = 0;

	if( !match )
		return -1;

	for( i = 0; i < match->maxclients; i++ )
	{
		if( match->clients[i] )
			count++;
	}

	return count;
}

//================
// MM_FindClientByUserId
// Finds a client in the match with the specified userid
//================
mm_client_t **MM_FindClientByUserId( mm_match_t *match, const int uid )
{
	int i;

	if( !match || !uid )
		return NULL;

	for( i = 0; i < match->maxclients; i++ )
	{
		if( !match->clients[i] )
			continue;

		if( match->clients[i]->uid == uid )
			return &match->clients[i];
	}

	return NULL;
}

//================
// MM_FindClientByAddress
//================
mm_client_t **MM_FindClientByAddress( mm_match_t *match, const netadr_t *address )
{
	int i;

	if( !match || !address )
		return NULL;

	for( i = 0; i < match->maxclients; i++ )
	{
		if( !match->clients[i] )
			continue;

		if( NET_CompareAddress( match->clients[i]->address, address ) )
			return &match->clients[i];
	}

	return NULL;
}

//================
// MM_SendMsgToServer
//================
void MM_SendMsgToServer( const socket_t *socket, const char *format, ... )
{
	va_list argptr;
	char msg[1024];
	netadr_t address;
	const char *server;

	if( !socket || !socket->open )
		return;

	va_start( argptr, format );
	Q_vsnprintfz( msg, sizeof( msg ), format, argptr );
	va_end( argptr );

	if( !*msg )
		return;

	server = Cvar_String( MM_SERVER_VAR );
	if( !server )
		return;

	if( !NET_StringToAddress( server, &address ) )
		return;

	if( address.type != NA_IP )
		return;

	if( !address.port )
		address.port = BigShort( PORT_MASTER );

	Netchan_OutOfBandPrint( socket, &address, msg );
}
