-- This is a player context script for MoO2 1.50 patch project.
--
-- This script lists amount, race and arrival time for population that is being transported to another colony using
-- freighters. As an option, jobs of transported androids can be displayed.
--
-- To run the script press 1 in main screen (the file should be named MAIN1.LUA)

SHOW_ANDROID_JOBS = false -- usually results in new-lines when grouped with any other kind

local players = get_players()
local current_player = players[get_current_player_id()]

local function orbit_as_int(planet_id, star_orbits)
	local orbit_int = 0
	for i, planet_of_star_id in pairs(star_orbits) do
		if planet_of_star_id == planet_id then
			break
		end
		orbit_int = orbit_int + 1
	end
	return orbit_int
end

local function orbit_to_roman(orbit_int)
	-- there can be gaps in star-orbits (e.g. 0, 2, 3, 4) so find it with planet.id instead of planet.orbit
	local orbit_str = ''
	if orbit_int == 0 then
		orbit_str = 'I'
	elseif orbit_int == 1 then
		orbit_str = 'II'
	elseif orbit_int == 2 then
		orbit_str = 'III'
	elseif orbit_int == 3 then
		orbit_str = 'IV'
	elseif orbit_int == 4 then
		orbit_str = 'V'
	else
		msgbox('ERROR: invalid  orbit ID ' .. tostring(orbit_int) .. ', expected between 0 and 4')
	end
	return orbit_str
end

local function sort_by_destination_then_eta(a, b)
	if a.destination_name < b.destination_name then
		return true
	elseif a.destination_name == b.destination_name then
		return a.eta < b.eta
	else
		return false
	end
end

local function generate_output_for_given_aggregation(current_aggregation_eta, current_aggregation_name, race_to_amount, players, owned_pop_races)
	local output = current_aggregation_name .. ' - ETA ' .. tostring(current_aggregation_eta) .. ' - '
	for j, a in pairs(race_to_amount) do
		local race_name
		if j == 100 then
			race_name = 'Android Farmer'
		elseif j == 101 then
			race_name = 'Android Worker'
		elseif j == 102 then
			race_name = 'Android Scientist'
		elseif j == 8 then
			race_name = 'Android'
		elseif j == 9 then
			race_name = 'Native'
		else
			if players[j] ~= nil then
				race_name = players[j].race
			else
				race_name = owned_pop_races[j].race_default_name
			end
		end
		output = output .. tostring(a) .. 'x ' .. tostring(race_name) .. ' '
	end
	output = output .. '\n'
	return output
end

local planets = get_planets()
local stars = get_stars()

-- need to ensure starting with higher index than .freighted_pop, otherwise sorting will skip first entry
local sorted_freighted_pop = {}
for i, fp in pairs(current_player.freighted_pop) do
	local destination_id = fp.destination_planet
	local planet = planets[destination_id]
	local star = stars[planet.star]
	local orbit_int = orbit_as_int(planet.id, star.orbits)
	fp.destination_name = star.name .. ' ' .. orbit_to_roman(orbit_int)
	table.insert(sorted_freighted_pop, fp)
end

planets = nil
stars = nil
collectgarbage()


table.sort(sorted_freighted_pop, sort_by_destination_then_eta)

local header = 'Population in transit:\n\n'
local output = header
local race_to_amount = {}
local current_aggregation_name = ''
local current_aggregation_eta = 0
local owned_pop_races = get_pop_race_info()

for i, fp in pairs(sorted_freighted_pop) do
	if current_aggregation_eta == 0 then
		current_aggregation_eta = fp.eta
		current_aggregation_name = fp.destination_name
	end
	if current_aggregation_name ~= fp.destination_name or current_aggregation_eta ~= fp.eta then
		output = output .. generate_output_for_given_aggregation(current_aggregation_eta, current_aggregation_name, race_to_amount, players, owned_pop_races)
		race_to_amount = {}
		current_aggregation_eta = fp.eta
		current_aggregation_name = fp.destination_name
	end
	if fp.eta == current_aggregation_eta and fp.destination_name == current_aggregation_name then
		local race_index = fp.race
		if race_index == 8 then
			if SHOW_ANDROID_JOBS == true then
				race_index = 100 + fp.job
			end
		end
		if race_to_amount[race_index] == nil then
			race_to_amount[race_index] = 1
		else
			race_to_amount[race_index] = race_to_amount[race_index] + 1
		end
	end
end
if current_aggregation_eta ~= 0 then
	output = output .. generate_output_for_given_aggregation(current_aggregation_eta, current_aggregation_name, race_to_amount, players, owned_pop_races)
	race_to_amount = {}
end
race_to_amount = nil
players = nil
owned_pop_races = nil
collectgarbage()

if output == header then
	output = 'No population in transit.'
end
msgbox(output)
