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


pmb_inventory.player = {}

local me = pmb_inventory.player

function pmb_inventory.get_itemslot_array(x, y, width, height, hotbar)
    local ret = ""
    local o = 0.250
    local p = 0.185
    for k = 0, height - 1, 1 do
        if hotbar and k == height - 1 then y = y + hotbar end
        for i = 0, width - 1, 1 do
            ret = ret .."image["..(x+i+0.025 - o/2)..","..(y+k-0.0 - p/2)..";"..(1+o)..","..(1+p)..";pmb_inv_itemslot_bg.png^[opacity:150]"
        end
    end
    return ret
end

me.p = {}

me.width = 10
me.height = 4

local o_ = {x=6, y=7}
local function p(x,y)
    return tostring(x+o_.x) .. "," .. tostring(y + o_.y)
end

function pmb_inventory.player.init_hotbar(player)
    player:hud_set_hotbar_itemcount(me.width)
    player:hud_set_hotbar_selected_image("pmb_inv_hotbar_select.png^[colorize:#603866:256")
    player:hud_set_hotbar_image("white.png^[colorize:#81507b:256")
    -- player:hud_set_flags({hotbar=false})
    me.p[player] = {}
end

function pmb_inventory.player.set_size(width, height)
    me.width = width
    me.height = height
end

local function get_formspec(offset, size)
    if offset==nil then offset = {x=6, y=7} end
    if size==nil then size = {x=13,y=5} end
    return (
        "bgcolor[#00000000]"..
        pmb_inventory.get_itemslot_array(offset.x, offset.y, me.width, me.height, 0.3)..
        "list[current_player;main;"..tostring(offset.x)..","..tostring(offset.y)..     ";"..(me.width)..","..(me.height-1)..";10]"..
        "list[current_player;main;"..tostring(offset.x)..","..tostring(0.3+offset.y+me.height-1)..";"..(me.width)..","..(1)..";]"..
        "listcolors[#66504f00;#554a6440]"..
        pmb_inventory.player.get_armor({x=offset.x+10.3,y=offset.y+0})..
        pmb_inventory.player.get_accessories({x=offset.x+11.3,y=offset.y+0})..
        "background["..(offset.x-0.5)..","..(offset.y-0.5)..";"..(size.x)..","..(size.y)..";pmb_inv_bg.png^[opacity:200]"
    )
end
pmb_inventory.player.get_formspec = get_formspec

function pmb_inventory.player.get_armor(o)
    return (
        pmb_inventory.get_itemslot_array(o.x, o.y, 1, 4)..
        "list[current_player;armor;"..(o.x)..","..(o.y)..";1,4;]"..
        "image["..(o.x)..","..(o.y+0)..";1,1;pmb_inv_head.png^[colorize:#33333344:255]"..
        "image["..(o.x)..","..(o.y+1)..";1,1;pmb_inv_torso.png^[colorize:#33333344:255]"..
        "image["..(o.x)..","..(o.y+2)..";1,1;pmb_inv_legs.png^[colorize:#33333344:255]"..
        "image["..(o.x)..","..(o.y+3)..";1,1;pmb_inv_boots.png^[colorize:#33333344:255]"
    )
end

function pmb_inventory.player.get_accessories(o)
    return (
        pmb_inventory.get_itemslot_array(o.x, o.y, 1, 1)..
        "list[current_player;accessories;"..(o.x)..","..(o.y)..";1,1;]"..
        -- "list[current_player;accessories;"..(o.x+1)..","..(o.y + 0)..";1,4;]"..
        "image["..(o.x)..","..(o.y+0)..";1,1;pmb_inv_backpack.png^[colorize:#33333344:255]"
        -- "image["..(o.x)..","..(o.y+0)..";1,1;pmb_inv_ring.png^[colorize:#33333344:255]".. -- left out for now since there probably won't even be items for this
        -- "image["..(o.x)..","..(o.y+1)..";1,1;pmb_inv_ring.png^[colorize:#33333344:255]"..
        -- "image["..(o.x)..","..(o.y+2)..";1,1;pmb_inv_necklace.png^[colorize:#33333344:255]"
    )
end

local function get_craft_menu(player, method)
    local crafting_disabled = (minetest.get_modpath("pmb_gamemodes")) and not pmb_gamemodes.player_has_tag(player, "crafting")
    return (
        "size[24.00,12.0]"..
        ((crafting_disabled and "") or pmb_inventory.tcraft_get_formspec(player, method))..
        pmb_inventory.player.get_formspec({x=o_.x+0,y=o_.y+-0.0}))
end
pmb_inventory.player.get_craft_menu = get_craft_menu

pmb_inventory.player.get_craft_menu = pmb_inventory.player.get_craft_menu

local pl = {}
local _t = 0.1
minetest.register_globalstep(function(dtime)
    _t = _t - dtime
    if _t > 0 then return end
    _t = 0.2

    for i, player in ipairs(minetest.get_connected_players()) do
        local new_spec = ""
        repeat
            if (minetest.get_modpath("pmb_gamemodes")) and not pmb_gamemodes.player_has_tag(player, "inventory") then
                pl[player] = new_spec
                player:set_inventory_formspec(new_spec)
                break
            end

            new_spec = pmb_inventory.player.get_craft_menu(player)
            if string.len(new_spec) ~= string.len(pl[player] or "") then
                pl[player] = new_spec
                player:set_inventory_formspec(new_spec)
                break
            end
        until true
    end
end)

minetest.register_on_joinplayer(function(player, last_login)
    player:set_inventory_formspec(pmb_inventory.player.get_craft_menu(player, "normal"))
end)


-- represents the inventory WITH the crafting menu
function pmb_inventory.player.set_craft_menu_builder(funcref)
    pmb_inventory.player.get_craft_menu = funcref
end
-- represents the inventory WITH the crafting menu
function pmb_inventory.player.unset_craft_menu_builder(funcref)
    pmb_inventory.player.get_craft_menu = get_craft_menu
end

-- represents the inventory without the crafting menu
function pmb_inventory.player.set_inventory_menu_builder(funcref)
    pmb_inventory.player.get_formspec = funcref
end
-- represents the inventory without the crafting menu
function pmb_inventory.player.unset_inventory_menu_builder(funcref)
    pmb_inventory.player.get_formspec = get_formspec
end


pmb_inventory.player.inventory_slot_groups = {}

function pmb_inventory.player.bind_group_to_inventory_slot(group, listname, listindex)
    local invslots = pmb_inventory.player.inventory_slot_groups
    if not invslots[listname] then invslots[listname] = {} end
    invslots[listname][listindex] = group
end

pmb_inventory.player.bind_group_to_inventory_slot("armor_head", "armor", 1)
pmb_inventory.player.bind_group_to_inventory_slot("armor_torso", "armor", 2)
pmb_inventory.player.bind_group_to_inventory_slot("armor_legs", "armor", 3)
pmb_inventory.player.bind_group_to_inventory_slot("armor_boots", "armor", 4)
pmb_inventory.player.bind_group_to_inventory_slot("accessory", "accessories", 1)


local function fix_bad_inventory_action_args(player, action, inventory, inventory_info)
    local info = {}
    -- deal with the silly way this callback gives its parameters
    if (action == "move") then
        info.to_list = inventory_info.to_list
        info.to_index = inventory_info.to_index
        info.from_list = inventory_info.from_list
        info.from_index = inventory_info.from_index
        info.from_stack = inventory:get_stack(inventory_info.from_list, inventory_info.from_index)
        info.to_stack = inventory:get_stack(inventory_info.to_list, inventory_info.to_index)
    elseif (action == "put") then
        info.to_list = inventory_info.listname
        info.to_index = inventory_info.index
        info.to_stack = inventory_info.stack
    elseif (action == "take") then
        info.from_list = inventory_info.listname
        info.from_index = inventory_info.index
        info.to_stack = inventory_info.stack
    end
    return info
end

minetest.register_allow_player_inventory_action(function(player, action, inventory, inventory_info)
    local to_list = inventory_info.listname or inventory_info.to_list

    -- nothing is defined for this list name so just forget about it
    if not pmb_inventory.player.inventory_slot_groups[to_list] then return end

    local info = fix_bad_inventory_action_args(player, action, inventory, inventory_info)
    if not info then return end
    local slotgroups = pmb_inventory.player.inventory_slot_groups[to_list]

    -- nothing is defined for this index so just forget about it
    if not slotgroups[info.to_index] then return end

    -- now test if it has the group
    if minetest.get_item_group(info.from_stack:get_name(), slotgroups[info.to_index]) > 0 then return end

    -- return 0 will prevent any item from being moved
    return 0
end)

