-- LUALOCALS < ---------------------------------------------------------
local dofile, error, ipairs, minetest, pairs, piredo_api, string,
      table, vector
    = dofile, error, ipairs, minetest, pairs, piredo_api, string,
      table, vector
local string_format, string_sub, table_sort
    = string.format, string.sub, table.sort
-- LUALOCALS > ---------------------------------------------------------

local modname = minetest.get_current_modname()
local api = piredo_api.get_mod_api()

local function rehydrate(schem)
	schem.totals = {}
	schem.size = {}
	schem.data = {}
	schem.size.y = #schem.nodes
	for y, ys in ipairs(schem.nodes) do
		if schem.size.z and schem.size.z ~= #ys then
			error("inconsistent z size")
		end
		schem.size.z = #ys
		for z, zs in ipairs(ys) do
			if schem.size.x and schem.size.x ~= #zs then
				error("inconsistent x size")
			end
			schem.size.x = #zs
			for x = 1, zs:len() do
				local node = schem.legend[zs:sub(x, x)]
				if node and node.name then
					schem.totals[node.name] = (schem.totals[node.name] or 0) + 1
				end
				schem.data[(schem.size.z - z) * schem.size.x * schem.size.y
				+ (y - 1) * schem.size.x + x] = node
			end
		end
	end

	local keys = {}
	for k in pairs(schem.totals) do keys[#keys + 1] = k end
	table_sort(keys, function(a, b) return schem.totals[a] > schem.totals[b] end)
	local report = string_format("ezschematic %s %q %dx%dx%d",
		minetest.get_current_modname() or "runtime", schem.key,
		#schem.nodes[1][1], #schem.nodes, #schem.nodes[1])
	for _, k in ipairs(keys) do
		report = string_format("%s, %d %s", report, schem.totals[k], k)
	end
	minetest.log("info", report)

	schem.mts = minetest.register_schematic(schem)
end

local modpath = minetest.get_modpath(modname)
for _, fn in pairs(minetest.get_dir_list(modpath, false)) do
	if string_sub(fn, 1, 6) == "schem_" and string_sub(fn, -4) == ".lua" then
		local schem = dofile(modpath .. "/" .. fn)
		schem.key = string_sub(fn, 7, -5)
		rehydrate(schem)
		api[schem.key] = schem
	end
end

do
	local depth = 36
	local height = 28
	local void = {name = "piredo_terrain:void", force_place = true}
	local air = {name = "air", force_place = true}
	for _, xz in ipairs({20, 40}) do
		local data = {}
		for _ = 1, xz do
			for y = 1, depth + height do
				for _ = 1, xz do
					data[#data + 1] = (y > depth) and air or void
				end
			end
		end
		local size = vector.new(xz, depth + height, xz)
		api["clear_" .. xz] = {
			pos = vector.new(0, -depth, 0),
			size = size,
			mts = minetest.register_schematic({
					size = size,
					data = data
			})}
	end
end
