local class = require("core.class")
local levelmonitor = require("level.levelmonitor")
local HealthMonitor = class.Class("HealthMonitor", levelmonitor.LevelMonitor)
local callHealthChangedCallback
function HealthMonitor:OnHealthEquals(healthValue, fn, ...)
  self.equalsCallbacks[healthValue] = {
    fn = fn,
    ...
  }
  self:OnChanged(callHealthChangedCallback, self)
end
function HealthMonitor:OnHealthGreaterThan(healthValue, fn, ...)
  self.greaterThanCallbacks[healthValue] = {
    fn = fn,
    ...
  }
  self:OnChanged(callHealthChangedCallback, self)
end
function HealthMonitor:OnHealthLessThan(healthValue, fn, ...)
  self.lessThanCallbacks[healthValue] = {
    fn = fn,
    ...
  }
  self:OnChanged(callHealthChangedCallback, self)
end
function HealthMonitor:OnHealthPercentageLessThan(percentage, fn, ...)
  self.lessThanPercentageCallbacks[percentage] = {
    fn = fn,
    ...
  }
  self:OnChanged(callHealthChangedCallback, self)
end
local AddHealthMonitor = function(ai)
  return HealthMonitor.New(ai)
end
function callHealthChangedCallback(oldValue, newValue, self)
  local foundValidCallback = false
  if oldValue == nil or newValue == nil then
    return
  end
  for v, f in pairs(self.equalsCallbacks) do
    if newValue == v and oldValue ~= v then
      self:dprint("Health Monitor triggered: Current health on creature '" .. tostring(self.ai) .. "' crossed threshold (" .. tostring(v) .. ")")
      f.fn(self, unpack(f))
      foundValidCallback = foundValidCallback or true
    end
  end
  for v, f in pairs(self.greaterThanCallbacks) do
    if oldValue <= v and v < newValue then
      self:dprint("Health Monitor triggered: Current health on creature '" .. tostring(self.ai) .. "' became greater than " .. tostring(v))
      f.fn(self, unpack(f))
      foundValidCallback = foundValidCallback or true
    end
  end
  for v, f in pairs(self.lessThanCallbacks) do
    if v <= oldValue and newValue < v then
      self:dprint("Health Monitor triggered: Current health on creature '" .. tostring(self.ai) .. "' became less than " .. tostring(v))
      f.fn(self, unpack(f))
      foundValidCallback = foundValidCallback or true
    end
  end
  for v, f in pairs(self.lessThanPercentageCallbacks) do
    if 1 < v then
      v = v / 100
    end
    if v <= oldValue / self.startValue and v > newValue / self.startValue then
      self:dprint("Health Monitor triggered: Current health percentage on creature '" .. tostring(self.ai) .. "' became less than " .. tostring(v * 100) .. " percent")
      f.fn(self, unpack(f))
      foundValidCallback = foundValidCallback or true
    end
  end
  return foundValidCallback
end
function HealthMonitor:init(ai)
  self.ai = ai
  if self.ai ~= nil then
    self.value = self.ai:GetHitPoints()
  end
  self:Watch(self.watch_callback, self)
  self.equalsCallbacks = {}
  self.greaterThanCallbacks = {}
  self.lessThanCallbacks = {}
  self.lessThanPercentageCallbacks = {}
  self:Start()
end
function HealthMonitor:watch_callback()
  if self.ai ~= nil and self.value == nil then
    self.value = self.ai:GetHitPoints()
    self.startValue = self.value
    return self.value
  elseif self.ai ~= nil and self.value ~= nil then
    return self.ai:GetHitPoints()
  elseif self.ai == nil and self.value ~= nil then
    self:Stop()
  end
end
_G.AddHealthMonitor = AddHealthMonitor
return {HealthMonitor = HealthMonitor, Add = AddHealthMonitor}
