#pragma once
#include "Resources.h"

class BaseLocation;

class ResourcesAcquisitionRate
{
public:
  ResourcesAcquisitionRate(double mineralsPerSecond, double gasPerSecond)
    : m_mineralsPerSecond(mineralsPerSecond)
    , m_gasPerSecond(gasPerSecond)
  {}
protected:
  double m_mineralsPerSecond;
  double m_gasPerSecond;
};

class ResourcesSaturation
{
public:
  ResourcesSaturation(size_t nbProbesMinerals, size_t nbCrystals, double mineralsSaturationRatio,
                      size_t nbProbesGas, size_t nbGeysers)
    : m_nbProbesMinerals(nbProbesMinerals)
    , m_nbProbesGas(nbProbesGas)
    , m_nbCrystals(nbCrystals)
    , m_mineralsSaturationRatio(mineralsSaturationRatio)
    , m_nbGeysers(nbGeysers)
  {}
  size_t getNbProbesOnMinerals() const { return m_nbProbesMinerals; }
  size_t getNbProbesOnGas() const { return m_nbProbesGas; }
  size_t getTotalNbProbes() const { return m_nbProbesMinerals + m_nbProbesGas; }

  size_t getNbCrystals() const { return m_nbCrystals; }
  double getMineralsSaturationRatio() const { return m_mineralsSaturationRatio; }
  size_t getNbGeysers() const { return m_nbGeysers; } // Total number of geysers, including depleted ones
  double getGasSaturationRatio() const { return m_nbProbesGas > 0 ? double(m_nbGeysers * 3) / double(m_nbProbesGas) : 0.; }
protected:
  size_t m_nbProbesMinerals;
  size_t m_nbProbesGas;

  size_t m_nbCrystals;
  double m_mineralsSaturationRatio;
  size_t m_nbGeysers;
};

/**
 * @brief Percentage of effort towards mining minerals and gas
 */
class ResourcesAcquisitionPercentage
{
public:
  ResourcesAcquisitionPercentage(double minerals, double gas)
    : m_pctMinerals(minerals / (minerals + gas))
    , m_pctGas(gas / (minerals + gas))
  {}
  double getPctMinerals() const { return m_pctMinerals; }
  double getPctGas() const { return m_pctGas; }
  bool operator==(const ResourcesAcquisitionPercentage& other) const
  {
    return m_pctMinerals == other.m_pctMinerals &&
           m_pctGas == other.m_pctGas;
  }
  bool operator!=(const ResourcesAcquisitionPercentage& other) const
  {
    return m_pctMinerals != other.m_pctMinerals ||
           m_pctGas != other.m_pctGas;
  }
private:
  // Resources quantities are defined in relative terms w.r.t. each other
  double m_pctMinerals;
  double m_pctGas;
};

class ResourceManager
{
public:
  // Model as a function? - saturation would be the highest value
  ResourcesAcquisitionRate calculateResourcesAcquisitionRate(const BaseLocation* baseLocation,
                                                             size_t nbProbesMinerals,
                                                             size_t nbProbesGas) const;
  size_t calculateMineralsSaturation(const BaseLocation* baseLocation);
  size_t calculateGasSaturation(const BaseLocation* baseLocation);

  // To delete
  ResourcesSaturation calculateProbesSaturationRatio() const;
};
