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

#include "ai.h"
#include "neonz.h"
#include "solararray.h"
#include "ship.h"
#include "buildscreen.h"
#include "quadtree.h"
#include "orders.h"
#include "world.h"

extern SQuadNode* g_qnRootNode;
extern SShip* g_obMotherShip[2];
extern int g_nPlayer;
extern vector<SSolarArray*> g_vecSolarArrays;

float g_fAITimer;//ai frequency

void InitAI()
{
	g_fAITimer = 1.0f;
}

//here's the general idea behind this AI... build ships like crazy and send them to locations
//we have two staging grounds, one above the mothership where new ships are built
//one... say at the mothership where the new ships are defending it
//and one below it where ships are gathered and then sent to attack the enemy mothership
//Brilliant to say the least
void HandleAI()
{
	if(g_obMotherShip[1 - g_nPlayer] == 0)
		return;
	if(g_fAITimer < 0)
	{
		g_fAITimer = 5.0f;
		if(GetBuildListSize(1 - g_nPlayer) < 1)
			AddToBuildList(int(Rand(0, 5.9f)), 1 - g_nPlayer);

		list<SCollidableObject*> selected_list;


		vector2d mothership_pos = g_obMotherShip[1 - g_nPlayer]->polar_pos;
		vector2d cur_pol_pos = mothership_pos + vector2d(100, 0);
		vector2d cur_pos(cur_pol_pos.x * cosf(cur_pol_pos.y), cur_pol_pos.x * sinf(cur_pol_pos.y));

		//move ships from the build area
		if(QuadTreeCircleTestMulti(g_qnRootNode, cur_pos, 100, &selected_list))
		{
			for(list<SCollidableObject*>::iterator it = selected_list.begin(); it != selected_list.end(); it++)
			{
				SShip* ship = (SShip*)(*it);
				if(ship->player == 1 - g_nPlayer)
				{
					int what_to_do = int(Rand(0, 6.0f));
					if(what_to_do == 0)//move to defend mothership
					{
						vector2d dest = mothership_pos + vector2d(0, Rand(-AL_PI / 16, AL_PI / 16));

						SMoveOrder* order = new SMoveOrder(dest);
						order->ship = ship;
						ship->order_list.clear();
						ship->order_list.push_back(order);
					}
					else//move to staging area
					{
						vector2d dest = mothership_pos - vector2d(100, 0);

						SMoveOrder* order = new SMoveOrder(dest);
						order->ship = ship;
						ship->order_list.clear();
						ship->order_list.push_back(order);
					}
				}
			}
		}
		selected_list.clear();

		cur_pol_pos = mothership_pos - vector2d(100, 0);
		cur_pos.Set(cur_pol_pos.x * cosf(cur_pol_pos.y), cur_pol_pos.x * sinf(cur_pol_pos.y));

		//order ships in the staging area
		if(QuadTreeCircleTestMulti(g_qnRootNode, cur_pos, 100, &selected_list))
		{
			if(selected_list.size() > 1)
			{
				int what_to_do = int(Rand(0, 2.0f));
				vector2d dest = g_obMotherShip[g_nPlayer]->polar_pos;
				if(what_to_do == 0)//move to attack enemy mothership
				{
					if(g_obMotherShip[g_nPlayer])
					{
						
						if(Rand() > 0.5)
							dest += vector2d(0, AL_PI / 16);
						else
							dest -= vector2d(0, AL_PI / 16);
					}
				}
				else//get the solar array
				{
					dest = g_vecSolarArrays[(int)(Rand(0, (float)g_vecSolarArrays.size() - 0.9))]->polar_pos;
				}
				for(list<SCollidableObject*>::iterator it = selected_list.begin(); it != selected_list.end(); it++)
				{
					SShip* ship = (SShip*)(*it);
					if(ship->player == 1 - g_nPlayer)
					{
						SMoveOrder* order = new SMoveOrder(dest);
						order->ship = ship;
						ship->order_list.clear();
						ship->order_list.push_back(order);
					}
				}
			}
		}

		selected_list.clear();

		if(Rand(0, 1.0f) > 0.6)//now, pick a random ship from all over the map and send it to the staging area
		//this is a tad slow... :(
		{
			cur_pos.Set(0, 0);
			if(QuadTreeCircleTestMulti(g_qnRootNode, cur_pos, GetMaxWorldRadius(), &selected_list))
			{
				for(list<SCollidableObject*>::iterator it = selected_list.begin(); it != selected_list.end(); it++)
				{
					SShip* ship = (SShip*)(*it);
					if(ship->player == 1 - g_nPlayer && ship != g_obMotherShip[1 - g_nPlayer])
					{
						vector2d dest = mothership_pos + vector2d(-100, 0);

						SMoveOrder* order = new SMoveOrder(dest);
						order->ship = ship;
						ship->order_list.push_back(order);
						break;
					}
				}
			}
		}
	}
	g_fAITimer -= g_fDelta;
}
