ZO_RetraitStation_Retrait_Gamepad = ZO_RetraitStation_Retrait_Base:Subclass()

function ZO_RetraitStation_Retrait_Gamepad:Initialize(control, interactScene)
    ZO_RetraitStation_Retrait_Base.Initialize(self, control, "retrait_gamepad")

    GAMEPAD_RETRAIT_FRAGMENT = ZO_FadeSceneFragment:New(control)
    interactScene:AddFragment(GAMEPAD_RETRAIT_FRAGMENT)

    interactScene:RegisterCallback("StateChange", function(oldState, newState)
        if newState == SCENE_SHOWING then
            self:OnShowing()
        elseif newState == SCENE_HIDING then
            self:OnHiding()
        end
    end)

    self.sourceTooltip = self.control:GetNamedChild("SourceTooltip")
    self.sourceTooltip.tip:SetClearOnHidden(false)
    self.qualityBridge = self.control:GetNamedChild("QualityBridge")
    self.resultTooltip = self.control:GetNamedChild("ResultTooltip")

    --Register the source tooltip for narration
    local sourceTooltipNarrationInfo =
    {
        canNarrate = function()
            return not self.sourceTooltip:IsHidden()
        end,
        tooltipNarrationFunction = function()
            local narration = self.sourceTooltip.tip:GetNarrationText()
            --If the result tooltip is showing, add an additional bit of narration to the front that tells us this is the current item
            if not self.resultTooltip:IsHidden() then
                narration = { GetString(SI_GAMEPAD_RETRAIT_CURRENT_ITEM_NARRATION), narration }
            end
            return narration
        end,
    }
    GAMEPAD_TOOLTIPS:RegisterCustomTooltipNarration(sourceTooltipNarrationInfo)

    --Register the result tooltip for narration
    local resultTooltipNarrationInfo =
    {
        canNarrate = function()
            return not self.resultTooltip:IsHidden()
        end,
        tooltipNarrationFunction = function()
            return { GetString(SI_GAMEPAD_RETRAIT_UPDATED_ITEM_NARRATION), self.resultTooltip.tip:GetNarrationText()}
        end,
    }
    GAMEPAD_TOOLTIPS:RegisterCustomTooltipNarration(resultTooltipNarrationInfo)

    --Register the list of inventory items for narration
    --Order matters, do this before we initialize the header
    local narrationInfo =
    {
        canNarrate = function()
            return self:IsShowing()
        end,
        headerNarrationFunction = function()
            return ZO_GamepadGenericHeader_GetNarrationText(self.header, self.headerData)
        end,
    }
    SCREEN_NARRATION_MANAGER:RegisterParametricList(self.inventory.list, narrationInfo)

    self:InitializeHeader()

    self.currentFilter = SMITHING_FILTER_TYPE_WEAPONS
    self:InitializeTraitList()
end

function ZO_RetraitStation_Retrait_Gamepad:InitializeInventory()
    self.inventoryControl = self.control:GetNamedChild("MaskInventory")
    self.inventory = ZO_Retrait_Inventory_Gamepad:New(self, self.inventoryControl, SLOT_TYPE_CRAFTING_COMPONENT)

    self.itemActions = ZO_ItemSlotActionsController:New(KEYBIND_STRIP_ALIGN_LEFT, ADDITIONAL_OVERBINDS, DONT_USE_KEYBIND_STRIP)
    self.itemActions:SetUseKeybindStrip(false)

    self.inventory.list:SetOnTargetDataChangedCallback(function(list, targetData)
        self:SetSourceItem(targetData)
    end)
end

function ZO_RetraitStation_Retrait_Gamepad:InitializeTraitList()
    self.traitListContainer = self.control:GetNamedChild("MaskTraitContainer")
    local traitListControl = self.traitListContainer:GetNamedChild("List")
    self.traitList = ZO_GamepadVerticalItemParametricScrollList:New(traitListControl)
    self.traitList:SetAlignToScreenCenter(true)

    self.traitList:AddDataTemplate("ZO_GamepadMenuEntryTemplateLowercase42", ZO_SharedGamepadEntry_OnSetup, ZO_GamepadMenuEntryTemplateParametricListFunction)

    self.traitList:SetOnTargetDataChangedCallback(function(list, targetData)
        self:ShowRetraitResult(true)
        KEYBIND_STRIP:UpdateKeybindButtonGroup(self.keybindStripDescriptor)
    end)

    --Register the trait list for narration
    local narrationInfo =
    {
        canNarrate = function()
            return self:IsShowing()
        end,
    }
    SCREEN_NARRATION_MANAGER:RegisterParametricList(self.traitList, narrationInfo)
end

function ZO_RetraitStation_Retrait_Gamepad:InitializeKeybindStripDescriptors()
    self.keybindStripDescriptor =
    {
        alignment = KEYBIND_STRIP_ALIGN_LEFT,

        -- need to have special exits for this scene
        {
            --Ethereal binds show no text, the name field is used to help identify the keybind when debugging. This text does not have to be localized.
            name = "Gamepad Retrait Exit",
            keybind = "UI_SHORTCUT_EXIT",
            callback = function()
                SCENE_MANAGER:ShowBaseScene()
            end,
            visible = function()
                return not ZO_CraftingUtils_IsPerformingCraftProcess()
            end,
            ethereal = true,
        },

        {
            name = function()
                if self.traitList:IsActive() then
                    return GetString(SI_ITEM_ACTION_REMOVE_FROM_CRAFT)
                else
                    return GetString(SI_GAMEPAD_BACK_OPTION)
                end
            end,
            keybind = "UI_SHORTCUT_NEGATIVE",
            callback = function()
                if self.traitList:IsActive() then
                    self:RemoveItemFromRetrait()
                    KEYBIND_STRIP:UpdateKeybindButtonGroup(self.keybindStripDescriptor)
                else
                    SCENE_MANAGER:HideCurrentScene()
                end
            end,
            visible = function()
                return not ZO_CraftingUtils_IsPerformingCraftProcess()
            end
        },

        -- Select
        {
            name = function()
                if self.traitList:IsActive() then
                    local retraitCost, retraitCurrency, retraitCurrencyLocation = GetItemRetraitCost()
                    local currencyFormat = ZO_CURRENCY_FORMAT_WHITE_AMOUNT_ICON
                    if retraitCost > GetCurrencyAmount(retraitCurrency, retraitCurrencyLocation) then
                        currencyFormat = ZO_CURRENCY_FORMAT_ERROR_AMOUNT_ICON
                    end

                    local formattedRetraitCost = ZO_Currency_FormatPlatform(retraitCurrency, retraitCost, currencyFormat)
                    return zo_strformat(SI_RETRAIT_STATION_PERFORM_RETRAIT_WITH_COST, formattedRetraitCost)
                else
                    return GetString(SI_ITEM_ACTION_ADD_TO_CRAFT)
                end
            end,
            narrationOverrideName = function()
                if self.traitList:IsActive() then
                    local retraitCost, retraitCurrency, retraitCurrencyLocation = GetItemRetraitCost()
                    local formattedRetraitCost = ZO_Currency_FormatPlatform(retraitCurrency, retraitCost, ZO_CURRENCY_FORMAT_AMOUNT_NAME)
                    return zo_strformat(SI_RETRAIT_STATION_PERFORM_RETRAIT_WITH_COST, formattedRetraitCost)
                else
                    return GetString(SI_ITEM_ACTION_ADD_TO_CRAFT)
                end
            end,
            keybind = "UI_SHORTCUT_PRIMARY",
            visible =  function()
                return self.inventory:CurrentSelection() and not ZO_CraftingUtils_IsPerformingCraftProcess()
            end,
            enabled = function()
                if self.traitList:IsActive() then
                    local targetTrait = self.traitList:GetTargetData()
                    if targetTrait then
                        if not targetTrait:IsEnabled() then
                            return false
                        end
                        local retraitCost, retraitCurrency, retraitCurrencyLocation = GetItemRetraitCost()
                        local hasEnoughCurrency = retraitCost <= GetCurrencyAmount(retraitCurrency, retraitCurrencyLocation)
                        if not hasEnoughCurrency then
                            return false, GetString("SI_RETRAITRESPONSE", RETRAIT_RESPONSE_INSUFFICIENT_FUNDS)
                        end
                    else
                        return false
                    end
                end

                return true
            end,
            callback = function()
                if self.traitList:IsActive() then
                    self:PerformRetrait()
                else
                    self:AddItemToRetrait()
                    KEYBIND_STRIP:UpdateKeybindButtonGroup(self.keybindStripDescriptor)
                end
            end,
        },

        -- Item Options
        {
            name = GetString(SI_GAMEPAD_INVENTORY_ACTION_LIST_KEYBIND),
            keybind = "UI_SHORTCUT_TERTIARY",
            callback = function()
                self:ShowItemActions()
            end,
            visible = function()
                return not ZO_CraftingUtils_IsPerformingCraftProcess() and self.inventory:CurrentSelection() ~= nil and not self.traitList:IsActive()
            end
        },
    }

    ZO_Gamepad_AddListTriggerKeybindDescriptors(self.keybindStripDescriptor, self.inventory.list)
end

function ZO_RetraitStation_Retrait_Gamepad:InitializeHeader()
    self.header = self.control:GetNamedChild("HeaderContainerHeader")
    ZO_GamepadGenericHeader_Initialize(self.header, ZO_GAMEPAD_HEADER_TABBAR_CREATE)

    local function OnInventoryUpdate()
        if not self.control:IsHidden() then
            self:RefreshHeader()
        end
    end

    self.control:RegisterForEvent(EVENT_INVENTORY_FULL_UPDATE, OnInventoryUpdate)
    self.control:RegisterForEvent(EVENT_INVENTORY_SINGLE_SLOT_UPDATE, OnInventoryUpdate)

    local function OnCurrencyUpdate(currencyType, currencyLocation, newAmount, oldAMount, reason)
        if not self.control:IsHidden() and currencyType == CURT_CHAOTIC_CREATIA then
            self:RefreshHeader()
        end
    end

    self.control:RegisterForEvent(EVENT_CURRENCY_UPDATE, OnCurrencyUpdate)

    local function CreateTabEntryForFilter(smithingFilter)
        return 
        {
            text = GetString("SI_SMITHINGFILTERTYPE", smithingFilter),
            callback =  function()
                self:OnFilterChanged(smithingFilter)
                --Re-narrate on tab change
                local NARRATE_HEADER = true
                SCREEN_NARRATION_MANAGER:QueueParametricListEntry(self.inventory.list, NARRATE_HEADER)
            end,
            mode = smithingFilter,
        }
    end

    local tabBarEntries = 
    {
        CreateTabEntryForFilter(SMITHING_FILTER_TYPE_WEAPONS),
        CreateTabEntryForFilter(SMITHING_FILTER_TYPE_ARMOR),
        CreateTabEntryForFilter(SMITHING_FILTER_TYPE_JEWELRY),
    }

    local function GetCapacity()
        return zo_strformat(SI_GAMEPAD_INVENTORY_CAPACITY_FORMAT, GetNumBagUsedSlots(BAG_BACKPACK), GetBagSize(BAG_BACKPACK))
    end

    local HAS_ENOUGH = false
    local displayOptions =
    {
        currencyCapAmount = GetMaxPossibleCurrency(CURT_CHAOTIC_CREATIA, CURRENCY_LOCATION_ACCOUNT),
    }
    local function SetChaoticCreatiaAmount(control)
        ZO_CurrencyControl_SetSimpleCurrency(control, CURT_CHAOTIC_CREATIA, GetCurrencyAmount(CURT_CHAOTIC_CREATIA, CURRENCY_LOCATION_ACCOUNT), ZO_GAMEPAD_CURRENCY_OPTIONS_LONG_FORMAT, CURRENCY_SHOW_ALL, HAS_ENOUGH, displayOptions)
        -- must return a non-nil value so that the control isn't auto-hidden
        return true
    end

    local CURRENCY_NARRATION_OPTIONS = 
    {
        showCap = true,
        currencyLocation = CURRENCY_LOCATION_ACCOUNT,
    }
    local function GetChaoticCreatiaAmountNarration()
        return ZO_Currency_FormatGamepad(CURT_CHAOTIC_CREATIA, GetCurrencyAmount(CURT_CHAOTIC_CREATIA, CURRENCY_LOCATION_ACCOUNT), ZO_CURRENCY_FORMAT_AMOUNT_ICON, CURRENCY_NARRATION_OPTIONS)
    end

    local IS_PLURAL = false
    local IS_LOWER = true
    local retraitCurrencyName = GetCurrencyName(CURT_CHAOTIC_CREATIA, IS_PLURAL, IS_LOWER)

    self.headerData = 
    {
        data1HeaderText = GetString(SI_GAMEPAD_INVENTORY_CAPACITY),
        data1Text = GetCapacity,
        data2HeaderText = retraitCurrencyName,
        data2Text = SetChaoticCreatiaAmount,
        data2TextNarration = GetChaoticCreatiaAmountNarration,
        tabBarEntries = tabBarEntries,
    }

    self:RefreshHeader()
end

function ZO_RetraitStation_Retrait_Gamepad:AddInventoryAdditionalFilter(additionalFilterFunction)
    if self.inventory then
        self.inventory.additionalFilter = additionalFilterFunction
    end
end

function ZO_RetraitStation_Retrait_Gamepad:RefreshHeader()
    ZO_GamepadGenericHeader_Refresh(self.header, self.headerData)
end

function ZO_RetraitStation_Retrait_Gamepad:OnShowing()
    self:AddKeybinds()
    self:SetInventoryActive(true)

    self:Refresh()

    self:RefreshHeader()
    ZO_GamepadGenericHeader_Activate(self.header)
end

function ZO_RetraitStation_Retrait_Gamepad:OnHiding()
    self.itemActions:SetInventorySlot(nil)
    self:RemoveKeybinds()
    self:SetInventoryActive(false)
    self:SetTraitListActive(false)

    ZO_GamepadGenericHeader_Deactivate(self.header)
    self:LayoutSourceItemTooltip()
    self:ShowRetraitResult(false)
    GAMEPAD_CRAFTING_RESULTS:SetCraftingTooltip(nil)
end

function ZO_RetraitStation_Retrait_Gamepad:OnFilterChanged(filterType)
    self.filterType = filterType

    self.inventory:SetFilter(filterType)
    self:SetSourceItem(self.inventory:CurrentSelection())
end

function ZO_RetraitStation_Retrait_Gamepad:SetSourceItem(itemData)
    KEYBIND_STRIP:UpdateKeybindButtonGroup(self.keybindStripDescriptor)
    self.itemActions:SetInventorySlot(itemData)

    self:LayoutSourceItemTooltip(itemData)
end

function ZO_RetraitStation_Retrait_Gamepad:AddKeybinds()
    KEYBIND_STRIP:RemoveDefaultExit()
    KEYBIND_STRIP:AddKeybindButtonGroup(self.keybindStripDescriptor)
end

function ZO_RetraitStation_Retrait_Gamepad:RemoveKeybinds()
    KEYBIND_STRIP:RemoveKeybindButtonGroup(self.keybindStripDescriptor)
    KEYBIND_STRIP:RestoreDefaultExit()
end

function ZO_RetraitStation_Retrait_Gamepad:Refresh()
    self.inventory:HandleDirtyEvent()
    ZO_RetraitStation_Retrait_Base.Refresh(self)
end

function ZO_RetraitStation_Retrait_Gamepad:ShowItemActions()
    local dialogData = 
    {
        targetData = self.inventory:CurrentSelection(),
        itemActions = self.itemActions,
    }

    ZO_Dialogs_ShowPlatformDialog(ZO_GAMEPAD_INVENTORY_ACTION_DIALOG, dialogData)
end

function ZO_RetraitStation_Retrait_Gamepad:SetupTraitListEntryData(entryData, trait, bag, slot)
    entryData.trait = trait
    entryData.knownTrait = IsItemTraitKnownForRetraitResult(bag, slot, trait)

    entryData:SetEnabled(entryData.knownTrait)
    entryData:SetIconDisabledTintOnSelection(true)
end

function ZO_RetraitStation_Retrait_Gamepad:SetTraitListActive(active)
    if active then
        self.traitList:Activate()
    else
        self.traitList:Deactivate()
    end

    self.traitListContainer:SetHidden(not active)
end

function ZO_RetraitStation_Retrait_Gamepad:SetInventoryActive(active)
    if active then
        self.inventory:Activate()
        local targetData = self.inventory:CurrentSelection()
        self:LayoutSourceItemTooltip(targetData)
    else
        self.inventory:Deactivate()
    end

    self.inventoryControl:SetHidden(not active)
end

function ZO_RetraitStation_Retrait_Gamepad:RefreshTraitList()
    self.traitList:Clear()

    local bag, slot = self.inventory:CurrentSelectionBagAndSlot()
    local selectedItemTrait = GetItemTrait(bag, slot)
    local traitData = ZO_RETRAIT_STATION_MANAGER:GetTraitInfoForCategory(GetItemTraitCategory(bag, slot))
    internalassert(traitData)

    for index, traitRowData in ipairs(traitData) do
        if selectedItemTrait ~= traitRowData.traitType then
            local entryData = ZO_GamepadEntryData:New(traitRowData.traitName, traitRowData.traitItemIcon)
            self:SetupTraitListEntryData(entryData, traitRowData.traitType, bag, slot)

            self.traitList:AddEntry("ZO_GamepadMenuEntryTemplateLowercase42", entryData)
        end
    end

    self.traitList:Commit()
end

function ZO_RetraitStation_Retrait_Gamepad:AddItemToRetrait()
    -- rediscover inventory actions since they have changed
    self.itemActions:SetInventorySlot(self.inventory:CurrentSelection())
    KEYBIND_STRIP:UpdateKeybindButtonGroup(self.keybindStripDescriptor)

    -- create the tooltip string for what research is required for this item now,
    -- so we don't have to create it every time we mouse over an unknown trait
    local bag, slot = self.inventory:CurrentSelectionBagAndSlot()
    self:UpdateRequireResearchTooltipString(bag, slot)

    self:RefreshTraitList()

    self:SetInventoryActive(false)
    self:SetTraitListActive(true)

    ZO_GamepadGenericHeader_Deactivate(self.header)

    self:ShowRetraitResult(true)
end

function ZO_RetraitStation_Retrait_Gamepad:RemoveItemFromRetrait()
    self:SetTraitListActive(false)
    self:SetInventoryActive(true)

    -- rediscover inventory actions since they have changed
    -- do this after setting the lists active/inactive since some of the actions/keybinds check that
    self.itemActions:SetInventorySlot(self.inventory:CurrentSelection())
    KEYBIND_STRIP:UpdateKeybindButtonGroup(self.keybindStripDescriptor)

    ZO_GamepadGenericHeader_Activate(self.header)
    self:ShowRetraitResult(false)
end

function ZO_RetraitStation_Retrait_Gamepad:IsItemAlreadySlottedToCraft(bagId, slotIndex)
    if self.traitList:IsActive() then
        local selectedBag, selectedSlot = self.inventory:CurrentSelectionBagAndSlot()
        return bagId == selectedBag and slotIndex == selectedSlot
    end

    return false
end

function ZO_RetraitStation_Retrait_Gamepad:AddItemToCraft(bagId, slotIndex)
    -- we just add the selected item to the craft, so make sure this matches
    local selectedBag, selectedSlot = self.inventory:CurrentSelectionBagAndSlot()
    if bagId == selectedBag and slotIndex == selectedSlot then
        self:AddItemToRetrait()
    end
end

function ZO_RetraitStation_Retrait_Gamepad:RemoveItemFromCraft(bagId, slotIndex)
    self:RemoveItemFromRetrait()
end

function ZO_RetraitStation_Retrait_Gamepad:PerformRetrait()
    if self.traitList:IsActive() then
        local bag, slot = self.inventory:CurrentSelectionBagAndSlot()
        local selectedTrait = self.traitList:GetTargetData().trait
        self:ShowRetraitDialog(bag, slot, selectedTrait)
    end
end

function ZO_RetraitStation_Retrait_Gamepad:OnRetraitAnimationsStopped(result)
    if self:IsShowing() then
        self:SetTraitListActive(false)
        self:SetInventoryActive(true)

        self.itemActions:SetInventorySlot(self.inventory:CurrentSelection())
        KEYBIND_STRIP:UpdateKeybindButtonGroup(self.keybindStripDescriptor)

        ZO_GamepadGenericHeader_Activate(self.header)
        self:ShowRetraitResult(false)
    end
end

do
    local CUSTOM_STACK_COUNT = 1
    local DONT_FORCE_FULL_DURABILITY = false
    local NO_PREVIEW_VALUE = nil
    local NO_TRADE_BOP_DATA = nil

    function ZO_RetraitStation_Retrait_Gamepad:LayoutSourceItemTooltip(itemData)
        self.sourceTooltip.tip:ClearLines()
        if itemData then
            local bagId = itemData.bagId
            local slotIndex = itemData.slotIndex
            local itemLink = GetItemLink(itemData.bagId, itemData.slotIndex)
            local equipped = bagId == BAG_WORN
            local equipSlot = equipped and slotIndex or EQUIP_SLOT_NONE
            local creatorName = GetItemCreatorName(bagId, slotIndex)
            local showPlayerLocked = IsItemPlayerLocked(bagId, slotIndex)

            local extraData =
            {
                bagId = bagId,
                slotIndex = slotIndex
            }

            self.sourceTooltip.tip:LayoutItemWithStackCount(itemLink, equipped, creatorName, DONT_FORCE_FULL_DURABILITY, NO_PREVIEW_VALUE, CUSTOM_STACK_COUNT, equipSlot, showPlayerLocked, NO_TRADE_BOP_DATA, extraData)
            self.sourceTooltip.icon:SetTexture(itemData.pressedIcon)
        end
        self.sourceTooltip:SetHidden(not itemData)
    end

    function ZO_RetraitStation_Retrait_Gamepad:LayoutResultItemTooltip(traitData)
        local itemData = self.inventory:CurrentSelection()
        self.resultTooltip.tip:ClearLines()
        if itemData and traitData then
            local bagId = itemData.bagId
            local slotIndex = itemData.slotIndex
            local resultItemLink = GetResultingItemLinkAfterRetrait(bagId, slotIndex, traitData.trait)
            local equipped = bagId == BAG_WORN
            local equipSlot = equipped and slotIndex or EQUIP_SLOT_NONE
            local creatorName = GetItemCreatorName(bagId, slotIndex)
            local showPlayerLocked = IsItemPlayerLocked(bagId, slotIndex)
            local extraData =
            {
                showTraitAsNew = true,
                bagId = bagId,
                slotIndex = slotIndex,
            }
            self.resultTooltip.tip:LayoutItemWithStackCount(resultItemLink, equipped, creatorName, DONT_FORCE_FULL_DURABILITY, NO_PREVIEW_VALUE, CUSTOM_STACK_COUNT, equipSlot, showPlayerLocked, NO_TRADE_BOP_DATA, extraData)
            self.resultTooltip.icon:SetTexture(itemData.pressedIcon)

            GAMEPAD_CRAFTING_RESULTS:SetCraftingTooltip(self.resultTooltip)
            -- there's no chance of failure on the craft, so we'll fill out the fail sound with a sound that already exists instead of making a new one
            GAMEPAD_CRAFTING_RESULTS:SetTooltipAnimationSounds(SOUNDS.RETRAITING_RETRAIT_TOOLTIP_GLOW_SUCCESS, SOUNDS.BLACKSMITH_IMPROVE_TOOLTIP_GLOW_FAIL)

            GAMEPAD_CRAFTING_RESULTS:ClearSecondaryTooltipAnimationControls()
            GAMEPAD_CRAFTING_RESULTS:AddSecondaryTooltipAnimationControl(self.sourceTooltip)
            GAMEPAD_CRAFTING_RESULTS:AddSecondaryTooltipAnimationControl(self.qualityBridge)
        end
    end
end

function ZO_RetraitStation_Retrait_Gamepad:ShowRetraitResult(show)
    local targetTraitData = self.traitList:GetTargetData()

    if not self.traitList:IsActive() or targetTraitData:IsEnabled() then
        self.sourceTooltip:SetHidden(false)
        self.sourceTooltip.scrollTooltip:ResetToTop()
        self.sourceTooltip:ClearAnchors()
        if show then
            local offsetX = 21
            self.sourceTooltip:SetAnchor(RIGHT, self.qualityBridge, LEFT, offsetX)
        else
            self.sourceTooltip:SetAnchor(CENTER, self.qualityBridge, CENTER)
        end

        self.qualityBridge:SetHidden(not show)

        if show then
            self:LayoutResultItemTooltip(targetTraitData)
        end
        self.resultTooltip:SetHidden(not show)

        GAMEPAD_TOOLTIPS:Reset(GAMEPAD_LEFT_TOOLTIP)
    else
        self.sourceTooltip:SetHidden(true)
        self.qualityBridge:SetHidden(true)
        self.resultTooltip:SetHidden(true)

        GAMEPAD_TOOLTIPS:LayoutUnknownRetraitTrait(GAMEPAD_LEFT_TOOLTIP, targetTraitData:GetText(), self.requiredResearchTooltipString)
    end
end

-----
-- ZO_Retrait_Inventory_Gamepad
-----

ZO_Retrait_Inventory_Gamepad = ZO_GamepadCraftingInventory:Subclass()

function ZO_Retrait_Inventory_Gamepad:New(...)
    return ZO_GamepadCraftingInventory.New(self, ...)
end

function ZO_Retrait_Inventory_Gamepad:Initialize(owner, control, ...)
    ZO_GamepadCraftingInventory.Initialize(self, control, ...)

    self.owner = owner
    self.filterType = SMITHING_FILTER_TYPE_WEAPONS
    self:SetCustomSort(function(bagId, slotIndex)
        --Sort equipped items to the top of the list
        --but items from other bags will be equal so they sort by category name
        if bagId == BAG_WORN then
            return 0
        else
            return 1
        end
    end)

    self:SetCustomBestItemCategoryNameFunction(function(slotData)
        if slotData.bagId == BAG_WORN then
            local equipSlot = GetItemComparisonEquipSlots(slotData.bagId, slotData.slotIndex)
            local visualCategory = ZO_Character_GetEquipSlotVisualCategory(equipSlot)
            slotData.bestItemCategoryName = zo_strformat(SI_GAMEPAD_SECTION_HEADER_EQUIPPED_ITEM, GetString("SI_EQUIPSLOTVISUALCATEGORY", visualCategory))
        else
            slotData.bestItemCategoryName = ZO_InventoryUtils_Gamepad_GetBestItemCategoryDescription(slotData)
        end
    end)

    self:SetCustomExtraData(function(bagId, slotIndex, data)
        data:SetIgnoreTraitInformation(true)
    end)
end

function ZO_Retrait_Inventory_Gamepad:GetCurrentFilterType()
    return self.filterType
end

function ZO_Retrait_Inventory_Gamepad:Refresh(data)
    local USE_WORN_BAG = true

        local function ItemFilterFunction(bagId, slotIndex, filterType, isQuestFilterChecked, questInfo)
        if not ZO_RetraitStation_DoesItemPassFilter(bagId, slotIndex, filterType) then
            return false
        end

        if self.additionalFilter and type(self.additionalFilter) == "function" then
            return self.additionalFilter(bagId, slotIndex, filterType)
        end

        return true
    end

    self:GetIndividualInventorySlotsAndAddToScrollData(ZO_RetraitStation_CanItemBeRetraited, ItemFilterFunction, self.filterType, data, USE_WORN_BAG)
end

function ZO_Retrait_Inventory_Gamepad:SetFilter(filterType)
    self.filterType = filterType

    self:SetNoItemLabelText(GetString("SI_SMITHINGFILTERTYPE_IMPROVENONE", self.filterType))

    self:HandleDirtyEvent()
end
