#include "PvZAlpha.h"

PvZAlpha::PvZAlpha( Overseer* ov )
{
	overseer = ov;
	id = HIGHLEVEL_STRAT_PVZ_ALPHA;
}

void PvZAlpha::setUpBranches() { 


	/*
			Before doing anything, configure the Synapse system to maintain certain unit ratios. This can be changed in the future
			but it's best to first give it some initial idea of what we want.

			Remember we also need to send the command to turn Synapse on later, typically after our opener is done.

	*/

	Synapse* synapseCore = overseer->getUnitManager()->getSynapse();
	synapseCore->setRallyPoint((*BWTA::getStartLocation(Broodwar->self())->getRegion()->getChokepoints().begin())->getCenter());

	synapseCore->registerNewRatio(new UnitRatio(UnitTypes::Protoss_Dragoon, UnitTypes::Protoss_Zealot, 2, 1, overseer, 0)); // 0
	synapseCore->registerNewRatio(new UnitRatio(UnitTypes::Protoss_Dragoon, UnitTypes::Protoss_Reaver, 5, 1, overseer, 0)); // 1
	//synapseCore->registerNewRatio(new UnitRatio(UnitTypes::Protoss_Arbiter, UnitTypes::Protoss_Dragoon, 1, 10, overseer, 0)); // 2
	synapseCore->registerNewRatio(new UnitRatio(UnitTypes::None, UnitTypes::Protoss_Observer, 0, 6, overseer, 0)); // 3
	synapseCore->registerNewRatio(new UnitRatio(UnitTypes::Protoss_Nexus, UnitTypes::Protoss_Gateway, 1, 3, overseer, 6)); // 4
	synapseCore->registerNewRatio(new UnitRatio(UnitTypes::Protoss_Reaver, UnitTypes::Protoss_Shuttle, 3, 1, overseer, 2)); // 5
	synapseCore->registerNewRatio(new UnitRatio(UnitTypes::Protoss_Dragoon, UnitTypes::Protoss_High_Templar, 10, 2, overseer, 0)); // 6
	synapseCore->setCentralManagement(0, true);

	/*
			Finish synapse configuration
	*/

	BuildOrderTemplate* rootOpener = new BuildOrderTemplate(overseer);

	rootOpener->setTargetMineralWorkers(19);
	rootOpener->setTargetGasWorkers(3);
	rootOpener->setTargetParent(overseer->getUnitManager()->getFriendlyMainBase());

		rootOpener->addToOpeningSequence(UnitTypes::Protoss_Forge);
		rootOpener->addToOpeningSequence(new InternalStateChangeTask(overseer, PAUSE_WORKER_PRODUCTION_GLOBAL));
		rootOpener->addToOpeningSequence(UnitTypes::Protoss_Photon_Cannon);
		rootOpener->addToOpeningSequence(UnitTypes::Protoss_Photon_Cannon);

		rootOpener->addToOpeningSequence(new InternalStateChangeTask(overseer, RESUME_WORKER_PRODUCTION_GLOBAL));

		std::set<BWTA::BaseLocation*> bases = BWTA::getBaseLocations();
		BWTA::BaseLocation* nearestBase = NULL;
		TilePosition bestLoc = TilePositions::None;
		for (std::set<BaseLocation*>::iterator i = bases.begin(); i != bases.end(); ++i)
		{
			BaseLocation* cur = *i;
			if(overseer->getUnitManager()->knownBaseInRegion((Position)cur->getTilePosition())) {
				continue;
			}
			if(nearestBase == NULL) {
				nearestBase = cur;
				bestLoc = nearestBase->getTilePosition();
			} else {
				TilePosition startLoc = (TilePosition)overseer->getUnitManager()->getFriendlyMainBase()->getPosition();
				TilePosition curLoc = cur->getTilePosition();

				int distance = BWTA::getGroundDistance(startLoc, curLoc);
				int bestDistance = BWTA::getGroundDistance(startLoc, bestLoc);
				if(distance < bestDistance && distance > 5) {
					nearestBase = cur;
					bestLoc = nearestBase->getTilePosition();
				}
			}
		}
		bestLoc = nearestBase->getTilePosition();

		// first expansion
		BuildOrderTemplate* expansionBuildOrder = new BuildOrderTemplate(overseer);
		expansionBuildOrder->setTargetMineralWorkers(18);
		expansionBuildOrder->setTargetGasWorkers(3);

		expansionBuildOrder->addToOpeningSequence(UnitTypes::Protoss_Pylon);
		expansionBuildOrder->addToOpeningSequence(UnitTypes::Protoss_Photon_Cannon);
		expansionBuildOrder->addToOpeningSequence(UnitTypes::Protoss_Photon_Cannon);	
		expansionBuildOrder->addToOpeningSequence(UnitTypes::Protoss_Photon_Cannon);
		expansionBuildOrder->addToOpeningSequence(UnitTypes::Protoss_Photon_Cannon);
				expansionBuildOrder->addToOpeningSequence(UnitTypes::Protoss_Photon_Cannon);
		//expansionBuildOrder->addToOpeningSequence(UnitTypes::Protoss_Assimilator);
		expansionBuildOrder->setTargetParent(overseer->getUnitManager()->getFriendlyMainBase());
		rootOpener->addToOpeningSequenceWithGuardStrength(UnitTypes::Protoss_Nexus, 0, expansionBuildOrder);
			rootOpener->addToOpeningSequence(UnitTypes::Protoss_Assimilator);
		rootOpener->addToOpeningSequence(UnitTypes::Protoss_Gateway);
		
		rootOpener->addToOpeningSequenceWithRally(UnitTypes::Protoss_Zealot, RALLY_NATURAL);
		rootOpener->addToOpeningSequenceWithRally(UnitTypes::Protoss_Zealot, RALLY_NATURAL);
		rootOpener->addToOpeningSequenceWithRally(UnitTypes::Protoss_Zealot, RALLY_NATURAL);
	rootOpener->addToOpeningSequence(new InternalStateChangeTask(overseer, ACTIVATE_SYNAPSE));
		rootOpener->addToOpeningSequence(UnitTypes::Protoss_Cybernetics_Core);
		expansionBuildOrder->addToOpeningSequence(UnitTypes::Protoss_Assimilator);
		rootOpener->addToOpeningSequence(UpgradeTypes::Singularity_Charge);
		rootOpener->addToOpeningSequence(UpgradeTypes::Protoss_Ground_Weapons);
		rootOpener->addToOpeningSequence(UnitTypes::Protoss_Robotics_Facility);
		rootOpener->addToOpeningSequence(UnitTypes::Protoss_Templar_Archives);
				rootOpener->addToOpeningSequence(TechTypes::Psionic_Storm);
		rootOpener->addToOpeningSequence(UnitTypes::Protoss_Observatory);
		rootOpener->addToOpeningSequence(UnitTypes::Protoss_Robotics_Support_Bay);
		rootOpener->addToOpeningSequence(UnitTypes::Protoss_Forge);
		rootOpener->addToOpeningSequence(UpgradeTypes::Leg_Enhancements);
		rootOpener->addToOpeningSequence(UpgradeTypes::Protoss_Ground_Weapons);
		rootOpener->addToOpeningSequence(UpgradeTypes::Protoss_Ground_Armor);
		rootOpener->addToOpeningSequence(UpgradeTypes::Protoss_Ground_Weapons);
		rootOpener->addToOpeningSequence(UpgradeTypes::Protoss_Ground_Armor);
		rootOpener->addToOpeningSequence(UpgradeTypes::Protoss_Ground_Armor);
		rootOpener->addToOpeningSequence(UpgradeTypes::Protoss_Plasma_Shields);
		rootOpener->addToOpeningSequence(UpgradeTypes::Protoss_Plasma_Shields);
		rootOpener->addToOpeningSequence(UpgradeTypes::Protoss_Plasma_Shields);




	buildOrder.push_back(rootOpener);
}

void PvZAlpha::loadOpener()
{
	BaseModel* startBase = overseer->getUnitManager()->getFriendlyMainBase();
	startBase->setBuildOrderTemplate(buildOrder.at(0));
}

void PvZAlpha::monitorBuildOrder()
{
	// consistency checking code?
}


