#pragma once

#include "Common.h"
#include "InformationManager.h"
#include "WorkerManager.h"
#include "BuildOrder.h"
#include "BuildOrderQueue.h"

namespace UAlbertaBot
{
typedef std::pair<MacroAct, size_t> MetaPair;
typedef std::vector<MetaPair> MetaPairVector;

struct Strategy
{
    std::string _name;
    BWAPI::Race _race;
	std::string _openingGroup;
    BuildOrder  _buildOrder;

    Strategy()
        : _name("None")
        , _race(BWAPI::Races::None)
 		, _openingGroup("")
    {
    }

	Strategy(const std::string & name, const BWAPI::Race & race, const std::string & openingGroup, const BuildOrder & buildOrder)
        : _name(name)
        , _race(race)
		, _openingGroup(openingGroup)
		, _buildOrder(buildOrder)
	{
    }
};

class The;

class StrategyManager 
{
	StrategyManager();

	The & the;

	BWAPI::Race					    _selfRace;
	BWAPI::Race					    _enemyRace;
    std::map<std::string, Strategy> _strategies;
    int                             _totalGamesPlayed;
    const BuildOrder                _emptyBuildOrder;
	std::string						_openingGroup;
	bool							_hasDropTech;
	int								_highWaterBases;				// most bases we've ever had, terran and protoss only
	bool							_openingStaticDefenseDropped;	// make sure we do this at most once ever

	///////////7.17.2019
	std::string                     _lastModule;//上一个策略模块
	std::string                     _currentModule;//当前的策略模块
	std::vector<std::string>        _previousModule;//之前使用过的所有策略模块，按照使用顺序记录在这之中
	bool                            _startModuleC;
	bool                            _buildSecondBase;
	bool                            _eBayIsLifted;
	int                             _numFreeFactory;
	bool                            _buildSecondBaseIn;
	///////////7.17.2019


    const	MetaPairVector		    getProtossBuildOrderGoal();
	const	MetaPairVector		    getTerranBuildOrderGoal();
	const	MetaPairVector		    getZergBuildOrderGoal() const;

	bool							detectSupplyBlock(BuildOrderQueue & queue) const;
	bool							handleExtremeEmergency(BuildOrderQueue & queue);

	bool							canPlanBuildOrderNow() const;
	void							performBuildOrderSearch();

public:
    
	static	StrategyManager &	    Instance();
	const	bool				    shouldExpandNow() const;

            void                    addStrategy(const std::string & name, Strategy & strategy);
			void					setOpeningGroup();
	const	std::string &			getOpeningGroup() const;
 	const	MetaPairVector		    getBuildOrderGoal();
	const	BuildOrder &            getOpeningBookBuildOrder() const;

			void					handleUrgentProductionIssues(BuildOrderQueue & queue);
			void					freshProductionPlan();

			bool					dropIsPlanned() const;
			bool					hasDropTech();
////////////////////////////////++
			std::vector<int>        numAttackUnitAdd();//计算需要添加到生产队列中的单位数量
			std::vector<int>        isMechanicalUnitAdd();//根据经济状况，判断是否添加单位到生产队列中

			bool                    enemyFlyArmyGroup();//判断敌方的主力是否为飞行单位
			bool                    shouldBuildEBay();//判断是否需要修建工程湾
			bool                    shouldBuildBunker();
			bool                    shouldBuildTurret();
			bool                    shouldBuildCenter();
			bool                    shouldBuildFactory();

			void                    executeStrategy(BuildOrderQueue & queue);//更新当前的建筑和单位，包括开局的实现，游戏状态的更新等
			void                    updateCommonState(BuildOrderQueue & queue);//所有策略通用的状态更新，比如人口建筑，分基放雷队列等
			void                    doSwitchModule();//暂时代替学习模块，进行策略的切换
			void                    shouldSwitchModule();//紧急情况下的策略切换

			void                    updateAntiRush(BuildOrderQueue & queue);//对抗虫族的开局
			void                    updateDefault(BuildOrderQueue & queue);//6.29//默认开局
			void                    update8BB(BuildOrderQueue & queue);//7.1//应对人族的一种策略
			//////////////++6.24
			bool                    openingFinished();//开局结束后该函数返回的值为true
			//////////////__6.24
			bool                    shouldUpgrade(BWAPI::UpgradeType type);//7.4//根据当前经济判断是否要升级机械单位的攻击和防御

			//////////////7.17
			void                    drawModuleInformation();
			void                    updateModuleA1(BuildOrderQueue & queue);
			void                    updateModuleA2(BuildOrderQueue & queue);//8SCV修供给所，地堡堵路口
			void                    updateModuleA3(BuildOrderQueue & queue);//8SCV修供给所，不修地堡
			void                    updateModuleA4(BuildOrderQueue & queue);//8BB
			void                    updateModuleB1(BuildOrderQueue & queue);//机枪兵Rush
			void                    updateModuleB2(BuildOrderQueue & queue);
			void                    updateModuleB3(BuildOrderQueue & queue);
			void                    updateModuleB4(BuildOrderQueue & queue);
			void                    updateModuleB5(BuildOrderQueue & queue);//最快发展策略,不反隐，不防空
			void                    updateModuleB6(BuildOrderQueue & queue);
			void                    updateModuleB7(BuildOrderQueue & queue);//防空

			void                    updateModuleC(BuildOrderQueue & queue);//把C类策略也改成及时生成模式

			const MetaPairVector    updateModuleC1();
			std::string             getCurrentModule(){ return _currentModule; };
			bool                    enemyUnitsFrontPosition(BWAPI::Position currentPos, BWAPI::Position referencePos, bool isFront);//判断是否有敌方单位堵在家门口
			//////////////7.17

			bool                    isSecondBaseReady(){ return _buildSecondBase; };//8.7.2019//返回是否开始扩张二基地//从分基地的地堡加入队列开始，该函数返回true
			void                    setEbayIsLifted(bool isLifted){ _eBayIsLifted = isLifted; };//8.7.2019
			void                    buildTurret(BuildOrderQueue & queue, int aimNumOfBaseTurret, int numChoke1, int numChoke2);//8.8.2019//负责修建主基地和两个路口的防空台，进入C类后改为使用shouldBuildTurret()函数修建阵线上的防空台
			void                    buildBaseTurret(BuildOrderQueue & queue);//8.22.2019//分基地的防空由防空台替代机器人
			bool                    shouldBuildSecondBaseIn(){ return _buildSecondBaseIn; };
////////////////////////////////__

};

}