local folder = "scenes.subgame.sonic-boost.actors."
local ParentEntity = Object:extend() -- On créer la classe des entitées, c'est la classe de base

local Timer = require(folder .. "utils.timers")

function ParentEntity:new(world, type, x, y, z, w, h, d) -- On enregistre une nouvelle entité, avec par défaut sa hitbox.
  self:setHitbox(x, y, z, w, h, d)
  self:register(world)
  --self:initPhysics()
  --self:resetTimers()
  self:setDebugColor(0,0,0)
  self.destroyed = false
  self.invisible = false
  self.appearence = "none"

  self.type = type

  self:setSprite("", 0, 0, false)

  self:setFilter()

  self.depth = 0
  self.id               = self.world.creationID
  self.world.creationID = self.world.creationID + 1

  self:resetTimers()
end

function ParentEntity:setHitbox(x, y, z, w, h, d)
  self.x = x
  self.y = y
  self.z = z
  self.w = w
  self.h = h
  self.d = d
end

function ParentEntity:setSprite(name, ox, oy, active)
  self.sprite = {}

  self.sprite.name    = name
  self.sprite.ox      = ox
  self.sprite.oy      = oy
  self.sprite.active  = active or false
end

function ParentEntity:update(dt)
  self:updateTimers(dt)
end

function ParentEntity:register(world)
  -- On enregistre la hitbox dans le monde, pour l'instant les deux parties du programmes
  -- sont séparé (génération et enregistrement, peut-être qu'elles seront fusionnées)
  self.world      = world
  self.controller = world.controller
  self.assets     = self.controller.assets

  self.world:register(self)
end

function ParentEntity:destroy()
  if self.destroyed == false then
    self.world:remove(self)
    self.destroyed = true
  end
end

function ParentEntity:move()
  local x, y, z, cols, coll_number = self.x, self.y, self.z, {}, 0
  if self.destroyed == false then
    x, y, z, cols, coll_number = self.world:move(
      self,
      self.x,
      self.y,
      self.z,
      self.filter
    )
  end

  return x, y, z, cols, coll_number
end

function ParentEntity:drawDebug()
  if self.invisible == true then
    return 0
  end

  self:draw()
end

--------------------------- DEBUG FUNCTIONS ------------------------------------

function ParentEntity:setDebugColor(r,g,b)
  self.debugColor = {}

  self.debugColor.r = r
  self.debugColor.g = g
  self.debugColor.b = b
end

---------- COLLISION ----------

function ParentEntity:setFilter()
  self.filter = function(item, other)
    return nil
  end
end

function ParentEntity:set2DFilter()
  self.filter2D = function(item, other)
    return "cross"
  end
end

function ParentEntity:pickedUp()
  self:destroy()
end

--------------------------- COORDINATE FUNCTIONS ------------------------------------

function ParentEntity:getCenter()
  local x, y, z
  x = math.floor(self.x + self.w / 2)
  y = math.floor(self.y + self.h / 2)
  z = math.floor(self.z + self.d / 2)

  return x, y, z
end

function ParentEntity:getViewCenter()
  return self:getCenter()
end

function ParentEntity:getOrigin()
  local x, y, z
  y = math.floor(self.y + self.h / 2)
  x = math.floor(self.x + self.w / 2) + math.floor(y / 2)
  z = math.floor(self.z)

  return x, y, z
end

function ParentEntity:getSpritePosition()
  local x, y, z = self:getOrigin()
  y = y - z

  return x, y, z
end

--------------------------- DRAW FUNCTIONS ------------------------------------

function ParentEntity:draw()
  self:drawSprite()
end

function ParentEntity:drawEcho()
  self:drawSprite(self.world.width, 0)
end

function ParentEntity:drawSprite(tx, ty)
  utils.graphics.resetColor()

  local x, y, z = self:getSpritePosition()

  local tx = tx or 0
  local ty = ty or 0

  if (self.sprite.active) then
    self.assets.sprites[self.sprite.name]:drawAnimation(x + tx, y + ty, 0, 1, 1, self.sprite.ox, self.sprite.oy)
  end
end

function ParentEntity:drawShadow(tx, ty)
  local x, y, z = self:getOrigin()
  utils.graphics.resetColor()
  local tx = tx or 0
  local ty = ty or 0
  x = math.floor(x + tx)
  y = math.floor(y + ty)
  self.assets:drawImage("shadow", x, y, 0, 1, 1, 12, 3)
end

function ParentEntity:drawShadowEcho()
  self:drawShadow(self.world.width, 0)
end

function ParentEntity:drawHitBox()
  x, y, z = self:getOrigin()

  local r, g, b, a = self.debugColor.r, self.debugColor.g, self.debugColor.b, self.debugColor.a

  --utils.graphics.box(self.x, self.y + self.z + self.h, self.w, self.d, self.h, r, g, b, a)
  --utils.graphics.box(x - (self.w/2), y - (self.w/2) - self.z, self.w, self.h, r, g, b, a)
  --utils.graphics.box(x - (self.w/2), y - (self.w/2) - self.z, self.w, self.d, r, g, b, a)
  --utils.graphics.box(x - (self.w/2), y + (self.w/2) - self.z - self.d, self.w, self.d, r, g, b, a)
  --utils.graphics.box(x - (self.w/2), y - (self.w/2) - self.z - self.d, self.w, self.h, r, g, b, a)
  --utils.graphics.box(x - (self.w/2), y + (self.w/2) - self.z - self.d, self.w, self.d, r, g, b, a)

  utils.graphics.box(x - (self.w/2), y - (self.h/2), self.w, self.h, r/5, g/5, b/5, 1)

  utils.graphics.box(x - (self.w/2), y - z - self.d, self.w, self.d, r, g, b, 1)

end

----------- TIMER RELATED FUNCTIONS ----------

function ParentEntity:resetTimers()
  self.timers = {}
end

function ParentEntity:addTimer(name, t)
  self.timers[name] = Timer(self, name, t)
  return name
end

function ParentEntity:updateTimers(dt)
  for i, v in pairs(self.timers) do
    v:update(dt)
  end
end

function ParentEntity:endedTimer(name)
  if name == "destroy" then
    self:destroy()
  end
end

return ParentEntity
