local LD = require("design.LevelDesignLibrary")
local timer = require("level.timer")
local thisObj
local enabled = true
local rewardObject, drainCount, activeCount, singleCrystal, leftCrystal, rightCrystal
local C_Unlocked = false
local L_Unlocked = false
local R_Unlocked = false
local vaultOpened = false
local singleDrainAnims = {
  open = "drainVault00Open",
  close = "drainVault00Close"
}
local doubleDrainAnims = {
  openL = "drainVault00LeftUnlockDoorOpen",
  openR = "drainVault00RightUnlockDoorOpen",
  unlockL = "drainVault00LeftUnlockRightLocked",
  unlockR = "drainVault00LeftLockedRightUnlock"
}
local delay_unlocking = 0.55
local delay_locking = 0
local debug_nextAnim = ""
function OnScriptLoaded(level, obj)
  thisObj = obj
  rewardObject = obj:FindLuaTableAttribute("RewardObject")
  drainCount = obj:GetLuaTableAttribute("DrainCount")
  activeCount = obj:GetLuaTableAttribute("ActiveCount")
  if rewardObject ~= "" and rewardObject ~= nil then
    rewardObject = level:FindSingleGameObject(rewardObject)
    if rewardObject == nil then
      engine.Error("Could not find Reward Object, ", obj:FindLuaTableAttribute("RewardObject"), " - please provide one in the lua table for object, ", obj.Parent)
    elseif rewardObject.IsRefNode then
      rewardObject = rewardObject.Child
    end
    local rewardJoint = thisObj:GetJointIndex("rewardJoint")
    rewardObject:SetWorldPosition(thisObj:GetWorldJointPosition(rewardJoint))
    rewardObject = rewardObject:FindSingleGOByName("ChestScript")
  else
    rewardObject = nil
  end
  leftCrystal = thisObj:FindSingleGOByName("LeftDrain")
  rightCrystal = thisObj:FindSingleGOByName("RightDrain")
  singleCrystal = thisObj:FindSingleGOByName("SingleDrain")
  if drainCount == 2 then
    leftCrystal.LuaObjectScript.OnFullyLit(function()
      SetL_Unlocked(true)
    end)
    rightCrystal.LuaObjectScript.OnFullyLit(function()
      SetR_Unlocked(true)
    end)
    leftCrystal.LuaObjectScript.OnFullyUnlit(function()
      SetL_Unlocked(false)
    end)
    rightCrystal.LuaObjectScript.OnFullyUnlit(function()
      SetR_Unlocked(false)
    end)
  else
    singleCrystal.LuaObjectScript.OnFullyLit(function()
      UnlockDoor(singleDrainAnims.open)
    end)
    singleCrystal.LuaObjectScript.OnFullyUnlit(function()
      LockDoor(singleDrainAnims.close)
    end)
  end
  game.SubObject.Sleep(obj)
  game.SubObject.SetForgetOnCheckpoint(obj)
  SoundInit()
end
function OnFirstStart(level, obj)
  if rewardObject then
    rewardObject.LuaObjectScript.Disable()
  end
  if drainCount == 2 then
    if activeCount == 2 then
      leftCrystal.LuaObjectScript.SetActive(true)
      rightCrystal.LuaObjectScript.SetActive(true)
      if rewardObject then
        rewardObject.LuaObjectScript.Enable()
      end
    elseif activeCount == 1 then
      leftCrystal.LuaObjectScript.SetActive(true)
    end
  elseif 0 < activeCount then
    singleCrystal.LuaObjectScript.SetActive(true)
    if rewardObject then
      rewardObject.LuaObjectScript.Enable()
    end
  end
  SoundSetup()
end
function OnStart(level, obj)
  if drainCount == 2 then
    singleCrystal:Hide()
  else
    leftCrystal:Hide()
    rightCrystal:Hide()
  end
end
function SetL_Unlocked(isUnlocked)
  if L_Unlocked ~= isUnlocked then
    local animName = doubleDrainAnims.unlockL
    L_Unlocked = isUnlocked
    if R_Unlocked then
      animName = doubleDrainAnims.openL
    end
    if L_Unlocked then
      UnlockDoor(animName)
    else
      LockDoor(animName)
    end
  end
end
function SetR_Unlocked(isUnlocked)
  if R_Unlocked ~= isUnlocked then
    local animName = doubleDrainAnims.unlockR
    R_Unlocked = isUnlocked
    if L_Unlocked then
      animName = doubleDrainAnims.openR
    end
    if R_Unlocked then
      UnlockDoor(animName)
    else
      LockDoor(animName)
    end
  end
end
function UnlockDoor(animName)
  if drainCount == 1 and thisObj:GetAnimationName() ~= singleDrainAnims.open or drainCount == 2 and thisObj:GetAnimationName() ~= doubleDrainAnims.openL and thisObj:GetAnimationName() ~= doubleDrainAnims.openR then
    timer.StartLevelTimer(delay_unlocking, function()
      debug_nextAnim = animName
      thisObj:StartAnimation({Animation = animName})
      if drainCount == 1 or L_Unlocked and R_Unlocked then
        PlaySoundOnOpen()
        if rewardObject then
          rewardObject.LuaObjectScript.Enable()
        end
      end
    end)
  end
end
function LockDoor(animName)
  timer.StartLevelTimer(delay_locking, function()
    if drainCount == 2 then
      debug_nextAnim = animName
      thisObj:JumpAnimationToPercent(1, {Animation = animName})
      thisObj:PlayAnimationToFrame(0, {
        Animation = animName,
        Rate = -1.7,
        Tween = 0.1
      })
      if L_Unlocked or R_Unlocked then
        PlaySoundOnClose()
      end
      if L_Unlocked == false and R_Unlocked then
        thisObj:OnAnimationDone(thisObj, "JumpAnim_LeftLock", {Force = true})
      elseif L_Unlocked and R_Unlocked == false then
        thisObj:OnAnimationDone(thisObj, "JumpAnim_RightLock", {Force = true})
      end
    else
      PlaySoundOnClose()
      thisObj:PlayAnimationToEnd({Animation = animName})
    end
    if rewardObject then
      rewardObject.LuaObjectScript.Disable()
    end
  end)
end
function JumpAnim_LeftLock()
  debug_nextAnim = doubleDrainAnims.unlockL
  thisObj:ClearAllAnimationCallbacks()
  thisObj:JumpAnimationToPercent(1, {
    Animation = doubleDrainAnims.unlockR
  })
end
function JumpAnim_RightLock()
  debug_nextAnim = doubleDrainAnims.unlockR
  thisObj:ClearAllAnimationCallbacks()
  thisObj:JumpAnimationToPercent(1, {
    Animation = doubleDrainAnims.unlockL
  })
end
local soundEmitter
local soundEvents = {
  isLooping = false,
  OnOpen = "SND_DOOR_Stone_Drainvault_Open",
  OnClose = "SND_DOOR_Stone_Drainvault_Open"
}
function SoundInit()
  soundEmitter = thisObj:FindSingleSoundEmitterByName("SNDLockStone")
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
    end
  end
end
function PlaySoundOnOpen()
  LD.PlaySound(soundEmitter, soundEvents.OnOpen)
end
function PlaySoundOnClose()
  LD.PlaySound(soundEmitter, soundEvents.OnClose)
end
function GetDebugText()
  local debugText = "AnimName:      " .. thisObj:GetAnimationName()
  debugText = debugText .. [[

>NextAnimName: ]] .. debug_nextAnim
  debugText = debugText .. [[

>AnimPercent: ]] .. tostring(thisObj.AnimPercent)
  debugText = debugText .. [[

>L_Unlocked: ]] .. tostring(L_Unlocked)
  debugText = debugText .. [[

>R_Unlocked: ]] .. tostring(R_Unlocked)
  return debugText
end
function ShowDebugText()
  local color = require("core.color")
  engine.DrawTextInWorld(thisObj:GetWorldPosition() + engine.Vector.New(-0.15, 1.5, 0), GetDebugText(), color.white)
end
