local LD = require("design.LevelDesignLibrary")
local timers = require("level.timer")
local color = require("core.color")
local thisObj
local curRuneNum = 1
local totalRuneSlots = 3
local currentState = 1
local runeTable = {}
local cwObject, ccwObject, flipperModule
local isRevealedByLight = false
local isLit
local onStartRotate = {}
local onRotate = {}
local log = ""
local isDim = false
local debug_runesOn = false
function OnScriptLoaded(level, obj)
  thisObj = obj
  isRevealedByLight = obj:GetLuaTableAttribute("RevealedByLight")
  local isFreeStanding = obj:GetLuaTableAttribute("FreeStanding")
  runeTable[1] = {
    num = 1,
    frame = 0,
    snapBackframe = 112,
    slotObj = nil,
    runeVisual = nil
  }
  runeTable[2] = {
    num = 2,
    frame = 40,
    snapBackframe = 32,
    slotObj = nil,
    runeVisual = nil
  }
  runeTable[3] = {
    num = 3,
    frame = 80,
    snapBackframe = 72,
    slotObj = nil,
    runeVisual = nil
  }
  for i = 1, totalRuneSlots do
    runeTable[i].num = obj:FindLuaTableAttribute("RuneSlot" .. tostring(i))
    runeTable[i].runeVisual = thisObj:FindSingleGOByName("RuneGroup" .. tostring(i))
  end
  cwObject = thisObj:FindSingleGOByName("cwObject")
  ccwObject = thisObj:FindSingleGOByName("ccwObject")
  if isFreeStanding == true then
    local floorStand = obj:FindSingleGOByName("FloorStand")
    floorStand:Hide()
  end
  currentState = 1
  game.SubObject.Sleep(obj)
end
function OnPreStart(level, obj)
  curRuneNum = runeTable[currentState].num
  local frameTable = {
    enabled = 0,
    disabled = 60,
    dimEnabled = 60,
    dimDisabled = 60
  }
  for i = 1, totalRuneSlots do
    runeTable[i].runeVisual.LuaObjectScript.SetDimFrames(frameTable)
    runeTable[i].runeVisual.LuaObjectScript.SelectRune(runeTable[i].num)
  end
end
function OnFirstStart(level, obj)
  for i = 1, totalRuneSlots do
    if isRevealedByLight then
      runeTable[i].runeVisual.LuaObjectScript.HideRune(runeTable[i].num)
    end
  end
end
function OnSaveCheckpoint(level, obj)
  return {previousState = currentState}
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  currentState = savedInfo.previousState
end
function StoreFlipperObj(newFlipper)
  flipperModule = newFlipper
end
function SoftSave()
  game.SubObject.SoftSave(thisObj)
  flipperModule.LuaObjectScript.SoftSave()
end
function ResolveSoftSave()
  flipperModule.LuaObjectScript.ResolveSoftSave(currentState)
end
function AnimSyncToSpinner(cwSyncObj, ccwSyncObj, rate)
  game.GameObject.AnimSync(cwObject, cwSyncObj)
  game.GameObject.AnimSync(ccwObject, ccwSyncObj)
end
function RotateClockwise(newState, playRate)
  currentState = newState
  if isRevealedByLight == false or isLit == true then
    curRuneNum = runeTable[newState].num
    ExecuteOnRotate()
  end
end
function RotateCounterclockwise(newState, playRate)
  currentState = newState
  if isRevealedByLight == false or isLit == true then
    curRuneNum = runeTable[newState].num
    ExecuteOnRotate()
  end
end
function GetCurrentRune()
  if isRevealedByLight and isLit == false then
    return -1
  end
  return curRuneNum
end
function OverrideRuneNumber(i, runeNumber)
  runeTable[i].num = runeNumber
  runeTable[i].runeVisual.LuaObjectScript.SelectRune(runeNumber)
  runeTable[i].runeVisual.LuaObjectScript.ShowRune()
  runeTable[i].runeVisual.LuaObjectScript.Enable()
  curRuneNum = runeTable[currentState].num
end
function ResetRotateCW()
  return flipperModule.LuaObjectScript.ResetRotateCW()
end
function ResetRotateCCW()
  return flipperModule.LuaObjectScript.ResetRotateCCW()
end
function RotateCW()
  flipperModule.LuaObjectScript.RotateCW()
end
function RotateCCW()
  flipperModule.LuaObjectScript.RotateCCW()
end
function RegisterOnRotateCallback(fn)
  if fn ~= nil then
    table.insert(onRotate, fn)
  end
end
function ExecuteOnRotate()
  for i = 1, #onRotate do
    onRotate[i]()
  end
end
function ShowRunes()
  for i = 1, totalRuneSlots do
    runeTable[i].runeVisual.LuaObjectScript.ShowRune()
  end
end
function HideRunes()
  for i = 1, totalRuneSlots do
    runeTable[i].runeVisual.LuaObjectScript.HideRune()
  end
end
function LightReveal()
  isLit = true
  ShowRunes()
end
function LightHide()
  isLit = false
  HideRunes()
end
function DimRunes()
  for i = 1, 3 do
    runeTable[i].runeVisual.LuaObjectScript.Dim()
  end
end
function UndimRunes()
  for i = 1, 3 do
    runeTable[i].runeVisual.LuaObjectScript.Undim()
  end
end
function Debug_ToggleRunes()
  debug_runesOn = not debug_runesOn
  if debug_runesOn then
    for i = 1, 3 do
      runeTable[i].runeVisual.LuaObjectScript.Enable()
    end
  else
    for i = 1, 3 do
      runeTable[i].runeVisual.LuaObjectScript.Disable()
    end
  end
end
function ShowDebugText()
  local debugText = thisObj.Parent:GetName()
  local newState = currentState + 1
  if 3 < newState then
    newState = 1
  end
  debugText = debugText .. [[

 CW Frame ]] .. tostring(cwObject.AnimFrame)
  debugText = debugText .. [[

 CCW Frame ]] .. tostring(ccwObject.AnimFrame)
  debugText = debugText .. [[

> Current-Future State ]] .. tostring(currentState)
  engine.DrawTextInWorld(thisObj:GetWorldPosition(), debugText, color.white)
end
