local S = minetest.get_translator("hbhunger")

if minetest.settings:get_bool("enable_damage") then

hbhunger = {}
hbhunger.food = {}

-- HUD statbar values
hbhunger.hunger = {} --players current satiation
hbhunger.hunger_out = {} --???
hbhunger.max = {} --players max satiation

-- Count number of poisonings a player has at once
hbhunger.poisonings = {}

-- HUD item ids
local hunger_hud = {}

hbhunger.HUD_TICK = 0.1

--Some hunger settings
hbhunger.exhaustion = {} -- Exhaustion is experimental!

hbhunger.HUNGER_TICK = 800 -- time in seconds after that 1 hunger point is taken
hbhunger.EXHAUST_DIG = 3  -- exhaustion increased this value after digged node
hbhunger.EXHAUST_PLACE = 1 -- exhaustion increased this value after placed
hbhunger.EXHAUST_MOVE = 0.3 -- exhaustion increased this value if player movement detected
hbhunger.EXHAUST_LVL = 160 -- at what exhaustion player satiation gets lowerd


--load custom settings
local set = io.open(minetest.get_modpath("hbhunger").."/hbhunger.conf", "r")
if set then
   dofile(minetest.get_modpath("hbhunger").."/hbhunger.conf")
   set:close()
end

local function custom_hud(player)
   local player_attr = player:get_meta()
   local name = player:get_player_name()
   hb.init_hudbar(player, "satiation", tonumber(hbhunger.hunger[name]), tonumber(hbhunger.max[name]))
end

dofile(minetest.get_modpath("hbhunger").."/hunger.lua")

-- register satiation hudbar
hb.register_hudbar("satiation", 0xFFFFFF, S("Satiation"), {icon = "hbhunger_icon.png", bgicon = "hbhunger_bgicon.png", bar = "hbhunger_bar.png" }, 20, 30, false, nil, { format_value = "%.1f", format_max_value = "%d" })

-- update hud elements if value has changed
local function update_hud(player, max)
   local name = player:get_player_name()
 --hunger
   local h_out = tonumber(hbhunger.hunger_out[name])
   local h = tonumber(hbhunger.hunger[name])
   local max = tonumber(hbhunger.max[name])
   if h_out ~= h or max then
      hbhunger.hunger_out[name] = h
      hb.change_hudbar(player, "satiation", h, max)
   end
end

hbhunger.save_hunger = function(player)
   local name = player:get_player_name()
   local player_attr = player:get_meta()
   local value = hbhunger.hunger[name]
   if not value then return nil end
   local max_sat = hbhunger.max[name]
   if value > max_sat then value = max_sat end
   if value < 0 then value = 0 end
   player_attr:set_int('satiation', value)
   player_attr:set_int('max_satiation', max_sat)
   return true
end

minetest.register_on_joinplayer(function(player)
   local name = player:get_player_name()
   local player_attr = player:get_meta()
   local sat = player_attr:get_int('satiation')
   local max_sat = player_attr:get_int('max_satiation')
   if max_sat == 0 then
      max_sat = 30
   end
   hbhunger.hunger[name] = sat
   hbhunger.max[name] = max_sat
   hbhunger.hunger_out[name] = hbhunger.hunger[name]
   hbhunger.exhaustion[name] = 0
   hbhunger.poisonings[name] = 0
   custom_hud(player)
end)

minetest.register_on_respawnplayer(function(player)
   local name = player:get_player_name()
   local max = hbhunger.max[name]
   hbhunger.hunger[name] = max/2
   hbhunger.save_hunger(player)
   hbhunger.exhaustion[name] = 0
end)

local main_timer = 0
local timer = 0
local timer2 = 0

minetest.register_globalstep(function(dtime)
   main_timer = main_timer + dtime
   timer = timer + dtime
   timer2 = timer2 + dtime
   if main_timer > hbhunger.HUD_TICK or timer > 4 or timer2 > hbhunger.HUNGER_TICK then
      if main_timer > hbhunger.HUD_TICK then main_timer = 0 end
      for _, player in ipairs(minetest.get_connected_players()) do
         local name = player:get_player_name()
         local h = tonumber(hbhunger.hunger[name])
         local max = hbhunger.max[name]
         local max_hp = player:get_properties().hp_max
         local hp = player:get_hp()
         if timer > 4 then
            -- heal player by 1 hp
            if h > max/4 and hp > 0 and hp < max_hp and player:get_breath() > 0 then
               player:set_hp(hp+1)
               hbhunger.hunger[name] = h-1
               -- or damage player by 1 hp if satiation is < 2 (of 30)
               elseif h <= 1 then
                  if hp-1 >= 0 then player:set_hp(hp-1) end
               end
            end
            -- lower satiation by 1 point after xx seconds
            if timer2 > hbhunger.HUNGER_TICK then
               if h > 0 then
                  h = h-1
                  hbhunger.hunger[name] = h
                  hbhunger.save_hunger(player)
               end
            end

            -- update all hud elements
            update_hud(player)

            local controls = player:get_player_control()
            -- Determine if the player is walking
            if controls.up or controls.down or controls.left or controls.right then
               hbhunger.handle_node_actions(nil, nil, player)
            end
         end
      end
      if timer > 4 then timer = 0 end
      if timer2 > hbhunger.HUNGER_TICK then timer2 = 0 end
   end)
end
