local storage = minetest.get_mod_storage()


local data = {}

--register a table, the content of which is stored
dwarf_characters.intramodcom.register_for_storage = function(key, tab)
	--registering non-tables would make it so they would be copies, not
	--references making them immutable by the user program
	assert(type(tab) == "table",
		"Cannot register non-table values to be handled by storage")

	--this function gets called after load time so data may contain something
	--loaded from mod storage
	if data[key]
	then
		--tab is no longer needed since it's replaced by a loaded table
		tab = data[key]
	else
		data[key] = tab
	end
	--return whatever table gets stored.
	--It's a reference so the data it contains is both visible
	--and mutable by the functions here and the user program
	return tab
end



--for turning dead people inventories into something that minetest.serialize can handle
--we use a function that returns this so the table can get garbage collected when it's no longer needed
local function deuserdatafy_itemstacks(tab)
	local newtab = {}
	for i, v in pairs(tab)
	do
		local tv = type(v)
		if tv == "userdata" and v.to_string --if itemstack or AreaStore. If AreaStore propably weird things happen.
		then
			newtab[i] = {value = v:to_string(), was_userdata = true}
		elseif tv == "table"
		then
			newtab[i] = deuserdatafy_itemstacks(v)
		else
			--sadly no error message will be displayed if an
			--assertion fails on shutdown

			assert(tv == "number" or tv == "boolean" or tv == "nil" or tv == "string")

			newtab[i] = v
		end
	end
	return newtab
end
local function reuserdatafy_itemstacks(tab)
	local newtab = {}
	for i, v in pairs(tab)
	do
		if type(v) == "table"
		then
			if v.was_userdata --if itemstack
			then
				newtab[i] = ItemStack(v.value)
			else
				newtab[i] = reuserdatafy_itemstacks(v)
			end
		else
			newtab[i] = v
		end
	end
	return newtab
end


local function save()
	--turn userdata into tables so they can be serialized
	--we assume that all userdata in there are ItemStacks
	data = deuserdatafy_itemstacks(data)
	--convert data from table form to string
	local data = minetest.serialize(data)
	storage:set_string("data", data)
end
minetest.register_on_shutdown(save)


local function load()
	local loaddata = storage:get_string("data")
	if loaddata ~= ""
	then
		--convert back to table
		data = minetest.deserialize(loaddata)
		--restore ItemStacks
		data = reuserdatafy_itemstacks(data)
	end
end
load()
