local TweenManager = Object:extend()

local tween = require "game.modules.tweenmanager.libs.tween"
local Timer = require "core.modules.world.actors.utils.timer"

function TweenManager:new(subject)
  self.subject  = subject
  self.time    = 0

  self.tweens   = {}
  self.switches = {}

  self.timers   = {}
end

function TweenManager:newTween(start, duration, target, easing)
  local newTween = {}
  -- we add the data into a tween wrapper
  newTween.tween = tween.new(duration, self.subject, target, easing)
  newTween.start = self.time + start -- /!\ START IS RELATIVE TO CURRENT TIME
  newTween.clear = newTween.start + duration

  table.insert(self.tweens, newTween)
end

function TweenManager:newTimer(start, name)
  self.timers[name] = Timer(self, name, start)
end

function TweenManager:newSwitch(start, bools)
  local newSwitch = {}
  -- we add the data into a tween wrapper
  newSwitch.bools = bools
  newSwitch.start = self.time + start -- /!\ START IS RELATIVE TO CURRENT TIME
  newSwitch.clear = newSwitch.start + 1

  table.insert(self.switches, newSwitch)
end

function TweenManager:update(dt)
  self.time = self.time + dt

  for i, tweenWrapper in ipairs(self.tweens) do
    if (self.time > tweenWrapper.start) then
      tweenWrapper.tween:update(dt)
    end
  end

  for i, switch in ipairs(self.switches) do
    if (self.time > switch.start) then
      -- We test each boolean in the switch
      for i, bool in ipairs(switch.bools) do
        -- if it's nil, we set it to true
        if self.subject[bool] == nil then
          self.subject[bool] = true
        else
          -- if it's not nil, we reverse the boolean
          self.subject[bool] = (self.subject[bool] == false)
        end
      end
      table.remove(self.switches, i)
    end
  end

  for k, timer in pairs(self.timers) do
    timer:update(dt)
  end

  self:clearEndedTweens()
end

function TweenManager:timerResponse(timername)
  if self.subject.timerResponse == nil then
    core.debug:warning("tweenmanager", "the subject have no timerResponse function")
    return 0
  end
  self.subject:timerResponse(timername)
end

function TweenManager:clearEndedTweens(dt)
  for i, tweenWrapper in ipairs(self.tweens) do
    if (self.time > tweenWrapper.clear) then
      table.remove(self.tweens, i)
    end
  end
end

return TweenManager
