module AR::Game::Health 
  

  #...initialize them here
  def self.init ar_object 
    #add attr_serializeable properties here... 
    #
    ar_object.register_gauge "health"
    ar_object.register_gauge "damage_resist"
    ar_object.after_gauges_init do |obj|
      health = obj.gauge("health")
      health.change_current_and_max 8
    end
    #if you do need them serialized on save
    #ar_object.attr_serializeable :prop1, :prop2, &block | ar_object, load_or_unload | 
  end

  def self.extended ar_object
    self.init ar_object
    ar_object.resolutions << receive_damage_on_damage_received
    ar_object.resolutions << release_game_over_or_object_removed_from_game_on_death
    #add to object's event subscriptions and resolutions here...
  end 


  def self.set_actual_for! e
    damaged = e.damaged
    damager = e.damager
    damage_amount = e.damage_amount 
    resist = damaged.gauge("damage_resist").modified_current

    unless damager.class == AR::Game::PoisonBuff
      actual = damage_amount - resist 
    else
      actual = damage_amount 
    end

    actual = 0 if actual < 0
    e.actual_amount = actual

      AR.log("DAMAGE CALC: #{damaged.tag} should take (#{damage_amount} - #{resist}) = #{actual}") 
    actual
  end


  def self.receive_damage_on_damage_received
    AR::Events::Resolution.new event_class: AR::Events::DamageReceived, as: "damaged" do |e|
      damaged = e.damaged
      damager = e.damager

      actual = self.set_actual_for! e
            
      damaged.take_damage e.actual_amount 

      if damaged.dead?
        #return a new object died event
        AR::Events::ARObjectDied.new ar_object: damaged, killer: e.damager, cause: e
      end
    end
  end

  def self.release_game_over_or_object_removed_from_game_on_death
    AR::Events::Resolution.new event_class: AR::Events::ARObjectDied, as: "ar_object" do |e|
      ar_object = e.ar_object
      #should go in inhabitant
      #somehow, on reload, this fuck thing up.  There ends up being 2 player
      #instances floating around.  No idea how?
      if ar_object == e.engine.world.player
      #if ar_object.is_a? AR::Game::Player
        AR::Events::GameOverEvent.new
      else
        AR::Events::ObjectRemovedFromGame.new ar_object: ar_object
      end
    end
  end


  def hit_points
    g = gauge("health")
    return 0 if g.nil?
    gauge("health").modified_value
  end

  def dead?
    self.hit_points <= 0
  end

  def take_damage amount
    gauge("health").change_current -amount
  end
end
