local NodeManager = class('NodeManager', {
  state = 'running',
  stateTime = 0,
  currentNode = nil,
})

function NodeManager:init(config)
  self.config = config
  self.nodes = {}
  self.nodeConfs = {}

  self.currentNode = nil

  print('Initializing NodeManager')
end

function NodeManager:load()
  self:configChanged()
end

function NodeManager:resize(w, h)
  self.secondaryCanvas = love.graphics.newCanvas(w, h)
end

function NodeManager:configChanged()
  local cnt = {}
  local newNodes = {}
  local newNodeConfs = {}

  for _, c_ in ipairs(self.config.nodes) do
    local nodeConfig = lume.clone(c_)
    local hash = inspect(nodeConfig)
    if cnt[hash] == nil then cnt[hash] = 0 end
    cnt[hash] = cnt[hash] + 1
    hash = hash .. '-' .. tostring(cnt[hash])

    local nodeName = nodeConfig[1]
    table.remove(nodeConfig, 1)

    if self.nodeConfs[hash] then
      print('Using existing node:', self.nodeConfs[hash], hash)
      newNodes[#newNodes + 1] = self.nodeConfs[hash]
    else
      print('Creating new node.', nodeName, inspect(nodeConfig))
      local status, err = pcall(function()
        newNodes[#newNodes + 1] = require(nodeName)(nodeConfig)
      end)
      if err then
        print("Error occured while loading", nodeName, err)
        return
      end
    end

    newNodeConfs[hash] = newNodes[#newNodes]
  end

  self.nodes = newNodes
  self.nodeConfs = newNodeConfs
end

function NodeManager:render()
  if not self.currentNode then self.currentNode = self.nodes[1] end
  if not self.currentNode then return end


  love.graphics.print('state: ' .. self.state .. '; counter: ' .. tostring(self.stateTime), 50, 50)

  self.currentNode:render()

  if self.state == 'transitioning' and self.currentNode ~= self.nextNode and self.nextNode then
    self.secondaryCanvas:renderTo(function()
      self.nextNode:render()
    end)
    print("Transitioning!", 1.0 * (self.stateTime / self.config.transitionTime))
    love.graphics.setColor(1.0, 1.0, 1.0, 1.0 * (self.stateTime / self.config.transitionTime))
    love.graphics.draw(self.secondaryCanvas, 0, 0)
  end

  love.graphics.setColor(1.0, 1.0, 1.0, 0.3)

  if self.config.showProgress and self.state == 'running' then
    local stateTime
    stateTime = self.currentNode.displayTime or self.config.displayTime
    local h = 5
    love.graphics.rectangle("fill", 0, love.graphics.getHeight() - h, (self.stateTime / stateTime) * love.graphics.getWidth(), h)
  end
end

function NodeManager:update(dt)
  if not self.currentNode then self.currentNode = self.nodes[1] end
  if not self.currentNode then return end

  self.stateTime = self.stateTime + dt

  if self.state == 'transitioning' and self.stateTime >= self.config.transitionTime then
    self.stateTime = 0
    self.state = 'running'
    self.currentNode:afterExit()
    -- self.currentNode, self.nextNode = self.nextNode, self.nodes[(lume.find(self.nodes, self.nextNode) or 1) % #self.nodes + 1]
    self.currentNode = self.nextNode
    self.currentNode:afterEnter()
  elseif self.state == 'running' and self.stateTime >= (self.currentNode.displayTime or self.config.displayTime) then
    self.stateTime = 0
    self.state = 'transitioning'
    self.currentNode:beforeExit()
    self.nextNode = self.nodes[(lume.find(self.nodes, self.currentNode) or 1) % #self.nodes + 1]
    self.nextNode:beforeEnter()
  end

  self.currentNode:update(dt)
  if self.state == 'transitioning' and self.currentNode ~= self.nextNode and self.nextNode then
    self.nextNode:update(dt)
  end
end

return NodeManager
