-- LUALOCALS < ---------------------------------------------------------
local klots, math, minetest, string, type
    = klots, math, minetest, string, type
local math_ceil, math_floor, string_format
    = math.ceil, math.floor, string.format
-- LUALOCALS > ---------------------------------------------------------

local modname = minetest.get_current_modname()

------------------------------------------------------------------------

do
	local function clamp(x)
		if x < 0 then return 0 end
		if x > 255 then return 255 end
		return math_floor(x)
	end
	function klots.mktile(color, qty)
		if qty <= 0 then return "[combine:1x1" end
		if type(color) == "table" then
			color = string_format("#%02x%02x%02x",
				clamp(color.r),
				clamp(color.g),
				clamp(color.b))
		end
		qty = math_ceil(qty * 32) * 8
		return "[combine:1x1^[noalpha^[colorize:" .. color .. ":255"
		.. (qty < 255 and ("^[opacity:" .. qty) or "")
	end
end

------------------------------------------------------------------------

do
	local seen = {}
	local tiles = {}
	local idx = 0
	local function flush()
		if #tiles < 1 then return end
		idx = idx + 1
		minetest.register_node(modname .. ":preload" .. idx, {
				tiles = tiles
			})
		tiles = {}
	end
	local function preload(color)
		for i = 0, 1, 1/32 do
			local tile = klots.mktile(color, i)
			if not seen[tile] then
				seen[tile] = true
				tiles[#tiles + 1] = tile
			end
			if #tiles >= 6 then flush() end
		end
	end

	preload("#000000")

	flush()
end

------------------------------------------------------------------------

local getdata = klots.register_playerstep(function(player, data, dtime)
		local qty = 0
		if data.qty then
			qty = data.qty - data.rate * dtime
			data.qty = qty > 0 and qty or nil
		end
		local tile = klots.mktile(data.color, qty)

		if tile ~= data.tile then
			if data.hudid then
				player:hud_change(data.hudid, "text", tile)
			else
				data.hudid = player:hud_add({
						hud_elem_type = "image",
						position = {x = 0.5, y = 0.5},
						text = tile,
						direction = 0,
						scale = {x = -105, y = -105},
						offset = {x = 0, y = 0}
					})
			end
			data.tile = tile
		end
	end)

function klots.flash_screen(player, color, duration, opacity)
	color = color or "#000000"
	duration = duration or 2
	opacity = opacity or 1
	local data = getdata(type(player) == "string" and player
		or player:get_player_name())
	if duration == true then
		data.qty = opacity
		data.rate = 0
		data.color = color
	elseif opacity <= 0 or duration <= 0 then
		data.qty = nil
	else
		data.qty = opacity
		data.rate = opacity / duration
		data.color = color
	end
end
