package com.tyr.unitgroups;

import bwapi.Color;
import bwapi.Game;
import bwapi.Player;
import bwapi.Position;
import bwapi.Unit;
import bwapi.UnitType;

import com.tyr.EnemyManager;
import com.tyr.Tyr;
import com.tyr.agents.Agent;

public class ZealotDropGroup extends UnitGroup
{
	private Agent shuttle;
	private Position target;
	
	private Unit killTarget;
	
	public int attackMode = KILL_TANKS;
	public static final int KILL_TANKS = 0;
	public static final int ATTACK_BASE = 1;

	public ZealotDropGroup()
	{
		super(Tyr.bot.hobos);
	}

	public ZealotDropGroup(int attackMode)
	{
		super(Tyr.bot.hobos);
		this.attackMode = attackMode;
	}
	
	public void setTarget(Position target)
	{
		this.target = target;
	}

	@Override
	public void onFrame(Game game, Player self, Tyr bot)
	{
		if (shuttle != null && shuttle.isDead())
			shuttle = null;
		
		if (shuttle == null)
		{
			for (Agent agent : units)
			{
				if (agent.unit.getType() == UnitType.Protoss_Shuttle)
					shuttle = agent;
			}
		}
		
		if (attackMode == KILL_TANKS)
			killTanks();
		else if (attackMode == ATTACK_BASE)
			modeAttackBase();
	}
	
	private void killTanks()
	{
		if (killTarget != null && (Agent.isDead(killTarget) || killTarget.getType() != UnitType.Terran_Siege_Tank_Siege_Mode))
			killTarget = null;
		
		if (killTarget == null)
		{
			int dist = 400 * 400;
			
			for (Unit enemy : EnemyManager.getEnemyUnits())
			{
				if (enemy.getType() != UnitType.Terran_Siege_Tank_Siege_Mode)
					continue;
				
				int newDist = 1000000;
				for (Agent agent : units)
				{
					final int agentEnemyDist = agent.distanceSquared(enemy); 
					if (agentEnemyDist < newDist)
						newDist = agentEnemyDist;
				}
				
				if (newDist < dist)
				{
					killTarget = enemy;
					dist = newDist;
				}
			}
		}
		
		if (killTarget != null)
			attack();
		else
			move();
	}
	
	private void modeAttackBase()
	{
		if (killTarget != null && (Agent.isDead(killTarget)))
			killTarget = null;
		
		if (killTarget == null)
		{
			int dist = 400 * 400;
			
			for (Unit enemy : EnemyManager.getEnemyUnits())
			{
				if (!enemy.getType().isResourceDepot())
					continue;
				
				int newDist = 1000000;
				for (Agent agent : units)
				{
					int agentEnemyDist = agent.distanceSquared(enemy); 
					if (agentEnemyDist < newDist)
						newDist = agentEnemyDist;
				}
				
				if (newDist < dist)
				{
					killTarget = enemy;
					newDist = dist;
				}
			}
		}
		
		if (killTarget != null)
			attackBase();
		else
			move();
	}
	
	public void attackBase()
	{
		final int dist = shuttle.distanceSquared(killTarget);
		if (shuttle != null && dist <= 150 * 150)
			shuttle.move(Tyr.getStartLocation());
		
		boolean unloading = false;
		if (shuttle != null && dist <= 400 * 400 && dist > 150 * 150)
		{
			for (Agent agent : units)
				if (agent.unit.isLoaded())
				{
					shuttle.unit.unload(agent.unit);
					unloading = true;
					break;
				}
		}
		if (!unloading && shuttle != null && dist > 150 * 150)
		{
			Tyr.game.drawLineMap(killTarget.getPosition(), shuttle.unit.getPosition(), Color.Red);
			shuttle.move(killTarget.getPosition());
		}
		
		for (Agent agent : units)
		{
			if (agent.unit.isLoaded())
				continue;
			if (agent == shuttle)
				continue;
			agent.attack(killTarget.getPosition());
		}
	}
	
	public void attack()
	{
		boolean unloading = false;
		if (shuttle != null && shuttle.distanceSquared(killTarget) <= 100 * 100)
		{
			for (Agent agent : units)
				if (agent.unit.isLoaded())
				{
					shuttle.unit.unload(agent.unit);
					unloading = true;
					break;
				}
		}
		if (!unloading && shuttle != null)
		{
			Tyr.game.drawLineMap(killTarget.getPosition(), shuttle.unit.getPosition(), Color.Red);
			shuttle.move(killTarget.getPosition());
		}
		
		for (Agent agent : units)
			if (agent != shuttle && !agent.unit.isLoaded())
			{
				Tyr.game.drawLineMap(killTarget.getPosition(), agent.unit.getPosition(), Color.Red);
				agent.attack(killTarget);
			}
	}
	
	public void move()
	{
		boolean loaded = shuttle != null;
		for (Agent agent : units)
		{
			if (agent != shuttle && !agent.unit.isLoaded())
			{
				loaded = false;
				break;
			}
		}
		
		if (loaded)
		{
			//Tyr.game.drawLineMap(target, shuttle.unit.getPosition(), Color.Blue);
			shuttle.move(target);
			return;
		}
		
		if (shuttle == null)
		{
			for (Agent agent : units)
			{
				Tyr.game.drawLineMap(Tyr.getStartLocation(), agent.unit.getPosition(), Color.Green);
				agent.move(Tyr.getStartLocation());
			}
			return;
		}
		
		boolean loading = false;
		for (Agent agent : units)
		{
			if (agent == shuttle)
				continue;
			
			if (agent.unit.isLoaded())
				continue;
			
			if (loading)
			{
				Tyr.game.drawLineMap(agent.unit.getPosition(), shuttle.unit.getPosition(), Color.Blue);
				agent.move(shuttle.unit.getPosition());
				continue;
			}
			
			loading = true;
			if (agent.distanceSquared(shuttle) >= 100 * 100)
				agent.unit.move(shuttle.unit.getPosition());

			Tyr.game.drawLineMap(agent.unit.getPosition(), shuttle.unit.getPosition(), Color.Green);
			shuttle.unit.load(agent.unit);
		}
	}

	public boolean needsShuttle()
	{
		return shuttle == null;
	}

	public int getZealots() 
	{
		int result = 0;
		for (Agent agent : units)
			if (agent.unit.getType() == UnitType.Protoss_Zealot)
				result++;
		return result;
	}

	public Agent getShuttle()
	{
		return shuttle;
	}
}
