#pragma once
#include <BWAPI.h>
#include <windows.h> // To call autohotkeys to restart the match

#include <fstream> // ifstream & ofstream

#include "unordered_map_serialization.h"
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

#include "AgentManager.h"

#define EPISODES 100 // The number of learning episodes
#define BOOST true
#define SAVE true

// Remember not to use "Broodwar" in any global class constructor!

class ExampleAIModule : public BWAPI::AIModule
{
	AgentManager agentMgr;
	int match, victories, defeats, meanReward;
public:
  // Virtual functions for callbacks, leave these as they are.
  virtual void onStart();
  virtual void onEnd(bool isWinner);
  virtual void onFrame();
  virtual void onSendText(std::string text);
  virtual void onReceiveText(BWAPI::Player player, std::string text);
  virtual void onPlayerLeft(BWAPI::Player player);
  virtual void onNukeDetect(BWAPI::Position target);
  virtual void onUnitDiscover(BWAPI::Unit unit);
  virtual void onUnitEvade(BWAPI::Unit unit);
  virtual void onUnitShow(BWAPI::Unit unit);
  virtual void onUnitHide(BWAPI::Unit unit);
  virtual void onUnitCreate(BWAPI::Unit unit);
  virtual void onUnitDestroy(BWAPI::Unit unit);
  virtual void onUnitMorph(BWAPI::Unit unit);
  virtual void onUnitRenegade(BWAPI::Unit unit);
  virtual void onSaveGame(std::string gameName);
  virtual void onUnitComplete(BWAPI::Unit unit);


  // Everything below this line is safe to modify.
  void init();
  void finish(bool save);
  void drawInfo();
  void drawStats();
  void drawOnMap();

  // Saving and loading info from disk
  QTable loadQTable();
  void saveQTable(QTable qt);
  void loadMatchStats();
  void loadRewardStats();
  void saveMatchStats();
  void saveRewardStats();
  std::vector<double> loadWeights();
  void saveWeights(std::vector<double> weights);
  void saveLogWeights(std::vector<double> weights);

  // Game management related methods
  void boostGame(bool boost);
  void restartMatch();
};
