-- LUALOCALS < ---------------------------------------------------------
local ipairs, math, minetest, pairs, piredo_api, piredo_player, string,
      table, tonumber
    = ipairs, math, minetest, pairs, piredo_api, piredo_player, string,
      table, tonumber
local math_floor, string_format, string_match, table_concat
    = math.floor, string.format, string.match, table.concat
-- LUALOCALS > ---------------------------------------------------------

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

local endpos

function api.is_endcredits() return endpos and true end
function api.set_endcredits(pos) endpos = pos end

minetest.register_entity(modname .. ":playerhold", {
		initial_properties = {
			static_save = false,
			is_visible = true,
			visual = "cube",
			visual_size = {x = 8, y = 8, z = 8},
			backface_culling = false,
			textures = {
				"[combine:1x1^[noalpha",
				"[combine:1x1^[noalpha",
				"[combine:1x1^[noalpha",
				"[combine:1x1^[noalpha",
				"[combine:1x1^[noalpha",
				"[combine:1x1^[noalpha",
			},
			pointable = false,
			physical = false
		}
	})

local function timefmt(n)
	local s = string_format("%0.3f", n % 60)
	if n < 60 then return s end
	if (n % 60) < 10 then s = "0" .. s end
	local m = math_floor(n / 60)
	if m < 60 then return m .. ":" .. s end
	local h = math_floor(m / 60)
	m = m % 60
	m = (m < 10) and ("0" .. m) or ("" .. m)
	return h .. ":" .. m .. ":" .. s
end

local srclang = "en"
local function getcredits(player, timer, completion)
	local info = player and minetest.get_player_information(player:get_player_name())
	local lang = info and info.lang_code or srclang
	if lang == "" then lang = srclang end
	local prop = (piredo_api.translated_stats[lang] or 0) / piredo_api.translated_stats[srclang]
	local devver = S("DEVELOPMENT VERSION")
	return {
		[1/2] = {
			"",
			"",
			"",
			S("Programming - Warr1024"),
			S("Writing and Design - iarbat"),
			S("See LICENSE.txt for all contributors"),
			"",
			"https://gitlab.com/sztest/piranesi_redo",
			"",
			"https://hosted.weblate.org/projects/minetest/game-piranesi-redo/",
			S("~ @1% translated into your language (@2)",
				math_floor(prop * 100), lang),

			"",
			"",
			"",
			"",
			"",
			"",
			"",
		},
		[1/3] = {
			"",
			"",
			"",
			"",
			"",
			"",
			"",
			"",
			"",
			"",
			"",
			"",
			"",
			S("Version"),
			piredo_api.version or devver,
			"",
			S("Completion"),
			completion,
		},
		[2/3] = {
			"",
			"",
			"",
			"",
			"",
			"",
			"",
			"",
			"",
			"",
			"",
			"",
			"",
			S("Session(s)"),
			piredo_player.sessions,
			"",
			S("Time"),
			timer,
		}
	}
end
getcredits() -- translation detection

local function show_credit_hud(player)
	local credit_config = getcredits(
		player,
		timefmt(api.timer),
		math_floor((api.score / api.score_max) * 100 + 0.5) .. "%"
	)

	do
		local creditheight = 0
		for _, v in pairs(credit_config) do
			if #v > creditheight then creditheight = #v end
		end
		local titlesize = 0.262295081967
		player:hud_add({
				hud_elem_type = "image",
				position = {x = 0.5, y = 0.5},
				offset = {x = 0, y = -8 * creditheight},
				scale = {x = titlesize, y = titlesize},
				text = "piredo_player_header.png",
				z_index = -100,
			})
	end

	for xoffs, credit_text in pairs(credit_config) do
		for i = 1, #credit_text do
			local lines = {}
			for j = 1, #credit_text do
				lines[#lines + 1] = i == j and credit_text[j] or ""
			end
			local text = table_concat(lines, "\n")
			if string_match(text, "%S") then
				player:hud_add({
						hud_elem_type = "text",
						position = {x = xoffs, y = 0.5},
						offset = {x = 0, y = 32},
						text = text,
						number = 0xffffff,
						z_index = -100
					})
			end
		end
	end

	local volume = tonumber(minetest.settings:get("piranesi_music")) or 1
	if volume <= 0 then return end
	local soundid = minetest.sound_play(modname .. "_theme", {
			to_player = player:get_player_name(),
			gain = 0.0000001,
			loop = true
		})
	minetest.sound_fade(soundid, 0.05, volume)
end

local function check_end_credits(player)
	if not endpos then return end

	if player:get_properties().visual ~= "sprite" then
		player:set_properties({
				visual = "sprite",
				textures = {
					"[combine:1x1",
					"[combine:1x1",
				}
			})
		player:hud_set_flags({
				crosshair = false,
				wielditem = false,
			})
		api.hide_compass(player)
	end

	if not player:get_attach() then
		piredo_player.screenfade(player, true)
		local obj = minetest.add_entity(endpos,
			modname .. ":playerhold")
		if obj then
			player:set_attach(obj)
			show_credit_hud(player)
			piredo_player.screenfade(player)
		end
	end
end

minetest.register_globalstep(function()
		for _, player in ipairs(minetest.get_connected_players()) do
			check_end_credits(player)
		end
	end)
