local tablex = require("core.tablex")
local animationUtil = require("ui.animationUtil")
local classlib = require("core.class")
local fsm = require("ui.fsm")
local util = require("ui.util")
local pickupConsts = require("ui.pickupConsts")
local pickupUtil = require("ui.pickupUtil")
local UI = game.UI
local AnimationModule_Kratos = classlib.Class("AnimationModule_Kratos", fsm.UIState)
local AM_Kratos_Off = AnimationModule_Kratos:StateClass("AM_Kratos_Off", fsm.UIState)
local AM_Kratos_On = AnimationModule_Kratos:StateClass("AM_Kratos_On", fsm.UIState)
local AM_Kratos_Available = AnimationModule_Kratos:StateClass("AM_Kratos_Available", fsm.UIState)
local AM_Kratos_InTransition = AnimationModule_Kratos:StateClass("AM_Kratos_InTransition", fsm.UIState)
local animationModule_Kratos = AnimationModule_Kratos.New("animationModule_Kratos", {
  AM_Kratos_Off,
  AM_Kratos_On,
  {AM_Kratos_Available, AM_Kratos_InTransition}
})
local poses = {
  front = 1,
  back = 2,
  shield = 3
}
local delayToPlayAnim = 0.5
local creatureName = "goHeroA00"
local currAnimTime, _currAnimData, currMenu, currSubmenu
local animData = {
  BackIdle = {
    Duration = 0,
    Branch = "BRA_UI_PopToBackPose",
    Pose = poses.back
  },
  BackToFront = {
    Duration = 2,
    Branch = "BRA_UI_EnterFrontPose",
    Pose = poses.front
  },
  BackToShield = {
    Duration = 1,
    Branch = "BRA_UI_PauseWeapToShield",
    Pose = poses.shield
  },
  FrontIdle = {
    Duration = 0,
    Branch = "BRA_UI_PauseIdlePose",
    Pose = poses.front
  },
  FrontToBack = {
    Duration = 2,
    Branch = "BRA_UI_EnterBackPose",
    Pose = poses.back
  },
  FrontToShield = {
    Duration = 0,
    Branch = "BRA_UI_PauseArmToShieldTurn",
    Pose = poses.shield
  },
  ShieldIdle = {
    Duration = 0,
    Branch = "BRA_UI_PauseShieldIdle",
    Pose = poses.shield
  },
  ShieldToFront = {
    Duration = 1,
    Branch = "BRA_UI_PauseShieldToArmTurn",
    Pose = poses.front
  },
  ShieldToBack = {
    Duration = 1,
    Branch = "BRA_UI_PauseShieldToWeap",
    Pose = poses.back
  }
}
local GetCreature = function()
  return pickupUtil.GetUICreature(pickupConsts.TAG_PICKUP_KRATOS)
end
function AnimationModule_Kratos:Setup()
end
function AnimationModule_Kratos:Enter()
  self:Goto("AM_Kratos_Off")
end
function AnimationModule_Kratos:Exit()
end
function AnimationModule_Kratos:EVT_PAUSE_MENU_CLOSED()
  self:Goto("AM_Kratos_Off")
end
function AnimationModule_Kratos:EVT_PAUSE_MENU_OPEN()
  self:Goto("AM_Kratos_On")
end
function AnimationModule_Kratos:EVT_ResetClothForced()
  local uiCreature = GetCreature()
  if uiCreature.ResetCloth then
    uiCreature:ResetCloth()
  end
end
local InitAnims = function()
  currMenu = "Weapon"
  _currAnimData = animData.BackIdle
  util.ForceUICreatureMove(creatureName, animData.BackIdle.Branch)
  local goProxyKratos = util.GetUiObjByName("ProxyKratos")
  local uiCreature = GetCreature()
  if uiCreature ~= nil then
    uiCreature:ResetCloth()
  end
end
function AM_Kratos_Off:Setup()
end
function AM_Kratos_Off:Enter()
end
function AM_Kratos_Off:Exit()
end
function AM_Kratos_Off:EVT_InWorldMenu_OnTransition(oldMenu, newMenu)
  currMenu = newMenu
end
function AM_Kratos_Off:EVT_WeaponSubMenu_OnTransition(oldMenu, newMenu)
end
function AM_Kratos_On:Setup()
  InitAnims()
end
function AM_Kratos_On:Enter()
  self._initMenu = true
  if _currAnimData.Pose == poses.shield then
    self:PlayAnim(animData.ShieldToBack)
    self._initMenu = false
  end
end
function AM_Kratos_On:Exit()
  self._initMenu = false
  if _currAnimData.Pose ~= poses.shield then
    InitAnims()
  end
  self:KillTimer()
end
function AM_Kratos_On:PlayAnim(currAnimData, force)
  if _currAnimData ~= nil and _currAnimData.Pose == currAnimData.Pose and not force then
    return
  end
  currAnimTime = currAnimData.Duration
  _currAnimData = currAnimData
  util.ForceUICreatureMove(creatureName, currAnimData.Branch)
  self:KillTimer()
  self:Goto("AM_Kratos_InTransition")
end
function AM_Kratos_On:EVT_InWorldMenu_OnTransition(oldMenu, newMenu)
  currMenu = newMenu
  currSubmenu = nil
  if self._initMenu == true then
    self._initMenu = false
    self:Goto("AM_Kratos_Available")
  end
  local fsm_Available = self:GetState("AM_Kratos_Available")
  if fsm_Available:IsActive() then
    if _currAnimData.Pose == poses.shield then
      fsm_Available:OnTransition(oldMenu, newMenu)
    else
      self:UpdateTimer(function()
        fsm_Available:OnTransition(oldMenu, newMenu)
      end)
    end
  end
end
function AM_Kratos_On:EVT_WeaponMenu_OnAdvanceRelease(pickupEntered)
  currSubmenu = pickupEntered
  if pickupEntered == "ArmorShield" then
    local fsm_Available = self:GetState("AM_Kratos_Available")
    if fsm_Available:IsActive() then
      fsm_Available:OnTransition(nil, currMenu)
    end
  end
end
function AM_Kratos_On:EVT_WeaponMenu_Submenu_OnBackRelease(pickupExited)
  currSubmenu = nil
  if pickupExited == "ArmorShield" then
    local fsm_Available = self:GetState("AM_Kratos_Available")
    if fsm_Available:IsActive() then
      fsm_Available:OnTransition(nil, currMenu)
    end
  end
end
local timerName = "KratosAnimModule_TriggerDelay"
function AM_Kratos_On:KillTimer()
  if self:HaveTimer(timerName) then
    self:StopTimer(timerName)
  end
end
function AM_Kratos_On:UpdateTimer(callback)
  local delay = delayToPlayAnim
  self:KillTimer()
  self:StartTimer(timerName, delay, callback)
end
function AM_Kratos_Available:Setup()
  self._parent = self:GetState("AM_Kratos_On")
end
function AM_Kratos_Available:Enter()
  if currMenu == "Weapon" then
    if currSubmenu == "ArmorShield" then
      if _currAnimData.Pose == poses.front then
        self._parent:PlayAnim(animData.FrontToBack)
      elseif _currAnimData.Pose == poses.back then
        self._parent:PlayAnim(animData.BackToShield)
      end
    elseif _currAnimData.Pose == poses.shield then
      self._parent:PlayAnim(animData.ShieldToBack)
    elseif _currAnimData.Pose == poses.front then
      self._parent:PlayAnim(animData.FrontToBack)
    end
  elseif currMenu == "Stats" and _currAnimData.Pose ~= poses.front then
    if _currAnimData.Pose == poses.shield then
      self._parent:PlayAnim(animData.ShieldToFront)
    elseif _currAnimData.Pose == poses.back then
      self._parent:PlayAnim(animData.BackToFront)
    end
  elseif _currAnimData.Pose == poses.shield then
    self._parent:PlayAnim(animData.ShieldToBack)
  elseif currMenu ~= "Resources" then
    self._parent:PlayAnim(animData.FrontIdle)
  end
end
function AM_Kratos_Available:Exit()
end
function AM_Kratos_Available:OnTransition(oldMenu, newMenu)
  if newMenu == "Weapon" then
    if currSubmenu == "ArmorShield" then
      if _currAnimData.Pose == poses.front then
        self._parent:PlayAnim(animData.FrontToBack)
      elseif _currAnimData.Pose == poses.back then
        self._parent:PlayAnim(animData.BackToShield)
      end
    elseif _currAnimData.Pose == poses.shield then
      self._parent:PlayAnim(animData.ShieldToBack)
    elseif _currAnimData.Pose == poses.front then
      self._parent:PlayAnim(animData.FrontToBack)
    end
  elseif newMenu == "Stats" then
    if _currAnimData.Pose == poses.shield then
      self._parent:PlayAnim(animData.ShieldToFront)
    elseif _currAnimData.Pose == poses.back then
      self._parent:PlayAnim(animData.BackToFront)
    end
  elseif _currAnimData.Pose == poses.shield then
    self._parent:PlayAnim(animData.ShieldToFront)
  end
end
function AM_Kratos_InTransition:Setup()
  self._parent = self:GetState("AM_Kratos_On")
end
function AM_Kratos_InTransition:Enter()
  self:StartTimer("TransitionTimer", currAnimTime, function()
    self:Goto("AM_Kratos_Available")
  end)
end
function AM_Kratos_InTransition:Exit()
  currAnimTime = nil
end
