-- LUALOCALS < ---------------------------------------------------------
local ipairs, math, minetest, pairs, piredo_api, string, table
    = ipairs, math, minetest, pairs, piredo_api, string, table
local math_floor, string_format, table_concat, table_sort
    = math.floor, string.format, table.concat, table.sort
-- LUALOCALS > ---------------------------------------------------------

local api = piredo_api.get_mod_api()

-- TOTAL POSSIBLE SCORE:
-- 10 clues to read
-- 32 critical items to collect
-- 26 rooms to visit
-- - except mystery_gold (bonus)
-- - except outside & outside_ruined (forced)
-- - except special_blocked (forced)
-- 8 forest machine puzzles
-- 6 potion puzzles
-- 2 doors to unlock
-- 6 other puzzles
api.score_max = 90
-- (+1 for the bonus room)

local modstore = minetest.get_mod_storage()

local scorekey = "discovered"
local status = modstore:get_string(scorekey)
status = status and status ~= "" and minetest.deserialize(status) or {}

local function calcscore()
	local n = 0
	for _ in pairs(status) do n = n + 1 end
	api.score = n
end
calcscore()

minetest.register_chatcommand("score", {
		description = "",
		privs = {["debug"] = true},
		func = function()
			local lines = {}
			for k in pairs(status) do lines[#lines + 1] = '+ ' .. k end
			table_sort(lines)
			lines[#lines + 1] = string_format("total %d (%d%%)",
				api.score,
				math_floor((api.score / api.score_max) * 100 + 0.5))
			return true, table_concat(lines, "\n")
		end
	})

function api.discover(label, cb)
	if not status[label] then
		status[label] = true
		calcscore()
		modstore:set_string(scorekey, minetest.serialize(status))
		minetest.log("action", string_format(
				"player discovered %q, total score %d",
				label, api.score))
	end
	-- cb is an optional callback that gives the player their "reward" for
	-- completing a puzzle, enabling mods to override puzzle rewards for
	-- specific puzzles (e.g. for randomizers)
	if cb then return cb() end
end

api.register_playerstep(function(player)
		for _, stack in ipairs(player:get_inventory():get_list("main")) do
			local name = stack:get_name()
			if name ~= "" and minetest.get_item_group(name,
			"puzzle_item") > 0 then
				api.discover("inv:" .. name)
			end
		end
	end)
