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



local models = asset.syncedResource({
  Name = "Rosetta Models",
  Type = "HttpSynchronization",
  Identifier = "rosetta_model",
  Version = 5
})

local kernels = asset.syncedResource({
  Name = "Rosetta Kernels",
  Type = "HttpSynchronization",
  Identifier = "rosetta_kernels",
  Version = 1
})


local RosettaKernels = {
  kernels .. "ROS_160718_STEP.TSC",
  kernels .. "ros_triv.tsc",

  kernels .. "CORB_DV_243_01___T19_00325.BSP",
  kernels .. "CORB_DV_223_01___T19_00302.BSP",
  kernels .. "CORB_DV_145_01___T19_00216.BSP",

  kernels .. "LORB_DV_236_01___T19_00318.BSP",
  kernels .. "LORB_DV_223_01___T19_00302.BSP",
  kernels .. "LORB_DV_145_01___T19_00216.BSP",

  kernels .. "RORB_DV_243_01___T19_00325.BSP",
  kernels .. "RORB_DV_223_01___T19_00302.BSP",
  kernels .. "RORB_DV_145_01___T19_00216.BSP",

  kernels .. "ATNR_P040302093352_00127.BC",

  kernels .. "ROS_STRUCT_V5.BSP",

  kernels .. "ROS_NAVCAM_V01.TI",

  kernels .. "ROS_CHURYUMOV_V01.TF",
  kernels .. "ROS_V26.TF",

  -- CK
  -- Rosetta attitude
  kernels .. "RATT_DV_243_01_01____00325.BC",
  kernels .. "RATT_DV_223_01_01____00302.BC",
  kernels .. "RATT_DV_145_01_01____00216.BC",

  -- Comet attitude
  kernels .. "CATT_DV_243_01_______00325.BC",
  kernels .. "CATT_DV_223_01_______00302.BC",
  kernels .. "CATT_DV_145_01_______00216.BC",

  -- High gain antenna
  kernels .. "ROS_HGA_2016_V0035.BC",
  kernels .. "ROS_HGA_2015_V0053.BC",
  kernels .. "ROS_HGA_2014_V0044.BC",

  -- Solar arrays
  kernels .. "ROS_SA_2016_V0034.BC",
  kernels .. "ROS_SA_2015_V0042.BC",
  kernels .. "ROS_SA_2014_V0047.BC",

  kernels .. "ROS_CGS_RSOC_V03.TPC"
}

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

local RosettaPosition = {
  Identifier = "RosettaPosition",
  Parent = sunTransforms.SolarSystemBarycenter.Identifier,
  Transform = {
    Translation = {
      Type = "SpiceTranslation",
      Target = "ROSETTA",
      Observer = "SSB"
    },
    Rotation = {
      Type = "SpiceRotation",
      SourceFrame = "ROS_SPACECRAFT",
      DestinationFrame = "GALACTIC"
    }
  },
  GUI = {
    Name = "Rosetta Position",
    Path = "/Solar System/Missions/Rosetta",
    Hidden = true
  }
}

local Rosetta = {
  Identifier = "Rosetta",
  Parent = RosettaPosition.Identifier,
  Transform = {
    Rotation = {
      Type = "StaticRotation",
      Rotation = { 0.0, math.pi / 2.0, 0.0 }
    }
  },
  Renderable = {
    Type = "RenderableModel",
    GeometryFile = models .. "rosetta.glb",
    ModelTransform = RotationMatrix,
    LightSources = {
      sun.LightSource,
      {
        Identifier = "Camera",
        Type = "CameraLightSource",
        Intensity = 0.5
      }
    }
  },
  GUI = {
    Name = "Rosetta",
    Path = "/Solar System/Missions/Rosetta"
  }
}

local PhilaePosition = {
  Identifier = "PhilaePosition",
  Parent = transforms.Barycenter.Identifier,
  -- This should need a transform, but currently the model contains it instead
  Transform = {
    Translation = {
      Type = "SpiceTranslation",
      Target = "PHILAE",
      Observer = "CHURYUMOV-GERASIMENKO"
    },
    Rotation = {
      Type = "SpiceRotation",
      SourceFrame = "ROS_SPACECRAFT",
      DestinationFrame = "GALACTIC",
    }
  },
  GUI = {
    Name = "Philae Position",
    Path = "/Solar System/Missions/Rosetta",
    Hidden = true
  }
}

local Philae = {
  Identifier = "Philae",
  Parent = PhilaePosition.Identifier,
  Transform = {
    Rotation = {
      Type = "StaticRotation",
      Rotation = { 0.0, math.pi / 2.0, 0.0 }
    }
  },
  Renderable = {
    Type = "RenderableModel",
    GeometryFile = models .. "lander.glb",
    ModelTransform = RotationMatrix,
    LightSources = {
      sun.LightSource,
      {
        Identifier = "Camera",
        Type = "CameraLightSource",
        Intensity = 0.5
      }
    }
  },
  GUI = {
    Name = "Philae",
    Path = "/Solar System/Missions/Rosetta"
  }
}

local NavCam = {
  Identifier = "NAVCAM",
  Parent = RosettaPosition.Identifier,
  GUI = {
    Path = "/Solar System/Missions/Rosetta/Instruments"
  }
}

local NavCamFov = {
  Identifier = "NAVCAM_FOV",
  Parent = NavCam.Identifier,
  Renderable = {
    Type = "RenderableFov",
    Body = "ROSETTA",
    Frame = "ROS_NAVCAM-A",
    RGB = { 0.8, 0.7, 0.7 },
    Instrument = {
      Name = "ROS_NAVCAM-A",
      Method = "ELLIPSOID",
      Aberration = "NONE"
    },
    PotentialTargets = { "CHURYUMOV-GERASIMENKO" },
    FrameConversions = {
      ["CHURYUMOV-GERASIMENKO"] = "67P/C-G_CK"
    }
  },
  GUI = {
    Name = "NAVCAM FOV",
    Path = "/Solar System/Missions/Rosetta/Instruments"
  }
}

local ImagePlane = {
  Identifier = "ImagePlaneRosetta",
  Parent = transforms.Comet67P.Identifier,
  Renderable = {
    Type = "RenderablePlaneProjection",
    Frame = "67P/C-G_CK",
    DefaultTarget = "CHURYUMOV-GERASIMENKO",
    Spacecraft = "ROSETTA",
    Instrument = "ROS_NAVCAM-A",
    Moving = false,
    Texture = models .. "defaultProj.png"
  },
  GUI = {
    Name = "Rosetta Image Plane",
    Path = "/Solar System/Missions/Rosetta"
  }
}

local RosettaCometTrail = {
  Identifier = "RosettaCometTrail",
  Parent = transforms.Barycenter.Identifier,
  Renderable = {
    Type = "RenderableTrailTrajectory",
    Translation = {
      Type = "SpiceTranslation",
      Target = "ROSETTA",
      Observer = "CHURYUMOV-GERASIMENKO"
    },
    Color = { 0.288, 0.375, 0.934 },
    StartTime = "2014 AUG 01 12:00:00",
    EndTime = "2016 SEP 30 12:00:00",
    SampleInterval = 3600
  },
  GUI = {
    Name = "Rosetta Comet Trail",
    Path = "/Solar System/Missions/Rosetta"
  }
}

local PhilaeTrail = {
  Identifier = "PhilaeTrail",
  Parent = transforms.Barycenter.Identifier,
  Renderable = {
    Type = "RenderableTrailTrajectory",
    Translation = {
      Type = "SpiceTranslation",
      Target = "PHILAE",
      Observer = "CHURYUMOV-GERASIMENKO"
    },
    Color = { 0.8, 0.5, 1.0 },
    StartTime = "2014 NOV 12 08:35:00",
    EndTime = "2014 NOV 12 17:00:00",
    SampleInterval = 2
  },
  GUI = {
    Name = "Philae Trail",
    Path = "/Solar System/Missions/Rosetta"
  }
}

local FocusRosetta = {
  Identifier = "os.rosetta.FocusRosetta",
  Name = "Focus on Rosetta",
  Command = [[
    openspace.setPropertyValue("NavigationHandler.OrbitalNavigator.Anchor", "Rosetta")
    openspace.setPropertyValue("NavigationHandler.OrbitalNavigator.Aim", "")
    openspace.setPropertyValue("NavigationHandler.OrbitalNavigator.RetargetAnchor", nil)
  ]],
  Documentation = "Sets the focus of the camera on Rosetta",
  GuiPath = "/Missions/Rosetta",
  isLocal = false
}

local SetupLanderRelease = {
  Identifier = "os.rosetta.SetupLanderRelease",
  Name = "Set lander release time",
  Command = [[
    openspace.time.setTime("2014-11-12T08:20:00.00")
  ]],
  Documentation = "Jumps to the time when the Philae lander is released",
  GuiPath = "/Missions/Rosetta",
  isLocal = false
}

local ToggleImagePlane = {
  Identifier = "os.rosetta.ToggleImagePlane",
  Name = "Toggle image plane",
  Command = [[
    openspace.setPropertyValueSingle(
      "Scene.ImagePlaneRosetta.Renderable.Enabled",
      not openspace.getPropertyValue("Scene.ImagePlaneRosetta.Renderable.Enabled")
    )
  ]],
  Documentation = "Toggles the visibility of the free floating image plane",
  GuiPath = "/Missions/Rosetta",
  isLocal = false
}

local TogglePhilaeTrail = {
  Identifier = "os.rosetta.TogglePhilaeTrail",
  Name = "Toggle Philae trail",
  Command = [[
    openspace.setPropertyValueSingle(
      "Scene.PhilaeTrail.Renderable.Enabled",
      not openspace.getPropertyValue("Scene.PhilaeTrail.Renderable.Enabled")
    )
  ]],
  Documentation = "Toggles the visibility of Philae's trail",
  GuiPath = "/Missions/Rosetta",
  isLocal = false
}


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

  openspace.addSceneGraphNode(RosettaPosition)
  openspace.addSceneGraphNode(Rosetta)
  openspace.addSceneGraphNode(PhilaePosition)
  openspace.addSceneGraphNode(Philae)
  openspace.addSceneGraphNode(NavCam)
  openspace.addSceneGraphNode(NavCamFov)
  openspace.addSceneGraphNode(ImagePlane)
  openspace.addSceneGraphNode(RosettaCometTrail)
  openspace.addSceneGraphNode(PhilaeTrail)

  openspace.action.registerAction(FocusRosetta)
  openspace.action.registerAction(SetupLanderRelease)
  openspace.action.registerAction(ToggleImagePlane)
  openspace.action.registerAction(TogglePhilaeTrail)
end)

asset.onDeinitialize(function()
  openspace.action.removeAction(TogglePhilaeTrail)
  openspace.action.removeAction(ToggleImagePlane)
  openspace.action.removeAction(SetupLanderRelease)
  openspace.action.removeAction(FocusRosetta)

  openspace.removeSceneGraphNode(PhilaeTrail)
  openspace.removeSceneGraphNode(RosettaCometTrail)
  openspace.removeSceneGraphNode(ImagePlane)
  openspace.removeSceneGraphNode(NavCamFov)
  openspace.removeSceneGraphNode(NavCam)
  openspace.removeSceneGraphNode(Philae)
  openspace.removeSceneGraphNode(PhilaePosition)
  openspace.removeSceneGraphNode(Rosetta)
  openspace.removeSceneGraphNode(RosettaPosition)

  openspace.spice.unloadKernel(RosettaKernels)
end)

asset.export(RosettaPosition)
asset.export(Rosetta)
asset.export(PhilaePosition)
asset.export(Philae)
asset.export(NavCam)
asset.export(NavCamFov)
asset.export(ImagePlane)
asset.export(RosettaCometTrail)
asset.export("FocusRosetta", FocusRosetta.Identifier)
asset.export("SetupLanderRelease", SetupLanderRelease.Identifier)
asset.export("ToggleImagePlane", ToggleImagePlane.Identifier)
asset.export("TogglePhilaeTrail", TogglePhilaeTrail.Identifier)
