#include "GameCommander.h"

using namespace MyBot;

GameCommander::GameCommander(){
	isToFindError = false;
}
GameCommander::~GameCommander(){
}

void GameCommander::onStart() 
{
	BWAPI::TilePosition startLocation = BWAPI::Broodwar->self()->getStartLocation();
	if (startLocation == BWAPI::TilePositions::None || startLocation == BWAPI::TilePositions::Unknown) {
		return;
	}

	StrategyManager::Instance().onStart();
}

void GameCommander::onEnd(bool isWinner)
{
	StrategyManager::Instance().onEnd(isWinner);
}

void GameCommander::onFrame()
{
	/*
	if (BWAPI::Broodwar->isPaused() 
		|| BWAPI::Broodwar->self() == nullptr || BWAPI::Broodwar->self()->isDefeated() || BWAPI::Broodwar->self()->leftGame()
		|| BWAPI::Broodwar->enemy() == nullptr || BWAPI::Broodwar->enemy()->isDefeated() || BWAPI::Broodwar->enemy()->leftGame()) {
		return;
	}
	*/

	if (isToFindError) std::cout << "(a";

	// 아군 베이스 위치. 적군 베이스 위치. 각 유닛들의 상태정보 등을 Map 자료구조에 저장/업데이트
	InformationManager::Instance().update();

	if (isToFindError) std::cout << "b";

	// 각 유닛의 위치를 자체 MapGrid 자료구조에 저장
	MapGrid::Instance().update();
		
	if (isToFindError) std::cout << "c";

	// economy and base managers
	// 일꾼 유닛에 대한 명령 (자원 채취, 이동 정도) 지시 및 정리
	WorkerManager::Instance().update();

	if (isToFindError) std::cout << "d";

	// 빌드오더큐를 관리하며, 빌드오더에 따라 실제 실행(유닛 훈련, 테크 업그레이드 등)을 지시한다.
	BuildManager::Instance().update();

	if (isToFindError) std::cout << "e";

	// 빌드오더 중 건물 빌드에 대해서는, 일꾼유닛 선정, 위치선정, 건설 실시, 중단된 건물 빌드 재개를 지시한다
	ConstructionManager::Instance().update();

	if (isToFindError) std::cout << "f";

	// 게임 초기 정찰 유닛 지정 및 정찰 유닛 컨트롤을 실행한다
	//ScoutManager::Instance().update();

	if (isToFindError) std::cout << "g";

	// 전략적 판단 및 유닛 컨트롤
	StrategyManager::Instance().update();

	if (isToFindError) std::cout << "h)";
}

// BasicBot 1.1 Patch Start ////////////////////////////////////////////////

void GameCommander::onUnitShow(BWAPI::Unit unit)
{
	InformationManager::Instance().onUnitShow(unit);
}

// BasicBot 1.1 Patch End //////////////////////////////////////////////////

void GameCommander::onUnitHide(BWAPI::Unit unit)			
{
	InformationManager::Instance().onUnitHide(unit); 
}

// BasicBot 1.1 Patch Start ////////////////////////////////////////////////

void GameCommander::onUnitCreate(BWAPI::Unit unit)
{
	InformationManager::Instance().onUnitCreate(unit);
}

// BasicBot 1.1 Patch End //////////////////////////////////////////////////

// BasicBot 1.1 Patch Start ////////////////////////////////////////////////

void GameCommander::onUnitComplete(BWAPI::Unit unit)
{
	InformationManager::Instance().onUnitComplete(unit);

	// ResourceDepot 및 Worker 에 대한 처리
	WorkerManager::Instance().onUnitComplete(unit);
}

// BasicBot 1.1 Patch End //////////////////////////////////////////////////


void GameCommander::onUnitDestroy(BWAPI::Unit unit)		
{
	/*
	if (unit->getType() == BWAPI::UnitTypes::Zerg_Hatchery || unit->getType() == BWAPI::UnitTypes::Zerg_Lair || unit->getType() == BWAPI::UnitTypes::Zerg_Hive) {
		std::cout << "onUnitDestroy unit->getType() " << unit->getType().c_str()
			<< " isResourceDepot " << unit->getType().isResourceDepot()
			<< " isResourceContainer " << unit->getType().isResourceContainer()
			<< " isMorphing " << unit->isMorphing()
			<< std::endl;
	}
	*/
	// ResourceDepot 및 Worker 에 대한 처리
	WorkerManager::Instance().onUnitDestroy(unit);

	InformationManager::Instance().onUnitDestroy(unit); 
}

void GameCommander::onUnitRenegade(BWAPI::Unit unit)
{
	// Vespene_Geyser (가스 광산) 에 누군가가 건설을 했을 경우
	//BWAPI::Broodwar->sendText("A %s [%p] has renegaded. It is now owned by %s", unit->getType().c_str(), unit, unit->getPlayer()->getName().c_str());

	InformationManager::Instance().onUnitRenegade(unit);
}

void GameCommander::onUnitMorph(BWAPI::Unit unit)
{ 
	InformationManager::Instance().onUnitMorph(unit);

	// Zerg 종족 Worker 의 Morph 에 대한 처리
	WorkerManager::Instance().onUnitMorph(unit);
}

void GameCommander::onUnitDiscover(BWAPI::Unit unit)
{
}

void GameCommander::onUnitEvade(BWAPI::Unit unit)
{
}

void GameCommander::onNukeDetect(BWAPI::Position target)
{
	StrategyManager::Instance().onNukeDetect(target);
}

void GameCommander::onPlayerLeft(BWAPI::Player player)
{
}

void GameCommander::onSaveGame(std::string gameName)
{
}

void GameCommander::onSendText(std::string text)
{
	// Make sure to use %s and pass the text as a parameter,
	// otherwise you may run into problems when you use the %(percent) character!

	BWAPI::Player self = BWAPI::Broodwar->self();

	// 치트키
	if (text == "show") {
		BWAPI::Broodwar->sendText("show me the money");
	}
	else if (text == "black") {
		BWAPI::Broodwar->sendText("black sheep wall");
	}
	else if (text == "oper") {
		BWAPI::Broodwar->sendText("operation cwal");
	}

	// 화면 표시 여부 변경
	if (text == "grid") {
		Config::Debug::DrawMapGrid = !Config::Debug::DrawMapGrid;
	}
	else if (text == "resource") {
		Config::Debug::DrawResourceInfo = !Config::Debug::DrawResourceInfo;
	}
	else if (text == "worker") {
		Config::Debug::DrawWorkerInfo = !Config::Debug::DrawWorkerInfo;
	}
	else if (text == "building") {
		Config::Debug::DrawBuildingInfo = !Config::Debug::DrawBuildingInfo;
	}
	else if (text == "squadName") {
		Config::Debug::DrawSquadName = !Config::Debug::DrawSquadName;
	}
	else if (text == "squadList") {
		Config::Debug::DrawSquadList = !Config::Debug::DrawSquadList;
	}

}

void GameCommander::onReceiveText(BWAPI::Player player, std::string text)
{
}

