local profile = require("core.profile")
local RegionInfo_GetName = function(region)
  local regionTable = game.Map.GetRegionInfo(region)
  local regionID = regionTable.Id
  local REGION_ALFHEIM = "Alfheim"
  local REGION_BEACHCAVE = "BeachCave"
  local REGION_BEACHMAZE = "BeachMaze"
  local REGION_BEACHRUINS = "BeachRuins"
  local REGION_MUSPELHEIM = "MuspelheimArena"
  local REGION_BEACHSHIPWRECK = "BeachShipwreck"
  local REGION_BEACHTOWER = "BeachTower"
  local REGION_BEACHWATERFALL = "BeachWaterfall"
  local REGION_CALDERASHORES = "CalderaShores"
  local REGION_CALDERASHORESA = "CalderaShoresA"
  local REGION_CALDERASHORESB = "CalderaShoresB"
  local REGION_CALDERASHORESC = "CalderaShoresC"
  local REGION_CALDERASHORESD = "CalderaShoresD"
  local REGION_CALDERASHORESE = "CalderaShoresE"
  local REGION_CALDERASHORESF = "CalderaShoresF"
  local REGION_CALDERASHORESG = "CalderaShoresG"
  local REGION_CALDERASHORESH = "CalderaShoresH"
  local REGION_CALDERATEMPLE = "CalderaTemple"
  local REGION_FOOTHILLS = "Foothills"
  local REGION_FOREST = "Forest"
  local REGION_FORESTDUNGEON = "ForestDungeon"
  local REGION_HELHEIM = "Helheim"
  local REGION_HELHEIMRETURN = "HelheimReturn"
  local REGION_HTTK = "HTTK"
  local REGION_HULDRAMINE01 = "HuldraMine01"
  local REGION_HULDRAMINE02 = "HuldraMine02"
  local REGION_HULDRASTRONGHOLD = "HuldraStronghold"
  local REGION_ISLANDARCH = "IslandArch"
  local REGION_ISLANDCLIMB = "IslandClimb"
  local REGION_ISLANDSHIPWRECK = "IslandShipwreck"
  local REGION_LIGHTTEMPLE = "LightTemple"
  local REGION_MASONTRAIL = "MasonTrail"
  local REGION_NIFLHEIMMAIN = "NiflheimMain"
  local REGION_PEAKSPASS = "Peakspass"
  local REGION_RIVERPASS = "Riverpass"
  local REGION_STONEMASON = "Stonemason"
  local REGION_VIKINGFUNERAL = "VikingFuneral"
  local REGION_TYRSVAULT = "TyrsVault"
  local REGION_THEHALLOFTYR = "TheHallofTyr"
  local REGION_NAME_HASH_TO_STRING = {
    [tostring(engine.Hash(REGION_FOOTHILLS))] = REGION_FOOTHILLS,
    [tostring(engine.Hash(REGION_FOREST))] = REGION_FOREST,
    [tostring(engine.Hash(REGION_CALDERATEMPLE))] = REGION_CALDERATEMPLE,
    [tostring(engine.Hash(REGION_CALDERASHORES))] = REGION_CALDERASHORES,
    [tostring(engine.Hash(REGION_CALDERASHORESA))] = REGION_CALDERASHORESA,
    [tostring(engine.Hash(REGION_CALDERASHORESB))] = REGION_CALDERASHORESB,
    [tostring(engine.Hash(REGION_CALDERASHORESC))] = REGION_CALDERASHORESC,
    [tostring(engine.Hash(REGION_CALDERASHORESD))] = REGION_CALDERASHORESD,
    [tostring(engine.Hash(REGION_CALDERASHORESE))] = REGION_CALDERASHORESE,
    [tostring(engine.Hash(REGION_CALDERASHORESF))] = REGION_CALDERASHORESF,
    [tostring(engine.Hash(REGION_CALDERASHORESG))] = REGION_CALDERASHORESG,
    [tostring(engine.Hash(REGION_CALDERASHORESH))] = REGION_CALDERASHORESH,
    [tostring(engine.Hash(REGION_STONEMASON))] = REGION_STONEMASON,
    [tostring(engine.Hash(REGION_RIVERPASS))] = REGION_RIVERPASS,
    [tostring(engine.Hash(REGION_PEAKSPASS))] = REGION_PEAKSPASS,
    [tostring(engine.Hash(REGION_BEACHCAVE))] = REGION_BEACHCAVE,
    [tostring(engine.Hash(REGION_BEACHTOWER))] = REGION_BEACHTOWER,
    [tostring(engine.Hash(REGION_BEACHWATERFALL))] = REGION_BEACHWATERFALL,
    [tostring(engine.Hash(REGION_BEACHSHIPWRECK))] = REGION_BEACHSHIPWRECK,
    [tostring(engine.Hash(REGION_BEACHRUINS))] = REGION_BEACHRUINS,
    [tostring(engine.Hash(REGION_BEACHMAZE))] = REGION_BEACHMAZE,
    [tostring(engine.Hash(REGION_FORESTDUNGEON))] = REGION_FORESTDUNGEON,
    [tostring(engine.Hash(REGION_HULDRAMINE01))] = REGION_HULDRAMINE01,
    [tostring(engine.Hash(REGION_HULDRAMINE02))] = REGION_HULDRAMINE02,
    [tostring(engine.Hash(REGION_HULDRASTRONGHOLD))] = REGION_HULDRASTRONGHOLD,
    [tostring(engine.Hash(REGION_HTTK))] = REGION_HTTK,
    [tostring(engine.Hash(REGION_ISLANDARCH))] = REGION_ISLANDARCH,
    [tostring(engine.Hash(REGION_ISLANDCLIMB))] = REGION_ISLANDCLIMB,
    [tostring(engine.Hash(REGION_ISLANDSHIPWRECK))] = REGION_ISLANDSHIPWRECK,
    [tostring(engine.Hash(REGION_MASONTRAIL))] = REGION_MASONTRAIL,
    [tostring(engine.Hash(REGION_HELHEIM))] = REGION_HELHEIM,
    [tostring(engine.Hash(REGION_HELHEIMRETURN))] = REGION_HELHEIMRETURN,
    [tostring(engine.Hash(REGION_LIGHTTEMPLE))] = REGION_LIGHTTEMPLE,
    [tostring(engine.Hash(REGION_NIFLHEIMMAIN))] = REGION_NIFLHEIMMAIN,
    [tostring(engine.Hash(REGION_MUSPELHEIM))] = REGION_MUSPELHEIM,
    [tostring(engine.Hash(REGION_ALFHEIM))] = REGION_ALFHEIM,
    [tostring(engine.Hash(REGION_VIKINGFUNERAL))] = REGION_VIKINGFUNERAL,
    [tostring(engine.Hash(REGION_TYRSVAULT))] = REGION_TYRSVAULT,
    [tostring(engine.Hash(REGION_THEHALLOFTYR))] = REGION_THEHALLOFTYR
  }
  local hashAsStr = tostring(regionID)
  return REGION_NAME_HASH_TO_STRING[hashAsStr]
end
local SetRegionDiscovered = function(region)
  local regionTable = game.Map.GetRegionInfo(region)
  local regionName = regionTable.Id
  local regionState = regionTable.State
  print("region...........region state", regionState, regionName)
  if regionState ~= tweaks.eTokenState.kDiscovered then
    game.Map.ChangeRegionState(regionName, tweaks.eTokenState.kDiscovered)
  end
end
local SetMarkerState = function(marker, state)
  local kUndiscovered, kDiscovered, kDiscoveredButLocked = 0, 1, 2
  local markerTable = game.Map.GetMarkerInfo(marker)
  local markerName = markerTable.Id
  local markerState = markerTable.State
  if markerState ~= state then
    if state == kUndiscovered then
      game.Map.ChangeMarkerState(markerName, tweaks.eTokenState.kUndiscovered)
      print("setting undiscovered for ......", markerName)
      game.Compass.HideMarker(markerName)
    elseif state == kDiscovered then
      game.Map.ChangeMarkerState(markerName, tweaks.eTokenState.kDiscovered)
      print("setting discovered for ......", markerName)
    elseif state == kDiscoveredButLocked then
      game.Map.ChangeMarkerState(markerName, tweaks.eTokenState.kDiscoveredButLocked)
      print("setting discovered but locked for ......", markerName)
    else
      engine.Warning("Trying to set an invalid state on a marker")
    end
  end
end
local SetAllFTMarkersToDiscovered = function()
  local regionInfoTable = game.Map.GetRegionsInfoTable("Midgard")
  for _, regionInfo in ipairs(regionInfoTable) do
    local regionID = regionInfo.Id
    local regionMarkerInfoTable = game.Map.GetMarkersInfoTable(regionID)
    for _, markerInfo in ipairs(regionMarkerInfoTable) do
      local markerID = markerInfo.Id
      local markerState = markerInfo.State
      local isFT = game.Map.MarkerHasFlag(markerID, {"FastTravel"})
      local isFTnonTrack = game.Map.MarkerHasFlag(markerID, {
        "FastTravelNoTrack"
      })
      if (isFT or isFTnonTrack) and markerState == tweaks.eTokenState.kDiscoveredButLocked then
        game.Map.ChangeMarkerState(markerID, tweaks.eTokenState.kDiscovered)
      end
    end
  end
end
local UpdateJournal = function(resource, type)
  local triptych, loreMarker, scroll, lesson, mimirLore = 0, 1, 5, 6, 7
  if type == triptych then
    engine.SendHook("UI_CALL_EVENT", engine.GetUIWad(), "EVT_SEND_MSG_TO_JOURNAL_LOG", {
      Header = "Lore_Added",
      Body = "New_Triptych_Entry",
      Icon = "Lore",
      Data = {Resource = resource}
    })
  elseif type == loreMarker then
    engine.SendHook("UI_CALL_EVENT", engine.GetUIWad(), "EVT_SEND_MSG_TO_JOURNAL_LOG", {
      Header = "Lore_Added",
      Body = "New_Lore_Marker_Found",
      Icon = "Lore",
      Data = {Resource = resource}
    })
  elseif type == scroll then
    engine.SendHook("UI_CALL_EVENT", engine.GetUIWad(), "EVT_SEND_MSG_TO_JOURNAL_LOG", {
      Header = "Lore_Added",
      Body = "New_Scroll_Found",
      Icon = "Lore",
      Data = {Resource = resource}
    })
  elseif type == lesson then
    engine.SendHook("UI_CALL_EVENT", engine.GetUIWad(), "EVT_SEND_MSG_TO_JOURNAL_LOG", {
      Header = "Lore_Added",
      Body = "New_Lesson_Entry",
      Icon = "Lore",
      Data = {Resource = resource}
    })
  elseif type == mimirLore then
    engine.SendHook("UI_CALL_EVENT", engine.GetUIWad(), "EVT_SEND_MSG_TO_JOURNAL_LOG", {
      Header = "Lore_Added",
      Body = "Mimirs_Tales",
      Icon = "Lore",
      Data = {Resource = resource}
    })
  else
    local value = -1
    if resource ~= nil and resource ~= "" then
      if game.Resources.HasFlag(resource, "SaveOnly") then
        value = game.Wallets.GetResourceValue("HERO_SAVEONLY", resource)
      else
        value = game.Wallets.GetResourceValue("HERO", resource)
      end
    end
    if value < 0 then
      engine.SendHook("UI_CALL_EVENT", engine.GetUIWad(), "EVT_SEND_MSG_TO_JOURNAL_LOG", {
        Header = "Lore_Added",
        Body = "New_Lore_Found",
        Icon = "Lore",
        Data = {Resource = resource}
      })
    end
  end
  if resource ~= nil and resource ~= "" then
    if game.Resources.HasFlag(resource, "SaveOnly") then
      game.Wallets.AddResource("HERO_SAVEONLY", resource, 1)
    else
      game.Wallets.AddResource("HERO", resource, 1)
    end
  end
end
local UpdateMap = function(markerString, type)
  local map, boatDock, docksFirstTime = 0, 1, 2
  local markerTable = game.Map.GetMarkerInfo(markerString)
  local markerID = markerTable.Id
  if type == map then
    engine.SendHook("UI_CALL_EVENT", engine.GetUIWad(), "EVT_SEND_MSG_TO_JOURNAL_LOG", {
      Header = "Map_Updated",
      Body = "New_Location_Found",
      Icon = "Gateway",
      Data = {Mapmarker = markerID}
    })
  elseif type == boatDock then
    engine.SendHook("UI_CALL_EVENT", engine.GetUIWad(), "EVT_SEND_MSG_TO_JOURNAL_LOG", {
      Header = "Map_Updated",
      Body = "New_Boat_Dock_Found",
      Icon = "Dock",
      Data = {Mapmarker = markerID}
    })
  elseif type == docksFirstTime then
    engine.SendHook("UI_CALL_EVENT", engine.GetUIWad(), "EVT_SEND_MSG_TO_JOURNAL_LOG", {
      Header = "Map_Updated",
      Body = "Map_Updated_First_Time",
      Icon = "Dock",
      Data = {Mapmarker = markerID}
    })
  end
end
local UnlockBestiaryEntry = function(resource, uiDelayTime)
  local resourceCount = game.Wallets.GetResourceValue("HERO", resource)
  local tipResource01 = resource .. "_Tip_01"
  local tipResourceCount01 = game.Wallets.GetResourceValue("HERO", tipResource01)
  local tipResource02 = resource .. "_Tip_02"
  local tipResourceCount02 = game.Wallets.GetResourceValue("HERO", tipResource02)
  if resourceCount == -1 or resourceCount == 0 then
    game.Wallets.AddResource("HERO", resource, 1, "Bestiary", "Bestiary")
    if uiDelayTime ~= nil then
      local timer = require("level.timer")
      timer.StartLevelTimer(uiDelayTime, function()
        engine.SendHook("UI_CALL_EVENT", engine.GetUIWad(), "EVT_SEND_MSG_TO_JOURNAL_LOG", {
          Header = "Bestiary_Updated",
          Body = "New_Bestiary_Entry",
          Icon = "Bestiary",
          Data = {Resource = resource}
        })
      end)
    else
      engine.SendHook("UI_CALL_EVENT", engine.GetUIWad(), "EVT_SEND_MSG_TO_JOURNAL_LOG", {
        Header = "Bestiary_Updated",
        Body = "New_Bestiary_Entry",
        Icon = "Bestiary",
        Data = {Resource = resource}
      })
    end
    return
  elseif tipResourceCount01 == -1 then
    game.Wallets.AddResource("HERO", tipResource01, 1, "Bestiary", "Bestiary")
    if game.Wallets.GetResourceValue("HERO", tipResource01) ~= -1 then
      if uiDelayTime ~= nil then
        local timer = require("level.timer")
        timer.StartLevelTimer(uiDelayTime, function()
          engine.SendHook("UI_CALL_EVENT", engine.GetUIWad(), "EVT_SEND_MSG_TO_JOURNAL_LOG", {
            Header = "Bestiary_Updated",
            Body = "New_Tip_Added",
            Icon = "Bestiary",
            Data = {Resource = resource}
          })
        end)
      else
        engine.SendHook("UI_CALL_EVENT", engine.GetUIWad(), "EVT_SEND_MSG_TO_JOURNAL_LOG", {
          Header = "Bestiary_Updated",
          Body = "New_Tip_Added",
          Icon = "Bestiary",
          Data = {Resource = resource}
        })
      end
    end
    return
  elseif tipResourceCount02 == -1 then
    game.Wallets.AddResource("HERO", tipResource02, 1, "Bestiary", "Bestiary")
    if game.Wallets.GetResourceValue("HERO", tipResource02) ~= -1 then
      if uiDelayTime ~= nil then
        local timer = require("level.timer")
        timer.StartLevelTimer(uiDelayTime, function()
          engine.SendHook("UI_CALL_EVENT", engine.GetUIWad(), "EVT_SEND_MSG_TO_JOURNAL_LOG", {
            Header = "Bestiary_Updated",
            Body = "New_Tip_Added",
            Icon = "Bestiary",
            Data = {Resource = resource}
          })
        end)
      else
        engine.SendHook("UI_CALL_EVENT", engine.GetUIWad(), "EVT_SEND_MSG_TO_JOURNAL_LOG", {
          Header = "Bestiary_Updated",
          Body = "New_Tip_Added",
          Icon = "Bestiary",
          Data = {Resource = resource}
        })
      end
    end
    return
  end
end
local UnlockBestiaryEntry_EndOfEncounter = function(resource)
  local uiDelayTime = 6.5
  UnlockBestiaryEntry(resource, uiDelayTime)
end
local SetRealmDiscovered = function(realm)
  local realmTable = game.Map.GetRealmInfo(realm)
  local realmName = realmTable.Id
  local realmState = realmTable.State
  print("realm...........realm state", realmState, realmName)
  if realmState ~= tweaks.eTokenState.kDiscovered then
    game.Map.ChangeRealmState(realmName, tweaks.eTokenState.kDiscovered)
  end
end
local CheckMapDiscoveryState = function()
  print("calling map check")
  if game.Level.GetVariable("CompletedCineNumber") >= 115 and game.Level.GetVariable("CompletedCineNumber") < 180 then
    SetRegionDiscovered("Riverpass")
    print("Forcing map discovery state1")
  elseif game.Level.GetVariable("CompletedCineNumber") >= 180 and game.Level.GetVariable("CompletedCineNumber") < 185 then
    SetRegionDiscovered("Riverpass")
    SetRegionDiscovered("CalderaShores")
    SetRegionDiscovered("CalderaShoresA")
    SetRegionDiscovered("CalderaShoresB")
    SetRegionDiscovered("CalderaShoresC")
    SetRegionDiscovered("CalderaShoresD")
    SetRegionDiscovered("CalderaShoresE")
    SetRegionDiscovered("CalderaShoresF")
    SetRegionDiscovered("CalderaShoresG")
    SetRegionDiscovered("CalderaShoresH")
    print("Forcing map discovery state2")
  elseif game.Level.GetVariable("CompletedCineNumber") >= 185 and game.Level.GetVariable("CompletedCineNumber") < 210 then
    SetRegionDiscovered("Riverpass")
    SetRegionDiscovered("CalderaShores")
    SetRegionDiscovered("Foothills")
    print("Forcing map discovery state3")
    SetRegionDiscovered("CalderaShoresA")
    SetRegionDiscovered("CalderaShoresB")
    SetRegionDiscovered("CalderaShoresC")
    SetRegionDiscovered("CalderaShoresD")
    SetRegionDiscovered("CalderaShoresE")
    SetRegionDiscovered("CalderaShoresF")
    SetRegionDiscovered("CalderaShoresG")
    SetRegionDiscovered("CalderaShoresH")
  elseif game.Level.GetVariable("CompletedCineNumber") >= 210 and game.Level.GetVariable("CompletedCineNumber") < 270 then
    SetRegionDiscovered("Riverpass")
    SetRegionDiscovered("CalderaShores")
    SetRegionDiscovered("Realm Travel Room")
    SetRegionDiscovered("Foothills")
    SetRealmDiscovered("Alfheim")
    SetRegionDiscovered("CalderaShoresA")
    SetRegionDiscovered("CalderaShoresB")
    SetRegionDiscovered("CalderaShoresC")
    SetRegionDiscovered("CalderaShoresD")
    SetRegionDiscovered("CalderaShoresE")
    SetRegionDiscovered("CalderaShoresF")
    SetRegionDiscovered("CalderaShoresG")
    SetRegionDiscovered("CalderaShoresH")
    print("Forcing map discovery state4")
  elseif game.Level.GetVariable("CompletedCineNumber") >= 270 and game.Level.GetVariable("CompletedCineNumber") < 350 then
    SetRegionDiscovered("Riverpass")
    SetRegionDiscovered("CalderaShores")
    SetRegionDiscovered("Realm Travel Room")
    SetRegionDiscovered("Foothills")
    SetRealmDiscovered("Alfheim")
    SetRegionDiscovered("CalderaShoresA")
    SetRegionDiscovered("CalderaShoresB")
    SetRegionDiscovered("CalderaShoresC")
    SetRegionDiscovered("CalderaShoresD")
    SetRegionDiscovered("CalderaShoresE")
    SetRegionDiscovered("CalderaShoresF")
    SetRegionDiscovered("CalderaShoresG")
    SetRegionDiscovered("CalderaShoresH")
    SetRegionDiscovered("Peakspass")
    SetRegionDiscovered("Hive")
    SetRegionDiscovered("Secret Temple")
    print("Forcing map discovery state5")
  elseif game.Level.GetVariable("CompletedCineNumber") >= 350 and game.Level.GetVariable("CompletedCineNumber") < 387 then
    SetRegionDiscovered("Riverpass")
    SetRegionDiscovered("CalderaShores")
    SetRegionDiscovered("Realm Travel Room")
    SetRegionDiscovered("Foothills")
    SetRealmDiscovered("Alfheim")
    SetRegionDiscovered("CalderaShoresA")
    SetRegionDiscovered("CalderaShoresB")
    SetRegionDiscovered("CalderaShoresC")
    SetRegionDiscovered("CalderaShoresD")
    SetRegionDiscovered("CalderaShoresE")
    SetRegionDiscovered("CalderaShoresF")
    SetRegionDiscovered("CalderaShoresG")
    SetRegionDiscovered("CalderaShoresH")
    SetRegionDiscovered("Peakspass")
    SetRegionDiscovered("Hive")
    SetRegionDiscovered("Secret Temple")
    SetRegionDiscovered("Stonemason")
    SetRegionDiscovered("StoneMason Connector")
    SetRegionDiscovered("MasonTrail")
    print("Forcing map discovery state6")
  elseif game.Level.GetVariable("CompletedCineNumber") >= 387 and game.Level.GetVariable("CompletedCineNumber") < 492 then
    SetRegionDiscovered("Riverpass")
    SetRegionDiscovered("CalderaShores")
    SetRegionDiscovered("Realm Travel Room")
    SetRegionDiscovered("Foothills")
    SetRealmDiscovered("Alfheim")
    SetRegionDiscovered("CalderaShoresA")
    SetRegionDiscovered("CalderaShoresB")
    SetRegionDiscovered("CalderaShoresC")
    SetRegionDiscovered("CalderaShoresD")
    SetRegionDiscovered("CalderaShoresE")
    SetRegionDiscovered("CalderaShoresF")
    SetRegionDiscovered("CalderaShoresG")
    SetRegionDiscovered("CalderaShoresH")
    SetRegionDiscovered("Peakspass")
    SetRegionDiscovered("Hive")
    SetRegionDiscovered("Secret Temple")
    SetRegionDiscovered("Stonemason")
    SetRegionDiscovered("StoneMason Connector")
    SetRegionDiscovered("MasonTrail")
    SetRealmDiscovered("Helheim")
    print("Forcing map discovery state7")
  elseif game.Level.GetVariable("CompletedCineNumber") >= 492 then
    SetRegionDiscovered("Riverpass")
    SetRegionDiscovered("CalderaShores")
    SetRegionDiscovered("Realm Travel Room")
    SetRegionDiscovered("Foothills")
    SetRealmDiscovered("Alfheim")
    SetRegionDiscovered("MasonTrail")
    SetRegionDiscovered("CalderaShoresA")
    SetRegionDiscovered("CalderaShoresB")
    SetRegionDiscovered("CalderaShoresC")
    SetRegionDiscovered("CalderaShoresD")
    SetRegionDiscovered("CalderaShoresE")
    SetRegionDiscovered("CalderaShoresF")
    SetRegionDiscovered("CalderaShoresG")
    SetRegionDiscovered("CalderaShoresH")
    SetRegionDiscovered("Peakspass")
    SetRegionDiscovered("Hive")
    SetRegionDiscovered("Secret Temple")
    SetRegionDiscovered("Stonemason")
    SetRegionDiscovered("StoneMason Connector")
    SetRegionDiscovered("HelheimReturn")
    SetRegionDiscovered("BeachCave")
    SetRegionDiscovered("BeachTower")
    SetRegionDiscovered("VikingFuneral")
    SetRegionDiscovered("HuldraMine02")
    SetRegionDiscovered("HuldraMine01")
    SetRegionDiscovered("HTTK")
    SetRegionDiscovered("ForestDungeon")
    SetRegionDiscovered("IslandArch")
    SetRegionDiscovered("HuldraStronghold")
    SetRegionDiscovered("BeachMaze")
    SetRegionDiscovered("IslandClimb")
    SetRegionDiscovered("IslandShipwreck")
    SetRegionDiscovered("BeachShipwreck")
    SetRegionDiscovered("BeachWaterfall")
    print("Forcing map discovery state8")
  end
end
local SetFastTravelMarkerDiscovered = function(marker)
  local calMarkerName = "CALT_120_FT"
  if marker ~= nil then
    if game.Level.GetVariable("CompletedCineNumber") < 400 then
      if marker ~= calMarkerName then
        SetMarkerState(marker, 2)
      else
        SetMarkerState(marker, 1)
      end
    elseif game.Level.GetVariable("CompletedCineNumber") >= 400 then
      SetMarkerState(marker, 1)
    end
  end
end
local CheckFastTravelState = function()
  print("Checking fast travel state")
  if game.Level.GetVariable("CompletedCineNumber") >= 387 and game.Level.GetVariable("CompletedCineNumber") < 400 then
    SetMarkerState("Riv925_FreyaHouse", 1)
  else
    SetMarkerState("Riv925_FreyaHouse", 0)
  end
  if game.Level.GetVariable("CompletedCineNumber") >= 540 then
    SetMarkerState("SM_100_FT", 0)
  end
  if game.Level.GetVariable("_GBL_WaterDrop02Triggered") == true then
    SetMarkerState("RP_935_Upper_FT", 0)
  end
  if game.Level.GetVariable("CompletedCineNumber") >= 400 then
    print("Checking fast travel state stage 2")
    SetAllFTMarkersToDiscovered()
  end
end
local AddRecipe_Safe = function(walletName, recipeName)
  if not game.Wallets.HasRecipe(walletName, recipeName) then
    game.Wallets.AddRecipe(walletName, recipeName)
  end
end
local FixupRessurectionStones = function(stoneTable, softSavedStone, givenBackStone)
  local finalStone = softSavedStone == nil and givenBackStone or softSavedStone
  local currentStones = {}
  for stone, _ in pairs(stoneTable) do
    local stoneCount = game.Wallets.GetResourceValue("HERO", stone)
    if 0 < stoneCount then
      table.insert(currentStones, stone)
    end
  end
  local totalStones = #currentStones
  if 1 < totalStones then
    engine.Warning("After syncing resurrection stones, we have " .. totalStones .. " keeping only : " .. finalStone)
    for _, resource in pairs(currentStones) do
      if resource ~= finalStone then
        local heroCount = game.Wallets.GetResourceValue("HERO", resource)
        game.Wallets.RemoveResource("HERO", resource, heroCount)
        local saveOnlyCount = game.Wallets.GetResourceValue("HERO_SAVEONLY", resource)
        game.Wallets.RemoveResource("HERO_SAVEONLY", resource, saveOnlyCount)
      end
    end
  end
  local flagCount = game.Wallets.GetResourceValue("HERO", "ResurrectionStoneFlag")
  if 0 < flagCount and 0 < totalStones then
    engine.Warning("Hero has resurrectionStoneFlag while he has a stone in his wallet")
    game.Wallets.RemoveResource("HERO", "ResurrectionStoneFlag", flagCount)
    AddRecipe_Safe("HERO", stoneTable[finalStone].SellRecipe)
  end
end
local SyncResurrectionStones = function(fixupOnRestart)
  local stones = {
    ResurrectionRuneStoneA = {
      SoldMarker = "ResurrectionStoneASold",
      SellRecipe = "Recipe_ResurrectionRuneStoneA_Sell"
    },
    ResurrectionRuneStoneB = {
      SoldMarker = "ResurrectionStoneBSold",
      SellRecipe = "Recipe_ResurrectionRuneStoneB_Sell"
    },
    ResurrectionRuneStoneC = {
      SoldMarker = "ResurrectionStoneCSold",
      SellRecipe = "Recipe_ResurrectionRuneStoneC_Sell"
    }
  }
  local softSavedStone, givenBackStone
  for stone, stoneInfo in pairs(stones) do
    local heroWalletValue = game.Wallets.GetResourceValue("HERO", stone)
    local saveOnlyWalletValue = game.Wallets.GetResourceValue("HERO_SAVEONLY", stone)
    heroWalletValue = heroWalletValue == -1 and 0 or heroWalletValue
    saveOnlyWalletValue = saveOnlyWalletValue == -1 and 0 or saveOnlyWalletValue
    local isStoneSold = game.Wallets.GetResourceValue("HERO", stoneInfo.SoldMarker) > 0
    if 0 < heroWalletValue then
      softSavedStone = stone
    end
    if heroWalletValue ~= saveOnlyWalletValue then
      if heroWalletValue > saveOnlyWalletValue then
        game.Wallets.AddResource("HERO_SAVEONLY", stone, heroWalletValue - saveOnlyWalletValue)
      elseif isStoneSold then
        if 0 < saveOnlyWalletValue then
          game.Wallets.RemoveResource("HERO_SAVEONLY", stone, saveOnlyWalletValue)
        end
      else
        givenBackStone = stone
        game.Wallets.AddResource("HERO", stone, saveOnlyWalletValue)
        AddRecipe_Safe("HERO", stoneInfo.SellRecipe)
        local resCount = game.Wallets.GetResourceValue("HERO", "ResurrectionStoneFlag")
        if 0 < resCount then
          game.Wallets.RemoveResource("HERO", "ResurrectionStoneFlag", resCount)
        end
      end
    end
  end
  if fixupOnRestart then
    FixupRessurectionStones(stones, softSavedStone, givenBackStone)
  end
end
local RollContainerConditionLoot = function(containerAndRarity, tier, WADName, index, gifter)
  if gifter == nil then
    gifter = "Unknown RollContainerConditionLoot"
  end
  local fullName = containerAndRarity .. tostring(tier) .. "_" .. string.upper(WADName) .. "_" .. tostring(index)
  local wadName = containerAndRarity .. tostring(tier) .. "_" .. string.upper(WADName)
  local levelName = containerAndRarity .. tostring(tier) .. "_" .. string.upper(WADName:gsub("%d", ""))
  local tierName = containerAndRarity .. tostring(tier)
  local defaultName = containerAndRarity .. "00"
  local switchTable = {
    function()
      return game.Loot.RollCondition(fullName, "HERO", nil, gifter)
    end,
    function()
      return game.Loot.RollConditionSet(fullName, "HERO", nil, gifter)
    end,
    function()
      return game.Loot.RollCondition(wadName, "HERO", nil, gifter)
    end,
    function()
      return game.Loot.RollConditionSet(wadName, "HERO", nil, gifter)
    end,
    function()
      return game.Loot.RollCondition(levelName, "HERO", nil, gifter)
    end,
    function()
      return game.Loot.RollConditionSet(levelName, "HERO", nil, gifter)
    end,
    function()
      return game.Loot.RollCondition(tierName, "HERO", nil, gifter)
    end,
    function()
      return game.Loot.RollConditionSet(tierName, "HERO", nil, gifter)
    end,
    function()
      return game.Loot.RollCondition(defaultName, "HERO", nil, gifter)
    end,
    function()
      return game.Loot.RollConditionSet(defaultName, "HERO", nil, gifter)
    end,
    function()
      engine.Warning("Unable to resolve loot table for " .. fullName)
    end
  }
  for i = 1, #switchTable do
    if switchTable[i]() then
      break
    end
  end
end
local ConsumeNiflheimCurrency = function(toConsume)
  local currentCurrency = game.Wallets.GetResourceValue("HERO", "NiflheimCurrency")
  if currentCurrency <= 0 then
    return
  end
  if toConsume == nil then
    toConsume = currentCurrency
  else
    toConsume = math.min(toConsume, currentCurrency)
  end
  game.Wallets.RemoveResource("HERO", "NiflheimCurrency", toConsume)
end
return profile.WrapLibrary({
  SetRegionDiscovered = SetRegionDiscovered,
  RegionInfo_GetName = RegionInfo_GetName,
  SetAllFTMarkersToDiscovered = SetAllFTMarkersToDiscovered,
  UpdateJournal = UpdateJournal,
  UpdateMap = UpdateMap,
  UnlockBestiaryEntry = UnlockBestiaryEntry,
  UnlockBestiaryEntry_EndOfEncounter = UnlockBestiaryEntry_EndOfEncounter,
  CheckMapDiscoveryState = CheckMapDiscoveryState,
  SetRealmDiscovered = SetRealmDiscovered,
  SetMarkerState = SetMarkerState,
  SetFastTravelMarkerDiscovered = SetFastTravelMarkerDiscovered,
  CheckFastTravelState = CheckFastTravelState,
  AddRecipe_Safe = AddRecipe_Safe,
  SyncResurrectionStones = SyncResurrectionStones,
  RollContainerConditionLoot = RollContainerConditionLoot,
  ConsumeNiflheimCurrency = ConsumeNiflheimCurrency
})
