#pragma once
#include "UnitRecordType/UnitRecordType.h"
#include "UnitRecord.h"
#include "../../BWAPI_AddOn.h"

class PerceptualState;

class UnitRecordManager
{
public:
  static UnitRecord* instantiate(BWAPI::Unit* unit)
  {
    UnitRecord* unitRecord = s_unitTypeInstantiate[unit->getType()].instantiateUnitRecord->instantiate(unit);

    if (unitRecord->getPlayer() == BWAPI::Broodwar->enemy())
    {
      SPAR_LOG(LogTypes.PERCEPTUAL_STATE, "Enemy unit record: Add \"%s\"", 
        toString(unitRecord).c_str());
    }

    return unitRecord;
  }

  static UnitRecordType* instantiate(UnitRecord* unitRecord, BWAPI::UnitType unitType)
  {
    return s_unitTypeInstantiate[unitType].instantiateUnitRecordType->instantiate(unitRecord, unitType);
  }

protected:
  friend class PerceptualState;

  static void initialize();

  static void terminate();

  class InstantiateUnitRecord
  {
  public:
    virtual UnitRecord* instantiate(BWAPI::Unit* unit) = 0;
  };

  class InstantiateUnitRecordType
  {
  public:
    virtual UnitRecordType* instantiate(UnitRecord* unitRecord, BWAPI::UnitType unitType) = 0;
  };

  struct UnitTypeInstantiate
  {
    InstantiateUnitRecord* instantiateUnitRecord;
    InstantiateUnitRecordType* instantiateUnitRecordType;
  };

  static UnitRecordManager s_instance;
  static UnitTypeInstantiate s_unitTypeInstantiate[BWAPI::NB_UNITS_TYPE];
};

