local class = require("core.class")
local levelmonitor = require("level.levelmonitor")
local BreakableMonitor = class.Class("BreakableMonitor", levelmonitor.LevelMonitor)
local callBrokenCallback
function BreakableMonitor:OnBreak(fn, ...)
  self.breakCallback = {
    fn = fn,
    ...
  }
  self:OnChanged(callBrokenCallback, self)
end
function BreakableMonitor:OnStage(stageNum, fn, ...)
  self.stageCallbacks[stageNum] = {
    fn = fn,
    ...
  }
  self:OnChanged(callBrokenCallback, self)
end
local AddBreakableMonitor = function(go)
  return BreakableMonitor.New(go)
end
function callBrokenCallback(oldValue, newValue, self)
  local foundValidCallback = false
  if self.breakCallback ~= nil and newValue == self.finalStage then
    self:dprint("Breakable Monitor triggered: '" .. tostring(self.breakable) .. "' broke")
    self.breakCallback.fn(self, self.breakCallback)
    foundValidCallback = foundValidCallback or true
  end
  for v, f in pairs(self.stageCallbacks) do
    if oldValue < v and newValue == v then
      self:dprint("Breakable Monitor triggered: '" .. tostring(self.breakable) .. "' changed stages")
      f.fn(self, unpack(f))
      foundValidCallback = foundValidCallback or true
    end
  end
  return foundValidCallback
end
function BreakableMonitor:init(go)
  if go.IsRefNode then
    self.breakable = go.Child:GetBreakable()
  else
    self.breakable = go:GetBreakable()
  end
  self.value = self.breakable.Stage
  self.finalStage = self.breakable.NumStages - 1
  self:Watch(self.watch_callback, self)
  self.breakCallback = nil
  self.stageCallbacks = {}
  self:Start()
end
function BreakableMonitor:watch_callback()
  if self.breakable == nil then
    return self.value
  end
  return self.breakable.Stage
end
_G.AddBreakableMonitor = AddBreakableMonitor
return {BreakableMonitor = BreakableMonitor, Add = AddBreakableMonitor}
