local Entity = Object:extend() -- On créer la classe des entitées, c'est la classe de base

function Entity:new(level, collType, x, y, w, h) -- On enregistre une nouvelle entité, avec par défaut sa hitbox.
  self:initPhysics(level, collType, x, y, w, h)
  self.destroyed = false
  self.registered = false
  self:setDebugColor(0,0,0)
end

function Entity:initPhysics(level, collType, x, y, w, h)
  self.level  = level
  self.world  = level.world
  self.camera = level.camera
  self.obj    = self.world.obj
  self.collType = collType

  self.gacc = 550
  self.xsp  = 0
  self.ysp  = 0

  self.bounce = 0
  self.grav   = 0
  self.frc    = 0

  self.x = x or 0
  self.y = y or 0
  self.w = w or 16
  self.h = h or 16
  self.onGround = false

  self.playerID = -1

  self:register()
end

function Entity:setDebugColor(r,g,b)
  self.debug = {}
  self.debug.r = r
  self.debug.g = r
  self.debug.b = r
end

function Entity:update(dt)

end

function Entity:register()
  self.world:addEntity(self, self.x, self.y, self.w, self.h)
end

function Entity:destroy()
  self.world:removeEntity(self)
end

function Entity:canBounce(bounce)
  self.bounce = bounce
end

function Entity:setMotion(xsp, ysp)
  self.xsp, self.ysp = xsp, ysp
end

function Entity:setMotionDirection(dir,spd)
  -- On commence par convertir l'angle en radians
  local dir = math.rad(dir)

  local xsp, ysp, cos, sin
  cos = math.cos(dir)
  sin = math.sin(dir)
  xsp = (spd * cos)
  ysp = (spd * sin)

  self.xsp, self.ysp = xsp, ysp
end

function Entity:gravity(dt)
  self.ysp = self.ysp + self.gacc * self.grav * dt
end

function Entity:friction(dt)
  if (math.abs(self.xsp) <= self.frc) then
    self.xsp = 0
  else
    self.xsp = self.xsp - (self.frc * utils.math.sign(self.xsp))
  end
end

function Entity:changeSpeedToCollisionNormal(nx, ny)
  local xsp, ysp = self.xsp, self.ysp

  if (nx < 0 and xsp > 0) or (nx > 0 and xsp < 0) then
    xsp = -xsp * self.bounce
  end

  if (ny < 0 and ysp > 0) or (ny > 0 and ysp < 0) then
    ysp = -ysp * self.bounce
  end

  self.xsp, self.ysp = xsp, ysp
end

function Entity:getCenter()
  return  self.x + self.w / 2,
          self.y + self.h / 2
end

function Entity:purge()
  self.world:removeEntity(self)
end

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

function Entity:checkGround(ny)
  if not (self.grav == 0) then
    if ny < 0 then self.onGround = true end
  end
end

function Entity:move(dt)
  self.onGround = false
  local xsp, ysp = self.xsp * dt, self.ysp * dt
  local cols, cols_len
  self.x, self.y, cols, cols_len = self.world:moveEntity(self, self.x + xsp, self.y + ysp, self.filter)

  for i=1, cols_len do
    local col = cols[i]
    if (col.type == "touch") or (col.type == "bounce") or (col.type == "slide") then
      self:changeSpeedToCollisionNormal(col.normal.x, col.normal.y)
      self:checkGround(col.normal.y)
    end
  end

  return cols, cols_len
end

function Entity:getDirection()
  if not (utils.math.sign(self.xsp) == 0) then
    self.direction = utils.math.sign(self.xsp)
  end
end

function Entity:isInsideView()
  return self.camera:isInsideView(self.x, self.y, self.w, self.h)
end

function Entity:draw()
  -- Cette fonction en contient rien par défaut
end

return Entity
