-------------------------------------------- DEFINITIONS ---------------------------------------------

local REGION_SIZE = 16

local math_ceil = math.ceil
local table_insert = table.insert


----------------------------------------------- REGION -----------------------------------------------

local Region = {class="Region"}

local RegionMT = {__index=Region}

Region.new = function(x, y)
	local region = {
		objects = {},
		grid = {}, -- index by calculation, one dimensional
		x = 1+(x-1)*REGION_SIZE,
		y = 1+(y-1)*REGION_SIZE,
		size = REGION_SIZE,
	}
	setmetatable(region,RegionMT)
	-- generate collectibles
	
	
	-- grid and object list both?
	-- grid: you only have to index ONCE per snake to check collisions
	-- objects: you don't have to iterate ten thousand times to find objects in a range
	-- (especially with regions)
	-- objects is needed client side, especially for other players and also rendering n shit
	-- grid is NOT needed client side, the server handles collisions n shit
	-- minimize workload on the server, send region objects but don't merge them, have client do that
	return region
end

Region.indexGrid = function(self, x, y)
	return self.grid[(y-1)*self.size+x]
end


----------------------------------------------- WORLD -----------------------------------------------

local World = {class="World"}

local WorldMT = {__index=World}

World.new = function(sizeInRegionsPerAxis)
	local size = sizeInRegionsPerAxis or 8
	world = {
		regions={},
		--snakes={},
		mobileObjects={},
		size=size,
		width=size*REGION_SIZE,
		height=size*REGION_SIZE,
	}
	setmetatable(world, WorldMT)
	for x=1,size do
		for y=1,size do
			world.regions[(y-1)*size+x] = Region.new(x, y)
		end
	end
	
	return world
end

World.getRegion = function(self, x, y)
	local rX,rY = math_ceil(x/REGION_SIZE), math_ceil(y/REGION_SIZE)
	return self.regions[(rY-1)*self.size+rX], rX ,rY
end

World.indexRegion = function(self, x, y)
	return self.regions[(y-1)*self.size+x]
end

World.indexGrid = function(self, x, y)
	local region, regX, regY = self:getRegion(x, y)
	local relX,relY = x-(regX-1)*REGION_SIZE, y-(regY-1)*REGION_SIZE
	return region:indexGrid(relX,relY)
end

return World

--[[World.place = function(self, object)
	local region, regX, regY = self:getRegion(object.x, object.y)
	local relX,relY = x-(regX-1)*REGION_SIZE, y-(regY-1)*REGION_SIZE
	if object.isMovable then
		-- AAAAAAAAAA
		table_insert(self.mobileObjects,object)
	else
		table.insret -- done with this shit]]
