//Copyright (C) 2007 SiegeLord
//See ReadMe.txt and License.txt for copying information

#include "selection.h"
#include "camera.h"
#include "ship.h"

list<SShip*> g_lstSelectedShips;
list<SCollidableObject*> g_lstSelection_buffer;

vector2d g_vecSelectStart;
float g_fSelectRadius = 0.0f;
bool g_bSelecting = false;

extern int g_nPlayer;

void DeselectAll()
{
	for(list<SShip*>::iterator it = g_lstSelectedShips.begin(); it != g_lstSelectedShips.end(); it++)
		(*it)->selected = false;
	g_lstSelectedShips.clear();
}

void DeselectNonPlayer(int player)
{
	for(list<SShip*>::iterator it = g_lstSelectedShips.begin(); it != g_lstSelectedShips.end(); it++)
	{
		if((*it)->player != player)
		{
			(*it)->selected = false;
			it = g_lstSelectedShips.erase(it);
		}
	}
}

bool FindAndDeselect(SShip* ship)
{
	for(list<SShip*>::iterator it = g_lstSelectedShips.begin(); it != g_lstSelectedShips.end(); it++)
	{
		if(*it == ship)
		{
			(*it)->selected = false;
			g_lstSelectedShips.erase(it);
			return true;
		}
	}
	return false;
}

void RemoveFromSelection(SShip* ship)
{
	FindAndDeselect(ship);
}

void HandleSelection(SQuadNode* node)
{
	if(IsMKeyJustPressed(0))
	{
		g_bSelecting = true;
		vector2d pos = GetWorldMousePos();
		g_vecSelectStart = pos;
	}
	else if(IsMKeyDown(0))
	{
		if(g_bSelecting)
		{
			vector2d pos = GetWorldMousePos();
			g_fSelectRadius = vector2d(g_vecSelectStart, pos).GetLength();

			//deselect all old ones
			for(list<SCollidableObject*>::iterator it = g_lstSelection_buffer.begin(); it != g_lstSelection_buffer.end(); it++)
			{
				((SShip*)(*it))->selected = false;
			}

			g_lstSelection_buffer.clear();

			QuadTreeCircleTestMulti(node, g_vecSelectStart, g_fSelectRadius, &g_lstSelection_buffer);

			for(list<SCollidableObject*>::iterator it = g_lstSelection_buffer.begin(); it != g_lstSelection_buffer.end(); it++)
			{
				((SShip*)(*it))->selected = true;
			}
		}
	}
	if(IsMKeyJustReleased(0))
	{
		if(g_bSelecting)
		{
			g_bSelecting = false;
			if(fabs(g_fSelectRadius) < 4)//we just clicked
			{
				//deselect all old ones
				for(list<SCollidableObject*>::iterator it = g_lstSelection_buffer.begin(); it != g_lstSelection_buffer.end(); it++)
				{
					((SShip*)(*it))->selected = false;
				}
				SShip* ship = (SShip*)QuadTreePointTest(node, g_vecSelectStart);
				if(ship)
				{
					if(IsShiftDown() && ship->player == g_nPlayer)//can't shift select enemy ships
					{
						//see if we have it already
						if(!FindAndDeselect(ship))
						{
							ship->selected = true;
							g_lstSelectedShips.push_back(ship);
						}
					}
					else
					{
						DeselectAll();
						ship->selected = true;
						g_lstSelectedShips.push_back(ship);
					}
				}
				else if(!IsShiftDown())
					DeselectAll();
			}
			else
			{
				if(!IsShiftDown())
					DeselectAll();
				for(list<SCollidableObject*>::iterator it = g_lstSelection_buffer.begin(); it != g_lstSelection_buffer.end(); it++)
				{
					SShip* ship = (SShip*)(*it);
					if(ship->player != g_nPlayer)//can't drag select enemy ships
					{
						ship->selected = false;
						continue;
					}
					if(IsShiftDown())
					{
						//see if we have it already
						if(!FindAndDeselect(ship))
						{
							ship->selected = true;
							g_lstSelectedShips.push_back(ship);
						}
					}
					else
					{
						ship->selected = true;
						g_lstSelectedShips.push_back(ship);
					}
				}

				if(IsShiftDown())
				{
					DeselectNonPlayer(g_nPlayer);
				}
				g_lstSelection_buffer.clear();
			}
			g_fSelectRadius = 0;
		}
	}
	if(IsMKeyUp(0))
		g_bSelecting = false;
}

void DrawSelection()
{
	if(g_bSelecting)
	{
		DrawModeAlpha();
		float old = SetLineThickness(1.0f);
		DrawCircle(g_vecSelectStart.x, g_vecSelectStart.y, g_fSelectRadius, -10, 0xff00ff00, 32);
		SetLineThickness(old);
		DrawModeSolid();
	}
}
