#pragma once
#include "../../../../../Commands/AttackUnitCommand.h"
#include "../../../../../Conditions/CompositeCondition.h"
#include "../../../../../Conditions/HasCriticalHealth.h"
#include "../../../../../Conditions/HasRangedAttack.h"
#include "../../../../../Conditions/IsTargeted.h"
#include "../../../../../Conditions/IsWorthFleeing.h"
#include "../../../../../Layer1FSM.h"
#include "../../../../UnitBehavior.h"

// TODO: location to attack should be included here?

class UnitAttackBehavior : public virtual UnitBehavior
{
public:
  UnitAttackBehavior(const Process* parent, unsigned int initialPriority, BWAPI::Unit* unit)
    : UnitBehavior(parent, initialPriority, unit)
    , Behavior(parent, initialPriority)
    , FSM(parent)
    , Process(parent)
  {
  }

  virtual bool selectTarget(const std::set<BWAPI::Unit*>& enemies) = 0;
  BWAPI::Unit* selectTargetImpl(const std::set<BWAPI::Unit*>& enemies) const;
};

template <class DerivedBehavior>
class UnitAttackBehaviorT : public virtual UnitAttackBehavior, public UnitBehaviorT<DerivedBehavior>
{
public:
  UnitAttackBehaviorT(const Process* parent, unsigned int initialPriority, BWAPI::Unit* unit)
    : UnitAttackBehavior(parent, initialPriority, unit)
    , UnitBehaviorT(parent, initialPriority, unit)
    , UnitBehavior(parent, initialPriority, unit)
    , Behavior(parent, initialPriority)
    , FSM(parent)
    , Process(parent)
  {
  }
};