/*
* Tyr is an AI for StarCraft: Broodwar, 
* 
* Please visit https://github.com/SimonPrins/Tyr for further information.
* 
* Copyright 2015 Simon Prins
*
* This file is part of Tyr.
* Tyr is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
* Tyr is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Tyr.  If not, see http://www.gnu.org/licenses/.
*/


package com.tyr;

import com.tyr.unitgroups.ScoutGroup;

import bwapi.Game;
import bwapi.Player;
import bwapi.Race;
import bwapi.Unit;
import bwapi.UnitType;


/**
 * This class determines the strategy the opponent is using.
 * This is recorded in a file, it is not meant to be used during the game.
 * For that the ScoutGroup class is used.
 * @author Simon
 *
 */
public class StrategyDetector 
{
	/**
	 * The strategy the opponent is using.
	 */
	public int opponentStrategy = ScoutGroup.unknown;
	
	/**
	 * This method is called every frame. It determines the strategy the opponent is using.
	 * @param game
	 * @param self
	 * @param bot
	 */
	public void onFrame(Game game, Player self, Tyr bot)
	{
		if (!Strategy.flagSet("DETECT"))
			for(Unit enemy : EnemyManager.getEnemyUnits())
				if (enemy.getType() == UnitType.Protoss_Dark_Templar
						|| enemy.getType() == UnitType.Protoss_Arbiter
						|| enemy.getType() == UnitType.Zerg_Lurker
						|| enemy.isBurrowed()
						|| enemy.getType() == UnitType.Terran_Ghost
						|| enemy.getType() == UnitType.Terran_Wraith
					)
					Strategy.addFlag("DETECT");
		
		if (!Strategy.flagSet("FLYERS"))
			for(Unit enemy : EnemyManager.getEnemyUnits())
				if (enemy.getType().isFlyer() && enemy.getType().canAttack())
					Strategy.addFlag("FLYERS");
		

		if (game.enemy().getRace() == Race.Protoss && !Strategy.flagSet("NZ"))
			for(Unit enemy : EnemyManager.getEnemyUnits())
				if (enemy.getType().canAttack() && !enemy.getType().isWorker() && enemy.getType() != UnitType.Protoss_Zealot)
					Strategy.addFlag("NZ");

		if (game.enemy().getRace() == Race.Zerg && !Strategy.flagSet("NZ"))
			for(Unit enemy : EnemyManager.getEnemyUnits())
				if (enemy.getType().canAttack() && !enemy.getType().isWorker() && enemy.getType() != UnitType.Zerg_Zergling)
					Strategy.addFlag("NZ");
		
		if (opponentStrategy != ScoutGroup.unknown)
			return;
		if(game.enemy().getRace() == Race.Protoss)
		{
			int nexusCount = 0;
			for(EnemyPosition enemy : EnemyManager.getManager().enemyBuildingMemory)
			{
				if (enemy.type == UnitType.Protoss_Nexus)
					nexusCount++;
			}
			if(nexusCount >= 2)
			{
				// An enemy who expands is likely going for lategame tech.
				opponentStrategy = ScoutGroup.tech;
				return;
			}
			for(Unit enemy : EnemyManager.getEnemyUnits())
			{
				// An enemy who uses gas is going for tech.
				if(enemy.getType().gasPrice() > 0 
						|| enemy.getType() == UnitType.Protoss_Assimilator 
						|| enemy.getType() == UnitType.Protoss_Cybernetics_Core)
				{
					opponentStrategy = ScoutGroup.tech;
					return;
				}
			}
				int gatewayCount = 0;
				for(EnemyPosition enemy : EnemyManager.getManager().enemyBuildingMemory)
				{
					if (enemy.type == UnitType.Protoss_Photon_Cannon || enemy.type == UnitType.Protoss_Forge)
					{
						// An enemy who builds  a forge or a cannon is most likely going for either a cannon rush or a cannon wall.
						opponentStrategy = ScoutGroup.cannons;
						return;
					}
					if (enemy.type == UnitType.Protoss_Gateway)
						gatewayCount++;
				}
				if(gatewayCount >= 2)
				{
					// An opponent who builds two gateways early on is most likely going for a zealot push.
					opponentStrategy = ScoutGroup.zealotPush;
					return;
				}
		}
		if(game.enemy().getRace() == Race.Terran)
		{
			// An enemy who builds bunkers is playin defensively.
			for(EnemyPosition enemy : EnemyManager.getManager().enemyBuildingMemory)
				if (enemy.type == UnitType.Terran_Bunker)
				{
					opponentStrategy = ScoutGroup.defensive;
					return;
				}
			
			// An enemy who builds at least three tanks is also playing defensively.
			int tankCount = 0;
			for(Unit enemy : EnemyManager.getEnemyUnits())
			{
				if(enemy.getType() == UnitType.Terran_Siege_Tank_Siege_Mode
						|| enemy.getType() == UnitType.Terran_Siege_Tank_Tank_Mode)
					tankCount++;
			}
			if(tankCount >= 3)
			{
				opponentStrategy = ScoutGroup.defensive;
				return;
			}
		}
			
	}
}
