local sun = asset.require("scene/solarsystem/sun/sun")
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")



local models = asset.syncedResource({
  Name = "Voyager Model",
  Type = "HttpSynchronization",
  Identifier = "voyager_model",
  Version = 1
})

local kernels = asset.syncedResource({
  Name = "Voyager 2 Kernels",
  Type = "HttpSynchronization",
  Identifier = "voyager2_spice",
  Version = 1
})


local Kernels = {
  kernels .. "vg2_v02.tf",
  kernels .. "vg200022.tsc",
  kernels .. "Voyager_2.m05016u.merged.bsp",
  kernels .. "voyager_2.ST+1992_m05208u.merged.bsp",
  kernels .. "vgr2_jup230.bsp",
  kernels .. "vgr2_sat337.bsp",
  kernels .. "vgr2_ura083.bsp",
  kernels .. "vgr2_nep081.bsp",
  kernels .. "vgr2_super.bc",
  kernels .. "vgr2_super_v2.bc"
}

local RotationMatrix = {
  -1, 0, 0, 0,
  0, 0, -1, 0,
  0, -1, 0, 0,
  0, 0, 0, 1
}


local Voyager2 = {
  Identifier = "Voyager_2",
  Parent = sunTransforms.SolarSystemBarycenter.Identifier,
  Transform = {
    Translation = {
      Type = "SpiceTranslation",
      Target = "VOYAGER 2",
      Observer = "SSB"
    },
    Rotation = {
      Type = "SpiceRotation",
      SourceFrame = "VG2_SC_BUS",
      DestinationFrame = "GALACTIC",
      TimeFrame = {
        Type = "TimeFrameInterval",
        Start = "1977-AUG-20 16:07:06.535",
        End = "2027-DEC-27"
      }
    }
  },
  GUI = {
    Name = "Voyager 2",
    Path = "/Solar System/Missions/Voyager 2"
  }
}

local Voyager2Main = {
  Identifier = "Voyager_2_Main",
  Parent = Voyager2.Identifier,
  Renderable = {
    Type = "RenderableModel",
    Enabled = asset.enabled,
    GeometryFile = models .. "voyager-main.obj",
    ModelTransform = RotationMatrix,
    LightSources = {
      sun.LightSource,
      {
        Identifier = "Camera",
        Type = "CameraLightSource",
        Intensity = 0.5
      }
    }
  },
  Tag = { "voyager2_part" },
  GUI = {
    Name = "Voyager 2 Main",
    Path = "/Solar System/Missions/Voyager 2"
  }
}

local Voyager2Antenna = {
  Identifier = "Voyager_2_Antenna",
  Parent = Voyager2.Identifier,
  Renderable = {
    Type = "RenderableModel",
    Enabled = asset.enabled,
    GeometryFile = models .. "voyager-antenna.obj",
    ModelTransform = RotationMatrix,
    LightSources = {
      sun.LightSource,
      {
        Identifier = "Camera",
        Type = "CameraLightSource",
        Intensity = 0.5
      }
    }
  },
  Tag = { "voyager2_part" },
  GUI = {
    Name = "Voyager 2 Antenna",
    Path = "/Solar System/Missions/Voyager 2"
  }
}

-- The trails are organized as follows.  The cruise phases can be resolved in relatively
-- low resolution since they are just straight lines
-- The encounter phases should be much higher resolution or otherwise artifacts would
-- appear
local VoyagerTrailCruiseEarthJupiter = {
  Identifier = "Voyager_2_Trail_Cruise_Earth_Jupiter",
  Parent = sunTransforms.SolarSystemBarycenter.Identifier,
  Renderable = {
    Type = "RenderableTrailTrajectory",
    Translation = {
      Type = "SpiceTranslation",
      Target = "VOYAGER 2",
      Observer = "SSB"
    },
    Color = { 0.70, 0.50, 0.20 },
    StartTime = "1977-AUG-20 16:07:06.535",
    EndTime = "1979 JUL 06",
    -- 669 is the number of days between the Start and End time
    SampleInterval = 669 * 2,
    Enabled = asset.enabled
  },
  Tag = { "voyager2_trail" },
  GUI = {
    Name = "Voyager 2 Trail Cruise Earth-Jupiter",
    Path = "/Solar System/Missions/Voyager 2"
  }
}

local VoyagerTrailEncounterJupiter = {
  Identifier = "Voyager_2_Trail_Encounter_Jupiter",
  Parent = sunTransforms.SolarSystemBarycenter.Identifier,
  Renderable = {
    Type = "RenderableTrailTrajectory",
    Enabled = asset.enabled,
    Translation = {
      Type = "SpiceTranslation",
      Target = "VOYAGER 2",
      Observer = "SSB"
    },
    Color = { 0.70, 0.50, 0.20 },
    EnableFade = false,
    -- @TODO: Probably an off-by-one bug in RenderableTrailTrajectory?
    StartTime = "1979 JUL 05 23:24:00",
    EndTime = "1979 JUL 15",
    SampleInterval = 100
  },
  Tag = { "voyager2_trail" },
  GUI = {
    Name = "Voyager 2 Trail Encounter Jupiter",
    Path = "/Solar System/Missions/Voyager 2"
  }
}

local VoyagerTrailCruiseJupiterSaturn = {
  Identifier = "Voyager_2_Trail_Cruise_Jupiter_Saturn",
  Parent = sunTransforms.SolarSystemBarycenter.Identifier,
  Renderable = {
    Type = "RenderableTrailTrajectory",
    Enabled = asset.enabled,
    Translation = {
      Type = "SpiceTranslation",
      Target = "VOYAGER 2",
      Observer = "SSB"
    },
    EnableFade = false,
    Color = { 0.70, 0.50, 0.20 },
    StartTime = "1979 JUL 15",
    EndTime = "1981 AUG 23",
    -- 770 is the number of days between the Start and End time
    SampleInterval = 770 * 2
  },
  Tag = { "voyager2_trail" },
  GUI = {
    Name = "Voyager 2 Trail Cruise Jupiter-Saturn",
    Path = "/Solar System/Missions/Voyager 2"
  }
}

local VoyagerTrailEncounterSaturn = {
  Identifier = "Voyager_2_Trail_Encounter_Saturn",
  Parent = sunTransforms.SolarSystemBarycenter.Identifier,
  Renderable = {
    Type = "RenderableTrailTrajectory",
    Enabled = asset.enabled,
    Translation = {
      Type = "SpiceTranslation",
      Target = "VOYAGER 2",
      Observer = "SSB"
    },
    EnableFade = false,
    Color = { 0.70, 0.50, 0.20 },
    -- @TODO: Probably an off-by-one bug in RenderableTrailTrajectory?
    StartTime = "1981 AUG 22 23:08:30",
    EndTime = "1981 AUG 30",
    SampleInterval = 100
  },
  Tag = { "voyager2_trail" },
  GUI = {
    Name = "Voyager 2 Trail Encounter Saturn",
    Path = "/Solar System/Missions/Voyager 2"
  }
}

local VoyagerTrailCruiseSaturnUranus = {
  Identifier = "Voyager_2_Trail_Cruise_Saturn_Uranus",
  Parent = sunTransforms.SolarSystemBarycenter.Identifier,
  Renderable = {
    Type = "RenderableTrailTrajectory",
    Enabled = asset.enabled,
    Translation = {
      Type = "SpiceTranslation",
      Target = "VOYAGER 2",
      Observer = "SSB"
    },
    EnableFade = false,
    Color = { 0.70, 0.50, 0.20 },
    StartTime = "1981 AUG 30",
    EndTime = "1986 JAN 22",
    -- 1971 is the number of days between the Start and End time
    SampleInterval = 1971 * 2
  },
  Tag = { "voyager2_trail" },
  GUI = {
    Name = "Voyager 2 Trail Cruise Saturn-Uranus",
    Path = "/Solar System/Missions/Voyager 2"
  }
}

local VoyagerTrailEncounterUranus = {
  Identifier = "Voyager_2_Trail_Encounter_Uranus",
  Parent = sunTransforms.SolarSystemBarycenter.Identifier,
  Renderable = {
    Type = "RenderableTrailTrajectory",
    Enabled = asset.enabled,
    Translation = {
      Type = "SpiceTranslation",
      Target = "VOYAGER 2",
      Observer = "SSB"
    },
    EnableFade = false,
    Color = { 0.70, 0.50, 0.20 },
    -- @TODO: Probably an off-by-one bug in RenderableTrailTrajectory?
    StartTime = "1986 JAN 21 23:30:00",
    EndTime = "1986 JAN 27",
    SampleInterval = 100
  },
  Tag = { "voyager2_trail" },
  GUI = {
    Name = "Voyager 2 Trail Encounter Uranus",
    Path = "/Solar System/Missions/Voyager 2"
  }
}

local VoyagerTrailCruiseUranusNeptune = {
  Identifier = "Voyager_2_Trail_Cruise_Uranus_Neptune",
  Parent = sunTransforms.SolarSystemBarycenter.Identifier,
  Renderable = {
    Type = "RenderableTrailTrajectory",
    Enabled = asset.enabled,
    Translation = {
      Type = "SpiceTranslation",
      Target = "VOYAGER 2",
      Observer = "SSB"
    },
    EnableFade = false,
    Color = { 0.70, 0.50, 0.20 },
    StartTime = "1986 JAN 27",
    EndTime = "1989 AUG 24",
    -- 1305 is the number of days between the Start and End time
    SampleInterval = 1305 * 2
  },
  Tag = { "voyager2_trail" },
  GUI = {
    Name = "Voyager 2 Trail Cruise Uranus-Neptune",
    Path = "/Solar System/Missions/Voyager 2"
  }
}

local VoyagerTrailEncounterNeptune = {
  Identifier = "Voyager_2_Trail_Encounter_Neptune",
  Parent = sunTransforms.SolarSystemBarycenter.Identifier,
  Renderable = {
    Type = "RenderableTrailTrajectory",
    Enabled = asset.enabled,
    Translation = {
      Type = "SpiceTranslation",
      Target = "VOYAGER 2",
      Observer = "SSB"
    },
    EnableFade = false,
    Color = { 0.70, 0.50, 0.20 },
    -- @TODO: Probably an off-by-one bug in RenderableTrailTrajectory?
    StartTime = "1989 AUG 23 22:30:00",
    EndTime = "1989 AUG 26",
    SampleInterval = 100,
    Enabled = asset.enabled
  },
  Tag = { "voyager2_trail" },
  GUI = {
    Name = "Voyager 2 Trail Encounter Neptune",
    Path = "/Solar System/Missions/Voyager 2"
  }
}

local VoyagerTrailCruiseNeptuneInf = {
  Identifier = "Voyager_2_Trail_Cruise_Neptune_Inf",
  Parent = sunTransforms.SolarSystemBarycenter.Identifier,
  Renderable = {
    Type = "RenderableTrailTrajectory",
    Enabled = asset.enabled,
    Translation = {
      Type = "SpiceTranslation",
      Target = "VOYAGER 2",
      Observer = "SSB"
    },
    EnableFade = false,
    Color = { 0.70, 0.50, 0.20 },
    StartTime = "1989 AUG 26",
    EndTime = "2021 JAN 01",
    -- 11451 is the number of days between the Start and End time
    SampleInterval = 11451 * 2
  },
  Tag = { "voyager2_trail" },
  GUI = {
    Name = "Voyager 2 Trail Cruise Neptune-Inf",
    Path = "/Solar System/Missions/Voyager 2"
  }
}

local FocusVoyager2 = {
  Identifier = "os.voyager.FocusVoyager2",
  Name = "Focus on Voyager 2",
  Command = [[
    openspace.setPropertyValueSingle("NavigationHandler.OrbitalNavigator.RetargetAnchor", nil)
    openspace.setPropertyValueSingle("NavigationHandler.OrbitalNavigator.Anchor", "Voyager_2")
    openspace.setPropertyValueSingle("NavigationHandler.OrbitalNavigator.Aim", "")
  ]],
  Documentation = "Set camera focus to Voyager 2",
  GuiPath = "/Missions/Voyager",
  isLocal = false
}


asset.onInitialize(function()
  openspace.spice.loadKernel(Kernels)

  openspace.action.registerAction(FocusVoyager2)

  openspace.addSceneGraphNode(Voyager2)
  openspace.addSceneGraphNode(Voyager2Main)
  openspace.addSceneGraphNode(Voyager2Antenna)
  openspace.addSceneGraphNode(VoyagerTrailCruiseEarthJupiter)
  openspace.addSceneGraphNode(VoyagerTrailEncounterJupiter)
  openspace.addSceneGraphNode(VoyagerTrailCruiseJupiterSaturn)
  openspace.addSceneGraphNode(VoyagerTrailEncounterSaturn)
  openspace.addSceneGraphNode(VoyagerTrailCruiseSaturnUranus)
  openspace.addSceneGraphNode(VoyagerTrailEncounterUranus)
  openspace.addSceneGraphNode(VoyagerTrailCruiseUranusNeptune)
  openspace.addSceneGraphNode(VoyagerTrailEncounterNeptune)
  openspace.addSceneGraphNode(VoyagerTrailCruiseNeptuneInf)
end)

asset.onDeinitialize(function()
  openspace.removeSceneGraphNode(VoyagerTrailCruiseNeptuneInf)
  openspace.removeSceneGraphNode(VoyagerTrailEncounterNeptune)
  openspace.removeSceneGraphNode(VoyagerTrailCruiseUranusNeptune)
  openspace.removeSceneGraphNode(VoyagerTrailEncounterUranus)
  openspace.removeSceneGraphNode(VoyagerTrailCruiseSaturnUranus)
  openspace.removeSceneGraphNode(VoyagerTrailEncounterSaturn)
  openspace.removeSceneGraphNode(VoyagerTrailCruiseJupiterSaturn)
  openspace.removeSceneGraphNode(VoyagerTrailEncounterJupiter)
  openspace.removeSceneGraphNode(VoyagerTrailCruiseEarthJupiter)
  openspace.removeSceneGraphNode(Voyager2Antenna)
  openspace.removeSceneGraphNode(Voyager2Main)
  openspace.removeSceneGraphNode(Voyager2)

  openspace.action.removeAction(FocusVoyager2)

  openspace.spice.unloadKernel(Kernels)
end)

asset.export(Voyager2)
asset.export(Voyager2Main)
asset.export(Voyager2Antenna)
asset.export(VoyagerTrailCruiseEarthJupiter)
asset.export(VoyagerTrailEncounterJupiter)
asset.export(VoyagerTrailCruiseJupiterSaturn)
asset.export(VoyagerTrailEncounterSaturn)
asset.export(VoyagerTrailCruiseSaturnUranus)
asset.export(VoyagerTrailEncounterUranus)
asset.export(VoyagerTrailCruiseUranusNeptune)
asset.export(VoyagerTrailEncounterNeptune)
asset.export(VoyagerTrailCruiseNeptuneInf)
