text: #pragma once
  
  #include "Common.h"
  
  #include "ActionInProgress.h"
  #include "BuildingData.h"
  #include "UnitData.h"
  #include "ActionType.h"
  #include "PrerequisiteSet.h"
  #include "ActionSet.h"
  
  //#define ENABLE_BWAPI_GAMESTATE_CONSTRUCTOR
  
  namespace BOSS
  {
      
  typedef std::pair<ResourceCountType, ResourceCountType>     ResourcePair;
  typedef std::pair<FrameCountType, FrameCountType>           FramePair;
  
  class ActionPerformed
  {
  public:
      ActionType          actionType;
      FrameCountType      actionQueuedFrame;
      ResourceCountType   mineralsWhenQueued;
      ResourceCountType   gasWhenQueued;
  
      ActionPerformed()
          : actionQueuedFrame(0)
          , mineralsWhenQueued(0)
          , gasWhenQueued(0)
      {
      
      }
  };
  
  class GameState 
  {
      UnitData                    _units;  
      RaceID                      _race;
  
      ActionType                  _actionPerformed; 		    // the action which generated this state
      size_t                      _actionPerformedK;
  
      FrameCountType              _currentFrame;
      FrameCountType              _lastActionFrame;		    // the current frame of the game
  
      ResourceCountType           _minerals; 			        // current mineral count
      ResourceCountType           _gas;						// current gas count
  
      std::vector<ActionPerformed>   _actionsPerformed;
  
      const FrameCountType        raceSpecificWhenReady(const ActionType & a) const;
      void                        fixZergUnitMasks();
      
      const FrameCountType        whenSupplyReady(const ActionType & action)                              const;
      const FrameCountType        whenPrerequisitesReady(const ActionType & action)                       const;
      const FrameCountType        whenBuildingPrereqReady(const ActionType & action)                      const;
      //const FrameCountType        whenConstructedBuildingReady(const ActionType & builder)                const;
      const FrameCountType        whenMineralsReady(const ActionType & action)                            const;
      const FrameCountType        whenGasReady(const ActionType & action)                                 const;
      const FrameCountType        whenWorkerReady(const ActionType & action)                              const;
  
  public: 
  
      GameState(const RaceID r = Races::None);
  
  // constructor based on BWAPI::Game only makes sense if using VS
  // we won't be using this if we're compiling to emscripten or linux
  #ifdef _MSC_VER
      GameState(BWAPI::GameWrapper & game, BWAPI::PlayerInterface * player, const std::vector<BWAPI::UnitType> & buildingsQueued);
  #endif
  
  	std::vector<ActionType>     doAction(const ActionType & action);
      std::vector<ActionType>     fastForward(const FrameCountType toFrame) ;
      void                        finishNextActionInProgress();
  
      const FrameCountType        getCurrentFrame()                                                       const;
      const FrameCountType        whenCanPerform(const ActionType & action)                               const;
      const FrameCountType        getLastActionFinishTime()                                               const;
  
      void                        getAllLegalActions(ActionSet & actions)                                 const;
      std::string                 whyIsNotLegal(const ActionType & action)                                const;
      bool                        isLegal(const ActionType & action)                                      const;
      bool                        canAfford(const ActionType & action)                                    const;
      bool                        canAffordGas(const ActionType & action)                                 const;
      bool                        canAffordMinerals(const ActionType & action)                            const;
  
      size_t 				        getMineralsPerFrame()		    const;
      size_t 				        getGasPerFrame()	            const;
      const UnitCountType 		getNumMineralWorkers()	        const;				
      const UnitCountType 		getNumGasWorkers()		        const;					
      const UnitCountType 		getNumBuildingWorkers()	        const;		
      const ResourceCountType 	getMinerals() 				    const;
      const ResourceCountType	    getGas()					    const;
      const RaceID                getRace()                       const;
  
      const UnitData &            getUnitData()                   const;
  
      const ResourceCountType     getMinerals(const int frame)    const;
      const ResourceCountType     getGas(const int frame)         const;
      const ResourceCountType     getFinishTimeMinerals()         const;
      const ResourceCountType     getFinishTimeGas()              const;
  
      const std::string           toString()                      const;
      const std::string           getActionsPerformedString()     const;
      const BuildingData &        getBuildingData()               const;
      const HatcheryData &        getHatcheryData()               const;
  
      void                        setStartingState();
      void                        setMinerals(const ResourceCountType & minerals);
      void                        setGas(const ResourceCountType & gas);
      void                        addCompletedAction(const ActionType & action, const size_t num = 1);
  	void                        removeCompletedAction(const ActionType & action, const size_t num = 1);
  };
  }
  