#include "users.h"

UsersList *users;
wxMutex users_mutex;

WX_DEFINE_OBJARRAY(Users);

UserData::UserData()
{
	prev = NULL;
	next = NULL;
	udp_port = CLIENT_UDP;
	tcp_port = CLIENT_TCP;
	lastPing = time((time_t *) NULL);
}

// -1 indicates item1 is closest to user, 1 for item2.
int UserData::Compare(UserData *item1, UserData *item2, UserData *user)
{
	float i1_xDelta = abs((int)(item1->latitude - user->latitude));
	float i1_yDelta = abs((int)(item1->longitude - user->longitude));
	float i1_distance = sqrt((i1_xDelta * i1_xDelta) + (i1_yDelta * i1_yDelta));
	float i2_xDelta = abs((int)(item2->latitude - user->latitude));
	float i2_yDelta = abs((int)(item2->longitude - user->longitude));
	float i2_distance = sqrt((i2_xDelta * i2_xDelta) + (i2_yDelta * i2_yDelta));
	if (i1_distance > i2_distance)
		return 1;
	else if (i1_distance < i2_distance)
		return -1;
	else return 0;
	return 1;
}
wxString UserData::toString()
{
	wxString msg;
	msg.Printf("%.5d\t\"%s\" (%s) -> %s",id,username,ip.c_str(),
		next!=NULL ? next->username : "");
	return msg;
}
UserData * UsersList::GetClosest(UserData *user)
{
	if (GetCount() < 1) return NULL;
	if (GetCount() == 1) return &Item(0);
	// simple sort to find the closest user to the given one
	UserData *best = NULL;
	int bestDist = 0;
	//wxUsersNode *node = GetFirst();
	best = &Item(0);
	bestDist = GetDistance(user,best);
	unsigned int i = 0;
	while (i < GetCount()) // for every user (inefficient i know)
	{
		if (&Item(i)!=user) // sanity check
		{
			float distance = GetDistance(user,&Item(i));
			if (distance < bestDist) // new best
			{
				best = &Item(i);
				bestDist = distance;
			}
		}
		i++;
	}
	return best;
}

float UsersList::GetDistance(UserData *item1, UserData *item2)
{
	float xDelta = abs((int)(item1->latitude - item2->latitude));
	float yDelta = abs((int)(item1->longitude - item2->longitude));
	return sqrt((xDelta * xDelta) + (yDelta * yDelta));
}

UserData * UsersList::Find(wxString username)
{
	// find the user with the given name
	unsigned int i=0;
	for (i=0; i < GetCount(); i++)
	{
		UserData *data = &Item(i);
		if (data->username==username)
			return data;
	}
	return NULL;
}

