local modpath = minetest.get_modpath("ikea_showroom")
dofile(modpath .. "/nodes.lua")
local rooms, displays = dofile(modpath .. "/displays.lua")

local place_opening = util.every_n_mapblocks(4)
local wall_height = 10
local c_wall = minetest.get_content_id("showroom:wall")
local c_floor = minetest.get_content_id("showroom:floor")

local Perlin = PerlinNoise({
	offset = 0,
	scale = 15,
	spread = {x = 10, y = 10, z = 10},
	seed = 2,
	octaves = 2,
	persistence = 3,
	lacunarity = 2,
	flags = "defaults, absvalue",
})

ikea.register_department({
	name = "showroom",

	get_data = function(data, param2s, va, x, z, edges)
		-- Corner North/South East/West Top/Bottom
		local corner_swb = {x = x + 0, y = 0, z = z + 0}
		local corner_seb = {x = x + 15, y = 0, z = z + 0}
		local corner_nwb = {x = x + 0, y = 0, z = z + 15}

		local corner_set = {x = x + 15, y = wall_height, z = z + 0}
		local corner_nwt = {x = x + 0, y = wall_height, z = z + 15}
		local corner_net = {x = x + 15, y = wall_height, z = z + 15}

		-- Walls
		if edges.s then
			data = util.fill_vmanip_area(data, va, corner_swb, corner_set, c_wall)
		end
		if edges.n then
			data = util.fill_vmanip_area(data, va, corner_nwb, corner_net, c_wall)
		end
		if edges.e then
			data = util.fill_vmanip_area(data, va, corner_seb, corner_net, c_wall)
		end
		if edges.w then
			data = util.fill_vmanip_area(data, va, corner_swb, corner_nwt, c_wall)
		end

		-- Inner Walls
		if (util.bound_perlin(Perlin, 10, x, 5, z) > 3) and not place_opening(x) then
			data = util.fill_vmanip_area(data, va, {x = x, y = 0, z = z}, {x = x, y = wall_height, z = z + 15}, c_wall)
		end
		if (util.bound_perlin(Perlin, 10, x, 6, z) > 7) and not place_opening(z) then
			data = util.fill_vmanip_area(data, va, {x = x, y = 0, z = z}, {x = x + 15, y = wall_height, z = z}, c_wall)
		end

		-- Doorways
		if place_opening(x) then
			if edges.s then
				if edges.inner.s then
					data = util.fill_vmanip_area(data, va, {x = x + 3, y = 0, z = z + 0}, {x = x + 12, y = 4, z = z + 0},
						minetest.CONTENT_AIR)
				else
					data = util.fill_vmanip_area(data, va, {x = x + 6, y = 0, z = z + 0}, {x = x + 9, y = 4, z = z + 0},
						minetest.CONTENT_AIR)
				end
			end
			if edges.n then
				if edges.inner.n then
					data = util.fill_vmanip_area(data, va, {x = x + 3, y = 0, z = z + 15}, {x = x + 12, y = 4, z = z + 15},
						minetest.CONTENT_AIR)
				else
					data = util.fill_vmanip_area(data, va, {x = x + 6, y = 0, z = z + 15}, {x = x + 9, y = 4, z = z + 15},
						minetest.CONTENT_AIR)
				end
			end
		end

		if place_opening(z) then
			if edges.e then
				if edges.inner.e then
					data = util.fill_vmanip_area(data, va, {x = x + 15, y = 0, z = z + 1}, {x = x + 15, y = 4, z = z + 10},
						minetest.CONTENT_AIR)
				else
					data = util.fill_vmanip_area(data, va, {x = x + 15, y = 0, z = z + 3}, {x = x + 15, y = 4, z = z + 6},
						minetest.CONTENT_AIR)
				end
			end
			if edges.w then
				if edges.inner.w then
					data = util.fill_vmanip_area(data, va, {x = x + 0, y = 0, z = z + 1}, {x = x + 0, y = 4, z = z + 10},
						minetest.CONTENT_AIR)
				else
					data = util.fill_vmanip_area(data, va, {x = x + 0, y = 0, z = z + 3}, {x = x + 0, y = 4, z = z + 6},
						minetest.CONTENT_AIR)
				end
			end
		end

		-- Furniture
		if not (((edges.n or edges.s) and place_opening(x)) or ((edges.e or edges.w) and place_opening(z))) then
			local room_name = rooms[util.bound_perlin(Perlin, #rooms, x, 0, z)]

			for x2 = x + 2, x + 13, 4 do
				for z2 = z + 2, z + 13, 4 do
					local display_id = util.bound_perlin(Perlin, #displays[room_name], x2, 1, z2)

					for _, v in ipairs(displays[room_name][display_id].nodes) do
						local groups = {ikea_furniture = 1}
						groups[v.type] = 1
						groups[room_name] = 1
						local applicable_furniture = util.get_nodes_by_groups(groups)
						local id = util.bound_perlin(Perlin, #applicable_furniture, x + x2, 2, z + z2)

						local index = va:indexp(vector.add(v.pos, {x = x2, y = 1, z = z2}))
						data[index] = minetest.get_content_id(applicable_furniture[id])
					end
				end
			end
		end

		for i in va:iter(x, 0, z, x + 15, 0, z + 15) do
			data[i] = c_floor
		end

		return data, param2s
	end,
})

