#pragma once
#include <BWAPI.h>
#include <limits>
#include <cmath>

typedef unsigned char uint8_t;

typedef std::set<BWAPI::Unit*> UnitSet;
typedef std::set<BWAPI::TilePosition> TilePositionSet;
typedef std::set<BWAPI::Player*> PlayerSet;

typedef std::map<BWAPI::UnitType, int> UnitToPercent;

// Display debug info on screen
#define DEBUG_DISPLAY 1

// Managers:
class InformationManager;
class WorkerManager;
class SquadManager;
class BuildManager;

// Initialized in NovaAIModule::onStart();
extern InformationManager* informationManager;
extern WorkerManager* workerManager;
extern SquadManager* squadManager;
extern BuildManager* buildManager;

#define GAME_STATE_REFRESH 70  // in game frames
#define HIGH_LEVEL_REFRESH 400 //in game frames

#ifdef NOVA_GUI
extern HANDLE gameStateMutex;
#endif

extern bool ONLY_MICRO;
extern bool HIGH_LEVEL_SEARCH;
extern bool PRINT_BUILD_ORDER;
extern bool PRINT_AIR_DPS;
extern bool PRINT_GROUND_DPS;
extern bool PRINT_PRODUCTION;
extern bool PRINT_BUILD_MAP;
extern bool PRINT_REGION_ID_MAP;
extern bool PRINT_SIEGE_MAP;

extern bool usingCloackUnits;
extern bool usingCloackUnits;
extern int totalKitingFrames;
extern bool kitingFrame;

BWAPI::Position rotatePosition(int degree, BWAPI::Position position, BWAPI::Position origen);
BWAPI::Position getPositionInDirection(BWAPI::Position origen, BWAPI::Position direction, int distance);
std::vector<std::string> &splitString(const std::string &s, char delim, std::vector<std::string> &elems);
std::vector<std::string> splitString(const std::string &s, char delim);
std::string intToString(const int& number);

#include "Utils/WalkPosition.h"

// High level search stats
struct HighLevelStats_t {
	std::map<unsigned int, double> groupTime;
	std::map<unsigned int, unsigned long> groupFrequency;
    std::map<unsigned int, double> groupBranchingMin;
    std::map<unsigned int, double> groupBranchingMax;
    std::map<unsigned int, double> groupBranchingAvg;
    std::map<unsigned int, unsigned long> groupTimeouts;
    std::map<unsigned int, unsigned long> groupDownSamplings;
    unsigned int orders;
    unsigned int ordersOverwritten;
};

extern HighLevelStats_t stats;

// --- INI config functions
extern std::string configPath;
std::string LoadConfigString(const char *pszKey, const char *pszItem, const char *pszDefault = NULL);
int LoadConfigInt(const char *pszKey, const char *pszItem, const int iDefault = 0);