
local mod_name = core.get_current_modname()
local mod_path = core.get_modpath(mod_name)
local save_path = core.get_worldpath()
local S = core.get_translator(core.get_current_modname())

aom_spawn = {}

local world_data = {
    spawn_pos = false,
    spawn_near_death = false,
    range = 50,
    players = {}
}

local function save_spawn_data()
    local data = core.serialize(world_data)
    local file = io.open(save_path.."/aom_spawn.txt", "w")
    if not file then return end
    file:write(data)
    file:close()
end
local function load_spawn_data()
    local file = io.open(save_path.."/aom_spawn.txt", "r")
    if not file then return end
    local data = core.deserialize(file:read("a"), true)
    file:close()
    for key, val in pairs(world_data) do
        world_data[key] = data[key] or world_data[key]
    end
end

function aom_spawn.set_spawn(pos)
    world_data.spawn_pos = vector.copy(pos)
    save_spawn_data()
end
function aom_spawn.set_spawn_for(player, pos)
    world_data.players[player:get_player_name()] = (pos and vector.copy(pos)) or nil
    save_spawn_data()
end

core.register_privilege("aom_spawn", {
    description = S("Allows a player to set the world spawn"),
    give_to_singleplayer = false
})

core.register_chatcommand("spawn", {
    params = S("/spawn [set | setplayer (player name) | clearplayer (player name)]"),
    description = S("Sets the world spawn to the current position of the player"),
    privs = {aom_spawn = true},
    func = function(name, param)
        local player = core.get_player_by_name(name)
        local parse = string.split(param, " ")
        if parse[1] == "set" then
            if player then
                local p = player:get_pos()
                aom_spawn.set_spawn(p)
                return true, S("Set spawn to x"..p.x..", y"..p.y..", z"..p.z)
            end
        elseif parse[1] == "setplayer" then
            player = core.get_player_by_name(parse[2])
            if player then
                local p = player:get_pos()
                aom_spawn.set_spawn_for(player, p)
                -- TL: @1 is player name ("Greg"), @2-4 are numbers (coordinates)
                return true, S("Set @1's spawn to x@2, y@3, z@4.", parse[2], p.x, p.y, p.z)
            end
        elseif parse[1] == "clearplayer" then
            player = core.get_player_by_name(parse[2])
            if player then
                aom_spawn.set_spawn_for(player, nil)
                -- TL: @1 is player name ("Greg")
                return true, S("Removed @1's spawn; they will now respawn at worldspawn.", parse[2])
            end
        elseif param == "" then
            aom_spawn.respawn_player(player)
        end
        return false, S("Error: Invalid. Use /spawn set or /spawn setplayer myname")
    end
})

-- make this find a nearby location instead of a fixed one eventually
function aom_spawn.get_spawn_pos(player)
    local name = player:get_player_name()
    if world_data.players[name] then
        return world_data.players[name]
    end
    if world_data.spawn_pos then
        return world_data.spawn_pos
    end
    return false
end

function aom_spawn.respawn_player(player)
    local r = aom_spawn.get_spawn_pos(player)
    if r then
        player:set_pos(r)
        return true
    else return false end
end

core.register_on_respawnplayer(aom_spawn.respawn_player)

load_spawn_data()
