function LeoAltholicChecklistUI.normalizeSettings()
    if not LeoAltholic.globalData.checklist then LeoAltholic.globalData.checklist = {} end
    if not LeoAltholic.globalData.settings.checklist then LeoAltholic.globalData.settings.checklist = {} end
    if not LeoAltholic.charData.settings.checklist then LeoAltholic.charData.settings.checklist = {} end
end

function LeoAltholicChecklistUI.SetPosition(left, top)
    LeoAltholic.globalData.checklist.position = {
        left = left,
        top = top
    }
end
function LeoAltholicChecklistUI.GetPosition()
    return LeoAltholic.globalData.checklist.position or { left = 100; top = 200; }
end

function LeoAltholicChecklistUI.SetFontScale(value)
    LeoAltholic.globalData.settings.checklist.fontScale = value
    LeoAltholicChecklistUI.update()
end
function LeoAltholicChecklistUI.GetFontScale()
    return LeoAltholic.globalData.settings.checklist.fontScale or 100
end
function LeoAltholicChecklistUI.SetDisplayName(value)
    LeoAltholic.globalData.settings.checklist.displayName = value
    LeoAltholicChecklistUI.update()
end
function LeoAltholicChecklistUI.DisplayName()
    if LeoAltholic.globalData.settings.checklist.displayName == nil then LeoAltholic.globalData.settings.checklist.displayName = true end
    return LeoAltholic.globalData.settings.checklist.displayName
end
function LeoAltholicChecklistUI.SetHideWhenToolbar(value)
    LeoAltholic.globalData.settings.checklist.hideWhenToolbar = value
    LeoAltholicChecklistUI.update()
end
function LeoAltholicChecklistUI.IsHideWhenToolbar()
    if LeoAltholic.globalData.settings.checklist.hideWhenToolbar == nil then LeoAltholic.globalData.settings.checklist.hideWhenToolbar = false end
    return LeoAltholic.globalData.settings.checklist.hideWhenToolbar
end

function LeoAltholicChecklistUI.SetUpwards(value)
    LeoAltholic.globalData.settings.checklist.upwards = value
    LeoAltholicChecklistUI.update()
end
function LeoAltholicChecklistUI.IsUpwards()
    return LeoAltholic.globalData.settings.checklist.upwards or false
end

function LeoAltholicChecklistUI.SetEnabled(value)
    LeoAltholic.charData.settings.checklist.enabled = value
    LeoAltholicChecklistUI.RestorePosition()
end
function LeoAltholicChecklistUI.IsEnabled()
    if LeoAltholic.charData.settings.checklist.enabled == nil then LeoAltholic.charData.settings.checklist.enabled = true end
    return LeoAltholic.charData.settings.checklist.enabled
end

function LeoAltholicChecklistUI.SetCraft(craft, value)
    if not LeoAltholic.charData.settings.checklist.craft then LeoAltholic.charData.settings.checklist.craft = {} end
    LeoAltholic.charData.settings.checklist.craft[craft] = value
    LeoAltholicChecklistUI.update()
end
function LeoAltholicChecklistUI.GetCraft(craft)
    if not LeoAltholic.charData.settings.checklist.craft then LeoAltholic.charData.settings.checklist.craft = {} end
    return LeoAltholic.charData.settings.checklist.craft[craft]
end
function LeoAltholicChecklistUI.SetRiding(value)
    LeoAltholic.charData.settings.checklist.riding = value
    LeoAltholicChecklistUI.update()
end
function LeoAltholicChecklistUI.GetRiding()
    if LeoAltholic.charData.settings.checklist.riding == nil then LeoAltholic.charData.settings.checklist.riding = true end
    return LeoAltholic.charData.settings.checklist.riding
end


function LeoAltholicChecklistUI.OnWindowMoveStop()
    LeoAltholicChecklistUI.SetPosition(LeoAltholicChecklist:GetLeft(), LeoAltholicChecklist:GetTop())
end

function LeoAltholicChecklistUI.ToggleUI()
    if not LeoAltholicChecklistUI.IsEnabled() then return end
    LeoAltholicChecklist:SetHidden(not LeoAltholicChecklist:IsHidden())
end

function LeoAltholicChecklistUI.ShowUI()
    if not LeoAltholicChecklistUI.IsEnabled() then return end
    LeoAltholicChecklist:SetHidden(false)
end

function LeoAltholicChecklistUI.RestorePosition()
    local position = LeoAltholicChecklistUI.GetPosition()
    local left = position.left
    local top = position.top

    LeoAltholicChecklist:ClearAnchors()
    LeoAltholicChecklist:SetAnchor(TOPLEFT, GuiRoot, TOPLEFT, left, top)
    if LeoAltholicChecklistUI.IsEnabled() and not LeoAltholicChecklistUI.IsHideWhenToolbar() then
        if not LeoAltholicChecklistUI.checkAllDone() then
            LeoAltholicChecklist:SetHidden(false)
        end
    else
        LeoAltholicChecklist:SetHidden(true)
    end
end

local SPACE = 32
local checklist = WINDOW_MANAGER:GetControlByName("LeoAltholicChecklist")
local panel = GetControl(checklist, "Panel")
local height = 0
local lastChecklist = GetTimeStamp()

local function createItem(label, labelText, texture, craftIcon, canShow)
    if canShow == true then
        texture:SetTexture("esoui/art/buttons/decline_up.dds")
        texture:SetColor(1,0,0,1)
        texture:SetDimensions(32, 32)
        texture:SetAnchor(TOPLEFT, panel, TOPLEFT, 10, height)
        texture.tooltip = "Quest not started"

        height = height + SPACE
        if LeoAltholicChecklistUI.DisplayName() then
            label:SetText(labelText)
            label:SetHidden(false)
            craftIcon:SetHidden(true)
        else
            craftIcon:SetHidden(false)
            label:SetHidden(true)
        end
        texture:SetHidden(false)
    else
        label:SetHidden(true)
        texture:SetHidden(true)
        craftIcon:SetHidden(true)
    end
end

function LeoAltholicChecklistUI.checkReset()
    if LeoAltholic.IsBeforeReset(lastChecklist) then
        LeoAltholicChecklistUI.update()
        lastChecklist = GetTimeStamp()
    end
end

local function doneItem(label, texture)
    texture:SetTexture("esoui/art/loot/loot_finesseItem.dds")
    texture:SetColor(0,1,0,1)
    texture.tooltip = GetString(SI_ACHIEVEMENTS_TOOLTIP_COMPLETE)
end

local function startItem(label, texture)
    texture:SetTexture("esoui/art/buttons/pointsminus_up.dds")
    texture:SetColor(1,1,1,1)
    texture.tooltip = "Quest Started"
end

local function updateItem(label, texture)
    texture:SetTexture("esoui/art/buttons/pointsplus_up.dds")
    texture:SetColor(1,0.9,0,1)
    texture.tooltip = "Quest Updated"
end

local function preDeliverItem(label, texture)
    texture:SetTexture("esoui/art/loot/loot_finesseItem.dds")
    texture:SetColor(1,1,0,1)
    texture.tooltip = "Ready for deliver"
end

local function stoppedItem(label, texture)
    texture:SetTexture("esoui/art/buttons/decline_up.dds")
    texture:SetColor(1,0,0,1)
    texture.tooltip = "Quest Deleted"
end

function LeoAltholicChecklistUI.checkAllDone()
    local char = LeoAltholic.GetMyself()

    for _, craft in pairs(LeoAltholic.allCrafts) do
        if LeoAltholicChecklistUI.GetCraft(craft) then
            for _, writ in pairs(char.quests.writs) do
                if craft == writ.craft then
                    if writ.lastDone == nil or not LeoAltholic.IsAfterReset(writ.lastDone) then return false end
                end
            end
        end
    end
    if LeoAltholicChecklistUI.GetRiding() and char.attributes.riding.time - GetTimeStamp() < 0 then
        return false
    end
    LeoAltholicChecklist:SetHidden(true)
    return true
end

function LeoAltholicChecklistUI.doneWrit(craft)
    if not LeoAltholicChecklistUI.IsEnabled() then return end

    local label = GetControl(panel, "Craft"..craft)
    local texture = GetControl(panel, "Craft"..craft.."Status")
    doneItem(label, texture)
    LeoAltholicChecklistUI.checkAllDone()
end

function LeoAltholicChecklistUI.startedWrit(craft)
    if not LeoAltholicChecklistUI.IsEnabled() then return end

    local label = GetControl(panel, "Craft"..craft)
    local texture = GetControl(panel, "Craft"..craft.."Status")
    startItem(label, texture)
end

function LeoAltholicChecklistUI.updateWrit(craft)
    if not LeoAltholicChecklistUI.IsEnabled() then return end

    local label = GetControl(panel, "Craft"..craft)
    local texture = GetControl(panel, "Craft"..craft.."Status")
    updateItem(label, texture)
end

function LeoAltholicChecklistUI.preDeliverWrit(craft)
    if not LeoAltholicChecklistUI.IsEnabled() then return end

    local label = GetControl(panel, "Craft"..craft)
    local texture = GetControl(panel, "Craft"..craft.."Status")
    preDeliverItem(label, texture)
end

function LeoAltholicChecklistUI.stoppedWrit(craft)
    if not LeoAltholicChecklistUI.IsEnabled() then return end

    local label = GetControl(panel, "Craft"..craft)
    local texture = GetControl(panel, "Craft"..craft.."Status")
    stoppedItem(label, texture)
end

function LeoAltholicChecklistUI.doneRiding()
    if not LeoAltholicChecklistUI.IsEnabled() then return end

    local label = GetControl(panel, "Riding")
    local texture = GetControl(panel, "RidingStatus")
    doneItem(label, texture)
end

function LeoAltholicChecklistUI.updateQuests()
    for i,trackedQuest in pairs(LeoAltholic.globalData.CharList[LeoAltholic.CharName].quests.writs) do
        for questIndex = 1, MAX_JOURNAL_QUESTS do
            if IsValidQuestIndex(questIndex) and GetJournalQuestName(questIndex) == trackedQuest.name then
                LeoAltholic.globalData.CharList[LeoAltholic.CharName].quests.writs[i].questIndex = questIndex
                local numConditions = GetJournalQuestNumConditions(questIndex, QUEST_MAIN_STEP_INDEX)
                for condition = 1, numConditions do
                    local condText = GetJournalQuestConditionInfo(questIndex, QUEST_MAIN_STEP_INDEX, condition)
                    if string.find(condText, GetString(LEOALT_DELIVER)) then
                        LeoAltholic.globalData.CharList[LeoAltholic.CharName].quests.writs[i].lastPreDeliver = GetTimeStamp()
                        LeoAltholicChecklistUI.preDeliverWrit(trackedQuest.craft)
                    end
                end
                break
            end
        end
    end
end

function LeoAltholicChecklistUI.update()

    if not LeoAltholicChecklistUI.IsEnabled() then return end

    local char = LeoAltholic.GetMyself()

    local texture, label, craftIcon

    height = 0

    local scale = LeoAltholicChecklistUI.GetFontScale() / 100

    for _, craft in pairs(LeoAltholic.allCrafts) do
        label = GetControl(panel, "Craft"..craft)
        label:SetScale(scale)
        craftIcon = GetControl(panel, "Craft"..craft.."Icon")
        craftIcon:SetScale(scale)
        texture = GetControl(panel, "Craft"..craft.."Status")
        texture:SetScale(scale)

        local isDone = false
        local isPreDeliver = false
        local isUpdated = false
        local isStarted = false
        for _, writ in pairs(char.quests.writs) do
            if craft == writ.craft then
                if writ.lastDone ~= nil and LeoAltholic.IsAfterReset(writ.lastDone) then
                    isDone = true
                elseif writ.lastPreDeliver ~= nil and LeoAltholic.IsAfterReset(writ.lastPreDeliver) then
                    isPreDeliver = true
                elseif writ.lastUpdated ~= nil and LeoAltholic.IsAfterReset(writ.lastUpdated) then
                    isUpdated = true
                elseif writ.lastStarted ~= nil and LeoAltholic.IsAfterReset(writ.lastStarted) then
                    isStarted = true
                end
            end
        end

        local canShow = LeoAltholicChecklistUI.GetCraft(craft)

        createItem(label, GetCraftingSkillName(craft), texture, craftIcon, canShow)
        if canShow then
            if isDone then
                doneItem(label, texture)
                LeoAltholicChecklistUI.checkAllDone()
            elseif isPreDeliver then
                preDeliverItem(label, texture)
            elseif isUpdated then
                updateItem(label, texture)
            elseif isStarted then
                startItem(label, texture)
            end
        end
    end

    label = GetControl(panel, "Riding")
    label:SetScale(scale)
    label:SetColor(1,1,1,1)
    texture = GetControl(panel, "RidingStatus")
    texture:SetScale(scale)
    craftIcon = GetControl(panel, "RidingIcon")
    craftIcon:SetScale(scale)
    createItem(label, GetString(SI_STAT_GAMEPAD_RIDING_HEADER_TRAINING), texture, craftIcon, LeoAltholicChecklistUI.GetRiding())
    if char.attributes.riding.time - GetTimeStamp() > 0 then
        doneItem(label, texture)
        LeoAltholicChecklistUI.checkAllDone()
    end

    checklist:SetHeight(60 + height)
    panel:SetHeight(10 + height)
    panel:ClearAnchors()
    local header = GetControl(checklist, "BGHeader")
    header:ClearAnchors()
    if LeoAltholicChecklistUI.IsUpwards() then
        header:SetAnchor(BOTTOMLEFT, checklist, BOTTOMLEFT, 0, 0)
        panel:SetAnchor(BOTTOMLEFT, header, TOPLEFT, 0, 2)
    else
        header:SetAnchor(TOPLEFT, checklist, TOPLEFT, 0, 0)
        panel:SetAnchor(TOPLEFT, checklist, TOPLEFT, 0, 40)
    end

    local width = 200
    if not LeoAltholicChecklistUI.DisplayName() then
        width = 120
    end
    checklist:SetWidth(width)
    panel:SetWidth(width)
    header:SetWidth(width)
end