--
-- /hud_map <player> <message>
-- /hud_map_all <message>
--
-- Sends a message to online player(s) using HUD elements.
-- Restricted to moderators, due to the potential for abuse.
--

local players = {}
local duration = tonumber(minetest.settings:get("hud_hud_map.duration")) or 10
local hide_sender = minetest.settings:get_bool("hud_hud_map.hide_sender") or false

local function hud_map(name, msg)
	local player = minetest.get_player_by_name(name)

	-- If notification is already being shown modify
	-- msg (and header if it exists) and time
	if players[name] then
		players[name].time = os.time() + duration
		player:hud_change(players[name].msg, "text", msg)
		if not hide_sender then
			player:hud_change(players[name].header, "text",
								"hud_map from " .. name .. ": ")
		end
		return
	end

	-- Else, add new elements
	players[name] = {time = os.time() + duration}
	players[name].bg = player:hud_add({
		hud_elem_type = "image",
		position = {x = 0, y = 0},
		offset = {x = 50, y = 300},
		scale = {x = -30, y = -30},
		alignment = {x = 1, y = 0},
		text = "hud_map.png"
	})
	players[name].msg = player:hud_add({
		hud_elem_type = "text",
		position = {x = 0, y = 0},
		offset = {x = 70, y = 230},
		alignment = {x = 1, y = 0},
		number = 0xFFFFFF,
		text = msg
	})

	if not hide_sender then
		local msg_header = "hud_map from " .. name .. ": "
		players[name].header = player:hud_add({
			hud_elem_type = "text",
			position = {x = 0, y = 0},
			offset = {x = 70, y = 200},
			alignment = {x = 1, y = 0},
			number = 0x3399FF,
			text = msg_header
		})
	end
end

local function update()
	for name, hud in pairs(players) do
		if hud and os.time() > hud.time then
			local player = minetest.get_player_by_name(name)
			if player then
				player:hud_remove(hud.bg)
				player:hud_remove(hud.msg)
				if not hide_sender then
					player:hud_remove(hud.header)
				end
			end

			players[name] = nil
		end
	end
end

minetest.register_chatcommand("hud_map", {
	params = "<pname> <message>",
	description = "Shows a message to player using HUD elements.",
	privs = {kick = true, ban = true},
	func = function(name, param)
		local pname, msg = param:trim():match("^(%S+)%s(.+)$")
		if not pname or not msg then
			return false, "Invalid usage, see /help hud_map."
		end
		if not core.get_player_by_name(pname) then
			return false, "The player " .. pname .. " is not online."
		end

		hud_map(pname, msg)
		return true, "hud_map sent to " .. pname .. ": \"" .. msg .. "\""
	end
})

minetest.register_chatcommand("hud_map_all", {
	params = "<message>",
	description = "Shows a message to all online players using HUD elements.",
	privs = {kick = true, ban = true},
	func = function(name, param)
		local msg = param:trim()
		if not msg then
			return false, "Invalid usage, see /help hud_map_all."
		end

		for _, player in pairs(minetest.get_connected_players()) do
			hud_map(player:get_player_name(), msg)
		end
		return true, "Global notification sent: \"" .. msg .. "\""
	end
})

minetest.register_globalstep(update)
