
br_core.loot = {}
br_core.loot.table = {}



function br_core.get_loot_table_default()
    return {
        node_names = {"br_core:loot_crate"},
        on_generate = function(pos, level, tier)
            return false
        end,
        max_items = 4,
        items = {
            {
                items = {'br_core:flashlight 1'},
                rarity = 200000
            },
        }
    }
end

function br_core.set_loot_table(level, tier, def)
    local ta = br_core.loot.table
    if not ta[level] then ta[level] = {} end
    ta[level][tier] = def
end

local loot_table_warnings = {}
function br_core.get_loot_table(level, tier)
    local loot_table = (br_core.loot.table[level] and br_core.loot.table[level][tier])
    if (not loot_table) then
        loot_table = br_core.get_loot_table_default()
        if (not loot_table_warnings[level..":"..tier]) then
            loot_table_warnings[level..":"..tier] = true
            minetest.log("warning", "No loot table for level "..level..":"..tier.."! Using default.")
        end
    end
    return loot_table
end

function br_core.get_loot(level, tier, seed)
    local loot_table = br_core.get_loot_table(level, tier)
    local loot_list = {}
    local itemcount = 0
    if loot_table.chance_of_nothing and math.random() < loot_table.chance_of_nothing then
        return
    end
    for i, def in pairs(loot_table.items) do
        math.randomseed((seed) + i)
        if ((not def.rarity) or math.random(1, def.rarity) == 1)
        and itemcount < (loot_table.max_items or 9999) then
            itemcount = itemcount + 1
            for k, itemstring in pairs(def.items) do
                loot_list[#loot_list+1] = itemstring
            end
        end
    end
    math.randomseed(os.time())
    return loot_list
end

function br_core.give_loot(loot_list, inventory, seed)
    if not loot_list then
        minetest.log("warning", "no loot list found")
        return
    end
    for i, itemstring in pairs(loot_list) do
        local stack = ItemStack(itemstring)
        local invsize = inventory:get_size("main")
        for k=0, invsize - 1 do
            math.randomseed((seed) + k + 394)
            local index = math.random(1, invsize)
            local to_stack = inventory:get_stack("main", (index + k) % invsize + 1)
            if (not to_stack) or to_stack:get_count() < 1 then
                inventory:set_stack("main", (index + k) % invsize + 1, stack)
                break
            end
        end
    end
end

function br_core.place_loot_at(pos, level, tier)
    if not br_core.flags.loot_crates then
        minetest.set_node(pos, {name="air"})
        return false
    end
    local loot_table = br_core.get_loot_table(level, tier)

    if loot_table.node_names then
        local ri = math.random(0, #loot_table.node_names-1) + 1
        minetest.swap_node(pos, {name=loot_table.node_names[ri]})
    end

    local skip_generation = (loot_table.on_generate and loot_table.on_generate(pos, level, tier)) or false
    if skip_generation then
        return
    end

    local loot_list = br_core.get_loot(level, tier, math.floor((pos.x * pos.z * pos.y) / 3))
    local inv = minetest.get_meta(pos):get_inventory()
    br_core.give_loot(loot_list, inv, math.floor((pos.x * pos.z * pos.y) / 3))
end

br_core.set_loot_table(167, 0, {
    -- if defined, a random node from this list is chosen
    node_names = {"br_core:loot_crate"},
    -- run before loot added, if return true, no loot added
    on_generate = function(pos, level, tier)
        return false
    end,
    max_items = 4,
    items = {
        {
            items = {'br_core:flashlight 1'},
            rarity = 20
        },
    },
    -- if defined, this will mean only one of these nodes and its loot will be chosen
    -- nodes = {
    --     [1] = {
    --         rarity = 1,
    --         node_name = "br_core:loot_crate_white",
    --         items = {
    --             {
    --                 items = {'br_core:flashlight 1'},
    --                 rarity = 20
    --             },
    --         },
    --     }
    -- }
})

local color = { main="#756052", alt="#fff",    outline="#877263", highlight="#877767", lowlight="#655052", raw="#6d6d73"}
minetest.register_node("br_core:loot_crate", {
    description = "br_core:loot_crate\nThe actual storage part of the loot system",
    pointable = true,
    groups = { solid = 1, full_solid = 1, loot_crate = 1, oddly_breakable_by_hand = 2, cracky = 1 },
    tiles = {{
        name = "(br_meta_blank.png^[colorize:"..(color.main)..":255"..
        "^(br_meta_overlay_dirt_3.png^[multiply:#753^[opacity:50))"..
        "^(br_meta_overlay_crisscross_0.png^[multiply:"..color.outline.."".."^[opacity:80)"..
        -- "^(br_meta_overlay_crisscross_1.png^[multiply:"..color.outline.."".."^[opacity:255)"..
        "^(br_meta_overlay_crisscross_2.png^[multiply:"..color.outline..")",
        align_style = "world",
        scale = 16,
    }},
    sounds = br_sounds.default(),
    light_source = (br_core.fullbright) or 0,
})

minetest.register_node("br_core:loot_crate_white", {
    description = "br_core:loot_crate\nThe actual storage part of the loot system",
    pointable = true,
    groups = { solid = 1, full_solid = 1, loot_crate = 1, oddly_breakable_by_hand = 2, cracky = 1 },
    tiles = {{
        name = "(br_meta_blank.png^[colorize:#eee:255"..
        "^(br_meta_overlay_dirt_3.png^[multiply:#ddd^[opacity:50))"..
        "^(br_meta_overlay_crisscross_0.png^[multiply:#fff^[opacity:80)"..
        -- "^(br_meta_overlay_crisscross_1.png^[multiply:"..color.outline.."".."^[opacity:255)"..
        "^(br_meta_overlay_crisscross_2.png^[multiply:#fff)",
        align_style = "world",
        scale = 16,
    }},
    sounds = br_sounds.default(),
    light_source = (br_core.fullbright) or 0,
})




function br_core.loot_crate_init(pos)
    local node = minetest.get_node(pos)
    local def = minetest.registered_nodes[node.name]
    minetest.set_node(pos, {name="br_core:loot_crate"})
    local meta = minetest.get_meta(pos)
    local inv = meta:get_inventory()
    inv:set_size("main", 4*4)
    meta:set_string("formspec",
        "formspec_version[3]"..
        "size[9,9]"..
        "background[0,0;9,9;br_crate_background.png]"..
        "bgcolor[#ffffff00]"..
        "listcolors[#f7ebeb20;#f7ebeb00]"..
        "list[context;main;2.1,1;4,4;]"..
        br_core.get_inventory_list({x=0.9,y=7})
    )
    meta:set_string("infotext", "Loot Crate")
    local level = br_core.get_level(pos)

    br_core.place_loot_at(pos, level, (def._loot_tier or 0))
end


for i, c in pairs({
    "#453e5e",
    "#7e5499",
    "#d9479e",
    "#e67d6c",
    "#f5ce7c",
}) do
    minetest.register_node("br_core:loot_area_"..(i-1), {
        description = "br_core:loot_area_"..(i-1).."\nOffers a place to spawn loot",
        pointable = br_core.dev_mode or false,
        groups = { not_in_creative_inventory = 1, clear_after_mapgen = 1, dig_immediate = 3 },
        drawtype = (br_core.dev_mode and "glasslike") or "glasslike",
        tiles = { 'br_loot_area.png^[multiply:'..c },
        use_texture_alpha = "clip",
        sounds = {},
        paramtype = "light",
        sunlight_propagates = true,
        walkable = false,
        drop = "br_core:loot_area_0",
        _loot_tier = i-1,
        on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
            local k = minetest.registered_nodes[node.name]._loot_tier or 0
            node.name = "br_core:loot_area_"..((k+1)%5)
            minetest.set_node(pos, node)
        end,
    })
    minetest.register_node("br_core:loot_crate_"..(i-1), {
        description = "br_core:loot_crate_"..(i-1),
        pointable = br_core.dev_mode or false,
        groups = { not_in_creative_inventory = 1, init_loot_crate = 1, dig_immediate = 3 },
        drawtype = (br_core.dev_mode and "glasslike") or "glasslike",
        tiles = { 'br_loot_area.png^[multiply:'..c },
        use_texture_alpha = "clip",
        sounds = {},
        paramtype = "light",
        sunlight_propagates = true,
        walkable = false,
        _loot_tier = i-1,
    })
    br_core.register_on_generate_node("br_core:loot_crate_"..(i-1), br_core.loot_crate_init)
end

-- minetest.register_abm({
--     nodenames = {"group:init_loot_crate"},
--     interval = 1,
--     chance = 1,
--     action = function(pos, node)
--     end,
-- })
