local classlib = require("core.class")
local Timer = classlib.Class("Timer") .. {
  time = 0,
  running = false,
  fired = false,
  autoreset = false
}
function Timer:init(runList, period, callback, ...)
  assert(runList)
  self.period = period
  self.callback = callback
  self.args = (...) and {
    ...
  }
  self.runList = runList
  self.isLinkedToGamePause = false
end
function Timer:Reassign(runList, period, callback, ...)
  assert(runList)
  self:Reset()
  self.period = period
  self.callback = callback
  self.args = (...) and {
    ...
  }
  self.runList = runList
  self.isLinkedToGamePause = false
end
function Timer:Update(dt, gameIsPaused)
  if self.isLinkedToGamePause and gameIsPaused == true then
    return
  end
  if self.running and not self.fired then
    self.time = self.time + dt
    if self.time >= self.period then
      self:Stop()
      self:CallCallback()
      if self.autoreset then
        self:Restart()
      end
    end
  end
end
function Timer:CallCallback()
  self.fired = true
  if self.callback and self.args then
    self.callback(self, unpack(self.args))
  elseif self.callback then
    self.callback(self)
  end
end
function Timer:Done()
  return self.fired
end
function Timer:Start()
  assert(self.period, "No period set on timer")
  if not self.fired then
    self.running = true
    self.runList:add(self)
  end
end
function Timer:Pause()
  assert(self.running)
  self.running = false
  self.runList:remove(self)
end
function Timer:Unpause()
  assert(not self.running)
  self.running = true
  self.runList:add(self)
end
function Timer:LinkToGamePause(value)
  self.isLinkedToGamePause = value
end
function Timer:Stop()
  self.running = false
  self.runList:remove(self)
end
function Timer:Finish()
  self:Stop()
  self:CallCallback()
end
function Timer:Restart()
  self:Reset()
  self:Start()
end
function Timer:GetElapsedTime()
  return self.time
end
function Timer:GetRemainingTime()
  return self.period - self.time
end
function Timer:Reset()
  self:Stop()
  self.time = 0
  self.fired = false
end
return {Timer = Timer}
