local timers, thisObj, thisLevel
local enable = true
local isDim = false
local frameTable = {}
local runeTable
local runeKey = "A"
local runeSymbolNumber = 1
local isHidden = false
local isDragonRunes = false
local myTimer
local timers_LoadLibrary = function()
  if timers == nil then
    timers = require("level.timer")
  end
end
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  isDragonRunes = thisObj:FindLuaTableAttribute("IsDragonRune")
  if isDragonRunes then
    runeTable = {
      Jormungandr = {min = 1, max = 1},
      Fafnirr = {min = 2, max = 2},
      Nidhoggr = {min = 3, max = 3}
    }
    runeKey = "Jormungandr"
  else
    runeTable = {
      A = {min = 1, max = 4},
      B = {min = 5, max = 8},
      F = {min = 9, max = 12},
      N = {min = 13, max = 16},
      P = {min = 17, max = 20},
      R = {min = 21, max = 24},
      S = {min = 25, max = 28},
      T = {min = 29, max = 32},
      TH = {min = 33, max = 36},
      H = {min = 37, max = 38}
    }
  end
  for key, _ in pairs(runeTable) do
    runeTable[key].obj = thisObj:FindSingleGOByName("Rune_" .. key)
    if runeTable[key].obj == nil then
      engine.Error("MISSING RUNES !! " .. key)
    elseif runeTable[key].obj.IsRefNode then
      runeTable[key].obj = runeTable[key].obj.Child
    end
    runeTable[key].obj:Hide()
  end
  frameTable = {
    enabled = 0,
    disabled = runeTable[runeKey].obj.AnimLengthFrames,
    dimEnabled = 30,
    dimDisabled = runeTable[runeKey].obj.AnimLengthFrames
  }
  game.SubObject.Sleep(obj)
end
function OnStart(level, obj)
  if enable then
    Enable()
  else
    Disable()
  end
  if isDim then
    Dim()
  else
    Undim()
  end
  if isHidden then
    HideRune()
  else
    ShowRune()
  end
end
function OnSaveCheckpoint(level, obj)
  return {
    enable = enable,
    isDim = isDim,
    frameTable = frameTable,
    isHidden = isHidden
  }
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  enable = savedInfo.enable
  isDim = savedInfo.isDim
  frameTable = savedInfo.frameTable
  isHidden = savedInfo.isHidden
end
function Enable(args)
  enable = true
  local delay
  if args then
    delay = args.delay or nil
  end
  if myTimer ~= nil then
    myTimer:Stop()
    myTimer = nil
  end
  if not isDim then
    if delay and 0 < delay then
      timers_LoadLibrary()
      myTimer = timers.StartLevelTimer(delay, function()
        runeTable[runeKey].obj:PlayAnimToFrame(frameTable.enabled, -1)
        myTimer = nil
      end)
    else
      runeTable[runeKey].obj:PlayAnimToFrame(frameTable.enabled, -1)
    end
  else
    Dim()
  end
end
function Disable()
  enable = false
  if myTimer ~= nil then
    myTimer:Stop()
    myTimer = nil
  end
  if not isDim then
    runeTable[runeKey].obj:PlayAnimToFrame(frameTable.disabled, 1.3)
  else
    Dim()
  end
end
function IsEnabled()
  return enable
end
function Dim(animSpeed)
  isDim = true
  if enable then
    if runeTable[runeKey].obj.AnimFrame < frameTable.dimEnabled then
      animSpeed = animSpeed or 0.8
    else
      animSpeed = animSpeed or -0.5
    end
    runeTable[runeKey].obj:PlayAnimToFrame(frameTable.dimEnabled, animSpeed)
  else
    if runeTable[runeKey].obj.AnimFrame < frameTable.dimDisabled then
      animSpeed = animSpeed or -0.7
    else
      animSpeed = animSpeed or 0.7
    end
    runeTable[runeKey].obj:PlayAnimToFrame(runeTable[runeKey].obj.AnimLengthFrames, animSpeed)
  end
end
function Undim(animSpeed)
  isDim = false
  if enable then
    runeTable[runeKey].obj:PlayAnimToFrame(frameTable.enabled, -1)
  else
    runeTable[runeKey].obj:PlayAnimToFrame(frameTable.disabled, -1)
  end
end
function HideRune()
  isHidden = true
  runeTable[runeKey].obj:Hide()
end
function ShowRune()
  isHidden = false
  runeTable[runeKey].obj:Show()
end
function SelectRune(index)
  if runeSymbolNumber == index then
    return
  end
  if runeKey then
    runeTable[runeKey].obj:Hide()
  end
  index = index or 1
  for key, _ in pairs(runeTable) do
    if index >= runeTable[key].min and index <= runeTable[key].max then
      runeSymbolNumber = index
      runeKey = key
      thisObj:JumpAnimToFrame((runeSymbolNumber - runeTable[runeKey].min) * 10)
      thisObj:PauseAnim()
      return
    end
  end
end
function CheckInBounds(value)
  if 38 <= value or value < 0 then
    engine.Error(" Error in ShowRune() on  ", thisObj.Parent:GetName(), " in level ", thisLevel:GetName(), " index provided ", tostring(value), " is out of bounds ")
    return
  end
end
function SetDimFrames(newTable)
  if newTable.enabled then
    frameTable.enabled = newTable.enabled
  end
  if newTable.disabled then
    frameTable.disabled = newTable.disabled
  end
  if newTable.dimEnabled then
    frameTable.dimEnabled = newTable.dimEnabled
  end
  if newTable.dimDisabled then
    frameTable.dimDisabled = newTable.dimDisabled
  end
end
function GetRuneNumber()
  return runeSymbolNumber
end
function GetDebugText()
  local debugText = "RuneRefNode: " .. thisObj.Parent:GetName()
  debugText = debugText .. [[

>RotateFrame: ]] .. tostring(thisObj.AnimFrame)
  debugText = debugText .. [[

>Hidden: ]] .. tostring(isHidden)
  debugText = debugText .. [[

>Enable: ]] .. tostring(enable)
  if runeKey and runeTable[runeKey].obj then
    debugText = debugText .. [[

>RuneLetter: ]] .. tostring(runeKey)
    debugText = debugText .. [[

	>AnimFrame: ]] .. tostring(runeTable[runeKey].obj.AnimFrame)
  end
  return debugText
end
function ShowDebugText()
  if engine.IsDebug() then
    local color = require("core.color")
    engine.DrawTextInWorld(thisObj:GetWorldPosition() + engine.Vector.New(-0.15, 0.75, 0), GetDebugText(), color.white)
  end
end
