#pragma once
#include "Jass.h"
#include "Natives.h"
#include "myJASSConstants.h"

extern struct HumanPlayer;
extern struct sRect2;
extern struct DataUnit;
extern unsigned short vW;
extern unsigned short vH;
extern unsigned short vH2;
extern unsigned short vW2;
extern unsigned short vH3;
extern unsigned short vW3;
extern unsigned int vSizeMap;

struct sDoom
{
	bool vBool;
	unsigned short vNBaseRight;
	unsigned short vNBaseBottom;
	unsigned short vNBaseLeft;
	unsigned short vNBaseTop;
};

struct sSides
{
	bool vLeft;
	bool vTop;
	bool vRight;
	bool vBottom;
};

struct sSmallCage
{
	unsigned short vNSmallCage;
	sSides vTree;
	unsigned short vQTree;
	sSmallCage * vHead;
	unsigned int vInt3;
	sSides vCliff;
	unsigned short vQCliff;
	unsigned short vIdSmallCage;
	unsigned short vInt;
	unsigned short vX;
	unsigned short vY;
	bool vBuild;
	unsigned short vNBase;
	unsigned short vNBaseTemp;
	unsigned short vNBaseTemp2;
	bool vLightning;
	bool vRicochet;
	bool vRepair;
	unsigned short vQObstacles;
	unsigned short vXBuild;
	unsigned short vYBuild;
	unsigned short vRemoteness;
	int vvi,vvj;
	unsigned short vNSmallCageTemp;
	bool vTower;
	bool vTemp;
	unsigned short vRemotenessTower;
	unsigned short vRemotenessTemp;
	unsigned short vRemotenessTemp2;
	unsigned short vRemotenessBase;
	bool vBusy;
	sDoom vDoom;
	unsigned short vIdDataUnit;
	sDoom vDoom2;
	bool vHeal;
	bool vGrive;
	unsigned short vRemotenessGrive;
	bool vExplorationOfTheArea;
	unsigned short vCliffLvl;
	bool vRedCell;
	bool vWalk;
};

struct sSmallCageRepair
{
	unsigned int vInt3;
	bool vBind;
	bool vRepair;
};

struct sSmallCageUniversal
{
	unsigned int vInt3;
	bool vBind;
	HumanPlayer *pHumanPlayer;
};

struct sWall
{
	static const int MAP_REPAIR_POS = 6;
	static const int MAP_SLAYER_DEFENSE_POS = 4;
	sSmallCage *pWall;
	sSmallCageUniversal vRepairPos[MAP_REPAIR_POS];
	unsigned short vQRepairPos;
	sSmallCageUniversal vMassSlayerDefense[MAP_SLAYER_DEFENSE_POS];
	unsigned short vQSlayerDefensePos;
	sSmallCageUniversal vRepairPosBehind[MAP_REPAIR_POS];
	unsigned short vQRepairPosBehind;
	sSmallCageUniversal vMassSlayerDefenseBehind[MAP_SLAYER_DEFENSE_POS];
	unsigned short vQSlayerDefensePosBehind;
	bool vWallCreated;
	real vTimeWallCreated;
	bool vBehind;
	
	unsigned short vQ;
	unsigned short vvi;

	bool fInit()
	{
		pWall = NULL;
		for (vvi = 0; vvi < MAP_REPAIR_POS; vvi++)
		{
			vRepairPos[vvi].vInt3 = vSizeMap;
			vRepairPos[vvi].vBind = FALSE;
			vRepairPos[vvi].pHumanPlayer = NULL;
		}
		vQRepairPos = 0;
		for (vvi = 0; vvi < MAP_SLAYER_DEFENSE_POS; vvi++)
		{
			vMassSlayerDefense[vvi].pHumanPlayer = NULL;
			vMassSlayerDefense[vvi].vBind = FALSE;
			vMassSlayerDefense[vvi].vInt3 = vSizeMap;
		}
		vQSlayerDefensePos = 0;
		for (vvi = 0; vvi < MAP_REPAIR_POS; vvi++)
		{
			vRepairPosBehind[vvi].vInt3 = vSizeMap;
			vRepairPosBehind[vvi].vBind = FALSE;
			vRepairPosBehind[vvi].pHumanPlayer = NULL;
		}
		vQRepairPosBehind = 0;
		for (vvi = 0; vvi < MAP_SLAYER_DEFENSE_POS; vvi++)
		{
			vMassSlayerDefenseBehind[vvi].pHumanPlayer = NULL;
			vMassSlayerDefenseBehind[vvi].vBind = FALSE;
			vMassSlayerDefenseBehind[vvi].vInt3 = vSizeMap;
		}
		vQSlayerDefensePosBehind = 0;
		vWallCreated = FALSE;
		vTimeWallCreated = 0;
		vBehind = FALSE;
		return TRUE;
	}

	sSmallCage * fGetWall()
	{
		return pWall;
	}

	void fSetWall(sSmallCage *pSmallCage)
	{
		if (pSmallCage == NULL)
		{
			vWallCreated = FALSE;
			vTimeWallCreated = 0;
		}
		pWall = pSmallCage;
	}

	unsigned short fQPosSlayerDefense()
	{
		vQ = 0;
		for (vvi = 0; vvi < MAP_SLAYER_DEFENSE_POS; vvi++)
		{
			if (vMassSlayerDefense[vvi].vBind == TRUE)
			{
				vQ++;
			}
		}
		return vQ;
	}

	unsigned short fQPosSlayerDefenseFree()
	{
		vQ = 0;
		for (vvi = 0; vvi < MAP_SLAYER_DEFENSE_POS; vvi++)
		{
			if (vMassSlayerDefense[vvi].vBind == FALSE)
			{
				vQ++;
			}
		}
		return vQ;
	}

	unsigned short fQPosRepairBindFree()
	{
		vQ = 0;
		for (vvi = 0; vvi < MAP_REPAIR_POS; vvi++)
		{
			if (vRepairPos[vvi].vBind == TRUE)
			{
				vQ++;
			}
		}
		return vQRepairPos - vQ;
	}

	unsigned short fQPosRepairBind()
	{
		vQ = 0;
		for (vvi = 0; vvi < MAP_REPAIR_POS; vvi++)
		{
			if (vRepairPos[vvi].vBind == TRUE)
			{
				vQ++;
			}
		}
		return vQ;
	}

	unsigned short fQPosSlayerDefenseBehind()
	{
		vQ = 0;
		for (vvi = 0; vvi < MAP_SLAYER_DEFENSE_POS; vvi++)
		{
			if (vMassSlayerDefenseBehind[vvi].vBind == TRUE)
			{
				vQ++;
			}
		}
		return vQ;
	}

	unsigned short fQPosSlayerDefenseFreeBehind()
	{
		vQ = 0;
		for (vvi = 0; vvi < MAP_SLAYER_DEFENSE_POS; vvi++)
		{
			if (vMassSlayerDefenseBehind[vvi].vBind == FALSE)
			{
				vQ++;
			}
		}
		return vQ;
	}

	unsigned short fQPosRepairBindFreeBehind()
	{
		vQ = 0;
		for (vvi = 0; vvi < MAP_REPAIR_POS; vvi++)
		{
			if (vRepairPosBehind[vvi].vBind == TRUE)
			{
				vQ++;
			}
		}
		return vQRepairPos - vQ;
	}

	unsigned short fQPosRepairBindBehind()
	{
		vQ = 0;
		for (vvi = 0; vvi < MAP_REPAIR_POS; vvi++)
		{
			if (vRepairPosBehind[vvi].vBind == TRUE)
			{
				vQ++;
			}
		}
		return vQ;
	}
};

struct sBase
{

	unsigned short vNBase;
	bool vBind;
	bool vTypeBazeOneCell;
	unsigned short vBeginningOfBase;
	sWall vMainWall;
	sWall vMainWall2;
	sSmallCage *vBuild;
	bool vSlayerBaze;
	HumanPlayer *pHumanPlayer;
	unsigned short vQCells;
	unsigned short vNBaseNoDear;
	bool vFreeAllRepairPos;
	char vColor[10];
	unsigned short vQ;
	unsigned short vvi;
	unsigned short vQFirstTower;
	unsigned short vQHeal;
	bool vTwoGold;
	bool vTempleAndLumberHouse;
	unsigned short vQGoldMine;
	unsigned short vHouse;
	bool vHouseForBlockVampire;
	unsigned short vNChainForHouseForBlockVampire;
	bool vBuildHeal;
	bool vFullWorkers;
	bool vDetoWorkers;
	bool vNPlayerHelp[MAX_HUMAN_PLAYERS];
	bool vSlayerDefense;
	bool vShaman;
	unsigned int vInt3_Shaman;
	unsigned short vDevelopmentPriority;
	unsigned short vQTowerInZoneMainWall;
	bool vExplorationOfTheArea;
	unsigned short vMinRemoteness;
	sWall *pWall;
	bool vMainWall2Repair;
	unsigned short vRemoteness2;

	bool fInit()
	{
		vNBase = 0;
		vBind = FALSE;
		vTypeBazeOneCell = FALSE;
		vBeginningOfBase = 0;
		vSlayerBaze = FALSE;
		pHumanPlayer = NULL;
		vQCells = 0;
		vNBaseNoDear = DO_NOT_FIND_BASE;
		vFreeAllRepairPos = FALSE;
		vQFirstTower = 0;
		vQHeal = 0;
		vTwoGold = FALSE;
		vTempleAndLumberHouse = FALSE;
		vQGoldMine = 0;
		vHouse = 0;
		vHouseForBlockVampire = FALSE;
		vNChainForHouseForBlockVampire = 0;
		vBuildHeal = FALSE;
		vFullWorkers = FALSE;
		vDetoWorkers = FALSE;
		for (vvi = 0; vvi < MAX_HUMAN_PLAYERS; vvi++)
		{
			vNPlayerHelp[vvi] = FALSE;
		}
		vSlayerDefense = FALSE;
		vDevelopmentPriority = 0;
		vExplorationOfTheArea = FALSE;
		vMinRemoteness = 0;
		vMainWall2Repair = FALSE;
		vRemoteness2 = MAP_MAX_SMALL_CAGE - 1;
		return TRUE;
	}

	sWall * fGetWall()
	{
		if (vMainWall2.vWallCreated == TRUE &&
			vMainWall2Repair == TRUE)
		{
			return &vMainWall2;
		}
		if (vMainWall.vWallCreated == TRUE)
		{
			return &vMainWall;
		}
		return NULL;
	}

	// Подсчитать кол-во помогающих игроков
	unsigned short fQBindNPlayerHelp()
	{
		vQ = 0;
		for (vvi = 0; vvi < MAX_HUMAN_PLAYERS; vvi++)
		{
			if (vNPlayerHelp[vvi] == TRUE)
			{
				vQ++;
			}
		}
		return vQ;
	}

};

class MapBases
{
private:;
	bool fDefinitionOfADangerousCell(sSmallCage * vSmallCage, unsigned short vR);
	bool fDistanceFromTheCenterOfTheMap();
	int vSetOff;
	int vNSmallCage3;
	unsigned short vNSmallCage;
	unsigned short vIdDataUnit;
	sSmallCage *vForest;
	int vvi,vvj,vvz;
	unsigned short vRemoteness;
	unsigned short vRemoteness2;
	int vRemoteness3;
	unsigned short vXBuild;
	unsigned short vYBuild;
	bool vFlagLightning;
	unsigned short vN;
	unsigned short vN2;
	DataUnit *pDataUnit;
	bool vFlagBuild;
	unsigned short vIdSmallCage;
	unsigned short vQ;
	sBase *vBase;
	unsigned int vInt3;
	bool vFlag;
	unsigned short vCliffLvl;
	real vRadiusReview;
	unsigned short vRadiusMap;
	unsigned short vRemotenessNext;
	bool vTop;
	bool vLeft;
	bool vBottom;
	bool vRight;
	sSmallCage *vTemp;
public:
	void fWriteFileTGA();
public:
	int MAP_W;
	int MAP_H;
	int MAP_MAX_SMALL_CAGE;
	static const int MAP_MAX_BASE = JASS_NumBase_MAX;
	static const int MAP_MAX_REPAIR = 6;
	static const int MAP_MIN_Q_CELL_FOR_BASE = 300;
	static const int MAP_MAX_Q_CELL_FOR_BASE = 2500;
	// Переменные
	sSmallCage *vMap;
	//bool vBindBase[MAP_MAX_BASE];
	//bool vBindSlayerPlace;
	//bool vBindDancePool;
	//sSmallCageRepair vRepairPos[MAP_MAX_BASE][6];
	//unsigned short vBeginningOfBase[MAP_MAX_BASE];
	MapBases();
	~MapBases();

	// Функции
	bool fInit ();

	bool fFreeBuild(sSmallCage *vSmallCage);
	sSmallCage * fFillBuild(unsigned int vInt3, unsigned short vXBuild, unsigned short vYBuild, unsigned short vIdSmallCage);
	unsigned int fFindHouse(sBase *vBase);
	bool fDetermineTheBeginningOfTheBase(sBase *vBase);
	bool fCheckFillBuild(sSmallCage *vSmallCage, unsigned short vXBuild, unsigned short vYBuild, unsigned short vIdSmallCage, bool vBoolDoom);
	bool fDetermineTheBeginningOfTheBaseOneCell(sBase *vBase);
	HRECT fFindRectForHouse(real vX, real vY, unsigned short vIdDataUnit);
	unsigned fFindPosBuild(sBase *vBase, integer vId, int vR1, int vR2, bool vFlag, bool vFlagTower, bool vBoolDoom);
	bool fZoneTower(sBase *vBase);
	unsigned int fFindPosRepair(sBase *vBase, HumanPlayer *pHumanPlayer);
	//bool fFreePosRepair(sBase *vBase, unsigned int vInt3);
	bool fFreeZoneTower(unsigned int vInt3);
	unsigned int fFindPosSafeZone(sBase *vBase);
	void fFreeBusy(sBase *vBase);
	void fFillBusy(sBase *vBase);
	bool fCheckFillBuildTower(sSmallCage *vSmallCage, unsigned short vXBuild, unsigned short vYBuild);
	unsigned short fQCellsToBase(sBase *vBase);
	//unsigned int fQPosRepair(sBase *vBase);
	//bool fFreeAllPosRepair(sBase *vBase);
	unsigned int fFindPosBuild(sBase *vBase, integer vId);
	bool fDoom(unsigned short vNSmallCage2, int vvj, int vInt2);
	unsigned short fQSmallCageForTower(sBase *vBase);
	bool fFillBuildHeal(sSmallCage *vSmallCage, unsigned short vXBuild, unsigned short vYBuild);
	bool fFillDoom2(sSmallCage *vSmallCage, unsigned short vXBuild, unsigned short vYBuild, int vvj2);
	//bool fPosRepairTrue(sBase *vBase, unsigned int vInt3);
	bool fFreePosRepairBind(sBase *vBase, unsigned int vInt3);
	//bool fCheckPosRepair(sBase *vBase, unsigned int vInt3);
	unsigned short fRemotenessBase(sBase *vBase);
	unsigned short fRemotenessBase(real vX, real vY);
	unsigned short fRemoteness(real vX, real vY);
	bool fClearRemotenessBase(sBase *vBase);
	bool fCheckPosBind(sBase *vBase, unsigned int vInt3);
	bool fBindNPlayerHelp(sBase *vBase, integer vNPlayer);
	bool fFreeBindNPlayerHelp(sBase *vBase, integer vNPlayer);
	unsigned short fMaxRemotenessBase(real vX, real vY);
	bool fCheckPos(unsigned int vInt3, unsigned short vXBuild, unsigned short vYBuild);
	unsigned int fFindPosSlayerDefense(sBase *vBase, HumanPlayer *pHumanPlayer);
	unsigned int fFindMyPosSlayerDefense(sBase *vBase, HumanPlayer *pHumanPlayer);
	bool fFreePosSlayerDefense(sBase *vBase, HumanPlayer *pHumanPlayer);
	bool fPosBindTrue(sBase *vBase, unsigned int vInt3);
	bool fFreePosRepair(sBase *vBase, HumanPlayer *pHumanPlayer);
	bool fCheckFillUnit(sSmallCage *vSmallCage, unsigned short vXBuild, unsigned short vYBuild, unsigned short vIdSmallCage);
	bool fZoneGrive(unsigned int vInt3);
	bool fFreeZoneGrive();
	unsigned int fRandPosBase(sBase *vBase1);
	unsigned short fBaseN(unsigned int vInt3);
	bool fConstructionBase(int vNSmallCage_1, int vMinCell, int vMaxCell, unsigned short vNBase);
	bool fDeadEnds();
	int fZoneTowerTemp(int vMainWall, unsigned short vNBase);
	bool fZoneTowerTemp2(sBase *vBase);
	bool fCleanZoneBaseExplorationOfTheArea(sBase *vBase);
	bool fFillRadiusReviewUnit(DataUnit *pDataUnit);
	unsigned int fNextPosBaseForExplorationOfTheArea(unsigned int vInt3, sBase *vBase1);
	int fTypeWoodBuild(sSmallCage *vSmallCage);
	unsigned short fRemotenessInt3ToInt3(unsigned int vInt3_1, unsigned int vInt3_2);
	bool fCheckAllPosRepair(sBase *vBase, HumanPlayer *pHumanPlayer);
};