#attacks are what should start battle
module AR::Game::Hostilities 
  #at this point, this behavior is only for determining when a character is in battle
  attr_accessor :is_hostile_against_block

  def self.init ar_object 
    ar_object.class.attr_serializeable :is_in_combat
    ar_object.is_in_combat = false
  end

  def self.extended ar_object
    self.init ar_object
    #this ordering should follow a lifecycle:
    ar_object.resolutions << release_battle_entered_on_discovery 
    ar_object.resolutions << enter_battle_on_event
    ar_object.resolutions << release_battle_exit_attempt_on_discovery_lost
    ar_object.resolutions << release_battle_exit_on_attempt
    ar_object.resolutions << exit_battle_on_event
  end 

  def self.release_battle_entered_on_discovery
    AR::Events::Resolution.new event_class: AR::Events::DiscoveryMadeEvent, as: "perceiver" do |e|
      p = e.perceiver
      d = e.discovered
      if d.is_a?(AR::Game::Character) and d.can_see?(p) and p.is_hostile_with? d
        AR::Events::CharacterEnteredBattle.new character: p, hostile_character: d
      end
    end
  end

  def self.release_battle_exit_attempt_on_discovery_lost
    AR::Events::Resolution.new event_class: AR::Events::DiscoveryLostEvent, as: "perceiver" do |e|
      p = e.perceiver
      d = e.undiscovered
      if p.is_hostile_with? d
        AR::Events::BattleExitAttempt.new character: p
      end
    end
  end

  def should_be_in_battle?
    known_chars = self.known_objects.select{|obj| obj.is_a? AR::Game::Character}
    known_chars.map{|obj| self.is_hostile_with? obj}.include? true 
  end

  def self.release_battle_exit_on_attempt
    AR::Events::Resolution.new event_class: AR::Events::BattleExitAttempt, as: "character" do |e|
      c = e.character
      unless c.should_be_in_battle? 
        AR::Events::CharacterExitedBattle.new character: c
      end
    end
  end




  def self.enter_battle_on_event
    AR::Events::Resolution.new event_class: AR::Events::CharacterEnteredBattle, as: "character" do |e|
      c = e.character
      c.is_in_combat = true
      unless e.hostile_character.is_in_combat
        AR::Events::CharacterEnteredBattle.new character: e.hostile_character, hostile_character: c
      end
    end
  end

  def self.exit_battle_on_event
    AR::Events::Resolution.new event_class: AR::Events::CharacterExitedBattle, as: "character" do |e|
      c = e.character
      c.is_in_combat = false
      nil
    end
  end


  def hostility_check &block
    self.is_hostile_against_block = block
  end

  def is_hostile_with? ar_object 
    return false if self.is_hostile_against_block.nil?
    self.is_hostile_against_block.call ar_object 
  end


end
