
aom_transit.transit_spire = {}

local pl = {}
function aom_transit.transit_spire.check_player(player)
    local pi = pl[player]
    if not pi then pi = {}; pl[player] = pi end
	if not pi.locations then
		pi.locations = aom_transit.transit_core.load_touched_locations(player)
        pi.locations_count = 0
        for hash, def in pairs(pi.locations) do
            pi.locations_count = pi.locations_count + 1
        end
	end
    return pi
end local check_player = aom_transit.transit_spire.check_player

local function log(t)
    do return end
    core.log(t)
end


function aom_transit.transit_core.save_touched_locations(player)
	local pi = check_player(player)
	local datastring = core.serialize(pi.locations)
	player:get_meta():set_string("aom_transit:spire_locations", datastring)
end

function aom_transit.transit_core.is_spire_valid_at_pos(pos)
    core.load_area(pos, pos)
    local node = core.get_node_or_nil(pos)

    if not node then
        log("failed to load spire location")
        return false
    end

    if node.name ~= "aom_transit:transit_spire" then
        log("spire in saved location was destroyed")
        return false
    end
    return pos
end

function aom_transit.transit_core.is_spire_valid_at_hash(hash)
    local n = tonumber(hash)
    if not n then
        log("hash was bad: " .. tostring(hash))
        return false
    end
    local pos = core.get_position_from_hash(n)
    return aom_transit.transit_core.is_spire_valid_at_pos(pos)
end


-- checks spire locations to see if they are still valid
function aom_transit.transit_core.validate_spire_data(player, data)
    -- verify spires still exist in saved locations
    for hash, def in pairs(data) do
        if not aom_transit.transit_core.is_spire_valid_at_hash(hash) then
            data[hash] = nil
        end
    end
end


function aom_transit.transit_core.load_touched_locations(player)
    -- disable persistence for testing purposes
    -- do return {} end

	local loaded = player:get_meta():get_string("aom_transit:spire_locations")
	if loaded == "" then return {} end
	loaded = core.deserialize(loaded, true)
	if not loaded then return {} end

    aom_transit.transit_core.validate_spire_data(player, loaded)
    return loaded
end


function aom_transit.transit_core.on_untouch_spire(player, pos)
    log("destroy spire touch")
end

function aom_transit.transit_core.on_first_touch_spire(player, pos)
    log("first touch")
end


function aom_transit.transit_core.untouch_spire_for_all_players(pos)
    for i, player in ipairs(core.get_connected_players()) do
        aom_transit.transit_core.untouch_spire(player, pos)
    end
end

-- remove tracking of this spire for this player
function aom_transit.transit_core.untouch_spire(player, pos)
	local pi = check_player(player)
    local hash = tonumber(core.hash_node_position(pos))
    if hash and pi.locations[hash] then
        -- pi.locations_count = (pi.locations_count or 1) - 1
        pi.locations[hash] = nil
        log("forgot a location")
    end
end

-- add tracking for this spire for this player
function aom_transit.transit_core.touch_spire(player, pos)
	local pi = check_player(player)
    log("any touch")
    local hash = tonumber(core.hash_node_position(pos))
    pi.last_touched_hash = hash
    pi.last_touched_pos = pos
    if (not hash) or pi.locations[hash] then
        return
    end
    pi.locations_count = (pi.locations_count or 0) + 1
    pi.locations[hash] = {
        name = "transit spire " .. tostring(pi.locations_count),
    }
    aom_transit.transit_core.on_first_touch_spire(player, pos)
    aom_transit.transit_core.save_touched_locations(player)
end

