/**
 * \file Params.h
 * \date 14.04.2003
 *
 * Server parameters in world model
 */

#include "Player/World/Params.h"
#include "Player/World/World.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

Params::Params(World* w) : WorldObject(w)
{
	server = NULL;
	player = NULL;
	types = NULL;
}

Params::Params(const Params& params) : WorldObject(params.world)
{
	server = NULL; player = NULL; types = NULL;
	
	if(params.server != NULL)
	{
		server = new SERVER_PARAMS;
		memcpy((void*) server, (void*) params.server, sizeof(SERVER_PARAMS));
	}
	
	if(params.player != NULL)
	{
		player = new PLAYER_PARAMS;
		memcpy((void*) player, (void*) params.player, sizeof(PLAYER_PARAMS));
	
		if(params.types != NULL)
		{
			types = (PLAYER_TYPE**) malloc(player->player_types * sizeof(PLAYER_TYPE*));
			
			for(int i = 0; i < player->player_types; i++)
			{
				types[i] = new PLAYER_TYPE;
				memcpy((void*) types[i], (void*) params.types[i], sizeof(PLAYER_TYPE));
			}
		}
	}

	SetupFlags();
}

void Params::ProcessServerParams(const SERVER_PARAMS* params)
{
	if(server == NULL) server = new SERVER_PARAMS;
	memcpy((void*) server, (void*) params, sizeof(SERVER_PARAMS));

	// Load all flag positions
	SetupFlags();

	// Initialize coach adjustable variables to their default values
	world->variables->Initialize();
}

void Params::ProcessPlayerParams(const PLAYER_PARAMS* params)
{
	if(player == NULL) player = new PLAYER_PARAMS;
	memcpy((void*) player, (void*) params, sizeof(PLAYER_PARAMS));

	// Reinitialize player types
	if(types != NULL && player != NULL)
		for(int i = 0; i < player->player_types; i++) delete types[i];
	free(types);
	
	types = (PLAYER_TYPE**) malloc(player->player_types * sizeof(PLAYER_TYPE*));
	memset((void*) types, 0, player->player_types * sizeof(PLAYER_TYPE*));
}

void Params::ProcessPlayerType(int id, const PLAYER_TYPE* type)
{
	types[id] = new PLAYER_TYPE;
	memcpy((void*) types[id], type, sizeof(PLAYER_TYPE));

	world->RelinkPlayerTypes();
}

void Params::SetupFlags()
{
	// Set up flag coordinates
	flags[GOAL_L] = Point(-52.5f, 0);
	flags[GOAL_R] = Point(52.5f, 0);

	flags[C] = Point(0, 0);
	flags[CT] = Point(0, -34);
	flags[CB] = Point(0, 34);
	flags[LT] = Point(-52.5f, -34);
	flags[LB] = Point(-52.5f, 34);
	flags[RT] = Point(52.5f, -34);
	flags[RB] = Point(52.5f, 34);
 
	flags[PLT] = Point(-36, -20.16f);
	flags[PLC] = Point(-36, 0);
	flags[PLB] = Point(-36, 20.16f);
	flags[PRT] = Point(36, -20.16f);
	flags[PRC] = Point(36, 0);
	flags[PRB] = Point(36, 20.16f);
 
	flags[GLT] = Point(-52.5f, -server->goal_width / 2);
	flags[GLB] = Point(-52.5f, server->goal_width / 2);
	flags[GRT] = Point(52.5f, -server->goal_width / 2);
	flags[GRB] = Point(52.5f, server->goal_width / 2);
 
	flags[TL50] = Point(-50, -39);
	flags[TL40] = Point(-40, -39);
	flags[TL30] = Point(-30, -39);
	flags[TL20] = Point(-20, -39);
	flags[TL10] = Point(-10, -39);
	flags[T0] = Point(0, -39);
	flags[TR10] = Point(10, -39);
	flags[TR20] = Point(20, -39);
	flags[TR30] = Point(30, -39);
	flags[TR40] = Point(40, -39);
	flags[TR50] = Point(50, -39);
 
	flags[BL50] = Point(-50, 39);
	flags[BL40] = Point(-40, 39);
	flags[BL30] = Point(-30, 39);
	flags[BL20] = Point(-20, 39);
	flags[BL10] = Point(-10, 39);
	flags[B0] = Point(0, 39);
	flags[BR10] = Point(10, 39);
	flags[BR20] = Point(20, 39);
	flags[BR30] = Point(30, 39);
	flags[BR40] = Point(40, 39);
	flags[BR50] = Point(50, 39);
 
	flags[LT30] = Point(-57.5f, -30);
	flags[LT20] = Point(-57.5f, -20);
	flags[LT10] = Point(-57.5f, -10);
	flags[L0] = Point(-57.5f, 0);
	flags[LB10] = Point(-57.5f, 10);
	flags[LB20] = Point(-57.5f, 20);
	flags[LB30] = Point(-57.5f, 30);
 
	flags[RT30] = Point(57.5f, -30);
	flags[RT20] = Point(57.5f, -20);
	flags[RT10] = Point(57.5f, -10);
	flags[R0] = Point(57.5f, 0);
	flags[RB10] = Point(57.5f, 10);
	flags[RB20] = Point(57.5f, 20);
	flags[RB30] = Point(57.5f, 30);
}

Params::~Params()
{
	if(types != NULL && player != NULL)
		for(int i = 0; i < player->player_types; i++) delete types[i];
	free(types);

	if(player != NULL) delete player;
	if(server != NULL) delete server;
}
