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 1 Kernels",
  Type = "HttpSynchronization",
  Identifier = "voyager1_spice",
  Version = 1
})


local Kernels = {
  kernels .. "vg1_v02.tf",
  kernels .. "vg100019.tsc",
  kernels .. "Voyager_1.a54206u_V0.2_merged.bsp",
  kernels .. "voyager_1.ST+1991_a54418u.merged.bsp",
  kernels .. "vgr1_jup230.bsp",
  kernels .. "vgr1_sat337.bsp",
  kernels .. "vgr1_super.bc",
  kernels .. "vgr1_super_v2.bc"
}

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

local Voyager1 = {
  Identifier = "Voyager_1",
  Parent = sunTransforms.SolarSystemBarycenter.Identifier,
  Transform = {
    Translation = {
      Type = "SpiceTranslation",
      Target = "VOYAGER 1",
      Observer = "SSB"
    },
    Rotation = {
      Type = "SpiceRotation",
      SourceFrame = "VG1_SC_BUS",
      DestinationFrame = "GALACTIC",
      TimeFrame = {
        Type = "TimeFrameInterval",
        Start = "1977-SEP-05 14:10:11.786",
        End = "2027-DEC-27"
      }
    }
  },
  GUI = {
    Name = "Voyager 1",
    Path = "/Solar System/Missions/Voyager 1"
  }
}

local Voyager1Main = {
  Identifier = "Voyager_1_Main",
  Parent = Voyager1.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 = { "voyager1_part" },
  GUI = {
    Name = "Voyager 1 Main",
    Path = "/Solar System/Missions/Voyager 1"
  }
}

local Voyager1Antenna = {
  Identifier = "Voyager_1_Antenna",
  Parent = Voyager1.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 = { "voyager1_part" },
  GUI = {
    Name = "Voyager 1 Antenna",
    Path = "/Solar System/Missions/Voyager 1"
  }
}

-- 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_1_Trail_Cruise_Earth_Jupiter",
  Parent = sunTransforms.SolarSystemBarycenter.Identifier,
  Renderable = {
    Type = "RenderableTrailTrajectory",
    Enabled = asset.enabled,
    Translation = {
      Type = "SpiceTranslation",
      Target = "VOYAGER 1",
      Observer = "SSB"
    },
    Color = { 0.70, 0.50, 0.20 },
    StartTime = "1977 SEP 05",
    EndTime = "1979 MAR 04",
    -- 545 is the number of days between the Start and End time
    SampleInterval = 545 * 2
  },
  Tag = { "voyager1_trail" },
  GUI = {
    Name = "Voyager 1 Trail Cruise Earth-Jupiter",
    Path = "/Solar System/Missions/Voyager 1"
  }
}

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

local VoyagerTrailCruiseJupiterSaturn = {
  Identifier = "Voyager_1_Trail_Cruise_Jupiter_Saturn",
  Parent = sunTransforms.SolarSystemBarycenter.Identifier,
  Renderable = {
    Type = "RenderableTrailTrajectory",
    Enabled = asset.enabled,
    Translation = {
      Type = "SpiceTranslation",
      Target = "VOYAGER 1",
      Observer = "SSB"
    },
    EnableFade = false,
    Color = { 0.70, 0.50, 0.20 },
    StartTime = "1979 MAR 09",
    EndTime = "1980 NOV 11",
    -- 618 is the number of days between the Start and End time
    SampleInterval = 618 * 2
  },
  Tag = { "voyager1_trail" },
  GUI = {
    Name = "Voyager 1 Trail Cruise Jupiter-Saturn",
    Path = "/Solar System/Missions/Voyager 1"
  }
}

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

local VoyagerTrailCruiseSaturnInf = {
  Identifier = "Voyager_1_Trail_Cruise_Saturn_Inf",
  Parent = sunTransforms.SolarSystemBarycenter.Identifier,
  Renderable = {
    Type = "RenderableTrailTrajectory",
    Enabled = asset.enabled,
    Translation = {
      Type = "SpiceTranslation",
      Target = "VOYAGER 1",
      Observer = "SSB"
    },
    EnableFade = false,
    Color = { 0.70, 0.50, 0.20 },
    StartTime = "1980 NOV 16",
    EndTime = "2021 JAN 01",
    -- 14656 is the number of days between the Start and End time
    SampleInterval = 14656 * 2
  },
  Tag = { "voyager1_trail" },
  GUI = {
    Name = "Voyager 1 Trail Cruise Saturn-Inf",
    Path = "/Solar System/Missions/Voyager 1"
  }
}


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


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

  openspace.addSceneGraphNode(Voyager1)
  openspace.addSceneGraphNode(Voyager1Main)
  openspace.addSceneGraphNode(Voyager1Antenna)
  openspace.addSceneGraphNode(VoyagerTrailCruiseEarthJupiter)
  openspace.addSceneGraphNode(VoyagerTrailEncounterJupiter)
  openspace.addSceneGraphNode(VoyagerTrailCruiseJupiterSaturn)
  openspace.addSceneGraphNode(VoyagerTrailEncounterSaturn)
  openspace.addSceneGraphNode(VoyagerTrailCruiseSaturnInf)

  openspace.action.registerAction(FocusVoyager1)
end)

asset.onDeinitialize(function()
  openspace.action.removeAction(FocusVoyager1)

  openspace.removeSceneGraphNode(VoyagerTrailCruiseSaturnInf)
  openspace.removeSceneGraphNode(VoyagerTrailEncounterSaturn)
  openspace.removeSceneGraphNode(VoyagerTrailCruiseJupiterSaturn)
  openspace.removeSceneGraphNode(VoyagerTrailEncounterJupiter)
  openspace.removeSceneGraphNode(VoyagerTrailCruiseEarthJupiter)
  openspace.removeSceneGraphNode(Voyager1Antenna)
  openspace.removeSceneGraphNode(Voyager1Main)
  openspace.removeSceneGraphNode(Voyager1)

  openspace.spice.unloadKernel(Kernels)
end)

asset.export(Voyager1)
asset.export(Voyager1Main)
asset.export(Voyager1Antenna)
asset.export(VoyagerTrailCruiseEarthJupiter)
asset.export(VoyagerTrailEncounterJupiter)
asset.export(VoyagerTrailCruiseJupiterSaturn)
asset.export(VoyagerTrailEncounterSaturn)
asset.export(VoyagerTrailCruiseSaturnInf)
