local constellationsCSV = asset.localResource("constellation_data.csv")
local transforms = asset.require("scene/solarsystem/sun/transforms")

local images = asset.syncedResource({
    Name = "Constellation Images",
    Type = "HttpSynchronization",
    Identifier = "constellation_images",
    Version = 4
})

--function that reads the file
local createConstellations = function (baseIdentifier, guiPath, constellationfile)
  local genConstellations = {};
  --skip the first line
  local notFirstLine = false;
  -- define parsec to meters
  local PARSEC_CONSTANT = 3.0856776E16;
  -- how many parsecs away do you want the images to be?
  -- this setting puts the billboards at the location of the constellation bounds grid from DU.
  -- but they can really be anywhere since the billboard size will scale with distance.
  local distanceMultiplier = 3.2;
  local baseScale = 1e17;
  for line in io.lines(openspace.absPath(constellationfile)) do
    if (notFirstLine) then
      -- describes the data
      local matchstring = "(.-),(.-),(.-),(.-),(.-),(.-),(.-),(.-),(.-),(.-),(.-),(.-)$"
      local group, abbreviation, name, x, y, z, scale, imageName, rotX, rotY, rotZ, centerStar = line:match(matchstring)
      local magVec = math.sqrt(x*x + y*y + z*z)
      local normx = x/magVec
      local normy = y/magVec
      local normz = z/magVec

      group = (group == "" and globe or group)

      local aconstellation = {
        -- Identifier = guiPath .. "-" .. name,
        Identifier = baseIdentifier .. "-" .. abbreviation,
        Parent = transforms.SolarSystemBarycenter.Identifier,
        Transform = {
          Translation = {
            Type = "StaticTranslation",
            -- position is in parsecs from the SolarSystemBarycenter, so convert to meters
            Position = {
              normx * PARSEC_CONSTANT * distanceMultiplier,
              normy * PARSEC_CONSTANT * distanceMultiplier,
              normz * PARSEC_CONSTANT * distanceMultiplier
            }
          },
          Rotation = {
            Type = "StaticRotation",
            Rotation = { tonumber(rotX), tonumber(rotY), tonumber(rotZ) }
          }
        },
        Renderable = {
          Type = "RenderablePlaneImageLocal",
          Size = tonumber(baseScale * scale * distanceMultiplier / 10),
          Enabled = false,
          Origin = "Center",
          Billboard = false,
          LazyLoading = true,
          Texture = images .. imageName,
          BlendMode = "Additive",
          Opacity = 0.1
        },
        Tag = { "ImageConstellation", group },
        GUI = {
          Name = name .. " Image",
          Path = "/Milky Way/" .. guiPath,
          Description = name .. " Image"
        }
      }
      table.insert(genConstellations, aconstellation);

    else
      notFirstLine = true
    end
  end
  return genConstellations
end


local show_art = {
  Identifier = "constellation_art.show_art",
  Name = "Show Constellation Art",
  Command = [[
    openspace.setPropertyValue("Scene.ImageConstellation*.Renderable.Opacity", 0);
    openspace.setPropertyValue("Scene.ImageConstellation*.Renderable.Enabled", true);
    openspace.setPropertyValue("Scene.ImageConstellation*.Renderable.Opacity", 0.2, 2);
  ]],
  Documentation = "Enables and fades up constellation art work",
  GuiPath = "/Rendering",
  IsLocal = false
}
asset.export("ShowArtAction", show_art)

local hide_art = {
  Identifier = "constellation_art.hide_art",
  Name = "Hide Constellation Art",
  Command = [[openspace.setPropertyValue("Scene.ImageConstellation*.Renderable.Opacity", 0, 2)]],
  Documentation = "Fades out constellation artwork",
  GuiPath = "/Rendering",
  IsLocal = false
}
asset.export("HideArtAction", hide_art)

local disable_art = {
  Identifier = "constellation_art.disable_art",
  Name = "Disable Constellation Art",
  Command = [[openspace.setPropertyValue("Scene.ImageConstellation*.Renderable.Enabled", false)]],
  Documentation = "Disable constellation artwork",
  GuiPath = "/Rendering",
  IsLocal = false
}
asset.export("DisableArtAction", disable_art)

local show_zodiac_art = {
  Identifier = "constellation_art.show_zodiac_art",
  Name = "Show Zodiac Art",
  Command = [[
    openspace.setPropertyValue("Scene.ImageConstellation*.Renderable.Opacity", 0);
    openspace.setPropertyValue("{zodiac}.Renderable.Enabled",true);
    openspace.setPropertyValue("{zodiac}.Renderable.Opacity", 1, 2);
  ]],
  Documentation = "Enables and fades up zodiac art work",
  GuiPath = "/Rendering",
  IsLocal = false
}
asset.export("ShowZodiacArt", show_zodiac_art)

local hide_zodiac_art = {
  Identifier = "constellation_art.hide_zodiac_art",
  Name = "Hide Zodiac Art",
  Command =  [[openspace.setPropertyValue("{zodiac}.Renderable.Opacity", 0, 2)]],
  Documentation = "fades down zodiac art work",
  GuiPath = "/Rendering",
  IsLocal = false
}
asset.export("HideZodiacArt", hide_zodiac_art)

local nodes = {}

asset.onInitialize(function ()
  local constellationsCSV = images .. "constellation_data.csv"

  nodes = createConstellations("ImageConstellation", "Constellation Art", constellationsCSV)
  for _, n in ipairs(nodes) do
    openspace.addSceneGraphNode(n);
  end

  openspace.action.registerAction(show_art)
  openspace.action.registerAction(hide_art)
  openspace.action.registerAction(disable_art)
  openspace.action.registerAction(show_zodiac_art)
  openspace.action.registerAction(hide_zodiac_art)
end)

asset.onDeinitialize(function ()
  for _, n in ipairs(nodes) do
    openspace.removeSceneGraphNode(n.Identifier);
  end

  openspace.action.removeAction(hide_zodiac_art)
  openspace.action.removeAction(show_zodiac_art)
  openspace.action.removeAction(disable_art)
  openspace.action.removeAction(hide_art)
  openspace.action.removeAction(show_art)
end)

for _, n in ipairs(nodes) do
  asset.export(n)
end

asset.meta = {
  Name = "Constellation Images",
  Version = "1.1",
  Description = "Artistic images depicting the constellations",
  Author = "James Hedberg",
  URL = "http://jameshedberg.com",
  License = "CC-BY"
}
