bb_noafk = {}

bb_noafk.timeout = 60 -- players may not AFK for this many seconds, or they will be kicked
bb_noafk.afkness_threshold = 40 -- how AFK does a person have to be to be considerd AFK (this is avery arbitrary value)

bb_noafk.valid_keys = {'left','down','right','up'} -- what keys count as "doing something" when held

local player_afk_data = {} -- stores how long players have been AFK for

-- determines whether a player is AFK
-- this function is based on how long a player has been holding each key, meaning holding a key for 
-- a long time will slowly start to consider it an "activity" less and less,
-- until eventually, the key is ignored for being held down too long.
local function is_afk (player, name)
	local controls = player:get_player_control()
	local afkness = 0
	
	for _, key in pairs(bb_noafk.valid_keys) do
		if controls[key] then
			afkness = afkness + player_afk_data[name].usages[key]
			player_afk_data[name].usages[key] = math.min(player_afk_data[name].usages[key] + 0.1, 10)
		else
			player_afk_data[name].usages[key] = 0 
			afkness = afkness + 10
		end
	end
	
	if controls.jump or controls.LMB then
		afkness = afkness - 10
	end
	
	return afkness >= bb_noafk.afkness_threshold
end

-- manufactures new usage data based on the configured keys
local function get_usages ()
	local r = {}
	
	for _, key in pairs(bb_noafk.valid_keys) do
		r[key] = 0
	end
	
	return r
end

-- update AFK check data
minetest.register_globalstep(function(dtime)
    for _, player in pairs(minetest.get_connected_players()) do
        local meta = player:get_meta()
        local p_name = player:get_player_name()

        if bb_loop.gamestate == "running" and meta:get_string("status") == "playing" and minetest.get_player_privs(p_name).server ~= true then -- only takes effect when fully in play
					if player_afk_data[p_name] and player_afk_data[p_name].time then
            if player_afk_data[p_name].time > bb_noafk.timeout then
							minetest.kick_player(p_name, 'Kicked for idling. Please re-join when ready!')
							player_afk_data[p_name] = nil -- delete unused entry
						else
							if is_afk(player, p_name) then
								player_afk_data[p_name].time = player_afk_data[p_name].time + dtime
							else
								player_afk_data[p_name].time = 0
							end
						end
					else
						player_afk_data[p_name] = { -- create an entry for the player if one is not present
							time = 0,
							usages = get_usages()
						}
					end
        end
    end
end)
