#include "ResearchTask.h"


ResearchTask::ResearchTask( BWAPI::UpgradeType up, Overseer* ov )
{
	overseer = ov;
	initialized = false;
	executing = false;
	finished = false;
	upgType = up;
	tecType = BWAPI::TechTypes::None;
	TASK_TYPE = RESEARCH;
	startFrame = Broodwar->getFrameCount();
}

ResearchTask::ResearchTask( BWAPI::TechType up, Overseer* ov )
{
	overseer = ov;
	initialized = false;
	executing = false;
	finished = false;
	upgType = BWAPI::UpgradeTypes::None;
	tecType = up;
	TASK_TYPE = RESEARCH;
	startFrame = Broodwar->getFrameCount();
}

//************************************
// Method:    canInitialize
// FullName:  ResearchTask::canInitialize
// Access:    virtual public 
// Returns:   bool
// Comments:  none
//************************************
bool ResearchTask::canInitialize()
{
	// firstly, can we afford to do this...
	if(overseer->canReserveResources(type.mineralPrice()*2, type.gasPrice()*2)) {
	} else {
		return false;
	}

	// we can initialize if we have a building capable of performing the research
	UnitType upgradeSource;


	// utterly ridiculous
	if(upgType != BWAPI::UpgradeTypes::None) {
		upgradeSource = upgType.whatUpgrades();
	}
	if(tecType != BWAPI::TechTypes::None) {
		upgradeSource = tecType.whatResearches();
	}


	// so lets see if we have one
	if(overseer->getUnitManager()->hasBuildingComplete(upgradeSource)) {

		// we might have multiple buildings, so lets find one that's free...
		std::vector<UnitModel*> facilities = overseer->getUnitManager()->getAllFriendlyUnitsOfType(upgradeSource);
		for (vector<UnitModel*>::iterator i = facilities.begin(); i != facilities.end(); ++i)
		{
			UnitModel* cur = *i;
			if(!cur->getUnit()->isResearching() && !cur->getUnit()->isUpgrading()) {
					subject = cur;
					initialized = true;
					return true;
			}
		}
	}
	return false;
}

//************************************
// Method:    execute
// FullName:  ResearchTask::execute
// Access:    virtual public 
// Returns:   bool
// Comments:  none
//************************************
bool ResearchTask::execute()
{
	if(overseer->canReserveResources(type.mineralPrice(), type.gasPrice())) {
	} else {
		return false;
	}
	if(tecType != TechTypes::None) {
		executing = subject->getUnit()->research(tecType);
	}
	if(upgType != UpgradeTypes::None) {
		executing = subject->getUnit()->upgrade(upgType);
	}
	return executing;
}

//************************************
// Method:    isExecuting
// FullName:  ResearchTask::isExecuting
// Access:    virtual public 
// Returns:   bool
// Comments:  none
//************************************
bool ResearchTask::isExecuting()
{
	return executing;
}

//************************************
// Method:    isFinished
// FullName:  ResearchTask::isFinished
// Access:    virtual public 
// Returns:   bool
// Comments:  none
//************************************
bool ResearchTask::isFinished()
{
	return finished;
}

//************************************
// Method:    isInitialized
// FullName:  ResearchTask::isInitialized
// Access:    virtual public 
// Returns:   bool
// Comments:  none
//************************************
bool ResearchTask::isInitialized()
{
	return initialized;
}

//************************************
// Method:    monitor
// FullName:  ResearchTask::monitor
// Access:    virtual public 
// Returns:   void
// Comments:  none
//************************************
void ResearchTask::monitor()
{
	if(executing) {
		if(upgType != BWAPI::UpgradeTypes::None) {
			if(subject->getUnit()->isUpgrading()) {

			} else {
				finished = true;
			}
		}
		if(tecType != BWAPI::TechTypes::None) {
			if(subject->getUnit()->isResearching()) {

			} else {
				finished = true;
			}
		}

	}
}
