#pragma once

#include "Runtime/RetroTypes.hpp"
#include "Runtime/Weapon/CWeaponMode.hpp"

namespace urde {

enum class EVulnerability { Weak, Normal, Deflect, Immune, PassThrough, DirectWeak, DirectNormal, DirectImmune };
enum class EDeflectType { None, One, Two, Three, Four };

class CDamageVulnerability {
  EVulnerability x0_power;
  EVulnerability x4_ice;
  EVulnerability x8_wave;
  EVulnerability xc_plasma;
  EVulnerability x10_bomb;
  EVulnerability x14_powerbomb;
  EVulnerability x18_missile;
  EVulnerability x1c_boostBall;
  EVulnerability x20_phazon;
  EVulnerability x24_enemyWp1;
  EVulnerability x28_enemyWp2Poison;
  EVulnerability x2c_enemyWp3Lava;
  EVulnerability x30_enemyWp4;
  EVulnerability x34_unk1;
  EVulnerability x38_unk2;

  EVulnerability x3c_chargedPower;
  EVulnerability x40_chargedIce;
  EVulnerability x44_chargedWave;
  EVulnerability x48_chargedPlasma;

  EVulnerability x4c_superMissile;
  EVulnerability x50_iceSpreader;
  EVulnerability x54_wavebuster;
  EVulnerability x58_flamethrower;

  EDeflectType x5c_deflected;
  EDeflectType x60_chargedDeflected;
  EDeflectType x64_comboDeflected;

  void ConstructNew(CInputStream& in, int propCount);

  static const CDamageVulnerability sNormalVulnerability;
  static const CDamageVulnerability sImmuneVulnerability;
  static const CDamageVulnerability sReflectVulnerability;
  static const CDamageVulnerability sPassThroughVulnerability;

public:
  explicit CDamageVulnerability(CInputStream& in);
  CDamageVulnerability(EVulnerability power, EVulnerability ice, EVulnerability wave, EVulnerability plasma,
                       EVulnerability bomb, EVulnerability powerBomb, EVulnerability missile, EVulnerability boostBall,
                       EVulnerability phazon, EVulnerability enemyWp1, EVulnerability wnemyWp2, EVulnerability enemyWp3,
                       EVulnerability enemyWp4, EVulnerability v1, EVulnerability v2, EDeflectType deflectType);
  CDamageVulnerability(EVulnerability power, EVulnerability ice, EVulnerability wave, EVulnerability plasma,
                       EVulnerability bomb, EVulnerability powerBomb, EVulnerability missile, EVulnerability boostBall,
                       EVulnerability phazon, EVulnerability enemyWp1, EVulnerability enemyWp2, EVulnerability enemyWp3,
                       EVulnerability enemyWp4, EVulnerability v1, EVulnerability v2, EVulnerability chargedPower,
                       EVulnerability chargedIce, EVulnerability chargedWave, EVulnerability chargedPlasma,
                       EVulnerability superMissile, EVulnerability iceSpreader, EVulnerability waveBuster,
                       EVulnerability flameThrower, EDeflectType deflected);

  EDeflectType GetDeflectionType(const CWeaponMode& mode) const;

  bool WeaponHurts(const CWeaponMode&, bool ignoreDirect) const;
  bool WeaponHits(const CWeaponMode& mode, bool checkDirect) const;
  EVulnerability GetVulnerability(const CWeaponMode& mode, bool ignoreDirect) const;

  static const CDamageVulnerability& NormalVulnerabilty() { return sNormalVulnerability; }
  static const CDamageVulnerability& ImmuneVulnerabilty() { return sImmuneVulnerability; }
  static const CDamageVulnerability& ReflectVulnerabilty() { return sReflectVulnerability; }
  static const CDamageVulnerability& PassThroughVulnerabilty() { return sPassThroughVulnerability; }
};
} // namespace urde
