function LeoTrainer.ShowUI()
    SCENE_MANAGER:ShowTopLevel(LeoTrainerWindow)
    LeoTrainerWindow:SetHidden(false)
    LeoTrainer.hidden = false;
end

function LeoTrainer.HideUI()
    SCENE_MANAGER:HideTopLevel(LeoTrainerWindow)
    LeoTrainerWindow:SetHidden(true)
    LeoTrainer.hidden = true;
end

function LeoTrainer.ToggleUI()
    SCENE_MANAGER:ToggleTopLevel(LeoTrainerWindow)
    if LeoTrainer.hidden then
        LeoTrainer.ShowUI()
    else
        LeoTrainer.HideUI()
    end
end

function LeoTrainer:OnMouseEnterTrait(control)
    InitializeTooltip(ItemTooltip, control, LEFT, 5, 0)
    ItemTooltip:SetLink(ZO_LinkHandler_CreateLink("",nil,ITEM_LINK_TYPE,control.materialItemID,30,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0))
    ItemTooltip:SetHidden(false)
end

local function copy(obj, seen)
    if type(obj) ~= 'table' then return obj end
    if seen and seen[obj] then return seen[obj] end
    local s = seen or {}
    local res = setmetatable({}, getmetatable(obj))
    s[obj] = res
    for k, v in pairs(obj) do res[copy(k, s)] = copy(v, s) end
    return res
end

LeoTrainerQueueList = ZO_SortFilterList:Subclass()
function LeoTrainerQueueList:New(control)

    ZO_SortFilterList.InitializeSortFilterList(self, control)

    local sorterKeys =
    {
        ["trainer"] = {},
        ["trainee"] = { tiebreaker = "trainer"},
        ["trait"] = { tiebreaker = "trainee"},
        ["item"] = { tiebreaker = "trainee"},
    }

    self.masterList = {}
    ZO_ScrollList_AddDataType(self.list, 1, "LeoTrainerQueueListTemplate", 32, function(control, data) self:SetupEntry(control, data) end)

    self.sortFunction = function(listEntry1, listEntry2)
        return ZO_TableOrderingFunction(listEntry1.data, listEntry2.data, self.currentSortKey, sorterKeys, self.currentSortOrder)
    end

    return self
end

function LeoTrainerQueueList:SetupEntry(control, data)

    control.data = data

    control.trainer = GetControl(control, "Trainer")
    control.trainer:SetText(data.trainer)

    control.trainee = GetControl(control, "Trainee")
    control.trainee:SetText(data.trainee)

    control.trait = GetControl(control, "Trait")
    control.trait:SetText(data.researchName)

    control.item = GetControl(control, "Item")
    control.item:SetText(data.itemLink)
    control.item:SetHandler('OnMouseUp', function(control, button, upInside)
        if upInside == false then return end
        if button == MOUSE_BUTTON_INDEX_RIGHT then
            LeoTrainer.RemoveFromQueue(data.index)
        end
    end)

    ZO_SortFilterList.SetupRow(self, control, data)
end

function LeoTrainerQueueList:BuildMasterList()
    self.masterList = {}
    local list = LeoTrainer.GetQueue()
    if list then
        for k, v in ipairs(list) do
            local data = copy(v)
            data.queueIndex = k
            table.insert(self.masterList, data)
        end
    end
end

function LeoTrainerQueueList:SortScrollList()
    local scrollData = ZO_ScrollList_GetDataList(self.list)
    table.sort(scrollData, self.sortFunction)
end

function LeoTrainerQueueList:FilterScrollList()

    local scrollData = ZO_ScrollList_GetDataList(self.list)
    ZO_ClearNumericallyIndexedTable(scrollData)

    for i = 1, #self.masterList do
        local data = self.masterList[i]
        local canShow = true
        if LeoTrainer.filterKnown == true and LeoTrainer.IKnowTrait(data.craft, data.line, data.trait) == false then
            canShow = false
        end
        if canShow == true and LeoTrainer.inStation > 0 and data.craft ~= LeoTrainer.inStation then
            canShow = false
        end
        if canShow then
            table.insert(scrollData, ZO_ScrollList_CreateDataEntry(1, data))
        end
    end
end

local function addLine(tooltip, text, color, alignment)
    if not color then color = ZO_TOOLTIP_DEFAULT_COLOR end
    local r, g, b = color:UnpackRGB()
    tooltip:AddLine(text, "", r, g, b, CENTER, MODIFY_TEXT_TYPE_NONE, alignment, alignment ~= TEXT_ALIGN_LEFT)
end

local function addLineCenter(tooltip, text, color)
    if not color then color = ZO_TOOLTIP_DEFAULT_COLOR end
    addLine(tooltip, text, color, TEXT_ALIGN_CENTER)
end

local function addLineTitle(tooltip, text, color)
    if not color then color = ZO_SELECTED_TEXT end
    local r, g, b = color:UnpackRGB()
    tooltip:AddLine(text, "ZoFontHeader3", r, g, b, CENTER, MODIFY_TEXT_TYPE_NONE, TEXT_ALIGN_CENTER, true)
end

local function addLineSubTitle(tooltip, text, color, alignment)
    if not color then color = ZO_SELECTED_TEXT end
    if not alignment then alignment = TEXT_ALIGN_CENTER end
    local r, g, b = color:UnpackRGB()
    tooltip:AddLine(text, "ZoFontWinH3", r, g, b, CENTER, MODIFY_TEXT_TYPE_NONE, alignment, true)
end

function LeoTrainer.CreateUI()
    local traitIcons = {}
    for traitItemIndex = 1, GetNumSmithingTraitItems() do
        local traitType, _, icon, _, _, _, _ = GetSmithingTraitItemInfo(traitItemIndex)
        if traitType and traitType ~= ITEM_TRAIT_TYPE_NONE then
            traitIcons[traitType] = icon
        end
    end

    for _,craft in pairs(LeoAltholic.craftResearch) do
        local panel = WINDOW_MANAGER:GetControlByName('LeoTrainerWindowCraft'..craft.."Panel")
        if craft == CRAFTING_TYPE_JEWELRYCRAFTING then
            panel = WINDOW_MANAGER:GetControlByName('LeoTrainerWindowCraft6PanelCraft7Panel')
        end
        for line = 1, GetNumSmithingResearchLines(craft) do
            local lineName, lineIcon, numTraits = GetSmithingResearchLineInfo(craft, line)
            local labelLine = panel:GetNamedChild('Line' .. line)
            labelLine.tooltip = lineName
            labelLine:SetText("|t30:30:"..lineIcon.."|t")
            for trait = 1, numTraits do
                local traitType = GetSmithingResearchLineTraitInfo(craft, line, trait)
                local traitName = GetString('SI_ITEMTRAITTYPE', traitType)
                local i = trait
                local posY = 14 + (trait * 28)
                if craft == CRAFTING_TYPE_BLACKSMITHING and line <= 7 then
                    i = i + 10
                elseif craft == CRAFTING_TYPE_WOODWORKING and line <= 5 then
                    i = i + 10
                end
                local labelTrait = panel:GetNamedChild('Trait' .. i)
                labelTrait:SetText(traitName .. " |t28:28:"..traitIcons[traitType].."|t")
                labelTrait.materialItemID = LeoTrainer.const.traitMaterials[traitType]

                local t = WINDOW_MANAGER:CreateControl('LeoTrainerWindowCraft'..craft..'Line'..line..'Trait'..trait..'Texture', labelLine, CT_TEXTURE)
                t:SetAnchor(CENTER, labelLine, CENTER, 0, posY)
                t:SetDimensions(25,25)

                local myself, known, unknown, all = LeoTrainer.GetCharKnowsTrait(craft, line, trait)
                local icon
                local color
                if myself == true then
                    icon = 'esoui/art/buttons/accept_up.dds'
                    if #unknown == 0 then
                        color = {0,1,0,1}
                    else
                        color = {1,1,0,1}
                        --icon = 'esoui/art/buttons/pointsplus_up.dds'
                    end
                else
                    icon = 'esoui/art/buttons/decline_up.dds'
                    if #known == 0 then
                        color = {1,0,0,1}
                    else
                        color = {1,0.7,0,1}
                    end
                end

                t:SetColor(unpack(color))
                t:SetMouseEnabled(true)
                t:SetTexture(icon)
                t:SetHandler('OnMouseEnter', function(self)
                    InitializeTooltip(InformationTooltip, self, LEFT, 5, 0)
                    addLineTitle(InformationTooltip, lineName .." - ".. traitName, ZO_TOOLTIP_DEFAULT_COLOR)
                    ZO_Tooltip_AddDivider(InformationTooltip)

                    addLineSubTitle(InformationTooltip, "Trainers", ZO_TOOLTIP_DEFAULT_COLOR, TEXT_ALIGN_LEFT)
                    if #known > 0 then
                        for _, charName in pairs(known) do
                            addLine(InformationTooltip, charName, LeoTrainer.const.colors.green)
                        end
                    else
                        addLine(InformationTooltip, "None", LeoTrainer.const.colors.red)
                    end

                    addLineSubTitle(InformationTooltip, "Trainees", ZO_TOOLTIP_DEFAULT_COLOR, TEXT_ALIGN_LEFT)
                    if #unknown > 0 then
                        for _, charName in pairs(unknown) do
                            addLine(InformationTooltip, charName, LeoTrainer.const.colors.red)
                        end
                    else
                        addLine(InformationTooltip, "None", LeoTrainer.const.colors.green)
                    end
                    if #known > 0 and #unknown > 0 then
                        text = "Queue for EACH trainee"
                        addLine(InformationTooltip, zo_iconTextFormat("esoui/art/icons/icon_lmb.dds", 26, 26, text))
                        --addLine(InformationTooltip, zo_iconTextFormat("esoui/art/icons/icon_rmb.dds", 26, 26, "Choose trainees"))
                    end
                    InformationTooltip:SetHidden(false)
                end)
                t:SetHandler('OnMouseExit', function(self)
                    ClearTooltip(InformationTooltip)
                    InformationTooltip:SetHidden(true)
                end)
                if #known > 0 and #unknown > 0 then
                    t:SetHandler('OnMouseUp', function(control, button, upInside)
                        if not upInside then return end
                        if button == MOUSE_BUTTON_INDEX_RIGHT then
                            return
                        end
                        if button == MOUSE_BUTTON_INDEX_LEFT and #unknown > 0 then
                            local matReq = LeoTrainer.const.materialRequirements[craft][line]
                            local styleId = LeoTrainer.maxStyle(line)
                            for _, charName in pairs(unknown) do
                                LeoTrainer.AddToQueue({
                                    trainer = "Anyone",
                                    trainee = charName,
                                    craft = craft,
                                    line = line,
                                    trait = trait,
                                    patternIndex = -1,
                                    materialIndex = 1,
                                    materialQuantity = matReq,
                                    itemStyleId = styleId,
                                    traitIndex = traitType,
                                    useUniversalStyleItem = false,
                                    researchName = lineName .. " " .. traitName,
                                    itemLink = LeoTrainer.const.craftItems[craft][line][trait]
                                })
                            end
                            LeoTrainer.queueScroll:RefreshData()
                        end
                    end)
                end
            end
        end
    end
    LeoTrainer.queueScroll = LeoTrainerQueueList:New(LeoTrainerWindowQueuePanelQueueScroll)
    LeoTrainer.queueScroll:RefreshData()
end

function LeoTrainer.GetQueue()
    return LeoTrainer.savedVariables.queue
end

function LeoTrainer.ClearQueue()
    LeoTrainer.savedVariables.queue = {}
    LeoTrainer.queueScroll:RefreshData()
end

function LeoTrainer.AddToQueue(data)
    table.insert(LeoTrainer.savedVariables.queue, data)
end

function LeoTrainer.RemoveFromQueue(pos)
    table.remove(LeoTrainer.savedVariables.queue, pos)
    LeoTrainer.queueScroll:RefreshData()
end