if not mods["space-exploration"] then return end

local default_simulation_length = 60 * settings.startup["se-default-simulation-length"].value

if not data.raw["utility-constants"]["default"].main_menu_simulations then
  data.raw["utility-constants"]["default"].main_menu_simulations = {}
end
local menu_simulations = data.raw["utility-constants"]["default"].main_menu_simulations

-- Remove default menu sims
if settings.startup["se-remove-vanilla-simulations"].value then
  menu_simulations.nauvis_solar_power_construction = nil
  menu_simulations.nauvis_lab = nil
  menu_simulations.nauvis_burner_city = nil
  menu_simulations.nauvis_mining_defense = nil
  menu_simulations.nauvis_forest_fire = nil
  menu_simulations.nauvis_oil_pumpjacks = nil
  menu_simulations.nauvis_oil_refinery = nil
  menu_simulations.nauvis_early_smelting = nil
  menu_simulations.nauvis_train_station = nil
  menu_simulations.nauvis_logistic_robots = nil
  menu_simulations.nauvis_nuclear_power = nil
  menu_simulations.nauvis_train_junction = nil
  menu_simulations.nauvis_artillery = nil
  menu_simulations.nauvis_biter_base_spidertron = nil
  menu_simulations.nauvis_biter_base_artillery = nil
  menu_simulations.nauvis_biter_base_laser_defense = nil
  menu_simulations.nauvis_biter_base_player_attack = nil
  menu_simulations.nauvis_biter_base_steamrolled = nil
  menu_simulations.nauvis_chase_player = nil
  menu_simulations.nauvis_big_defense = nil
  menu_simulations.nauvis_brutal_defeat = nil
  menu_simulations.nauvis_spider_ponds = nil
  menu_simulations.nauvis_uranium_processing = nil
  -- Elevated rails
  menu_simulations.nauvis_ship_rails = nil
  menu_simulations.nauvis_river_bridge = nil
  menu_simulations.nauvis_t_section = nil
end

if not settings.startup["se-add-menu-simulations"].value then
  return
end

local remove_button_flow = [[
    local mod_gui = require("__core__/lualib/mod-gui")
    if script.level.is_simulation then
      local frame = mod_gui.get_button_flow(game.players[1])
      frame.parent.visible = false
    end
    ]]

-- NO SCRIPTS SIMULATIONS (e.g. static bases) --

menu_simulations.vita =
{
  checkboard = false,
  save = "__space-exploration-menu-simulations__/menu-simulations/no-scripts/menu-simulation-vita.zip",
  length = default_simulation_length,
  init =
  [[
    -- SE sim: vita
    local logo = game.surfaces.nauvis.find_entities_filtered{name = "se-space-exploration-logo-shattered-15tiles", limit = 1}[1]
    game.simulation.camera_position = {logo.position.x, logo.position.y+10.50}
    game.simulation.camera_zoom = 1
    game.tick_paused = false
    game.surfaces.nauvis.daytime = 0

    game.forces.player.inserter_stack_size_bonus = 2
    game.forces.player.bulk_inserter_capacity_bonus = 7
  ]] .. remove_button_flow
}

menu_simulations.vulcanite_processing =
{
  checkboard = false,
  save = "__space-exploration-menu-simulations__/menu-simulations/no-scripts/menu-simulation-vulcanite-processing.zip",
  length = default_simulation_length,
  init =
  [[
    -- SE sim: vulcanite_processing
    local logo = game.surfaces.nauvis.find_entities_filtered{name = "se-space-exploration-logo-shattered-15tiles", limit = 1}[1]
    game.simulation.camera_position = {logo.position.x, logo.position.y+10.50}
    game.simulation.camera_zoom = 1
    game.tick_paused = false
    game.surfaces.nauvis.daytime = 0
  ]] .. remove_button_flow
}

menu_simulations.burner_base_night =
{
  checkboard = false,
  save = "__space-exploration-menu-simulations__/menu-simulations/no-scripts/menu-simulation-burner-base-night.zip",
  length = default_simulation_length,
  init =
  [[
    -- SE sim: burner_base_night
    local logo = game.surfaces.nauvis.find_entities_filtered{name = "se-space-exploration-logo-shattered-15tiles", limit = 1}[1]
    game.simulation.camera_position = {logo.position.x, logo.position.y+10.50}
    game.simulation.camera_zoom = 1
    game.tick_paused = false
    game.surfaces.nauvis.daytime = 0.5

    game.forces.player.technologies["fuel-processing"].researched = true
    game.forces.player.technologies["electricity"].researched = true
    game.forces.player.technologies["automation"].researched = true
    game.forces.player.technologies["electronics"].researched = true
    game.forces.player.add_research("logistic-science-pack")
  ]] .. remove_button_flow
}

menu_simulations.space_insight =
{
  checkboard = false,
  save = "__space-exploration-menu-simulations__/menu-simulations/no-scripts/menu-simulation-space-insight.zip",
  length = default_simulation_length,
  init =
  [[
    -- SE sim: space_insight
    local logo = game.surfaces.nauvis.find_entities_filtered{name = "se-space-exploration-logo-shattered-15tiles", limit = 1}[1]
    game.simulation.camera_position = {logo.position.x, logo.position.y+10.50}
    game.simulation.camera_zoom = 1
    game.tick_paused = false
    game.surfaces.nauvis.daytime = 0.65

    game.forces.player.bulk_inserter_capacity_bonus = 11
  ]] .. remove_button_flow
}

menu_simulations.space_bio_sludge_loop =
{
  checkboard = false,
  save = "__space-exploration-menu-simulations__/menu-simulations/no-scripts/menu-simulation-space-bio-sludge-loop.zip",
  length = default_simulation_length,
  init =
  [[
    -- SE sim: space_bio_sludge_loop
    local logo = game.surfaces.nauvis.find_entities_filtered{name = "se-space-exploration-logo-shattered-15tiles", limit = 1}[1]
    game.simulation.camera_position = {logo.position.x, logo.position.y+10.50}
    game.simulation.camera_zoom = 1
    game.tick_paused = false
    game.surfaces.nauvis.daytime = 0.65

    game.forces.player.bulk_inserter_capacity_bonus = 11
    game.forces.player.inserter_stack_size_bonus = 1
  ]] .. remove_button_flow
}

menu_simulations.space_mat_impact_data_scrap =
{
  checkboard = false,
  save = "__space-exploration-menu-simulations__/menu-simulations/no-scripts/menu-simulation-space-mat-impact-data-scrap.zip",
  length = default_simulation_length,
  init =
  [[
    -- SE sim: space_mat_impact_data_scrap
    local surface = game.surfaces.nauvis
    local logo = surface.find_entities_filtered{name = "se-space-exploration-logo-shattered-15tiles", limit = 1}[1]
    game.simulation.camera_position = {logo.position.x, logo.position.y+10.50}
    game.simulation.camera_zoom = 1
    game.tick_paused = false
    surface.daytime = 0.65

    game.forces.player.bulk_inserter_capacity_bonus = 11
    game.forces.player.inserter_stack_size_bonus = 1
    game.forces.player.worker_robots_speed_modifier = 1.45

    local character = surface.create_entity{name = "character", position = {-3, 8}, force = "player"}
    local center_locomotive = surface.find_entities_filtered{name = "locomotive", area = {{-2, 7}, {0, 9}}, limit = 1}[1]
    center_locomotive.set_driver(character)

    script.on_nth_tick(1, function()
      local tick_loop = game.tick % 600

      if 0 <= tick_loop and tick_loop < 30 then
        character.riding_state = {acceleration = defines.riding.acceleration.reversing, direction = defines.riding.direction.straight }
      elseif 30 <= tick_loop and tick_loop < 150 then
        character.riding_state = {acceleration = defines.riding.acceleration.nothing, direction = defines.riding.direction.straight }
      elseif 60 <= tick_loop and tick_loop < 180 then
        character.riding_state = {acceleration = defines.riding.acceleration.accelerating, direction = defines.riding.direction.straight }
      else
        character.riding_state = {acceleration = defines.riding.acceleration.nothing, direction = defines.riding.direction.straight }
      end
    end)
  ]] .. remove_button_flow
}

menu_simulations.space_astro_data =
{
  checkboard = false,
  save = "__space-exploration-menu-simulations__/menu-simulations/no-scripts/menu-simulation-space-astro-data.zip",
  length = default_simulation_length,
  init =
  [[
    -- SE sim: space_astro_data
    local surface = game.surfaces.nauvis
    local logo = surface.find_entities_filtered{name = "se-space-exploration-logo-shattered-15tiles", limit = 1}[1]
    game.simulation.camera_position = {logo.position.x, logo.position.y+10.50}
    game.simulation.camera_zoom = 1
    game.tick_paused = false
    surface.daytime = 0.65

    game.forces.player.bulk_inserter_capacity_bonus = 7
    game.forces.player.inserter_stack_size_bonus = 2
  ]] .. remove_button_flow
}

local runway_effective_length = 60 * 85 -- Zoom out only
if default_simulation_length > (60 * 60) then
  runway_effective_length = 60 * 145 -- Zoom out then zoom back in
end
menu_simulations.ground_runway =
{
  checkboard = false,
  save = "__space-exploration-menu-simulations__/menu-simulations/no-scripts/menu-simulation-runway-ground.zip",
  length = runway_effective_length,
  init =
  [[
    -- SE sim: ground_runway
    local logo = game.surfaces.nauvis.find_entities_filtered{name = "se-space-exploration-logo-shattered-15tiles", limit = 1}[1]
    game.simulation.camera_position = {logo.position.x, logo.position.y+10.50}
    local zoom = 1
    game.simulation.camera_zoom = zoom
    game.tick_paused = false
    game.surfaces.nauvis.daytime = 0.5

    game.forces.player.bulk_inserter_capacity_bonus = 11

    local start_tick = game.tick
    local final_zoom_speed = 0.0002

    local startup_start = 20*60
    local startup_end = 25*60
    local slowdown_start = 61.65*60
    local slowdown_end = 66.65*60

    local startup2_start = 95*60
    local startup2_end = 100*60
    local slowdown2_start = 136.65*60
    local slowdown2_end = 141.65*60

    script.on_nth_tick(1, function()
      local ticks_since_start = game.tick - start_tick

      -- Zoom out
      if startup_start <= ticks_since_start and ticks_since_start <= slowdown_end then
        if ticks_since_start <= startup_end then
          zoom = zoom - final_zoom_speed * (ticks_since_start - startup_start) / (startup_end - startup_start)
        elseif ticks_since_start <= slowdown_start then
          zoom = zoom - final_zoom_speed
        elseif ticks_since_start < slowdown_end then
          zoom = zoom - final_zoom_speed * (slowdown_end - ticks_since_start) / (slowdown_end - slowdown_start)
        else
          zoom = 0.5
        end
        
        game.simulation.camera_zoom = zoom

      -- Zoom back
      elseif startup2_start <= ticks_since_start and ticks_since_start <= slowdown2_end then
        if ticks_since_start <= startup2_end then
          zoom = zoom + final_zoom_speed * (ticks_since_start - startup2_start) / (startup2_end - startup2_start)
        elseif ticks_since_start <= slowdown2_start then
          zoom = zoom + final_zoom_speed
        elseif ticks_since_start < slowdown2_end then
          zoom = zoom + final_zoom_speed * (slowdown2_end - ticks_since_start) / (slowdown2_end - slowdown2_start)
        else
          zoom = 1
        end
        
        game.simulation.camera_zoom = zoom
      end
    end)
  ]] .. remove_button_flow
}

-- menu_simulations.space_runway =
-- {
--   checkboard = false,
--   save = "__space-exploration-menu-simulations__/menu-simulations/menu-simulation-runway-1.zip",
--   length = default_simulation_length,
--   init =
--   [[
--     local logo = game.surfaces.nauvis.find_entities_filtered{name = "se-space-exploration-logo-shattered-15tiles", limit = 1}[1]
--     game.simulation.camera_position = {logo.position.x, logo.position.y+10.50}
--     game.simulation.camera_zoom = 1
--     game.tick_paused = false
--     game.surfaces.nauvis.daytime = 0.65

--     game.forces.player.bulk_inserter_capacity_bonus = 11
--   ]]
-- }


-- SCRIPTED SIMULATIONS (uses SE scripts not just its buildings, e.g. cannons, rocket, spaceship, etc.) --

menu_simulations.scrap_processing =
{
  checkboard = false,
  save = "__space-exploration-menu-simulations__/menu-simulations/scripted/menu-simulation-scrap-processing.zip",
  mods = {"space-exploration"},
  length = math.max(default_simulation_length, 60 * 34), -- At least show the rocket landing
  init =
  [[
    -- SE sim: scrap_processing
    local surface = game.surfaces.nauvis
    local logo = surface.find_entities_filtered{name = "se-space-exploration-logo-shattered-15tiles", limit = 1}[1]
    game.simulation.camera_position = {logo.position.x, logo.position.y+10.50}
    game.simulation.camera_zoom = 1
    game.tick_paused = false
    surface.daytime = 0

    game.forces.player.bulk_inserter_capacity_bonus = 5
    game.forces.player.worker_robots_speed_modifier = 1.25

    game.forces.player.technologies["se-rocket-launch-pad"].researched = true
    game.forces.player.technologies["se-rocket-reusability-1"].researched = true
    game.forces.player.technologies["se-rocket-reusability-2"].researched = true
    game.forces.player.technologies["se-rocket-reusability-3"].researched = true
    game.forces.player.technologies["se-rocket-reusability-4"].level = 6

    local tick_start = game.tick
    script.on_nth_tick(1, function()
      local ticks_since_start = game.tick - tick_start

      if ticks_since_start == 60 * 20 then
        local journey_task_data = {
          landing_pad_position = {x=-20.5, y=2.5},
          launch_timer = nil,
          contents = {
            {name = "se-scrap", count = 25000},
          },
        }
        remote.call("space-exploration-menu-simulations", "make_launchpad_journey_task", journey_task_data)
      end
    end)
  ]] .. remove_button_flow
}

menu_simulations.shield_projector_defense =
{
  checkboard = false,
  save = "__space-exploration-menu-simulations__/menu-simulations/scripted/menu-simulation-shield-projector-defense.zip",
  init_file = "__space-exploration-menu-simulations__/menu-simulations-scripts/menu-simulation-shield-projector-defense.lua",
  mods = {"space-exploration", "shield-projector"},
  length = math.min(default_simulation_length, 60 * 36) -- All biters dead at 31 sec, gets boring past 36
}

-- {top_left_chunk = {x=-4, y=-10}, bottom_right_chunk = {x=3, y=2}}
menu_simulations.weapon_delivery =
{
  checkboard = false,
  save = "__space-exploration-menu-simulations__/menu-simulations/scripted/menu-simulation-weapon-delivery.zip",
  init_file = "__space-exploration-menu-simulations__/menu-simulations-scripts/menu-simulation-weapon-delivery.lua",
  mods = {"space-exploration"},
  length = 60 * 30,
}

menu_simulations.tesla_gun =
{
  checkboard = false,
  save = "__space-exploration-menu-simulations__/menu-simulations/scripted/menu-simulation-tesla-gun.zip",
  init_file = "__space-exploration-menu-simulations__/menu-simulations-scripts/menu-simulation-tesla-gun.lua",
  mods = {"space-exploration"},
  length = 60 * 30,
}

-- Currently causes a Hard Crash in Factorio.
-- menu_simulations.spidertron_deployment =
-- {
--   checkboard = false,
--   save = "__space-exploration-menu-simulations__/menu-simulations/scripted/menu-simulation-spidertron-deployment.zip",
--   init_file = "__space-exploration-menu-simulations__/menu-simulations-scripts/menu-simulation-spidertron-deployment.lua",
--   mods = {"space-exploration"},
--   length = 60 * 102,
-- }

menu_simulations.spaceship_speedster =
{
  checkboard = false,
  save = "__space-exploration-menu-simulations__/menu-simulations/scripted/menu-simulation-spaceship-speedster.zip",
  length = default_simulation_length,
  mods = {"space-exploration"},
  init = [[
    -- SE sim: spaceship_speedster
    local logo = game.surfaces.nauvis.find_entities_filtered{name = "se-space-exploration-logo-shattered-15tiles", limit = 1}[1]
    game.simulation.camera_position = {logo.position.x, logo.position.y+10.50}
    game.simulation.camera_zoom = 1
    game.tick_paused = false
    game.surfaces.nauvis.daytime = 0.65

    game.surfaces.nauvis.solar_power_multiplier = 15

    game.forces.player.set_ammo_damage_modifier("laser", 3.5)
    game.forces.player.set_gun_speed_modifier("laser", 1.7)

    remote.call("space-exploration-menu-simulations", "find_and_create_simulation_spaceship", {position = {14, -1}})
    remote.call("space-exploration-menu-simulations", "enable_simulation_spaceship_flying")
    remote.call("space-exploration-menu-simulations", "fly_simulation_spaceship", {spaceship_index = 1, starting_speed = 175, target_speed = 300})
  ]] .. remove_button_flow
}

menu_simulations.spaceship_thermofluid_hauler =
{
  checkboard = false,
  save = "__space-exploration-menu-simulations__/menu-simulations/scripted/menu-simulation-spaceship-thermofluid-hauler.zip",
  length = default_simulation_length,
  mods = {"space-exploration", "shield-projector"},
  init = [[
    -- SE sim: spaceship_thermofluid_hauler
    local logo = game.surfaces.nauvis.find_entities_filtered{name = "se-space-exploration-logo-shattered-15tiles", limit = 1}[1]
    game.simulation.camera_position = {logo.position.x, logo.position.y+10.50}
    game.simulation.camera_zoom = 1
    game.tick_paused = false
    game.surfaces.nauvis.daytime = 0.65

    game.forces.player.set_ammo_damage_modifier("laser", 4.0)
    game.forces.player.set_gun_speed_modifier("laser", 1.9)

    remote.call("space-exploration-menu-simulations", "find_and_create_simulation_spaceship", {position = {15, 3}})
    remote.call("space-exploration-menu-simulations", "enable_simulation_spaceship_flying")
    remote.call("space-exploration-menu-simulations", "fly_simulation_spaceship", {spaceship_index = 1, starting_speed = 275, target_speed = 350})
  ]] .. remove_button_flow
}

menu_simulations.spaceship_probe_data =
{
  checkboard = false,
  save = "__space-exploration-menu-simulations__/menu-simulations/scripted/menu-simulation-spaceship-probe-data.zip",
  length = default_simulation_length,
  mods = {"space-exploration"},
  init = [[
    -- SE sim: spaceship_probe_data
    local logo = game.surfaces.nauvis.find_entities_filtered{name = "se-space-exploration-logo-shattered-15tiles", limit = 1}[1]
    game.simulation.camera_position = {logo.position.x, logo.position.y+10.50}
    game.simulation.camera_zoom = 1
    game.tick_paused = false
    game.surfaces.nauvis.daytime = 0.65

    game.forces.player.set_ammo_damage_modifier("laser", 3.5)
    game.forces.player.set_gun_speed_modifier("laser", 1.7)

    remote.call("space-exploration-menu-simulations", "find_and_create_simulation_spaceship", {position = {14, -5}})
    remote.call("space-exploration-menu-simulations", "enable_simulation_spaceship_flying")
    remote.call("space-exploration-menu-simulations", "fly_simulation_spaceship", {spaceship_index = 1, starting_speed = 60, target_speed = 100})
  ]] .. remove_button_flow
}

menu_simulations.spaceship_dual_shuttles =
{
  checkboard = false,
  save = "__space-exploration-menu-simulations__/menu-simulations/scripted/menu-simulation-spaceship-dual-shuttles.zip",
  length = default_simulation_length,
  mods = {"space-exploration", "shield-projector"},
  init = [[
    -- SE sim: spaceship_dual_shuttles
    local logo = game.surfaces.nauvis.find_entities_filtered{name = "se-space-exploration-logo-shattered-15tiles", limit = 1}[1]
    game.simulation.camera_position = {logo.position.x, logo.position.y+10.50}
    game.simulation.camera_zoom = 1
    game.tick_paused = false
    game.surfaces.nauvis.daytime = 0.65

    game.forces.player.set_ammo_damage_modifier("laser", 1.2)
    game.forces.player.set_gun_speed_modifier("laser", 1.1)

    game.forces.player.create_ghost_on_entity_death = true
    game.forces.player.worker_robots_speed_modifier = 1.25

    remote.call("space-exploration-menu-simulations", "find_and_create_simulation_spaceship", {position = {-24, -1}})
    remote.call("space-exploration-menu-simulations", "find_and_create_simulation_spaceship", {position = {15, -3}})
    remote.call("space-exploration-menu-simulations", "merge_simulation_spaceships", {spaceship_index_1 = 1, spaceship_index_2 = 2})

    remote.call("space-exploration-menu-simulations", "enable_simulation_spaceship_flying")
    remote.call("space-exploration-menu-simulations", "fly_simulation_spaceship", {spaceship_index = 1, starting_speed = 60, target_speed = 200})
  ]] .. remove_button_flow
}

if mods["Krastorio2"] then
  require("compatibility/krastorio2")
end

-- menu_simulations.blank_normal_zoom =
-- {
--   checkboard = false,
--   save = "__space-exploration-menu-simulations__/menu-simulations/menu-simulation-blank-1.zip",
--   length = default_simulation_length,
--   init = [[
--     -- SE sim: blank
--     local logo = game.surfaces.nauvis.find_entities_filtered{name = "se-space-exploration-logo-shattered-15tiles", limit = 1}[1]
--     game.simulation.camera_position = {logo.position.x, logo.position.y+10.5}
--     game.simulation.camera_zoom = 1
--     game.tick_paused = false
--     game.surfaces.nauvis.daytime = 0
--   ]]
-- }


-- menu_simulations.blank_zoomed_out_1point5 =
-- {
--   checkboard = false,
--   save = "__space-exploration-menu-simulations__/menu-simulations/menu-simulation-blank-0.6875.zip",
--   length = default_simulation_length,
--   init = [[
--     -- SE sim: blank
--     local logo = game.surfaces.nauvis.find_entities_filtered{name = "se-space-exploration-logo-shattered-22tiles", limit = 1}[1]
--     game.simulation.camera_position = {logo.position.x, logo.position.y+15.272727}
--     game.simulation.camera_zoom = 0.6875
--     game.tick_paused = false
--     game.surfaces.nauvis.daytime = 0
--   ]]
-- }

-- menu_simulations.blank_zoomed_out_2 =
-- {
--   checkboard = false,
--   save = "__space-exploration-menu-simulations__/menu-simulations/menu-simulation-blank-0.5.zip",
--   length = default_simulation_length,
--   init = [[
--     -- SE sim: blank
--     local logo = game.surfaces.nauvis.find_entities_filtered{name = "se-space-exploration-logo-shattered-30tiles", limit = 1}[1]
--     game.simulation.camera_position = {logo.position.x, logo.position.y+21}
--     game.simulation.camera_zoom = 0.5
--     game.tick_paused = false
--     game.surfaces.nauvis.daytime = 0
--   ]]
-- }


-- Uncomment this and change the `menu_simulations.X` part to force the game to only use your simulation, for testing.
-- data.raw["utility-constants"]["default"].main_menu_simulations = {menu_simulations.blank_normal_zoom}
