local mod_name = minetest.get_current_modname()
local mod_path = minetest.get_modpath(mod_name)
local S = minetest.get_translator(mod_name)

local MAX_WEAR = 65534

pmb_combat.cooldown = {}

pmb_combat.cooldown.registered_items = {}
local reg_items = pmb_combat.cooldown.registered_items

local stacks = {}
local has_registered_items = false



local function clamp(a,min,max)
    return math.min(math.max(a, min),max)
end


-- un-wears a tool and returns wear in seconds
function pmb_combat.cooldown.wear_tick(itemstack, max_sec, dtime)
    -- instant if 0, also avoids x/0
    if max_sec == 0 then
        itemstack:set_wear(0)
        return itemstack
    end

    local wear = itemstack:get_wear()
    local new_wear = clamp(wear - (MAX_WEAR / max_sec) * dtime, 0, MAX_WEAR)
    itemstack:set_wear(new_wear)
    return itemstack
end


-- returns true if it can be used and is in end of windup state
function pmb_combat.cooldown.is_ready(itemstack)
    local def = reg_items[itemstack:get_name()]
    local windup = itemstack:get_meta():get_string("_windup_complete") ~= "true"
    if (windup or def.windup == 0) and itemstack:get_wear() == 0 then return true
    else return false end
end


-- sets back to max wear so it can count back up again
function pmb_combat.cooldown.wear_start(itemstack, mode)
    itemstack:set_wear(MAX_WEAR)
    itemstack:get_meta():set_string("_mode", mode)
    return itemstack
end


-- just tests if can use, based on wear
function pmb_combat.cooldown.can_use(itemstack)
    return itemstack:get_wear() == 0
end


-- returns "windup" or "cooldown" or ""
function pmb_combat.cooldown.get_mode(itemstack)
    return itemstack:get_meta():get_string("_mode") or ""
end


-- tells the system to track this item
function pmb_combat.cooldown.register_cooldown(name, def)
    has_registered_items = true
    reg_items[name] = def
end
--[[ example:
pmb_combat.cooldown.register_cooldown(name, {
    name = "pmb_fenn:spear",
    cooldown = 3,
    windup = 0.5,
    on_windup_complete = function(player, itemstack) return itemstack end,
    on_cooldown_complete = function(player, itemstack) return itemstack end,
})
]]


-- calls the appropriate trigger functions when cooldown or windup complete
function pmb_combat.cooldown.handle_triggers(player, itemstack, mode)
    local def = reg_items[itemstack:get_name()]
    if not def then
        minetest.chat_send_all("ERROR NO COOLDOWN DEFINITION FOR " .. itemstack:get_name())
        return itemstack
    end
    if mode == "windup" then
        itemstack:get_meta():set_string("_windup_complete", "true")
        if def.on_windup_complete then
            itemstack = def.on_windup_complete(player, itemstack)
        end
    elseif mode == "cooldown" then
        itemstack:get_meta():set_string("_windup_complete", "")
        if def.on_cooldown_complete then
            itemstack = def.on_cooldown_complete(player, itemstack)
        end
    end
    return itemstack
end


-- update all items registered, by going through entire inventory
function pmb_combat.cooldown.update_all_in_inventory(player, dtime)
    local inv = player:get_inventory()
    for i = 0, inv:get_size("main") do
        local itemstack = inv:get_stack("main", i)
        local stackname = itemstack:get_name()
        if reg_items[stackname] and itemstack:get_wear() > 0 then
            local mode = itemstack:get_meta():get_string("_mode") --"windup" or "cooldown"
            if mode ~= "windup" then mode = "cooldown" end
            itemstack = pmb_combat.cooldown.wear_tick(itemstack, reg_items[stackname][mode] or 1, dtime)
            if itemstack:get_wear() == 0 then
                itemstack = pmb_combat.cooldown.handle_triggers(player, ItemStack(itemstack), mode) or itemstack
            end
            inv:set_stack("main", i, itemstack)
        end
    end
end


minetest.register_globalstep(function(dtime)
    -- don't bother if there are no items registered, save cpu
    if not has_registered_items then return end
    for i, player in ipairs(minetest.get_connected_players()) do
        pmb_combat.cooldown.update_all_in_inventory(player, dtime)
    end
end)





minetest.register_tool("pmb_combat:cooldown_debug", {
    description = S("For debug"),
    inventory_image = "pmb_wooden_pickaxe.png^[transformR180",
    groups = { not_in_creative_inventory = 1 },
    on_secondary_use = function(itemstack, user, pointed_thing)
        if pmb_combat.cooldown.can_use(itemstack) then
            itemstack = pmb_combat.cooldown.wear_start(itemstack, "windup")
        end
        return itemstack
    end,
})

pmb_combat.cooldown.register_cooldown("pmb_combat:cooldown_debug", {
    cooldown = 3,
    windup = 0.3,
    on_windup_complete = function(player, itemstack)
        return itemstack
    end,
    on_cooldown_complete = function(player, itemstack)
        return itemstack
    end,
})


