#include "stdafx.h"
#include "MapLocation.h"

MapLocation::MapLocation()
{
	maxW = 0;
	parent = 0;
}

MapLocation::~MapLocation()
{

}

void MapLocation::UpdateLocationList()
{
	// update the locationlist to reflect this change
	// note: this may seem redundant since the location list will receive
	//		a notification but at that time the map hasn't been updated yet
	ListItem * item = theApp.locationlist.list.GetItemByKey(record.LocationId);
	if(item){
		Location * location = (Location *)item->userdata;
		location->ShallowRefresh();
		theApp.locationlist.UpdateActiveCount();
	}
}

int MapLocation::UserCount()
{
	// returns the users in this location and all of it children locations
	int count = users.size();
	std::list<MapLocation *>::iterator i;
	for(i=children.begin();i!=children.end();i++){
		MapLocation * ml = *i;
		count += ml->UserCount(); 
	}
	return count;
}

std::wstring MapLocation::UserList(){
	int first = 1;
	std::list<MapUser*>::iterator i;
	std::wstring userlist;

	// first append the users from this location
	for(i=users.begin();i!=users.end();i++){
		MapUser* mu = *i;
		if(!first){
			userlist += L", ";
		} else
			first = 0;
		userlist += mu->record.UserLogin;
	}

	// next append the users from each child location
	std::list<MapLocation *>::iterator j;
	for(j=children.begin();j!=children.end();j++){
		MapLocation * ml = *j;
		if(!first){
			userlist += L", ";
		} else
			first = 0;
		userlist += ml->UserList();
	}

	return userlist;
}

void MapLocation::AddUser(MapUser * mu)
{	
	users.push_back(mu);

	// now reposition all the other users to reflect the addition of this user
	std::list<MapUser*>::iterator i;
	int x = origin.X+location.X, y = origin.Y+location.Y;
	maxW = 0;
	for(i=users.begin();i!=users.end();i++){
		MapUser * mu2 = *i;
		mu2->SetLocation(x,y);
		y += mu2->size.Height;
		if(maxW<mu2->size.Width)
			maxW = mu2->size.Width;
		if(y+mu2->size.Height>origin.Y+location.Y+size.Height){
			y = origin.Y+location.Y;
			x += maxW;
			maxW = 0;
		}
	}

	// Make sure the MapUser's window is on top
	BringWindowToTop(mu->hWnd);

	UpdateLocationList();

}

void MapLocation::RemoveUser(MapUser * mu)
{
	int found = 0;
	std::list<MapUser*>::iterator i;
	for(i=users.begin();i!=users.end();i++){
		if(mu==*i){
			users.erase(i);
			found = 1;
			break;
		}
	}

	if(found){
		// now reposition all the other users to reflect the removal of this user
		int x = origin.X+location.X, y = origin.Y+location.Y;
		maxW = 0;
		for(i=users.begin();i!=users.end();i++){
			mu = *i;
			mu->SetLocation(x,y);
			y += mu->size.Height;
			if(maxW<mu->size.Width)
				maxW = mu->size.Width;
			if(y+mu->size.Height>origin.Y+location.Y+size.Height){
				y = origin.Y+location.Y;
				x += maxW;
				maxW = 0;
			}
		}
	}

	UpdateLocationList();
}

void MapLocation::Show()
{
	if(hWnd){
		ShowWindow(hWnd,SW_SHOWNOACTIVATE);
		// all of its children locations
		{
			std::list<MapLocation *>::iterator i;
			for(i=children.begin();i!=children.end();i++){
				MapLocation * ml = *i;
				ml->Show();
			}
		}
	}
	hidden = 0;
}

void MapLocation::SetState(AppearanceState s)
{
	if(s!=visual.state){
		visual.SetState(s);
		if(!hidden){
			//theApp.mapwindow.UpdateMapAround(this);
			theApp.mapwindow.UpdateMap();
		}
	}
}