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

pmb_dimensions = {}
pmb_dimensions.registered_dimensions = {}
pmb_dimensions.reg_on_enter_dimension = {}
pmb_dimensions.reg_on_leave_dimension = {}
local _on_enter = pmb_dimensions.reg_on_enter_dimension
local _on_leave = pmb_dimensions.reg_on_leave_dimension

local pl = {}

function pmb_dimensions.register_dimension(param)
    param.min_x = param.min_x or -30912
    param.min_y = param.min_y or -30912
    param.min_z = param.min_z or -30912
    param.max_x = param.max_x or 30927
    param.max_y = param.max_y or 30927
    param.max_z = param.max_z or 30927
    param.sealevel = param.sealevel or -30912
    param.ore_multiplier = param.ore_multiplier or 1 -- not implemented

    pmb_dimensions.registered_dimensions[param.name] = param
end

function pmb_dimensions.get_player_dimension(player)
    if not pl[player] then pl[player] = {last_dimension="none"} end
    return pl[player].last_dimension
end

function pmb_dimensions.is_in(dimension, pos)
    local d = pmb_dimensions.registered_dimensions[dimension]
    if not d then return false end
    if d.is_full_strata then
        if pos.y <= d.max_y and pos.y >= d.min_y then
            return true
        end
    else
        if pos.y <= d.max_y and pos.y >= d.min_y
        and pos.x <= d.max_x and pos.x >= d.min_x
        and pos.z <= d.max_z and pos.z >= d.min_z then
            return true
        end
    end
    return false
end


-- register overworld
pmb_dimensions.register_dimension({
    name = "overworld",
    is_full_strata = true,
    min_y = -500,
    max_y = 2000,
    sea_level = 0,
})


function pmb_dimensions.register_on_enter_dimension(dimension, func)
    if not _on_enter[dimension] then _on_enter[dimension] = {} end
    _on_enter[dimension][#_on_enter[dimension]+1] = func
end
function pmb_dimensions.register_on_leave_dimension(dimension, func)
    if not _on_leave[dimension] then _on_leave[dimension] = {} end
    _on_leave[dimension][#_on_leave[dimension]+1] = func
end


function pmb_dimensions.on_enter_dimension(dimension, player)
    for i, func in ipairs(_on_enter[dimension] or {}) do
        func(player)
    end
end
function pmb_dimensions.on_leave_dimension(dimension, player)
    for i, func in ipairs(_on_leave[dimension] or {}) do
        func(player)
    end
end


local t = 1
local on_globalstep = function(dtime)
if t > 0 then t = t - dtime return end t = 1

for i, player in ipairs(minetest.get_connected_players()) do
    if not pl[player] then pl[player] = {last_dimension="none"} end
    local pos = player:get_pos()
    if not pmb_dimensions.is_in(pl[player].last_dimension, pos) then
        for dimensionname, def in pairs(pmb_dimensions.registered_dimensions) do
            if dimensionname ~= pl[player].last_dimension
            and pmb_dimensions.is_in(dimensionname, pos) then
                pmb_dimensions.on_leave_dimension(pl[player].last_dimension)
                pl[player].last_dimension = dimensionname
                pmb_dimensions.on_enter_dimension(dimensionname)
                return
            end
        end
    end
end
end
minetest.register_globalstep(on_globalstep)
