local World2D = require "core.modules.world.world2D"
local World = World2D:extend()

local Obj = require "scenes.levels.entities"

local Sti   = require "libs.sti"

-- INIT FUNCTIONS
-- All functions to init the world and the map

function World:new(scene, mapfile, actorlist)
  self.scene      = scene
  self.actorlist  = actorlist
  self.mapfile    = mapfile

  self:initActors()

  self:initMap(self.mapfile)
  self:setActorList(self.actorlist)
  self:setGravity()

  self:register()

  self.isActive = true
end

function World:loadMapObjects()
  self:loadMapCollisions()
  self:loadMapActors()
end

function World:getStartPosition()
  local startx, starty
  for k, objectlayer in pairs(self.map.layers) do
    if objectlayer.name == "playerstart" then
        for k, object in pairs(objectlayer.objects) do
          startx = object.x + (object.width/2)
          starty = object.y + (object.height) - 12
        end
        self.map:removeLayer("playerstart")
    end
  end
  return startx, starty
end

-- MAP FUNCTIONS
-- All map wrappers

function World:getDimensions()
  return  self.map.width  * self.map.tilewidth,
          self.map.height * self.map.tileheight
end

-- UPDATE FUNCTIONS
-- All update functions

function World:update(dt)
  self.scene.playermanager:update(dt)
  self:updateEntities(dt)
  self:updateMap(dt)
  self.scene.camera:update(dt)
end

function World:updateEntities(dt)
  --l,t,w,h = l or 0, t or 0, w or self.width, h or self.height
    local visibleThings, len = self.scene.camera:getVisibleEntities()
    --table.sort(visibleThings, sortByUpdateOrder)

    for i=1, len do
      visibleThings[i]:update(dt)
    end

    self.activeObjects = len
end

function World:updateMap(dt)
  self.map:update(dt)
end

-- DRAW FUNCTIONS
-- All function to draw the map, world and entities

function World:draw()
  -- Ona attache puis détache la caméra pour dessiner le monde, afin que celui
  -- reste "fixe" tandis que le jouer bouge.
  self.scene.camera:floorCoord()
  self:drawBackgroundColor()
  self.scene.camera:attach()
  self:drawMap()
  self:drawEntities()
  self.scene.camera:detach()
end

function World:drawEntities()
  --l,t,w,h = l or 0, t or 0, w or self.width, h or self.height
    local visibleThings, len = self.scene.camera:getVisibleEntities()
    --table.sort(visibleThings, sortByUpdateOrder)

    for i=1, len do
      visibleThings[i]:draw(dt)
    end
end

function World:drawMap()
  -- Du à la manière dont fonctionne STI, on est obligé de récupérer les info
  -- de position de camera pour afficher la carte par rapport à ces infos
  local tx, ty  = self.scene.camera:getCoord()
  local scale   = self.scene.camera:getScale()
  local tx = tx
	local ty = ty

	tx = math.floor(tx)
	ty = math.floor(ty)

	self.map:draw(-tx, -ty, scale, scale)
end

return World
