local LD = require("design.LevelDesignLibrary")
local timers = require("level.timer")
local thisObj
local previousState = 1
local currentState = 1
local playRate = 1.5
local animFrameStep = 1
local animSynchedObjects = {}
local flipperModule
function OnScriptLoaded(level, obj)
  thisObj = obj
  local cwCollision_obj = thisObj:FindSingleGOByName("cwObject_Collision")
  local ccwCollision_obj = thisObj:FindSingleGOByName("ccwObject_Collision")
  flipperModule = thisObj:FindSingleGOByName("FlipperModule").Child
  local animSynchedObjectNames = thisObj:GetLuaTableAttribute("ThingsToSpin")
  local activeCount = obj:GetLuaTableAttribute("NumberOfPaddles")
  local displayHead = obj:GetLuaTableAttribute("DisplayHead")
  playRate = flipperModule:GetLuaTableAttribute("playRate")
  animSynchedObjectNames = LD.ConvertStringListToTable(animSynchedObjectNames)
  for i = 1, #animSynchedObjectNames do
    local obj = GameObjects[animSynchedObjectNames[i]]
    if obj ~= nil then
      table.insert(animSynchedObjects, obj)
    end
  end
  if activeCount < 3 then
    local Paddle = cwCollision_obj:GetJointIndex("Paddle_01_Hit_CW")
    cwCollision_obj:HideJoint(Paddle)
    Paddle = ccwCollision_obj:GetJointIndex("Paddle_01_Hit_CCW")
    ccwCollision_obj:HideJoint(Paddle)
    thisObj:FindSingleGOByName("DiskA"):Hide()
  end
  if activeCount < 2 then
    local Paddle = cwCollision_obj:GetJointIndex("Paddle_02_Hit_CW")
    cwCollision_obj:HideJoint(Paddle)
    Paddle = ccwCollision_obj:GetJointIndex("Paddle_02_Hit_CCW")
    ccwCollision_obj:HideJoint(Paddle)
    thisObj:FindSingleGOByName("DiskB"):Hide()
  end
  if displayHead == false then
    local headPiece = thisObj:FindSingleGOByName("Head")
    headPiece:Hide()
  end
  game.SubObject.Sleep(obj)
  game.SubObject.SetForgetOnCheckpoint(obj)
  SoundInit()
end
function OnPreStart(level, obj)
  for i = 1, #animSynchedObjects do
    if animSynchedObjects[i].LuaObjectScript.StoreFlipperObj then
      animSynchedObjects[i].LuaObjectScript.StoreFlipperObj(flipperModule)
    end
  end
end
function OnStart(level, obj)
  previousState = flipperModule.LuaObjectScript.GetCurrentState()
  flipperModule.LuaObjectScript.RegisterOnRotateCWCallback(OnRotateClockwiseCallback)
  flipperModule.LuaObjectScript.RegisterOnRotateCCWCallback(OnRotateCounterclockwiseCallback)
  local cwObject = obj:FindSingleGOByName("cwObject")
  local ccwObject = obj:FindSingleGOByName("ccwObject")
  for i = 1, #animSynchedObjects do
    if animSynchedObjects[i].LuaObjectScript.AnimSyncToSpinner then
      animSynchedObjects[i].LuaObjectScript.AnimSyncToSpinner(cwObject, ccwObject, playRate)
    end
  end
end
function Enable()
  flipperModule.LuaObjectScript.EnableRotation()
end
function Disable()
  flipperModule.LuaObjectScript.DisableRotation()
end
function RotateClockwise(newState)
  flipperModule.LuaObjectScript.RotateCW()
  previousState = newState
end
function RotateCounterclockwise(newState)
  flipperModule.LuaObjectScript.RotateCCW()
  previousState = newState
end
function OnRotateClockwiseCallback(newState, empty, prevState)
  for i = 1, #animSynchedObjects do
    animSynchedObjects[i].LuaObjectScript.RotateClockwise(newState, playRate, previousState)
  end
  PlayHitSound()
end
function OnRotateCounterclockwiseCallback(newState, empty, prevState)
  for i = 1, #animSynchedObjects do
    animSynchedObjects[i].LuaObjectScript.RotateCounterclockwise(newState, playRate, previousState)
  end
  previousState = newState
  PlayHitSound()
end
local soundEmitter
local soundEvents = {
  OnHit = "SND_MECH_Rotary_Turnstile_Puzzle_Hit",
  OnSpinnerHit = "SND_MECH_Puzzle_Spinner_Turn"
}
function SoundInit()
  soundEmitter = thisObj:FindSingleSoundEmitterByName("SNDSpinner")
end
function SoundSetup(sounds)
  if sounds ~= nil then
    if sounds.SoundEmitter ~= nil then
      soundEmitter = thisObj:FindSingleSoundEmitterByName(sounds.SoundEmitter)
    end
    for key in pairs(soundEvents) do
      for newKey, newValue in pairs(sounds) do
        if newKey == key and newValue ~= nil and newValue ~= "" then
          soundEvents[key] = newValue
        end
      end
      LD.SoundDebug(tostring(key) .. ": " .. tostring(soundEvents[key]))
    end
  end
end
function PlayHitSound()
  LD.PlaySoundAfterDelay(soundEmitter, soundEvents.OnSpinnerHit, 0.2)
  LD.PlaySound(soundEmitter, soundEvents.OnHit)
end
function ShowDebugText()
  if engine.IsDebug() then
    local debugText = thisObj.Parent:GetName()
    debugText = debugText .. [[

> Previous State ]] .. tostring(previousState)
    debugText = debugText .. [[

> CW-Frame: ]] .. tostring(thisObj:FindSingleGOByName("cwObject").AnimFrame)
    debugText = debugText .. [[

> CCW-Frame: ]] .. tostring(thisObj:FindSingleGOByName("ccwObject").AnimFrame)
    local color = require("core.color")
    engine.DrawTextInWorld(thisObj:GetWorldPosition(), debugText, color.white)
  end
end
