local class = require("core.class")
local levelmonitor = require("level.levelmonitor")
local DistanceMonitor = class.Class("DistanceMonitor", levelmonitor.LevelMonitor)
local callDistanceChangedCallback
function DistanceMonitor:OnCloserThan(dist, fn, ...)
  self.lessThanCallbacks[dist] = {
    fn = fn,
    ...
  }
  self:OnChanged(callDistanceChangedCallback, self)
end
function DistanceMonitor:OnFartherThan(dist, fn, ...)
  self.greaterThanCallbacks[dist] = {
    fn = fn,
    ...
  }
  self:OnChanged(callDistanceChangedCallback, self)
end
local AddDistanceMonitor = function(go1, go2)
  return DistanceMonitor.New(go1, go2)
end
function callDistanceChangedCallback(oldValue, newValue, self)
  local foundValidCallback = false
  for v, f in pairs(self.lessThanCallbacks) do
    if v <= oldValue and newValue < v then
      self:dprint("Distance Monitor triggered: Distance between '" .. tostring(self.go1) .. "' and '" .. tostring(self.go2) .. "' became less than " .. 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("Second: " .. tostring(newValue))
      self:dprint("Distance Monitor triggered: Distance between '" .. tostring(self.go1) .. "' and '" .. tostring(self.go2) .. "' became greater than " .. tostring(v))
      f.fn(self, unpack(f))
      foundValidCallback = foundValidCallback or true
    end
  end
  return foundValidCallback
end
function DistanceMonitor:init(go1, go2)
  self.go1 = go1
  self.go2 = go2
  self.value = go1.WorldPosition:Distance(go2.WorldPosition)
  self:dprint("First: " .. self.value)
  self:Watch(self.watch_callback, self)
  self.lessThanCallbacks = {}
  self.greaterThanCallbacks = {}
  self:Start()
end
function DistanceMonitor:watch_callback()
  if self.go1 == nil or self.go2 == nil then
    return self.value
  end
  return self.go1.WorldPosition:Distance(self.go2.WorldPosition)
end
_G.AddDistanceMonitor = AddDistanceMonitor
return {DistanceMonitor = DistanceMonitor, Add = AddDistanceMonitor}
