-- "I'll stop calling it Minetest when it stops being one."
minetest = core

artifact = {
    -- This toggles a lot of things, including whether initialization takes place,
    -- whether nodes can be pointed, and whether the player is permitted to
    -- bypass certain restrictions imposed by the story.
    debug = false,
    colors = {
        gold = "#faf17a",
        red = "#e94f3f",
        green = "#6aae68",
        blue = "#789fd8"
    }
}

-- For brevity.
function include(file)
    dofile(minetest.get_modpath(minetest.get_current_modname()).."/"..file)
end

function enum(cases)
    local out = {}
    local i = 0
    for _, x in ipairs(cases) do
        out[x] = i
        i = i +1
    end
    return out
end

say = minetest.chat_send_all

function extend(dst, src)
    for k, v in pairs(src) do
        dst[k] = v
    end
    return dst
end

-- Some kind of promise API. (Forget about async-await, though.)
function Promise(fn)
    local p = {resolved = false}
    p.resolve = function(...)
        if p.resolved then return end
        p.resolved = true
        if p.after then p.after(...) end
    end
    fn(p.resolve)
    return {
        after = function(fn)
            p.after = fn
        end
    }
end


function artifact.play_sound(def)
    def.max_hear_distance = def.range
    --def.gain = nil
    if def.pos then
        for _, m in pairs(artifact.players) do
            local dist = m.pos:distance(def.pos)
            if dist <= (def.range or 32) and m.name ~= def.exclude_player and not (def.to_player and m.name ~= def.to_player) then
                def.to_player = m.name
                def.gain = (def.gain or 1) *(1 -math.sqrt(dist /(def.range or 32)))
                minetest.sound_play(def, def)
            end
        end
    else
        minetest.sound_play(def.name, def)
    end
end


-- HACK: Lookup table for getting a rotation from a
-- facedir (because Minetest doesn't have any way
-- to get this information normally)
local facedir_rotations = {
    -- +Y
    [0] = vector.new(0, 0, 0),
    [1] = vector.new(0, math.pi * 1.5, 0),
    [2] = vector.new(0, math.pi * 1.0, 0),
    [3] = vector.new(0, math.pi * 0.5, 0),
    -- +Z
    [4] = vector.new(math.pi * 1.5, 0, 0),
    [5] = vector.new(0, math.pi * 1.5, math.pi * 1.5),
    [6] = vector.new(math.pi * 0.5, math.pi * 1.0, 0),
    [7] = vector.new(0, math.pi * 0.5, math.pi * 0.5),
    -- -Z
    [8] = vector.new(math.pi * 0.5, 0, 0),
    [9] = vector.new(0, math.pi * 1.5, math.pi * 0.5),
    [10] = vector.new(math.pi * 1.5, math.pi * 1.0, 0),
    [11] = vector.new(0, math.pi * 0.5, math.pi * 1.5),
    -- +X
    [12] = vector.new(0, 0, math.pi * 0.5),
    [13] = vector.new(math.pi * 1.5, math.pi * 1.5, 0),
    [14] = vector.new(0, math.pi * 1.0, math.pi * 1.5),
    [15] = vector.new(math.pi * 0.5, math.pi * 0.5, 0),
    -- -X
    [16] = vector.new(0, 0, math.pi * 1.5),
    [17] = vector.new(math.pi * 0.5, math.pi * 1.5, 0),
    [18] = vector.new(0, math.pi * 1.0, math.pi * 0.5),
    [19] = vector.new(math.pi * 1.5, math.pi * 0.5, 0),
    -- -Y
    [20] = vector.new(0, 0, math.pi * 1.0),
    [21] = vector.new(0, math.pi * 0.5, math.pi * 1.0),
    [22] = vector.new(0, math.pi * 1.0, math.pi * 1.0),
    [23] = vector.new(0, math.pi * 1.5, math.pi * 1.0),
}
function artifact.facedir_to_rotation(facedir)
    return facedir_rotations[facedir] or minetest.facedir_to_dir(facedir):dir_to_rotation()
end


minetest.register_lbm{
    name = ":artifact:on_load",
    nodenames = {"group:call_on_load"},
    action = function(pos, node)
        minetest.registered_nodes[node.name].on_load(pos)
    end
}

if artifact.debug then
    minetest.register_chatcommand("chest", {
        func = function(name, args)
            minetest.registered_chatcommands.giveme.func(name, "chest_with_everything:chest")
        end
    })
end

