#pragma once
#include "../../Utils/Component.h"
#include "../../Utils/Logger.h"
#include <Exp/Term/Object.h>
#include <BWAPI.h>

class CurrentWorld;

/**
 * @brief Base class for technologies, which are either upgrades, researches, units or buildings.
 */
class SparObject : public planning::Object
{
public:
  SparObject(const std::string& name, planning::PrimitiveType* type);
  virtual ~SparObject() {}
protected:
  friend class CurrentWorld;
  virtual void initialize();
  virtual void releaseMembers();
  virtual void _output(std::ostream& out) const;

#pragma region TODO-PLANNING-DELETE
public:
  /**
   * @return Whether all dependencies for the tech have been acquired (but the tech itself may not be acquired).
   */
  bool isActivated() const;
  const std::set<SparObject*>& getDependencies() const { return m_incomingDependencies; }
  bool allDependenciesAcquired() const;
  void onIncomingDependencyChanged(SparObject* dependency);
  void addDependency(BWAPI::UnitType unitType);
  void addDependency(BWAPI::TechType techType);
  void addDependency(BWAPI::UpgradeType upgradeType, int level);
  void addDependency(SparObject* dependency);
  void addOutgoingDependency(SparObject* tech) { m_outgoingDependencies.insert(tech); }
  void updateOutgoingDependencies();
  std::set<SparObject*> m_incomingDependencies;
  std::set<SparObject*> m_outgoingDependencies;
  void update();
#pragma endregion
};
