#pragma once
#include <BWAPI.h>
#include <cassert>

class UnitRecord;
template <typename T> class InfluenceMap;

/**
 * @brief Structure that holds information about units vulnerability per tile (only for the enemy player).
 */
struct Vulnerability
{
  typedef double value_type;
  value_type _airToAir;
  value_type _airToGround;
  value_type _groundToAir;
  value_type _groundToGround;

  Vulnerability() { reset(); }
  void reset() { _airToAir = _airToGround = _groundToAir = _groundToGround = 0.0; }

  bool isNull() const
  {
    return _airToAir == 0
      && _airToGround == 0
      && _groundToAir == 0 
      && _groundToGround == 0;
  }

  void display(int x, int y, int w, int h, BWAPI::Player* player) const;

  static void update(InfluenceMap<Vulnerability>& map);

  static const char* name() { return "Vulnerability"; }

  static value_type getAirToAir(const BWAPI::Unit * unit);
  static value_type getAirToGround(const BWAPI::Unit * unit);
  static value_type getGroundToAir(const BWAPI::Unit * unit);
  static value_type getGroundToGround(const BWAPI::Unit * unit);

private:
  static value_type getGeneralTemporary(const BWAPI::Unit * unit);
  static value_type getHitPoint(const BWAPI::Unit * unit);

  template <class Iterator>
  static void update(InfluenceMap<Vulnerability>& map, Iterator begin, Iterator end)
  {
    for (; begin != end; ++begin)
    {
      update(map, *begin);
    }
  }

  static void update(InfluenceMap<Vulnerability>& map, BWAPI::Unit* unit);
  static void update(InfluenceMap<Vulnerability>& map, const UnitRecord* unit);
};