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

local pl = {}
local rifts = {}
local function new_rift(p)
    return {
        from_level = br_core.get_level(p.pos),
        to_level = br_core.get_level(p.dest),
        pos = p.pos,
        dest = p.dest,
        timer = 30,
    }
end

function br_core.get_level_y(level)
    return level * br_core.level_height - br_core.offset + (br_core.level[level].base_height or 0)
end

function br_core.relocator_add_rift(pos, dest)
    rifts[#rifts+1] = new_rift({pos=pos, dest=dest})
end

local function do_rift_timers(dtime)
    for i, rift in pairs(rifts) do
        rifts[i].timer = rifts[i].timer - dtime
        if rifts[i].timer <= 0 then
            rifts[i] = nil
        end
    end
end

function br_core.relocator_get_rift_or_nil(pos)
    local level = br_core.get_level(pos)
    for i, rift in pairs(rifts) do
        if rift.from_level == level
        and vector.distance(rift.pos, pos) < 10 then
            return rift
        end
    end
end

minetest.register_node("br_core:portal_0", {
    description = "portal",
    pointable = br_core.nodes_pointable or false,
    groups = { oddly_breakable_by_hand = 2, cracky = 1, backrooms_portal = 1 },
    tiles = {{
        animation = {type="vertical_frames", aspect_w = 16, aspect_h = 16, length = 2.0},
        name = "br_portal_0.png^[multiply:#647",
    }},
    use_texture_alpha = "clip",
    sounds = {},
    paramtype = "light",
    -- sunlight_propagates = true,
    walkable = false,
	post_effect_color = {a=255, r=0x23, g=0x22, b=0x22},
})
pmb_util.register_slab("br_core:portal_0", {no_world_align=true})

minetest.register_node("br_core:portal_1", {
    description = "portal, relocates to same level",
    pointable = br_core.nodes_pointable or false,
    groups = { oddly_breakable_by_hand = 2, cracky = 1, backrooms_portal = 2 },
    tiles = {{
        animation = {type="vertical_frames", aspect_w = 16, aspect_h = 16, length = 2.0},
        name = "br_portal_0.png^[multiply:#667",
    }},
    use_texture_alpha = "clip",
    sounds = {},
    paramtype = "light",
    -- sunlight_propagates = true,
    walkable = false,
	post_effect_color = {a=255, r=0x23, g=0x22, b=0x22},
})
pmb_util.register_slab("br_core:portal_1", {no_world_align=true})

minetest.register_node("br_core:portal_1_invis", {
    description = "portal, relocates to same level",
    pointable = br_core.nodes_pointable or false,
    groups = { oddly_breakable_by_hand = 2, cracky = 1, backrooms_portal = 2 },
    drawtype = (br_core.dev_mode and "glasslike") or "airlike",
    tiles = { 'br_barrier.png^[colorize:#8ff:255' },
    use_texture_alpha = "clip",
    sounds = {},
    paramtype = "light",
    sunlight_propagates = true,
    walkable = false,
})
pmb_util.register_slab("br_core:portal_1_invis", {no_world_align=true})

minetest.register_node("br_core:portal_2", {
    description = "portal, relocates to random level",
    pointable = br_core.nodes_pointable or false,
    groups = { oddly_breakable_by_hand = 2, cracky = 1, backrooms_portal = 3 },
    tiles = {{
        animation = {type="vertical_frames", aspect_w = 16, aspect_h = 16, length = 2.0},
        name = "br_portal_0.png^[multiply:#612",
    }},
    use_texture_alpha = "clip",
    sounds = {},
    paramtype = "light",
    -- sunlight_propagates = true,
    walkable = false,
	post_effect_color = {a=255, r=0x23, g=0x22, b=0x22},
})
pmb_util.register_slab("br_core:portal_2", {no_world_align=true})



minetest.register_node("br_core:null_node", {
    description = "just to trick minetest into loading mapblocks",
    pointable = br_core.dev_mode or false,
    groups = { dig_immediate = 3 },
    drawtype = (br_core.dev_mode and "glasslike") or "airlike",
    tiles = { 'br_barrier.png^[colorize:#9f9:255' },
    use_texture_alpha = "clip",
    sounds = {},
    paramtype = "light",
    sunlight_propagates = true,
    walkable = false,
})
pmb_util.register_slab("br_core:portal_1_invis", {no_world_align=true})



local function get_level_pos(user, level)
    local y = br_spawn.get_level_y(level)
    local pos = user:get_pos()
    local rift = br_core.relocator_get_rift_or_nil(pos)
    if not rift then
        local dest = vector.new(pos.x, y, pos.z)
        dest = vector.offset(dest, (math.random() * 4 - 1)*2, 0, (math.random() * 2 - 1)*4)
        br_core.relocator_add_rift(pos, dest)
        return pos
    else
        return rift.dest
    end
end

local function relocator(user)
    local pli = br_spawn.player[user:get_player_name()]
    local level_index = (br_core.level[pli.level].index + 0) % #br_core.level_for_index + 1
    local level = br_core.level_for_index[level_index]
    local pos = get_level_pos(user, level)
    user:set_pos(pos)
end
local function same_level_relocator(user)
    local pli = br_spawn.player[user:get_player_name()]
    br_spawn.relocate_player(user, pli.level)
end
local function random_level_relocator(user)
    local pli = br_spawn.player[user:get_player_name()]
    local level_index = math.random(#br_core.level_for_index)
    local level = br_core.level_for_index[level_index]
    local pos = get_level_pos(user, level)
    user:set_pos(pos)
end

minetest.register_globalstep(function(dtime)

    -- do the timers for the rifts (which make it so you can follow people through portals)
    do_rift_timers(dtime)

    for i, player in pairs(minetest.get_connected_players() or {}) do
        local pos = vector.offset(player:get_pos(), 0, 1, 0)
        if (not minetest.is_creative_enabled(player:get_player_name())) then
            local portaltype = minetest.get_item_group(minetest.get_node(pos).name, "backrooms_portal")
            if portaltype ~= 0 then
                minetest.sound_play(("br_noclip"), {
                    gain = (br_sounds.master or 1) * 1,
                    pos = player:get_pos(),
                    pitch = (math.random()*0.2) + 0.80
                })
                if portaltype == 1 then
                    relocator(player)
                elseif portaltype == 2 then
                    same_level_relocator(player)
                elseif portaltype == 3 then
                    random_level_relocator(player)
                end
                minetest.sound_play(("br_noclip"), {
                    gain = (br_sounds.master or 1) * 1,
                    pos = player:get_pos(),
                    pitch = (math.random()*0.2) + 0.80
                })
            end
        end
    end
end)

