local classlib = require("core.class")
local tablex = require("core.tablex")
local timerlib = require("core.timer")
local animationUtil = require("ui.animationUtil")
local attributeCard = require("ui.attributeCard")
local attributeUtil = require("ui.attributeUtil")
local buttonUtil = require("ui.buttonUtil")
local cardManager = require("ui.cardManager")
local characterUtil = require("ui.characterUtil")
local colors = require("ui.colors")
local consts = require("ui.consts")
local hudConsts = require("ui.hudConsts")
local fsm = require("ui.fsm")
local lamsConsts = require("ui.lamsConsts")
local list = require("ui.list")
local menu = require("ui.menu")
local pickupConsts = require("ui.pickupConsts")
local pickupUtil = require("ui.pickupUtil")
local recipeUtil = require("ui.recipeUtil")
local resourceConsts = require("ui.resourceConsts")
local resourceUtil = require("ui.resourceUtil")
local runeUtil = require("ui.runeUtil")
local sliderHoldFill = require("ui.sliderHoldFill")
local skillUtil = require("ui.skillUtil")
local tutorials = require("ui.tutorials")
local tutorialUtil = require("ui.tutorialUtil")
local util = require("ui.util")
local uiCalls = require("ui.uicalls")
local AI = game.AI
local Audio = game.Audio
local UI = game.UI
local Player = game.Player
local Pickup = game.Pickup
local Resources = game.Resources
local Recipes = game.Recipes
local Wallets = game.Wallets
local Loot = game.Loot
local VendorMenu = classlib.Class("VendorMenu", fsm.UIState)
local VendorOff = VendorMenu:StateClass("VendorOff", fsm.UIState)
local VendorOn = VendorMenu:StateClass("VendorOn", fsm.UIState)
local VendorCraft = VendorMenu:StateClass("VendorCraft", fsm.UIState)
local VendorUpgrade = VendorMenu:StateClass("VendorUpgrade", fsm.UIState)
local VendorBuy = VendorMenu:StateClass("VendorBuy", fsm.UIState)
local VendorSell = VendorMenu:StateClass("VendorSell", fsm.UIState)
local VendorLostItems = VendorMenu:StateClass("VendorLostItems", fsm.UIState)
local vendorMenu = VendorMenu.New("vendorMenu", {
  VendorOff,
  VendorOn,
  {
    VendorCraft,
    VendorUpgrade,
    VendorBuy,
    VendorSell,
    VendorLostItems
  }
})
function VendorMenu:Setup()
end
function VendorMenu:Enter()
  self:WantPadEvents(true)
  self:Goto("VendorOff")
end
VendorMenu.EVT_GAME_OVER = VendorMenu.Enter
VendorMenu.EVT_Restart = VendorMenu.Enter
function VendorMenu:EVT_DM_PAUSE()
  self:WantPadEvents(false)
end
function VendorMenu:EVT_DM_UNPAUSE()
  self:WantPadEvents(true)
end
function VendorOff:Setup()
  self.vendorOn = self:GetState("VendorOn")
end
function VendorOff:Enter()
end
function VendorOff:Exit()
end
function VendorOff:EVT_TURN_ON_VENDOR_MENU(vendorWallet, bothHuldraAvailable, instructionEntries, instructionArgs)
  self.vendorOn.vendorWallet = vendorWallet
  self.vendorOn.bothHuldraAvailable = bothHuldraAvailable
  self.vendorOn.menu:set_instructionEntries(instructionEntries)
  self.vendorOn.menu:set_instructionArgs(instructionArgs)
  self:Goto("VendorOn")
end
function VendorOff:EVT_HIDE_ATTRIBUTE_DESCRIPTIONS()
  self.vendorOn.attributeCard:DisableDescriptions()
end
function VendorOn:Setup()
  self.menu = menu.Menu.New(self, {})
  local isVendor = true
  local goAttributeCardRefnode = util.GetUiObjByName("globalMenu_AttributeCard")
  self.attributeCard = attributeCard.AttributeCard.New(goAttributeCardRefnode)
  self.attributeCard:Init(self, isVendor)
  self.menu:SetupSubmenuList(consts.vendorMenu_SubmenuList, nil, nil, false)
  self.vendorMenu = self:GetState("vendorMenu")
  self.cardManager = cardManager.CardManager.New(self, util.GetUiObjByName("Vendor_Stave_Group"))
  self.cardManager:Init(isVendor, nil)
  self.vendorWallet = nil
  self.bothHuldraAvailable = nil
  self.exitAllowed = nil
  self.currSortingGroupIndex = nil
  self.shouldRefreshTablesOnExit = false
  local goSublist = util.GetUiObjByName("VendorList")
  local goSortList = goSublist:FindSingleGOByName("list_sort_nav")
  self.menu:SetupSortList("SortList", goSortList)
  self.previewTimer = timerlib.Timer.New(fsm.runList, 0, function()
    self:ShowPreview()
  end)
  self.clearPreviewTimer = timerlib.Timer.New(fsm.runList, 0, function()
    self:ShowOriginal()
  end)
  self.alreadyStreamedTable = {}
  self.prestreamingOn = true
  self.streamedElementOutwards = 0
  self.streamedElementsFromMain = 5
  self.goSubtitles = util.GetUiObjByName("RealTimeST1")
end
function VendorOn:Enter()
  self.prestreamingOn = true
  self.menu:Activate()
  UI.PadClear()
  UI.SetForcePauseMenuStreamingMode(true, consts.FORCED_HUD_STATE_VENDOR_SLOT)
  self.showDesc = false
  self.shouldRefreshTablesOnExit = false
  local Kratos = Player.FindPlayer()
  self.kratosOriginalHealth = Kratos:MeterGetValue(hudConsts.METER_HEALTH)
  util.Show("vendorMenu", "GlobalHeaderBacking", "XPandHS")
  Audio.PlaySound("SND_UX_Vendor_Screen_Enter")
  if game.UI.SetInVendor ~= nil then
    game.UI.SetInVendor(true)
  end
  self:SendEventUI("EVT_VENDOR_MENU_OPEN")
  self:SendEventToUIFsm("globalMenu", "EVT_REFRESH_GLOBAL_STATS")
  self:SetMenuToWorldTransform()
  local headerLabelText
  if self.bothHuldraAvailable == true then
    headerLabelText = util.GetLAMSMsg(lamsConsts.VendorShopBoth)
  elseif self.vendorWallet == resourceConsts.WALLET_BROK then
    headerLabelText = util.GetLAMSMsg(lamsConsts.VendorShopBrok)
  elseif self.vendorWallet == resourceConsts.WALLET_SINDRI then
    headerLabelText = util.GetLAMSMsg(lamsConsts.VendorShopSindri)
  end
  self:SendEventToUIFsm("globalMenu", "EVT_SET_HEADER_LABEL", headerLabelText)
  self.currSortingGroupIndex = resourceConsts.SORTING_GROUP_RARITY_STATS
  local sortListName = self.menu:get_sortListName()
  local sortList = self.menu:GetList(sortListName)
  local sort_newItemArray = resourceUtil.GetSortGroups(self.currSortingGroupIndex)
  local sort_showList = false
  local sort_useOnGainFocus = false
  local sort_itemDetermineFocusabilityFunc
  local sort_getDisplayNameFunc = resourceUtil.GetSortGroupDisplayName
  sortList:Refresh(sort_newItemArray, sort_showList, sort_useOnGainFocus, sort_itemDetermineFocusabilityFunc, sort_getDisplayNameFunc)
  sortList:SetSelectedButton(1, false)
  characterUtil.InitializePickupSlots()
  self:UpdateEquippedAttributes(pickupConsts.TAG_PICKUP_KRATOS)
  local isVendorMenu = true
  recipeUtil.AllRecipesTables_RefreshAll(self:Submenu_GetRefreshWallet(), isVendorMenu, nil)
  self.menu:ClearSubmenuListLabelText()
  recipeUtil.SubmenuList_Refresh(self, isVendorMenu)
  if not self.menu:HasInstructionEntryForMenuState() then
    local submenuList = self.menu:GetList(consts.vendorMenu_SubmenuList)
    submenuList:SetSelectedButton(1, true)
  end
  self:HideAllInfo()
  local showAll = false
  self.attributeCard:ShowCard(showAll)
  self:CheckForUpgradeTutorial()
  skillUtil.UpdateSkillTreeLockedStates()
  self.menu:ExecuteInstructions()
end
function VendorOn:Exit()
  if game.UI.SetInVendor ~= nil then
    game.UI.SetInVendor(false)
  end
  self.menu:Deactivate(true)
  self.vendorWallet = nil
  self.bothHuldraAvailable = nil
  self.exitAllowed = nil
  util.Hide("vendorMenu", "GlobalHeaderBacking", "XPandHS")
  Audio.PlaySound("SND_UX_Vendor_Screen_Exit")
  self:HideAllInfo()
  self.cardManager:UpdateHoldFill(nil, false, nil)
  self.attributeCard:HideCard()
  self:ClearPickupPreview()
  self:SendEventToUIFsm("globalMenu", "EVT_HIDE_RECIPE_NOTICE")
  self:SendEventToUIFsm("globalMenu", "EVT_SET_HEADER_LABEL", "")
  self:SendEventUI("EVT_VENDOR_MENU_CLOSED")
  util.CallScriptOnGameObject("vendor", "TriggerExit")
  local sonSpecialTutorialVarName = "TUT_ShownSonSpecialTutorial"
  if util.SonUI_ShouldShow() and not util.SonUI_ShouldDisable() and self.sonSpecialOnExit ~= nil and not game.Level.GetVariable(sonSpecialTutorialVarName) then
    game.Level.SetVariable(sonSpecialTutorialVarName, true)
    uiCalls.SendItemCardDesignerMessage({
      ItemCardArgs = {
        ResourceName = self.sonSpecialOnExit
      },
      FooterButtonInfo = {
        {
          Text = "[StartButton] " .. util.GetLAMSMsg(lamsConsts.Continue),
          EventHandlers = {
            {
              Events = {
                "EVT_Options_Release"
              },
              Handler = nil,
              UICalls = {
                {
                  CallName = "UI_Event_Open_Weapon_Menu",
                  ArgTable = {"SonBow", "SonSpecial"}
                },
                {
                  CallName = "UI_Event_Setup_Tutorial",
                  ArgTable = {
                    "Pause_SpiritSummons"
                  }
                }
              }
            }
          }
        }
      },
      AdvanceType = uiCalls.msgParam.ADVANCE_PRESS
    })
  end
  self.sonSpecialOnExit = nil
  local Kratos = Player.FindPlayer()
  local currHealth = Kratos:MeterGetValue(hudConsts.METER_HEALTH)
  local currMaxHealth = Kratos:MeterGetMax(hudConsts.METER_HEALTH)
  if currMaxHealth < self.kratosOriginalHealth then
    self.kratosOriginalHealth = currMaxHealth
  end
  if currHealth < self.kratosOriginalHealth then
    Kratos:MeterSetValue(hudConsts.METER_HEALTH, self.kratosOriginalHealth)
  end
end
function VendorOn:EVT_SMALL_ATTRIBUTE_CARD()
  self.attributeCard:SmallCard(true)
end
function VendorOn:EVT_LARGE_ATTRIBUTE_CARD()
  self.attributeCard:SmallCard(false)
end
function VendorOn:SubmenuList_Button_Update(button)
  recipeUtil.SubmenuList_Button_Update(self, button, true)
end
function VendorOn:SubmenuList_Button_OnGainFocus(button)
  recipeUtil.SubmenuList_Button_OnGainFocus(self, button, consts.vendorMenu_SubmenuList, true)
end
function VendorOn:SubmenuList_Button_OnLoseFocus(button)
  self:HideAllInfo()
end
function VendorOn:SortList_Button_OnGainFocus(button)
  local submenuListName = self.menu:get_submenuListName()
  local submenuList = self.menu:GetList(submenuListName)
  local isVendorMenu = true
  local subStateName = recipeUtil.GetSubMenuNameFromSubStateIndex(submenuList:GetSelectedItem(), isVendorMenu)
  local subState = self:GetState(subStateName)
  local subList = subState.menu:GetList("SubList")
  if subList:get_active() == true then
    local sortingGroup = resourceUtil.GetSortGroupFromMenu(self.menu)
    subList:Sort(sortingGroup, nil, true, false)
    local labelText = resourceUtil.GetSortGroupLabelDisplayText(button:get_item())
    self.menu:SetMenuListLabelText("SortList", labelText)
  else
    local sortListName = self.menu:get_sortListName()
    local sortList = self.menu:GetList(sortListName)
    local sortList_hideList = true
    local sortList_clearButtons = false
    sortList:Deactivate(sortList_hideList, sortList_clearButtons)
  end
end
function VendorOn:SetMenuToWorldTransform()
  local scale = 0.156
  UI.SetGOTransformCameraSpace(self.cardManager._gameObject, engine.Vector.New(-3.305, 2.545, -10), scale)
end
function VendorOn:CanCraftWeaponUpgrade(vendorWallet, weaponFlag)
  assert(not util.IsStringNilOrEmpty(weaponFlag), "No weapon flag passed into CanCraftWeaponUpgrade!")
  local canCraftWeaponUpgrade = false
  local isAxe = weaponFlag == resourceConsts.RESOURCE_FLAG_AXE
  local isBlades = weaponFlag == resourceConsts.RESOURCE_FLAG_BLADES
  local isSonBow = weaponFlag == resourceConsts.RESOURCE_FLAG_SON_BOW
  if isAxe or isBlades and resourceUtil.HasResource(pickupConsts.Blades) or isSonBow and util.SonUI_ShouldShow() then
    local upgradeRecipes = recipeUtil.AllRecipesTables_GetRecipeTable("Upgrade", weaponFlag, weaponFlag)
    for _, recipeName in ipairs(upgradeRecipes) do
      if recipeUtil.CanPurchase(recipeName) then
        canCraftWeaponUpgrade = true
        break
      end
    end
  end
  return canCraftWeaponUpgrade
end
function VendorOn:CheckForUpgradeTutorial()
  if tutorialUtil.IsStepQueueEmpty() then
    local tutorialName = "Pause_UpgradeAvailable"
    local canCraftAxeUpgrade = self:CanCraftWeaponUpgrade(self.vendorWallet, resourceConsts.RESOURCE_FLAG_AXE)
    local canCraftBladesUpgrade = self:CanCraftWeaponUpgrade(self.vendorWallet, resourceConsts.RESOURCE_FLAG_BLADES)
    local canCraftSonBowUpgrade = self:CanCraftWeaponUpgrade(self.vendorWallet, resourceConsts.RESOURCE_FLAG_SON_BOW)
    if canCraftAxeUpgrade then
      tutorialName = tutorialName .. "_" .. resourceConsts.RESOURCE_FLAG_AXE
    end
    if canCraftBladesUpgrade then
      tutorialName = tutorialName .. "_" .. resourceConsts.RESOURCE_FLAG_BLADES
    end
    if canCraftSonBowUpgrade then
      tutorialName = tutorialName .. "_" .. resourceConsts.RESOURCE_FLAG_SON_BOW
    end
    if tutorialName ~= "Pause_UpgradeAvailable" then
      tutorialUtil.SetupTutorialStepQueue(tutorials, tutorialName)
    end
  end
end
function VendorOn:UpdateEquippedAttributes(character, equippedAttributes)
  if character == pickupConsts.TAG_PICKUP_KRATOS then
    local creature = pickupUtil.GetCreatureFromCharacter(character)
    if equippedAttributes == nil then
      equippedAttributes = attributeUtil.GetCreaturesAttributes(creature)
    end
    self.attributeCard:UpdateMeter_Equipped(equippedAttributes, character, creature)
  end
end
function VendorOn:UpdateAttributesPreview(character)
  if character == pickupConsts.TAG_PICKUP_KRATOS then
    attributeUtil.UpdateAttributePreview(self, character, function()
      local isVendorMenu = true
      attributeUtil.UpdateAttributePreview_PostTimer(self.attributeCard, character, isVendorMenu)
    end)
  end
end
function VendorOn:ClearAttributePreview()
  if self:HaveTimer("UpdateAttributesDelayTimer") then
    self:StopTimer("UpdateAttributesDelayTimer")
  end
  self.attributeCard:UpdateMeter_Preview(nil)
  self.attributeCard:ClearPowerLevelPreview()
end
function VendorOn:UpdateAttributeDesc(currValue)
  self.showDesc = currValue
  if self.showDesc == true then
    self.attributeCard:ShowDescriptionGroup()
  else
    self.attributeCard:HideDescriptionGroup()
  end
end
function VendorOn:AcquireOriginal()
  local creature = self.originalPickup.creature
  local pickupName = self.originalPickup.pickupName
  local stage = Pickup.GetProfileStage(pickupName)
  creature:PickupAcquire(pickupName, stage)
  self:EVT_SET_EXIT_ALLOWED()
  self.originalPickup = nil
end
function VendorOn:ShowOriginal()
  if self.originalPickup == nil then
    self.prestreamingOn = true
    return
  end
  local character = self.originalPickup.character
  local creature = self.originalPickup.creature
  local pickupName = self.originalPickup.pickupName
  local pickupSlot = self.originalPickup.pickupSlot
  local stage = Pickup.GetProfileStage(pickupName)
  self.prestreamingOn = false
  local fullyStreamed = Pickup.RequestLoadHighMips(pickupUtil.GetPickupGO(character, creature, pickupSlot), pickupName, stage)
  if fullyStreamed then
    self.prestreamingOn = true
    self:AcquireOriginal()
  else
    self:EVT_SET_EXIT_NOT_ALLOWED()
    self.clearPreviewTimer:Restart()
  end
end
function VendorOn:ShowPreview()
  local pickup = self.previewPickup
  if pickup == nil then
    self.prestreamingOn = true
    return
  end
  self:ClearAttributePreview()
  local character = pickup.Character
  local creature = pickupUtil.GetCreatureFromCharacter(character)
  local pickupSlot = pickup.PickupSlot
  self.prestreamingOn = false
  local fullyStreamed = Pickup.RequestLoadHighMips(pickupUtil.GetPickupGO(character, creature, pickupSlot), pickup.Name, pickup.Stage)
  if fullyStreamed then
    self.prestreamingOn = true
    creature:PickupAcquire(pickup.Name, pickup.Stage)
    self:UpdateAttributesPreview(pickup.Character)
    local newGlowPickup
    local amount = resourceUtil.GetAmount(recipeUtil.GetRecipeItemName(pickup.primaryRecipeItem))
    if not pickup.isReinforcementRecipe and amount == 0 then
      newGlowPickup = pickupConsts.Slot_GlowPickups[pickup.PickupSlot]
    end
    if newGlowPickup ~= self.glowPickup then
      if self.glowPickup ~= nil and creature:PickupIsAcquired(self.glowPickup) then
        creature:PickupRelinquish(self.glowPickup, 0)
      end
      self.glowPickup = newGlowPickup
      if self.glowPickup ~= nil then
        creature:PickupAcquire(self.glowPickup, 0)
      end
    end
  else
    self.previewTimer:Restart()
  end
end
function VendorOn:ClearPickupPreview()
  self.prestreamingOn = true
  self.previewTimer:Stop()
  self:ClearAttributePreview()
  if self._currentlyEquippedPickup ~= nil then
    local character = self._currentlyEquippedPickup.Character
    local creature = pickupUtil.GetCreatureFromCharacter(character)
    local pickupName = self._currentlyEquippedPickup.Name
    local pickupSlot = self._currentlyEquippedPickup.PickupSlot
    if pickupName ~= nil then
      if self.originalPickup ~= nil then
        self:AcquireOriginal()
      end
      self.originalPickup = {
        character = character,
        creature = creature,
        pickupName = pickupName,
        pickupSlot = pickupSlot
      }
      self.clearPreviewTimer:Restart()
    elseif pickupUtil.IsValidSlotName(pickupSlot) and pickupUtil.GetPickupNameInSlot(creature, pickupSlot) ~= nil then
      creature:PickupRelinquishBySlot(pickupSlot)
    end
    if self.glowPickup ~= nil then
      if creature:PickupIsAcquired(self.glowPickup) then
        creature:PickupRelinquish(self.glowPickup, 0)
      end
      self.glowPickup = nil
    end
    self._currentlyEquippedPickup = nil
    self.previewPickup = nil
  end
end
function VendorOn:SetCurrentlyEquippedPickup(pickupName, pickupSlot, character)
  self._currentlyEquippedPickup = {
    Name = pickupName,
    Character = character,
    PickupSlot = pickupSlot,
    SlotIsEmpty = pickupName == nil
  }
end
function VendorOn:PreviewRecipe(currState, recipeListItem)
  local character = recipeUtil.GetCurrentCharacterByCategorySelection(currState)
  if recipeListItem == nil then
    self:ClearPickupPreview(character)
    return
  end
  local recipeName = recipeListItem.RecipeName
  if recipeName == nil then
    self:ClearPickupPreview(character)
    return
  end
  local primaryRecipeItem = recipeListItem.PrimaryItem
  local isPrimaryItemPickup = primaryRecipeItem.Type == resourceConsts.RESOURCE_FLAG_PICKUP
  local isReinforcementRecipe = Recipes.HasFlag(recipeName, resourceConsts.RESOURCE_FLAG_UPGRADE)
  if isReinforcementRecipe or isPrimaryItemPickup then
    if self._currentlyEquippedPickup == nil and self.originalPickup ~= nil then
      self:AcquireOriginal()
    end
    local itemName = isReinforcementRecipe and recipeListItem.ReinforcementPickupName or primaryRecipeItem.Name
    local pickupSlot = pickupUtil.GetSlotName(itemName)
    local creature = pickupUtil.GetCreatureFromCharacter(character)
    if self._currentlyEquippedPickup == nil then
      self:SetCurrentlyEquippedPickup(pickupUtil.GetPickupNameInSlot(creature, pickupSlot), pickupSlot, character)
    end
    local stage = Pickup.GetProfileStage(itemName)
    if stage < 0 then
      stage = 0
    end
    local maxStage = pickupUtil.GetMaxStage(itemName)
    if isReinforcementRecipe and stage < maxStage then
      stage = stage + 1
    end
    self.previewPickup = {
      Name = itemName,
      Stage = stage,
      Character = character,
      PickupSlot = pickupSlot,
      primaryRecipeItem = primaryRecipeItem,
      isReinforcementRecipe = isReinforcementRecipe
    }
    self.clearPreviewTimer:Stop()
    self.previewTimer:Restart()
  else
    self:ClearPickupPreview(character)
  end
end
function VendorOn:HideAllInfo()
  self.cardManager:HideAll()
  self:ClearPickupPreview()
  self:ClearAttributePreview()
  UI.SendEvent("*", consts.EVT_ENABLE_SUBTITLES)
  self.goSubtitles:Show()
end
function VendorOn:CanRecipeBeMade(recipeListItem)
  local recipeName = recipeUtil.RecipeListItem_GetRecipeName(recipeListItem)
  if not recipeUtil.IsValidRecipeName(recipeName) then
    return false
  end
  local canPurchase = recipeUtil.CanPurchase(recipeName)
  local atLimit = recipeUtil.RecipeListItem_AtLimit(recipeListItem)
  local canRecipeBeMade = canPurchase and not atLimit
  local recipeItem = recipeUtil.RecipeListItem_GetPrimaryItem(recipeListItem)
  local recipeItemName = recipeUtil.GetRecipeItemName(recipeItem)
  local recipeItemType = recipeUtil.GetRecipeItemType(recipeItem)
  if recipeUtil.RecipeIsForSell(recipeName) then
    if recipeUtil.HasFlag(recipeName, resourceConsts.RESOURCE_FLAG_RUNE) then
      canRecipeBeMade = true
    elseif recipeItemType == resourceConsts.RESOURCE_FLAG_PICKUP then
      if self._currentlyEquippedPickup ~= nil then
        canRecipeBeMade = canRecipeBeMade and self._currentlyEquippedPickup.Name ~= recipeItemName
      else
        canRecipeBeMade = canRecipeBeMade and not pickupUtil.IsEquipped(recipeItemName)
      end
    end
  elseif recipeUtil.HasFlag(recipeName, "Buy") and recipeUtil.HasFlag(recipeName, "Rune") and recipeUtil.HasFlag(recipeName, "Tier09") then
    local recipeInputs = recipeUtil.RecipeListItem_GetInputRecipeItems(recipeListItem)
    for i = 1, #recipeInputs do
      local item = recipeInputs[i]
      if item.Type == resourceConsts.RESOURCE_FLAG_PICKUP and characterUtil.ItemIsEquipped(item.Name) then
        canRecipeBeMade = false
        break
      end
    end
  end
  return canRecipeBeMade
end
function VendorOn:CanCompare(currState, subList)
  local canCompare = false
  local hasEquippedItem = self._currentlyEquippedPickup ~= nil and self._currentlyEquippedPickup.Name ~= nil
  if hasEquippedItem then
    local recipeListItem = subList:GetSelectedItem()
    local recipeName = recipeUtil.RecipeListItem_GetRecipeName(recipeListItem)
    local primaryRecipeItem = recipeUtil.RecipeListItem_GetPrimaryItem(recipeListItem)
    local isUpgradeRecipe = recipeUtil.IsReinforcementRecipe(recipeName)
    local itemToCompare
    if isUpgradeRecipe then
      itemToCompare = recipeUtil.RecipeListItem_GetReinforcementPickupName(recipeListItem)
    else
      local primaryRecipeItem = recipeUtil.RecipeListItem_GetPrimaryItem(recipeListItem)
      itemToCompare = recipeUtil.GetRecipeItemName(primaryRecipeItem)
    end
    if itemToCompare ~= nil then
      local canRecipeBeMade = self:CanRecipeBeMade(recipeListItem)
      local allowRecipeCompare = true
      if not canRecipeBeMade then
        local isBuyRecipe = recipeUtil.RecipeIsForBuy(recipeName)
        local isSellRecipe = recipeUtil.RecipeIsForSell(recipeName)
        if isUpgradeRecipe then
          local currStage = pickupUtil.GetProfileStage(itemToCompare)
          local maxStage = pickupUtil.GetMaxStage(itemToCompare)
          if currStage == maxStage then
            allowRecipeCompare = false
          end
        elseif isBuyRecipe then
          local resourceName = recipeUtil.GetRecipeItemName(primaryRecipeItem)
          if resourceUtil.IsValidResourceName(resourceName) and resourceUtil.GetAmount(resourceName) > 0 then
            allowRecipeCompare = false
          end
        elseif isSellRecipe then
          if recipeUtil.HasFlag(recipeName, resourceConsts.RESOURCE_FLAG_RESURRECTION_STONE) then
            local hasResStoneFlagResource = 0 < resourceUtil.GetAmount("ResurrectionStoneFlag")
            if hasResStoneFlagResource then
              allowRecipeCompare = false
            end
          else
            local resourceName = recipeUtil.GetRecipeItemName(primaryRecipeItem)
            if resourceUtil.IsValidResourceName(resourceName) and resourceUtil.GetAmount(resourceName) < 1 then
              allowRecipeCompare = false
            end
          end
        elseif recipeUtil.RecipeListItem_AtLimit(recipeListItem) then
          allowRecipeCompare = false
        end
      end
      if allowRecipeCompare then
        canCompare = self._currentlyEquippedPickup.Name ~= itemToCompare
      end
    end
  end
  return canCompare
end
function VendorOn:SelectRecipe(currState, button)
  local recipeListItem = button:get_item()
  local recipeName = recipeUtil.RecipeListItem_GetRecipeName(recipeListItem)
  if not recipeUtil.IsValidRecipeName(recipeName) then
    self:HideAllInfo()
  else
    local currCharacter = recipeUtil.GetCurrentCharacterByCategorySelection(currState)
    local shouldUpdateAttributes = recipeUtil.RecipeListItem_ShouldUpdateAttributes(recipeListItem)
    local canRecipeBeMade = self:CanRecipeBeMade(recipeListItem)
    if shouldUpdateAttributes then
      self:PreviewRecipe(currState, recipeListItem)
      self:UpdateAttributesPreview(currCharacter)
    end
    local submenuList = self.menu:GetList(consts.vendorMenu_SubmenuList)
    local subStateIndex = submenuList:GetSelectedItem()
    local canCompare = self:CanCompare(currState, button:get_list())
    if not canCompare then
      self.cardManager:HideComparisonCard()
    elseif self.cardManager:IsToggleActive() then
      local itemName = self._currentlyEquippedPickup.Name
      local itemType = resourceConsts.RESOURCE_FLAG_PICKUP
      local character = self._currentlyEquippedPickup.Character
      local isEquipped = true
      local args
      self.cardManager:ShowComparisonCard(itemName, itemType, character, isEquipped, args)
    end
    self.cardManager:DisplayCard_ForRecipe(recipeListItem, canRecipeBeMade, subStateIndex, currCharacter, canCompare)
    local height = self.cardManager.exchangeCard:IsShowing() and self.cardManager.exchangeCard:GetCardHeight() or self.cardManager.statsCard:GetCardHeight()
    if 22.5 < height then
      UI.SendEvent("*", consts.EVT_DISABLE_SUBTITLES)
      self.goSubtitles:Hide()
    else
      UI.SendEvent("*", consts.EVT_ENABLE_SUBTITLES)
      self.goSubtitles:Show()
    end
  end
  self:UpdateFooterButtonPrompt(currState.menu, false, false)
end
function VendorOn:UpdateFooterButtonPrompt(currMenu, showSelect, showExit)
  local kratos = Player.FindPlayer()
  currMenu:UpdateFooterButton("Select", showSelect)
  currMenu:UpdateFooterButton("Back", not showExit)
  currMenu:UpdateFooterButton("Exit", self.exitAllowed and showExit)
  currMenu:UpdateFooterButtonText()
end
function VendorOn:MakeFooterButtonInfo(advanceHandler, squareHandler)
  local text = "[AdvanceButton] " .. util.GetLAMSMsg(lamsConsts.Close)
  local eventHandlers = {
    {
      Events = {
        "EVT_Advance_Release"
      }
    }
  }
  if advanceHandler ~= nil then
    eventHandlers[1].Handler = advanceHandler
  end
  if squareHandler ~= nil then
    text = "[SquareButton] " .. util.GetLAMSMsg(lamsConsts.Equip) .. " " .. text
    local squareEventHandler = {
      Events = {
        "EVT_Square_Release"
      },
      Handler = squareHandler
    }
    tablex.FastInsert(eventHandlers, squareEventHandler, #eventHandlers + 1)
  end
  return {
    {Text = text, EventHandlers = eventHandlers}
  }
end
function VendorOn:RefreshRecipes(currState, recipeName, runeId)
  local sortingGroup = resourceConsts.POWER_LEVEL_SORTING
  local refreshWallet = currState:GetRefreshWallet()
  if currState.subStateIndex == resourceConsts.RESOURCE_FLAG_CRAFT then
    recipeUtil.AllRecipesTables_RefreshSubState(refreshWallet, resourceConsts.RESOURCE_FLAG_UPGRADE, sortingGroup)
    recipeUtil.SubmenuList_UpdateSingle(self, resourceConsts.RESOURCE_FLAG_UPGRADE)
    recipeUtil.AllRecipesTables_RefreshSubState(refreshWallet, resourceConsts.RESOURCE_FLAG_BUY, sortingGroup)
    recipeUtil.SubmenuList_UpdateSingle(self, resourceConsts.RESOURCE_FLAG_BUY)
    recipeUtil.AllRecipesTables_RefreshSubState(refreshWallet, resourceConsts.RESOURCE_FLAG_SELL, sortingGroup)
  elseif currState.subStateIndex == resourceConsts.RESOURCE_FLAG_UPGRADE then
    local pickupName = recipeUtil.GetReinforcementRecipePickup(recipeName)
    local currStage = pickupUtil.GetProfileStage(pickupName)
    local maxStage = pickupUtil.GetMaxStage(pickupName)
    if currStage < maxStage then
      local mainList = currState.menu:GetList("MainList")
      local currMainSelection = mainList:GetSelectedItem()
      local currCategorySelection = recipeUtil.GetCurrentCategorySelection(currState)
      local currSortingGroup = resourceUtil.GetSortGroupFromMenu(self.menu)
      local removeUnavailableRecipes = true
      recipeUtil.AllRecipesTables_RefreshSingle(refreshWallet, resourceConsts.RESOURCE_FLAG_UPGRADE, currMainSelection, currCategorySelection, currSortingGroup, removeUnavailableRecipes)
      recipeUtil.SubmenuList_UpdateSingle(self, resourceConsts.RESOURCE_FLAG_UPGRADE)
    end
    recipeUtil.AllRecipesTables_RefreshSubState(refreshWallet, resourceConsts.RESOURCE_FLAG_BUY, sortingGroup)
    recipeUtil.SubmenuList_UpdateSingle(self, resourceConsts.RESOURCE_FLAG_BUY)
    recipeUtil.AllRecipesTables_RefreshSubState(refreshWallet, resourceConsts.RESOURCE_FLAG_SELL, sortingGroup)
  elseif currState.subStateIndex == resourceConsts.RESOURCE_FLAG_BUY then
    recipeUtil.AllRecipesTables_RefreshSubState(refreshWallet, resourceConsts.RESOURCE_FLAG_UPGRADE, sortingGroup)
    recipeUtil.SubmenuList_UpdateSingle(self, resourceConsts.RESOURCE_FLAG_UPGRADE)
    recipeUtil.AllRecipesTables_RefreshSubState(refreshWallet, resourceConsts.RESOURCE_FLAG_SELL, sortingGroup)
  elseif currState.subStateIndex == resourceConsts.RESOURCE_FLAG_SELL then
    if recipeUtil.RecipeIsForSellRune(recipeName) then
      local currSortingGroup = resourceUtil.GetSortGroupFromMenu(self.menu)
      local removeUnavailableRecipes = true
      if runeId == nil then
        recipeUtil.AllRecipesTables_RefreshSingle(refreshWallet, resourceConsts.RESOURCE_FLAG_SELL, resourceConsts.RESOURCE_FLAG_RUNE, resourceConsts.RESOURCE_FLAG_RUNE, currSortingGroup, removeUnavailableRecipes)
      else
        local runeTable = recipeUtil.AllRecipesTables_GetRecipeTable(resourceConsts.RESOURCE_FLAG_SELL, resourceConsts.RESOURCE_FLAG_RUNE, resourceConsts.RESOURCE_FLAG_RUNE)
        tablex.Clear(runeTable)
        local subList = currState.menu:GetList("SubList")
        local sortItems = subList:GetSortItems()
        local itemIndex = 1
        for _, runeIdInTable in ipairs(sortItems) do
          if runeIdInTable ~= runeId then
            tablex.FastInsert(runeTable, runeIdInTable, itemIndex)
            itemIndex = itemIndex + 1
          end
        end
        recipeUtil.RemoveUnavailableRunes(runeTable)
      end
      currState.lastEnteredSubStateSelection = nil
    end
    recipeUtil.AllRecipesTables_RefreshSubState(refreshWallet, resourceConsts.RESOURCE_FLAG_UPGRADE, sortingGroup)
    recipeUtil.SubmenuList_UpdateSingle(self, resourceConsts.RESOURCE_FLAG_UPGRADE)
    recipeUtil.AllRecipesTables_RefreshSubState(refreshWallet, resourceConsts.RESOURCE_FLAG_BUY, sortingGroup)
    recipeUtil.SubmenuList_UpdateSingle(self, resourceConsts.RESOURCE_FLAG_BUY)
  end
end
local name_Axe = "axe00"
local name_Blades = "explosive00"
local slotToFXName = {
  [pickupConsts.Slot_ArmorChest] = {
    FX = "vendor_equipchest_flourish",
    Joints = {"JOBack1"}
  },
  [pickupConsts.Slot_ArmorLegs] = {
    FX = "vendor_equipwaist_flourish",
    Joints = {"JOPelvis1"}
  },
  [pickupConsts.Slot_ArmorWrist] = {
    FX = "vendor_equiparm_flourish",
    Joints = {
      "JORightLowerArm1",
      "JOLeftLowerArm1"
    }
  },
  [pickupConsts.Slot_ArmorTrinket] = nil,
  [pickupConsts.Slot_WeaponComponent] = {
    FX = "vendor_pommel_flourish",
    Weapon = name_Axe,
    Joints = {"JOPelvis1"}
  },
  [pickupConsts.Slot_WeaponComponent_Blades] = {
    FX = "vendor_blades_pommel_flourish",
    Weapon = name_Blades,
    Joints = {"JOPelvis1"}
  },
  [pickupConsts.Slot_SonArmor] = {
    FX = "vendor_equipson_flourish",
    Joints = {"JOPelvis1"}
  }
}
function VendorOn:EquipRecipeItem(currState, currList, recipeName, pickupName, character, previewAttributes, acquirePickup)
  local pickupSlot = pickupUtil.GetSlotName(pickupName)
  local currCreature = pickupUtil.GetCreatureFromCharacter(character)
  if acquirePickup then
    characterUtil.SetPickupSlot(character, pickupSlot, pickupName, acquirePickup)
    local goCreature = pickupUtil.GetCreatureFromCharacter(character)
    local currPickupSlotName = pickupUtil.GetSlotName(pickupName)
    local fxGroup = slotToFXName[currPickupSlotName]
    if fxGroup ~= nil then
      local particleName = fxGroup.FX
      for _, jointName in ipairs(fxGroup.Joints) do
        if fxGroup.Weapon == nil then
          animationUtil.SpawnFX(particleName, goCreature, jointName)
        else
          local jointName = slotToFXName[currPickupSlotName].Joint
          local targetWeapon = slotToFXName[currPickupSlotName].Weapon
          for activeWeapon in goCreature:IterateActiveWeapons() do
            local goWeapon = activeWeapon.Weapon
            local name = goWeapon:GetName()
            if name == targetWeapon then
              animationUtil.SpawnFX(particleName, goWeapon, jointName)
            end
          end
        end
      end
    end
  end
  if self.menu:get_active() then
    self:SetCurrentlyEquippedPickup(pickupName, pickupSlot, character)
    self:UpdateEquippedAttributes(character, previewAttributes)
    self:RefreshRecipes(currState, recipeName)
    local sortingGroup = resourceUtil.GetSortGroupFromMenu(self.menu)
    recipeUtil.SubList_Update(currState, sortingGroup)
  end
end
local s_sonRecipesByTier = {
  ReinforcementBow_Tier02 = {
    ArrowUnlock_Light = {
      "Recipe_SonPerk_LightArrow_Potency_Tier01"
    },
    ArrowUnlock_Shock = {
      "Recipe_SonPerk_ShockArrow_Potency_Tier01"
    }
  },
  ReinforcementBow_Tier03 = {
    ArrowUnlock_Light = {
      "Recipe_SonPerk_LightArrow_Potency_Tier02",
      "Recipe_SonPerk_LightArrow_ExplosionRadius"
    },
    ArrowUnlock_Shock = {
      "Recipe_SonPerk_ShockArrow_Potency_Tier02",
      "Recipe_SonPerk_ShockArrow_DetonationConduit"
    }
  },
  ReinforcementBow_Tier04 = {
    ArrowUnlock_Light = {
      "Recipe_SonPerk_LightArrow_Potency_Tier03"
    },
    ArrowUnlock_Shock = {
      "Recipe_SonPerk_ShockArrow_Potency_Tier03"
    }
  },
  ReinforcementBow_Tier05 = {
    ArrowUnlock_Light = {
      "Recipe_SonPerk_LightArrow_ExplosionSpread"
    },
    ArrowUnlock_Shock = {
      "Recipe_SonPerk_ShockArrow_OnHitSpark"
    }
  }
}
local Fixup_GiveSonSkillTreeRecipesByTier = function(resourceName)
  local bowReinforcement = s_sonRecipesByTier[resourceName]
  if bowReinforcement then
    for arrowUnlock, recipes in pairs(bowReinforcement) do
      if game.Wallets.HasResource("HERO", arrowUnlock, 1) then
        for _, recipe in pairs(recipes) do
          if not game.Wallets.HasRecipe("HERO", recipe) then
            game.Wallets.AddRecipe("HERO", recipe)
          else
            engine.Warning("Skill-tree recipe " .. recipe .. " was acquired before Arrow unlock. How was it originally granted?")
          end
        end
      end
    end
  end
end
function VendorOn:GetEquipSound(pickupName)
  local sound = "SND_UI_Vendor_Equip_Armor"
  if pickupUtil.IsWeaponComponent(pickupName) then
    sound = "SND_UI_Vendor_Equip_Weapon"
  elseif pickupUtil.IsWeaponSpecial(pickupName) then
    sound = "SND_UI_Vendor_Equip_Runic"
  elseif pickupUtil.GetSlotName(pickupName) == pickupConsts.Slot_ArmorTrinket then
    sound = "SND_UI_Vendor_Equip_Talisman"
  end
  return sound
end
function VendorOn:CraftRecipe(currState, currList, walletName)
  local recipeListItem = currList:GetSelectedItem()
  local canRecipeBeMade = self:CanRecipeBeMade(recipeListItem)
  if canRecipeBeMade then
    local recipeName = recipeUtil.RecipeListItem_GetRecipeName(recipeListItem)
    local primaryRecipeItem = recipeUtil.RecipeListItem_GetPrimaryItem(recipeListItem)
    local primaryItemName, primaryItemType
    if recipeUtil.RecipeIsForSellRune(recipeName) then
      primaryItemName = primaryRecipeItem
      primaryItemType = "RuneSelf"
    elseif recipeUtil.IsRuneCreatorRecipe(recipeName) then
      primaryItemName = nil
      primaryItemType = resourceConsts.RESOURCE_FLAG_RUNE
    else
      primaryItemName = recipeUtil.GetRecipeItemName(primaryRecipeItem)
      primaryItemType = recipeUtil.GetRecipeItemType(primaryRecipeItem)
    end
    local isPrimaryItemPickup = primaryItemType == resourceConsts.RESOURCE_FLAG_PICKUP
    if recipeUtil.RecipeIsForSell(recipeName) and isPrimaryItemPickup then
      local socketCount = pickupUtil.GetRuneSocketCount(primaryItemName)
      for socketIndex = 0, socketCount - 1 do
        runeUtil.UnsocketRune(primaryItemName, socketIndex)
      end
      self:ClearPickupPreview()
    end
    if recipeUtil.HasFlag(recipeName, resourceConsts.RESOURCE_FLAG_GENERATE_RUNE) then
      primaryItemName = recipeUtil.GenerateRunes(recipeName)
    elseif recipeUtil.HasFlag(recipeName, resourceConsts.RESOURCE_FLAG_ROLL_CONDITION) then
      primaryItemName = recipeUtil.RollCondition(recipeName)
    end
    local isForSellRune = recipeUtil.RecipeIsForSellRune(recipeName)
    local recipeRuneID
    if isForSellRune then
      recipeRuneID = runeUtil.GetRuneInfoRuneID(primaryRecipeItem)
      runeUtil.ExchangeRune(self.vendorWallet, resourceConsts.WALLET_KRATOS, recipeRuneID)
    elseif recipeUtil.RecipeIsForSellArtifact(recipeName) then
      while recipeUtil.CanPurchase(recipeName) do
        recipeUtil.Craft(recipeName, self.vendorWallet)
      end
    else
      recipeUtil.Craft(recipeName, self.vendorWallet)
      Fixup_GiveSonSkillTreeRecipesByTier(primaryItemName)
      if recipeUtil.HasFlag(recipeName, resourceConsts.RESOURCE_FLAG_CRAFT) and (recipeUtil.HasFlag(recipeName, resourceConsts.RESOURCE_FLAG_BROK) or recipeUtil.HasFlag(recipeName, resourceConsts.RESOURCE_FLAG_SINDRI)) and string.find(recipeName, "_Backup") == nil then
        local outputs = recipeUtil.GetOutputRecipeItems(recipeName)
        local backupRecipeName
        for _, outputItem in ipairs(outputs) do
          local outputItemName = recipeUtil.GetRecipeItemName(outputItem)
          if string.find(outputItemName, "_Backup") ~= nil then
            recipeUtil.ClearNew(outputItemName)
          end
        end
      end
    end
    self.shouldRefreshTablesOnExit = true
    self:SendEventToUIFsm("globalMenu", "EVT_REFRESH_GLOBAL_STATS")
    recipeUtil.SendTriggerEvent_Craft(currState, primaryItemName)
    self.cardManager:HideAll()
    local buttonCount = currList:GetButtonCount()
    local gcButtonCountAmount = isForSellRune and 15 or 50
    if buttonCount > gcButtonCountAmount then
      collectgarbage()
    end
    currState.lastEnteredCategorySelection = nil
    self:RefreshRecipes(currState, recipeName, recipeRuneID)
    local sortingGroup = resourceUtil.GetSortGroupFromMenu(self.menu)
    if isForSellRune then
      sortingGroup = nil
    end
    recipeUtil.SubList_Update(currState, sortingGroup)
    if buttonCount > gcButtonCountAmount then
      collectgarbage()
    end
    local currCharacter = recipeUtil.GetCurrentCharacterByCategorySelection(currState)
    local currCreature = pickupUtil.GetCreatureFromCharacter(currCharacter)
    local previewAttributes = attributeUtil.GetCreaturesAttributes(currCreature)
    local itemCardResource = primaryItemName
    local itemCardType = primaryItemType
    local advanceEventHandler, squareEventHandler
    uiCalls.UI_Event_ClearAllDesignerMessages()
    local continueHandler = function()
    end
    if self.glowPickup ~= nil and currCreature:PickupIsAcquired(self.glowPickup) then
      currCreature:PickupRelinquish(self.glowPickup, 0)
    end
    local equipHandler = function(messageRequest, acquirePickup, pickupName)
      local menuActive = self.menu:get_active()
      self:EquipRecipeItem(currState, currList, recipeName, pickupName, currCharacter, previewAttributes, acquirePickup)
      if menuActive then
        self:ClearAttributePreview()
      end
      if acquirePickup then
        local equipSound = self:GetEquipSound(pickupName)
        Audio.PlaySound(equipSound)
      end
      if messageRequest ~= nil and acquirePickup == true and menuActive == true then
        local goMessageRequestChild = messageRequest:get_goMessageRequestChild()
        local goListItemEquipFlourish = goMessageRequestChild:FindSingleGOByName("ListItemEquipFlourish")
        if goListItemEquipFlourish ~= nil then
          local animRate = 1
          local pStart = 0
          local pEnd = 1
          UI.Anim(goListItemEquipFlourish, consts.AS_Forward, "", animRate, pStart, pEnd)
        end
      end
    end
    if currState.subStateIndex == "Craft" then
      if primaryItemType == "Pickup" then
        advanceEventHandler = continueHandler
        function squareEventHandler(messageRequest)
          equipHandler(messageRequest, true, primaryItemName)
        end
      end
    elseif currState.subStateIndex == "Upgrade" then
      local pickupName = recipeUtil.RecipeListItem_GetReinforcementPickupName(recipeListItem)
      if pickupName ~= nil then
        itemCardResource = pickupName
        itemCardType = "Upgrade"
        do
          local pickupSlot = pickupUtil.GetSlotName(pickupName)
          local itemIsEquipped = recipeUtil.RecipeIsforQuiver(recipeName) or characterUtil.ItemIsEquipped(pickupName, currCharacter, pickupSlot)
          if itemIsEquipped then
            function advanceEventHandler(messageRequest)
              equipHandler(messageRequest, false, pickupName)
            end
          else
            advanceEventHandler = continueHandler
            function squareEventHandler(messageRequest)
              equipHandler(messageRequest, true, pickupName)
            end
          end
        end
      end
    elseif currState.subStateIndex == "Buy" then
      if primaryItemType == "Pickup" then
        advanceEventHandler = continueHandler
        function squareEventHandler(messageRequest)
          equipHandler(messageRequest, true, primaryItemName)
        end
      elseif primaryItemType == resourceConsts.RESOURCE_FLAG_RUNE and runeUtil.IsValidRuneID(primaryItemName) then
        advanceEventHandler = continueHandler
        squareEventHandler = nil
      elseif primaryItemType == "Resource" then
        if recipeUtil.RecipeIsForRunicAttack(recipeName) then
          advanceEventHandler = continueHandler
          function squareEventHandler(messageRequest)
            equipHandler(messageRequest, true, primaryItemName)
          end
        elseif recipeUtil.HasFlag(recipeName, resourceConsts.RESOURCE_FLAG_RESURRECTION_STONE) then
          advanceEventHandler = continueHandler
        end
      end
    end
    if advanceEventHandler ~= nil or squareEventHandler ~= nil then
      self.cardManager:HideRootLevelGOs()
      currList:Deactivate(false, false)
      local sortListName = self.menu:get_sortListName()
      local sortList = self.menu:GetList(sortListName)
      sortList:Deactivate(false, false)
      currState.waitingForItemCardAnimEnd = true
      uiCalls.SendItemCardDesignerMessage({
        ItemCardArgs = {
          ResourceName = itemCardResource,
          ResourceType = itemCardType,
          SendAnimEndEvent = true
        },
        FooterButtonInfo = self:MakeFooterButtonInfo(advanceEventHandler, squareEventHandler),
        AdvanceType = uiCalls.msgParam.ADVANCE_PRESS
      })
    else
      do
        local activate_showList = true
        local activate_useOnGainFocus = false
        currList:Activate(activate_showList, activate_useOnGainFocus)
        local useOnGainFocus = true
        currList:ReselectSelectedItem(useOnGainFocus)
        if 1 >= currList:GetButtonCount() then
          local sortListName = self.menu:get_sortListName()
          local sortList = self.menu:GetList(sortListName)
          local hide = true
          local clearButtons = false
          sortList:Deactivate(hide, clearButtons)
        end
        if currState.subStateIndex ~= "Sell" then
          self:UpdateEquippedAttributes(currCharacter, previewAttributes)
        end
      end
    end
  end
  self.attributeCard:UpdateGlobalInfoAttributes(pickupConsts.TAG_PICKUP_KRATOS)
end
function VendorOn:GetCharacterResourceFlag(selection)
  local isSonSelection = recipeUtil.IsSonSelection(selection)
  return isSonSelection and resourceConsts.RESOURCE_FLAG_SON or resourceConsts.RESOURCE_FLAG_KRATOS
end
function VendorOn:GetSubmenuMacroIcon(submenuName)
  return "[" .. tostring(submenuName) .. "]"
end
function VendorOn:SubmenuList_AfterDelay(list, delayStartButtonIndex, currButtonIndex)
  local currSubStateIndex = list:GetItemByButtonIndex(currButtonIndex)
  recipeUtil.SendTriggerEvent_Submenu(self.vendorWallet, "Enter", currSubStateIndex)
end
function VendorOn:SubmenuSetup(currState, checkFulfill, subStateIndex)
  currState.menu = menu.Menu.New(currState, {
    FooterFSM = "vendorMenu",
    FooterButtonInfo = {
      {
        Item = "Select",
        Text = "[AdvanceButton] " .. util.GetLAMSMsg(lamsConsts.Select)
      },
      {
        Item = "Back",
        Text = "[BackButton] " .. util.GetLAMSMsg(lamsConsts.Back)
      },
      {
        Item = "Exit",
        Text = "[BackButton] " .. util.GetLAMSMsg(lamsConsts.Exit)
      }
    }
  })
  currState.subStateIndex = subStateIndex
  currState.isVendorMenu = true
  currState.lastEnteredSubStateSelection = nil
  currState.lastEnteredCategorySelection = nil
  currState.waitingForItemCardAnimEnd = false
  local listObjectName = "VendorList"
  recipeUtil.Submenu_SetupLists(currState, listObjectName)
end
function VendorOn:SubmenuEnter(currState, purchaseRecipe)
  currState.vendorWallet = self.vendorWallet
  currState.lastEnteredSubStateSelection = nil
  currState.lastEnteredCategorySelection = nil
  currState.waitingForItemCardAnimEnd = false
  local showAll = false
  self.attributeCard:ShowCard(showAll)
  self:ClearAttributePreview()
  local subList = currState.menu:GetList("SubList")
  self.cardManager.holdFill:SetOnComplete(function()
    self:CraftRecipe(currState, subList, resourceConsts.WALLET_KRATOS)
  end)
  recipeUtil.MainList_Refresh(currState, true)
  currState.menu:ExecuteInstructions()
end
function VendorOn:SubmenuExit(currState)
  currState.vendorWallet = nil
  recipeUtil.SendTriggerEvent_Submenu(self.vendorWallet, "Exit", currState.subStateIndex)
  if self.shouldRefreshTablesOnExit then
    recipeUtil.AllRecipesTables_RefreshSubState(currState:GetRefreshWallet(), currState.subStateIndex, resourceConsts.POWER_LEVEL_SORTING)
    self.shouldRefreshTablesOnExit = false
  end
  currState.menu:Deactivate(true)
end
function VendorOn:Submenu_AnimEndHandler(currState)
  local subList = currState.menu:GetList("SubList")
  if currState.waitingForItemCardAnimEnd == true then
    local objNameHash = UI.GetEventArgStringHash(1)
    local percentComplete = UI.GetEventArgFloat(3) / 100
    local messageHash = engine.Hash("message")
    if objNameHash == messageHash and percentComplete < 0.001 then
      subList:Activate(false, false)
      local useOnGainFocus = true
      subList:ReselectSelectedItem(useOnGainFocus)
      local currCategorySelection = recipeUtil.GetCurrentCategorySelection(currState)
      local resetSort = false
      self:RefreshSortList(currState, currCategorySelection, resetSort)
      currState.waitingForItemCardAnimEnd = false
    end
  end
end
function VendorOn:Submenu_GetRefreshWallet()
  local refreshWallet
  if self.bothHuldraAvailable ~= true then
    refreshWallet = self.vendorWallet
  end
  return refreshWallet
end
function VendorOn:Submenu_SquarePressHandler(currState)
  local subList = currState.menu:GetList("SubList")
  if self.cardManager ~= nil and subList:get_active() then
    self.cardManager.holdFill:PlayUnavailableSound()
  end
end
function VendorOn:MainList_BackReleaseHandler()
  if self.exitAllowed then
    self:SendEventToUIFsm("globalMenu", "EVT_TURN_OFF_GLOBAL_MENU")
  end
end
function VendorOn:SubList_AdvanceReleaseHandler(currState, subList)
  local recipeListItem = subList:GetSelectedItem()
  local canRecipeBeMade = self:CanRecipeBeMade(recipeListItem)
  if not canRecipeBeMade then
    local recipeName = recipeUtil.RecipeListItem_GetRecipeName(recipeListItem)
    local primaryRecipeItem = recipeUtil.RecipeListItem_GetPrimaryItem(recipeListItem)
    local primaryItemName = recipeUtil.GetRecipeItemName(primaryRecipeItem)
    local primaryItemType = recipeUtil.GetRecipeItemType(primaryRecipeItem)
    local pickupName
    if currState.subStateIndex == "Craft" and primaryItemType == "Pickup" then
      pickupName = primaryItemName
    elseif currState.subStateIndex == "Upgrade" then
      pickupName = recipeUtil.RecipeListItem_GetReinforcementPickupName(recipeListItem)
    end
    if pickupUtil.IsValidName(pickupName) and resourceUtil.HasResource(pickupName) then
      local currCharacter = recipeUtil.GetCurrentCharacterByCategorySelection(currState)
      local currCreature = pickupUtil.GetCreatureFromCharacter(currCharacter)
      local previewAttributes = attributeUtil.GetCreaturesAttributes(currCreature)
      local pickupSlot = pickupUtil.GetSlotName(pickupName)
      if not characterUtil.ItemIsEquipped(pickupName, currCharacter, pickupSlot) then
        local acquirePickup = true
        self:EquipRecipeItem(currState, subList, recipeName, pickupName, currCharacter, previewAttributes, acquirePickup)
        local useOnGainFocus = true
        subList:ReselectSelectedItem(useOnGainFocus)
      end
    end
  end
end
function VendorOn:RefreshSortList(currState, currCategorySelection, resetSort)
  local sortListName = self.menu:get_sortListName()
  local sortList = self.menu:GetList(sortListName)
  local sortingGroupIndex
  local isBuyRune = currState.subStateIndex == resourceConsts.RESOURCE_FLAG_BUY and currCategorySelection == resourceConsts.RESOURCE_FLAG_RUNE
  if not isBuyRune then
    sortingGroupIndex = recipeUtil.GetSortingGroupIndex(currCategorySelection)
  end
  if sortList:get_active() == false and sortingGroupIndex ~= nil then
    local subList = currState.menu:GetList("SubList")
    if subList:GetButtonCount() > 1 then
      if self.currSortingGroupIndex ~= sortingGroupIndex then
        self.currSortingGroupIndex = sortingGroupIndex
        local sort_newItemArray = resourceUtil.GetSortGroups(self.currSortingGroupIndex)
        local sort_showList = false
        local sort_useOnGainFocus = false
        local sort_itemDetermineFocusabilityFunc
        local sort_getDisplayNameFunc = resourceUtil.GetSortGroupDisplayName
        sortList:Refresh(sort_newItemArray, sort_showList, sort_useOnGainFocus, sort_itemDetermineFocusabilityFunc, sort_getDisplayNameFunc)
      end
      if resetSort == true then
        sortList:SetSelectedButton(1, false)
      end
      local sortList_showList = true
      local sortList_useOnGainFocus = true
      sortList:Activate(sortList_showList, sortList_useOnGainFocus)
      self.menu:AnimateSortList()
    end
  end
end
function VendorOn:Category_OnSelect(currState, currMainSelection, currCategorySelection)
  self:SetMenuToWorldTransform(currState)
  if recipeUtil.ShouldHideAttributesCard(currState.subStateIndex, currCategorySelection) then
    self.attributeCard:HideCard()
  end
  local resetSort = true
  self:RefreshSortList(currState, currCategorySelection, resetSort)
end
function VendorOn:SubList_BackReleaseHandler(currState)
  self:HideAllInfo()
  self:ClearAttributePreview()
  recipeUtil.SubList_BackReleaseHandler(currState)
  local sortListName = self.menu:get_sortListName()
  local sortList = self.menu:GetList(sortListName)
  local sortList_hideList = true
  local sortList_clearButtons = false
  sortList:Deactivate(sortList_hideList, sortList_clearButtons)
  local mainList = currState.menu:GetList("MainList")
  local currMainSelection = mainList:GetSelectedItem()
  local categoryList = currState.menu:GetList("CategoryList")
  local currCategorySelection = categoryList:GetSelectedItem()
  local categoryItems = recipeUtil.CategoryList_GetItems(currState.subStateIndex, currMainSelection)
  if #categoryItems == 1 or currCategorySelection == nil then
    local isVendorMenu = true
    recipeUtil.SubmenuList_Activate(self, currState.subStateIndex, isVendorMenu)
    currCategorySelection = categoryItems[1]
  end
  if recipeUtil.ShouldHideAttributesCard(currState.subStateIndex, currCategorySelection) then
    self.attributeCard:ShowCard()
  end
  Audio.PlaySound("SND_UX_Menu_Tick_Back")
  self.cardManager:ForceToggleOff()
end
function VendorOn:SubList_R2PressHandler(currState, subList)
  if self:CanCompare(currState, subList) then
    local itemName = self._currentlyEquippedPickup.Name
    local itemType = resourceConsts.RESOURCE_FLAG_PICKUP
    local character = self._currentlyEquippedPickup.Character
    local isEquipped = true
    local args
    self.cardManager:ToggleComparisonCard(itemName, itemType, character, isEquipped, args)
  end
end
function VendorOn:SubList_R2ReleaseHandler(currState)
  self.cardManager:HideComparisonCard()
end
function VendorOn:SubList_R3ReleaseHandler(currState, subList)
  if self:CanCompare(currState, subList) then
    local itemName = self._currentlyEquippedPickup.Name
    local itemType = resourceConsts.RESOURCE_FLAG_PICKUP
    local character = self._currentlyEquippedPickup.Character
    local isEquipped = true
    local args
    self.cardManager:ToggleComparisonCard(itemName, itemType, character, isEquipped, args)
  end
end
function VendorOn:PreStreamPickup(character, pickupName)
  if pickupName ~= nil and pickupUtil.Exists(pickupName) then
    local creature = pickupUtil.GetCreatureFromCharacter(character)
    local slot = pickupUtil.GetSlotName(pickupName)
    local stage = pickupUtil.GetProfileStage(pickupName)
    if stage < 0 then
      stage = 0
    end
    return Pickup.RequestLoadHighMips(pickupUtil.GetPickupGO(character, creature, slot), pickupName, stage)
  end
  return true
end
function VendorOn:PreStreamRecipe(character, item)
  local primaryItem = recipeUtil.RecipeListItem_GetPrimaryItem(item)
  local pickupName
  if primaryItem ~= nil then
    if primaryItem.Type == "Pickup" then
      pickupName = primaryItem.Name
    elseif primaryItem.Type == "Resource" then
      pickupName = recipeUtil.GetReinforcementRecipePickup(item.RecipeName)
    end
  end
  return self:PreStreamPickup(character, pickupName)
end
function VendorOn:PreStreamRecipeFromSubList(character, subList, buttonIndex)
  if self.alreadyStreamedTable[buttonIndex] ~= nil then
    return
  end
  self.alreadyStreamedTable[buttonIndex] = true
  local item = subList:GetItemByButtonIndex(buttonIndex)
  if item then
    return self:PreStreamRecipe(character, item)
  end
  return true
end
function VendorOn:StreamingSubMenu()
  if self._currentlyEquippedPickup ~= nil and not self._currentlyEquippedPickup.SlotIsEmpty then
    local character = self._currentlyEquippedPickup.Character
    local creature = pickupUtil.GetCreatureFromCharacter(character)
    local pickupName = self._currentlyEquippedPickup.Name
    local pickupSlot = self._currentlyEquippedPickup.PickupSlot
    local stage = Pickup.GetProfileStage(pickupName)
    Pickup.RequestLoadHighMips(pickupUtil.GetPickupGO(character, creature, pickupSlot), pickupName, stage)
  end
  tablex.Clear(self.alreadyStreamedTable)
  local currState = self:GetCurrentState()
  if currState and currState.menu and currState.menu:get_active() then
    local subList = currState.menu:GetList("SubList")
    local character = recipeUtil.GetCurrentCharacterByCategorySelection(currState)
    self.streamedElementOutwards = pickupUtil.StreamSubList(character, subList, self.streamedElementOutwards, self.streamedElementsFromMain, function(character, subList, buttonIndex)
      return self:PreStreamRecipeFromSubList(character, subList, buttonIndex)
    end)
  end
end
function VendorOn:StreamingMainMenu()
  local currState = self:GetCurrentState()
  if currState and currState.menu and currState.menu:get_active() then
    local subList = currState.menu:GetList("SubList")
    if subList and subList:get_active() then
      return
    end
    local character = recipeUtil.GetCurrentCharacterByCategorySelection(currState)
    if character then
      recipeUtil.AllRecipesTables_PreStreamInitialSelection(currState.subStateIndex, function(character, pickupName)
        self:PreStreamPickup(character, pickupName)
      end)
    end
  end
end
function VendorOn:Update()
  if not self.prestreamingOn then
    return
  end
  self:StreamingMainMenu()
  self:StreamingSubMenu()
end
function VendorOn:EVT_TURN_OFF_VENDOR_MENU()
  self:Goto("VendorOff")
end
function VendorOn:EVT_SET_EXIT_ALLOWED()
  if self.exitAllowed ~= true then
    self.exitAllowed = true
    local submenuList = self.menu:GetList(self.menu:get_submenuListName())
    local currSubStateIndex = submenuList:GetSelectedItem()
    if not util.IsStringNilOrEmpty(currSubStateIndex) then
      local currSubstateName = recipeUtil.GetSubMenuNameFromSubStateIndex(currSubStateIndex, true)
      local currSubstate = self:GetState(currSubstateName)
      local mainList = currSubstate.menu:GetList("MainList")
      local subList = currSubstate.menu:GetList("SubList")
      if currSubstate.UpdateFooterButtonPrompt then
        currSubstate:UpdateFooterButtonPrompt()
      else
        self:UpdateFooterButtonPrompt(currSubstate.menu, not subList:get_active(), mainList:get_active())
      end
    end
  end
end
function VendorOn:EVT_SET_EXIT_NOT_ALLOWED()
  if self.exitAllowed ~= false then
    self.exitAllowed = false
    local submenuList = self.menu:GetList(self.menu:get_submenuListName())
    local currSubStateIndex = submenuList:GetSelectedItem()
    if not util.IsStringNilOrEmpty(currSubStateIndex) then
      local currSubstateName = recipeUtil.GetSubMenuNameFromSubStateIndex(currSubStateIndex, true)
      local currSubstate = self:GetState(currSubstateName)
      local mainList = currSubstate.menu:GetList("MainList")
      local subList = currSubstate.menu:GetList("SubList")
      if currSubstate.UpdateFooterButtonPrompt ~= nil then
        currSubstate:UpdateFooterButtonPrompt()
      else
        self:UpdateFooterButtonPrompt(currSubstate.menu, not subList:get_active(), mainList:get_active())
      end
    end
  end
end
function VendorCraft:Setup()
  self.vendorOn = self:GetState("VendorOn")
  self.vendorOn:SubmenuSetup(self, false, "Craft")
end
function VendorCraft:Enter()
  self.menu:Activate()
  self.vendorOn:SubmenuEnter(self, false)
end
function VendorCraft:Exit()
  self.vendorOn:SubmenuExit(self)
end
function VendorCraft:CanRecipeBeMade(recipeListItem)
  return self.vendorOn:CanRecipeBeMade(recipeListItem)
end
function VendorCraft:GetRefreshWallet()
  return self.vendorOn:Submenu_GetRefreshWallet()
end
function VendorCraft:MainList_AdvanceReleaseHandler()
  recipeUtil.MainList_AdvanceReleaseHandler(self.vendorOn, self)
end
function VendorCraft:MainList_BackReleaseHandler()
  self.vendorOn:MainList_BackReleaseHandler()
end
function VendorCraft:MainList_Button_Update(button)
  recipeUtil.MainList_Button_Update(self, button)
end
function VendorCraft:MainList_Button_OnGainFocus(button)
  local showExit = true
  self.vendorOn:UpdateFooterButtonPrompt(self.menu, true, showExit)
end
function VendorCraft:CategoryList_BackReleaseHandler()
  recipeUtil.CategoryList_BackReleaseHandler(self)
  local isVendorMenu = true
  recipeUtil.SubmenuList_Activate(self.vendorOn, self.subStateIndex, isVendorMenu)
end
function VendorCraft:CategoryList_Button_OnGainFocus(button)
  local showExit = false
  self.vendorOn:UpdateFooterButtonPrompt(self.menu, true, showExit)
end
function VendorCraft:Category_OnSelect(currMainSelection, currCategorySelection)
  self.vendorOn:Category_OnSelect(self, currMainSelection, currCategorySelection)
end
function VendorCraft:SubList_AfterDelay(button)
  self.vendorOn:SelectRecipe(self, button)
end
function VendorCraft:SubList_Button_OnLoseFocus(button)
  recipeUtil.SubList_Button_OnLoseFocus(self, button)
end
function VendorCraft:SubList_BackReleaseHandler()
  self.vendorOn:SubList_BackReleaseHandler(self)
end
function VendorCraft:SubList_R2PressHandler(subList)
end
function VendorCraft:SubList_R2ReleaseHandler()
end
function VendorCraft:SubList_R3ReleaseHandler(subList)
  self.vendorOn:SubList_R3ReleaseHandler(self, subList)
end
function VendorCraft:EVT_Anim_End()
  self.vendorOn:Submenu_AnimEndHandler(self)
end
function VendorCraft:EVT_Square_Press()
  self.vendorOn:Submenu_SquarePressHandler(self)
end
function VendorUpgrade:Setup()
  self.vendorOn = self:GetState("VendorOn")
  self.vendorOn:SubmenuSetup(self, false, "Upgrade")
end
function VendorUpgrade:Enter()
  self.menu:Activate()
  self.vendorOn:SubmenuEnter(self, false)
end
function VendorUpgrade:Exit()
  self.vendorOn:SubmenuExit(self)
end
function VendorUpgrade:CanRecipeBeMade(recipeListItem)
  return self.vendorOn:CanRecipeBeMade(recipeListItem)
end
function VendorUpgrade:GetRefreshWallet()
  return self.vendorOn:Submenu_GetRefreshWallet()
end
function VendorUpgrade:MainList_AdvanceReleaseHandler()
  recipeUtil.MainList_AdvanceReleaseHandler(self.vendorOn, self)
end
function VendorUpgrade:MainList_BackReleaseHandler()
  self.vendorOn:MainList_BackReleaseHandler()
end
function VendorUpgrade:MainList_Button_Update(button)
  recipeUtil.MainList_Button_Update(self, button)
end
function VendorUpgrade:MainList_Button_OnGainFocus(button)
  local showExit = true
  self.vendorOn:UpdateFooterButtonPrompt(self.menu, true, showExit)
end
function VendorUpgrade:CategoryList_BackReleaseHandler()
  recipeUtil.CategoryList_BackReleaseHandler(self)
  local isVendorMenu = true
  recipeUtil.SubmenuList_Activate(self.vendorOn, self.subStateIndex, isVendorMenu)
end
function VendorUpgrade:CategoryList_Button_OnGainFocus(button)
  local showExit = false
  self.vendorOn:UpdateFooterButtonPrompt(self.menu, true, showExit)
end
function VendorUpgrade:Category_OnSelect(currMainSelection, currCategorySelection)
  self.vendorOn:Category_OnSelect(self, currMainSelection, currCategorySelection)
end
function VendorUpgrade:SubList_AfterDelay(button)
  self.vendorOn:SelectRecipe(self, button)
end
function VendorUpgrade:SubList_Button_OnLoseFocus(button)
  recipeUtil.SubList_Button_OnLoseFocus(self, button)
end
function VendorUpgrade:SubList_BackReleaseHandler()
  self.vendorOn:SubList_BackReleaseHandler(self)
end
function VendorUpgrade:SubList_R2PressHandler(subList)
end
function VendorUpgrade:SubList_R2ReleaseHandler()
end
function VendorUpgrade:SubList_R3ReleaseHandler(subList)
  self.vendorOn:SubList_R3ReleaseHandler(self, subList)
end
function VendorUpgrade:EVT_Anim_End()
  self.vendorOn:Submenu_AnimEndHandler(self)
end
function VendorUpgrade:EVT_Square_Press()
  self.vendorOn:Submenu_SquarePressHandler(self)
end
function VendorBuy:Setup()
  self.vendorOn = self:GetState("VendorOn")
  self.vendorOn:SubmenuSetup(self, false, "Buy")
end
function VendorBuy:Enter()
  self.menu:Activate()
  self.vendorOn:SubmenuEnter(self, false)
end
function VendorBuy:Exit()
  self.vendorOn:SubmenuExit(self)
end
function VendorBuy:CanRecipeBeMade(recipeListItem)
  return self.vendorOn:CanRecipeBeMade(recipeListItem)
end
function VendorBuy:GetRefreshWallet()
  return self.vendorOn:Submenu_GetRefreshWallet()
end
function VendorBuy:MainList_AdvanceReleaseHandler()
  recipeUtil.MainList_AdvanceReleaseHandler(self.vendorOn, self)
end
function VendorBuy:MainList_BackReleaseHandler()
  self.vendorOn:MainList_BackReleaseHandler()
end
function VendorBuy:MainList_Button_Update(button)
  recipeUtil.MainList_Button_Update(self, button)
end
function VendorBuy:MainList_Button_OnGainFocus(button)
  local showExit = true
  self.vendorOn:UpdateFooterButtonPrompt(self.menu, true, showExit)
end
function VendorBuy:CategoryList_BackReleaseHandler()
  recipeUtil.CategoryList_BackReleaseHandler(self)
  local isVendorMenu = true
  recipeUtil.SubmenuList_Activate(self.vendorOn, self.subStateIndex, isVendorMenu)
end
function VendorBuy:CategoryList_Button_OnGainFocus(button)
  local showExit = false
  self.vendorOn:UpdateFooterButtonPrompt(self.menu, true, showExit)
end
function VendorBuy:Category_OnSelect(currMainSelection, currCategorySelection)
  self.vendorOn:Category_OnSelect(self, currMainSelection, currCategorySelection)
end
function VendorBuy:SubList_AfterDelay(button)
  self.vendorOn:SelectRecipe(self, button)
end
function VendorBuy:SubList_Button_OnLoseFocus(button)
  recipeUtil.SubList_Button_OnLoseFocus(self, button)
end
function VendorBuy:SubList_BackReleaseHandler()
  self.vendorOn:SubList_BackReleaseHandler(self)
end
function VendorBuy:SubList_R2PressHandler(subList)
end
function VendorBuy:SubList_R2ReleaseHandler()
end
function VendorBuy:SubList_R3ReleaseHandler(subList)
  self.vendorOn:SubList_R3ReleaseHandler(self, subList)
end
function VendorBuy:EVT_Anim_End()
  self.vendorOn:Submenu_AnimEndHandler(self)
end
function VendorBuy:EVT_Square_Press()
  self.vendorOn:Submenu_SquarePressHandler(self)
end
function VendorSell:Setup()
  self.vendorOn = self:GetState("VendorOn")
  self.vendorOn:SubmenuSetup(self, false, "Sell")
end
function VendorSell:Enter()
  self.menu:Activate()
  self.vendorOn:SubmenuEnter(self, false)
end
function VendorSell:Exit()
  self.vendorOn:SubmenuExit(self)
end
function VendorSell:CanRecipeBeMade(recipeListItem)
  return self.vendorOn:CanRecipeBeMade(recipeListItem)
end
function VendorSell:GetRefreshWallet()
  return self.vendorOn:Submenu_GetRefreshWallet()
end
function VendorSell:MainList_AdvanceReleaseHandler()
  recipeUtil.MainList_AdvanceReleaseHandler(self.vendorOn, self)
end
function VendorSell:MainList_BackReleaseHandler()
  self.vendorOn:MainList_BackReleaseHandler()
end
function VendorSell:MainList_Button_Update(button)
  recipeUtil.MainList_Button_Update(self, button)
end
function VendorSell:MainList_Button_OnGainFocus(button)
  local showExit = true
  self.vendorOn:UpdateFooterButtonPrompt(self.menu, true, showExit)
end
function VendorSell:CategoryList_BackReleaseHandler()
  recipeUtil.CategoryList_BackReleaseHandler(self)
  local isVendorMenu = true
  recipeUtil.SubmenuList_Activate(self.vendorOn, self.subStateIndex, isVendorMenu)
end
function VendorSell:CategoryList_Button_OnGainFocus(button)
  local showExit = false
  self.vendorOn:UpdateFooterButtonPrompt(self.menu, true, showExit)
end
function VendorSell:Category_OnSelect(currMainSelection, currCategorySelection)
  self.vendorOn:Category_OnSelect(self, currMainSelection, currCategorySelection)
end
function VendorSell:SubList_AfterDelay(button)
  self.vendorOn:SelectRecipe(self, button)
end
function VendorSell:SubList_Button_OnLoseFocus(button)
  recipeUtil.SubList_Button_OnLoseFocus(self, button)
end
function VendorSell:SubList_BackReleaseHandler()
  self.vendorOn:SubList_BackReleaseHandler(self)
end
function VendorSell:SubList_R2PressHandler(subList)
end
function VendorSell:SubList_R2ReleaseHandler()
end
function VendorSell:SubList_R3ReleaseHandler(subList)
  self.vendorOn:SubList_R3ReleaseHandler(self, subList)
end
function VendorSell:EVT_Anim_End()
  self.vendorOn:Submenu_AnimEndHandler(self)
end
function VendorSell:EVT_Square_Press()
  self.vendorOn:Submenu_SquarePressHandler(self)
end
function VendorLostItems:Setup()
  self.vendorOn = self:GetState("VendorOn")
  self.vendorOn:SubmenuSetup(self, false, "LostItems")
  local goList = self.menu:GetList("MainList"):GetButtonRootGameObject()
  self.goLostItemFooter = goList:FindSingleGOByName("LostItemFooter_GO")
  local goSliderCraft = self.goLostItemFooter:FindSingleGOByName("slider_craft")
  self.holdFill = sliderHoldFill.SliderHoldFill.New(self, {
    Name = "VendorLostItems_HoldFill",
    SliderObject = goSliderCraft,
    HoldSound = "SND_UX_HUD_Vendor_LostItems_Hold",
    SuccessSound = "SND_UX_HUD_Vendor_LostItems_Success",
    HoldStartSound = "SND_UX_Vendor_Upgrade_Hold_Button_Start",
    StopSound = "SND_UX_Vendor_Upgrade_Hold_Reset_LP",
    StopWhenFull = true,
    IncAnimRate = 1,
    DecAnimRate = 0.4,
    PressEvent = "EVT_Square_Press",
    ReleaseEvent = "EVT_Square_Release"
  })
  self.holdFill:SetOnComplete(function()
    self:GetAllLostItems()
  end)
  self.submenuList = self.vendorOn.menu:GetList(self.vendorOn.menu:get_submenuListName())
end
function VendorLostItems:Enter()
  self.menu:Activate()
  local sliderText = util.GetTextHandle(self.goLostItemFooter, "LostItemsSlider_Text")
  UI.SetText(sliderText, util.GetLAMSMsg(lamsConsts.GetAllLostItems))
  UI.SetTextIsClickable(sliderText)
  local lostItemsCount = recipeUtil.LostItems_Refresh(self, true)
  self:UpdateFooterButtonPrompt()
  self.vendorOn:SetMenuToWorldTransform(self)
  self.vendorOn.attributeCard:HideCard()
  if lostItemsCount <= 0 then
    self.vendorOn:HideAllInfo()
  end
end
function VendorLostItems:Exit()
  self.holdFill:Deactivate(true)
  self.vendorOn:SubmenuExit(self)
  self.goLostItemFooter:Hide()
end
function VendorLostItems:UpdateFooterButtonPrompt()
  self.vendorOn:UpdateFooterButtonPrompt(self.menu, false, true)
end
function VendorLostItems:CurrentCharacter()
  return pickupConsts.TAG_PICKUP_KRATOS
end
function VendorLostItems:MainList_EmptyText()
  return lamsConsts.NoItemsAvailable
end
function VendorLostItems:CanRecipeBeMade(recipeListItem)
  return false
end
function VendorLostItems:MainList_AdvanceReleaseHandler()
end
function VendorLostItems:GetAllLostItems()
  local lostResources = Wallets.GetExistingResources(resourceConsts.WALLET_LOST_ITEMS)
  for i = 1, #lostResources do
    local resourceName = lostResources[i]
    local value = Wallets.GetResourceValue(resourceConsts.WALLET_LOST_ITEMS, resourceName)
    if resourceUtil.HasFlag(resourceName, resourceConsts.RESOURCE_FLAG_ROLL_CONDITION) then
      if Wallets.HasMemorySpaceForRune() then
        Wallets.RemoveResource(resourceConsts.WALLET_LOST_ITEMS, resourceName, value)
        Wallets.AddResource(resourceConsts.WALLET_KRATOS, resourceName, value)
        Loot.RollCondition(resourceName, resourceConsts.WALLET_LOST_ITEMS)
      end
    elseif resourceUtil.HasFlag(resourceName, resourceConsts.RESOURCE_FLAG_AXE_FLAME) then
      Wallets.RemoveResource(resourceConsts.WALLET_LOST_ITEMS, resourceName, value)
      Wallets.AddResource(resourceConsts.WALLET_KRATOS, resourceName, value)
      local _, progress = game.QuestManager.GetQuestProgressAndGoal("Quest_AxeUpgrade_Find")
      if progress == 0 then
        game.QuestManager.StartQuest("Quest_AxeUpgrade_Parent")
        game.QuestManager.IncrementQuestProgress("Quest_AxeUpgrade_Find", value)
      elseif 0 < progress and progress < 5 then
        game.QuestManager.IncrementQuestProgress("Quest_AxeUpgrade_Find", value)
      end
    elseif resourceUtil.HasFlag(resourceName, resourceConsts.RESOURCE_FLAG_BLADE_FLAME) then
      Wallets.RemoveResource(resourceConsts.WALLET_LOST_ITEMS, resourceName, value)
      Wallets.AddResource(resourceConsts.WALLET_KRATOS, resourceName, value)
      local _, progress = game.QuestManager.GetQuestProgressAndGoal("Quest_BladesUpgrade_Find")
      if progress == 0 then
        game.QuestManager.StartQuest("Quest_BladesUpgrade_Parent")
        game.QuestManager.IncrementQuestProgress("Quest_BladesUpgrade_Find", value)
      elseif 0 < progress and progress < 5 then
        game.QuestManager.IncrementQuestProgress("Quest_BladesUpgrade_Find", value)
      end
    else
      if resourceUtil.HasFlag(resourceName, resourceConsts.RESOURCE_FLAG_WEAPON_SPECIAL_SON) then
        self.vendorOn.sonSpecialOnExit = resourceName
      end
      Wallets.RemoveResource(resourceConsts.WALLET_LOST_ITEMS, resourceName, value)
      Wallets.AddResource(resourceConsts.WALLET_KRATOS, resourceName, value)
    end
  end
  local lostRecipes = Wallets.GetRecipesWithFlags(resourceConsts.WALLET_LOST_ITEMS, {"LostItem"})
  for _, recipeName in pairs(lostRecipes) do
    Wallets.AddRecipe(resourceConsts.WALLET_KRATOS, recipeName)
    Wallets.RemoveRecipe(resourceConsts.WALLET_LOST_ITEMS, recipeName)
  end
  local lostRunes = Wallets.GetAllRunes(resourceConsts.WALLET_LOST_ITEMS)
  for i = 1, #lostRunes do
    local runeName = lostRunes[i]
    Wallets.MoveRune(resourceConsts.WALLET_KRATOS, resourceConsts.WALLET_LOST_ITEMS, runeName)
  end
  if 0 < #lostResources + #lostRunes then
    local lostItemsCount = recipeUtil.LostItems_Refresh(self, true)
    self:UpdateFooterButtonPrompt(lostItemsCount)
    if lostItemsCount <= 0 then
      self.vendorOn:HideAllInfo()
    end
  end
  self.submenuList:UpdateSelectedButton()
  local sortingGroup
  recipeUtil.AllRecipesTables_RefreshSubState(self.vendorOn.vendorWallet, "Upgrade", sortingGroup)
  recipeUtil.AllRecipesTables_RefreshSubState(self.vendorOn.vendorWallet, "Sell", sortingGroup)
end
function VendorLostItems:MainList_BackReleaseHandler()
  self.vendorOn:MainList_BackReleaseHandler()
end
function VendorLostItems:MainList_Button_Update(button)
  local item = button:get_item()
  if item ~= nil then
    if item.Type == resourceConsts.RESOURCE_FLAG_RESOURCE then
      if item.Category ~= "Resource" then
        button:SetText("text_rightAligned", "")
        buttonUtil.UpdateColorQuad(button, nil)
      else
        local amount = Wallets.GetResourceValue(resourceConsts.WALLET_LOST_ITEMS, item.Name)
        button:SetText("text_rightAligned", amount)
        local rarityColor = resourceUtil.GetRarityColor(item.Name)
        local rarity = resourceUtil.GetRarity(item.Name)
        if resourceUtil.GetRarity(item.Name) == nil then
          rarityColor = nil
        end
        buttonUtil.UpdateColorQuad(button, rarityColor)
      end
    elseif item.Type == resourceConsts.RESOURCE_FLAG_RUNE then
      button:SetText("text_rightAligned", "")
      buttonUtil.UpdateColorQuad(button, colors.RARITY[runeUtil.GetRarityFromID(item.Name)])
    else
      button:SetText("text_rightAligned", "")
      buttonUtil.UpdateColorQuad(button, nil)
    end
  else
    button:SetText("text_rightAligned", "")
    buttonUtil.UpdateColorQuad(button, nil)
  end
  button:UpdateNewIcon(function(button)
    local item = button:get_item()
    if item == nil then
      return
    end
    if item.Type == resourceConsts.RESOURCE_FLAG_RUNE then
      return UI.HasNotification(consts.NotificationTypes.Rune, item.Name)
    else
      return UI.HasNotification(consts.NotificationTypes.Resource, item.Name)
    end
  end)
  button:UpdateEquippedIcon(function(button)
    return false
  end)
end
function VendorLostItems:MainList_Button_OnGainFocus(button)
  local item = button:get_item()
  if item == nil then
    self.vendorOn:HideAllInfo()
  else
    self.vendorOn.cardManager:DisplayCard_ForLostItem(item)
  end
  self:UpdateFooterButtonPrompt()
end
function VendorLostItems:MainList_Button_OnLoseFocus(button)
  local item = button:get_item()
  if item.Type == resourceConsts.RESOURCE_FLAG_RUNE then
    UI.ClearNotification(consts.NotificationTypes.Rune, item.Name)
  else
    UI.ClearNotification(consts.NotificationTypes.Resource, item.Name)
  end
  self.submenuList:UpdateSelectedButton()
end
function VendorLostItems:CategoryList_BackReleaseHandler()
  recipeUtil.CategoryList_BackReleaseHandler(self)
  local isVendorMenu = true
  recipeUtil.SubmenuList_Activate(self.vendorOn, "LostItems", isVendorMenu)
end
function VendorLostItems:CategoryList_Button_OnGainFocus(button)
end
function VendorLostItems:Category_OnSelect(currMainSelection, currCategorySelection)
end
function VendorLostItems:SubList_AfterDelay(button)
end
function VendorLostItems:SubList_Button_OnLoseFocus(button)
end
function VendorLostItems:SubList_BackReleaseHandler()
end
function VendorLostItems:SubList_R2PressHandler()
end
function VendorLostItems:SubList_R2ReleaseHandler()
end
function VendorLostItems:SubList_R3ReleaseHandler(subList)
end
function VendorMenu:OnSaveCheckpoint(tab)
end
function VendorMenu:OnRestoreCheckpoint(tab)
end
