local has_worldedit = minetest.get_modpath("worldedit")

-- player -> inv-formspecs
local old_inv_formspecs = {}

local editor_privs = {
	"fly", "fast", "noclip", "debug"
}

-- returns true if in play mode
function super_sam.check_play_mode(player)
	local meta = player:get_meta()
	local mode = meta:get_string("super_sam_mode")
	return mode == "" or mode == "play"
end

-- play mode
function super_sam.set_play_mode(player)
	local playername = player:get_player_name()

	-- make player mortal
	player:set_armor_groups({
		immortal = nil,
		fall_damage_add_percent = -100
	})
	player:set_hp(super_sam.max_hp, "set_hp")

	-- clear inventory items
	local inv = player:get_inventory()
	local main_inv = inv:get_list("main")
	for i in ipairs(main_inv) do
		main_inv[i] = ""
	end
	inv:set_list("main", main_inv)

	-- disable inventory
	old_inv_formspecs[playername] = player:get_inventory_formspec()
	player:set_inventory_formspec("")

	-- restrict hud
	player:hud_set_flags({
		healthbar = false,
		breathbar = false,
		hotbar = false,
		wielditem = false,
		minimap = false,
		minimap_radar = false
	})

	-- revoke privs
	local privs = minetest.get_player_privs(playername)
	for _, name in pairs(editor_privs) do
		privs[name] = nil
	end
	minetest.set_player_privs(playername, privs)

	-- TODO: search nearest/last level
end

-- editor mode
function super_sam.set_edit_mode(player)
	local playername = player:get_player_name()

	-- make player immortal
	player:set_armor_groups({ immortal = 1 })

	-- abort level (if started)
	super_sam.abort_level(player)

	-- restore inventory formspec
	if old_inv_formspecs[playername] then
		player:set_inventory_formspec(old_inv_formspecs[playername])
	end

	-- add editor items to inv
	local inv = player:get_inventory()
	local main_inv = inv:get_list("main")
	main_inv[1] = "super_sam:editor"
	if has_worldedit then
		main_inv[2] = "worldedit:wand"
	end
	inv:set_list("main", main_inv)

	-- toggle hud items
	player:hud_set_flags({
		hotbar = true,
		wielditem = true,
		minimap = true,
		minimap_radar = true
	})

	-- reset time and stats
	super_sam.set_time(playername, nil)
	super_sam.set_coins(playername, 0)
	super_sam.set_score(playername, 0)

	-- grant privs
	local privs = minetest.get_player_privs(playername)
	for _, name in pairs(editor_privs) do
		privs[name] = true
	end
	minetest.set_player_privs(playername, privs)
end

-- restore previous mode on join
minetest.register_on_joinplayer(function(player)
	local meta = player:get_meta()
	local mode = meta:get_string("super_sam_mode")

	if mode == "edit" then
		super_sam.set_edit_mode(player)
	else
		super_sam.set_play_mode(player)
	end
end)

-- toggle command, requires the "super_sam_builder" priv
minetest.register_chatcommand("mode", {
	params = "[edit|play]",
	description = "Switch between edit and play mode",
	privs = { super_sam_builder=true },
	func = function(name, mode)
		local player = minetest.get_player_by_name(name)
		local meta = player:get_meta()
		meta:set_string("super_sam_mode", mode)

		if mode == "play" then
			super_sam.set_play_mode(player)
			return true, "Switched to play mode"

		elseif mode == "edit" then
			-- abort level
			super_sam.set_edit_mode(player)
			return true, "Switched to editor mode"

		else
			return true, "Invalid mode: '" .. mode .. "'"

		end
	end
})