--[[
Author: Jarth
Filename: CBs_Settings_List.lua
]] --
-------------------------------------------------------------------------------------------------
-- FUNCTIONS --
-------------------------------------------------------------------------------------------------
CBs_Settings_List = ZO_SortFilterList:Subclass()

function CBs_Settings_List:New(...)
    self.list = ZO_SortFilterList.New(self, ...)
    self.masterListType = "Selection"
    return self.list
end

function CBs_Settings_List:Initialize(base, _type, ...)
    ZO_SortFilterList.Initialize(self, ...)
    self.base = base
    self._type = _type
    self.masterList = {}
    if not (self._type and self._type.Enabled) then
        self.masterListType = "CollectionTypes"
    end

    self:SetAlternateRowBackgrounds(false)
    self:AppendDataTypes()
end

-------------------------------------------------------------------------------------------------
-- FUNCTIONS - Append DataTypes --
-------------------------------------------------------------------------------------------------

function CBs_Settings_List:AppendDataTypes()
    local dataTypes = {
        [10] = {
            name = "CBs_Settings_ListRow_Checkbox",
            height = 40,
            func = function(...)
                self:SetupRow_Checkbox(...)
            end
        },
        [15] = {
            name = "CBs_Settings_ListRow_Checkbox_CogButton",
            height = 40,
            func = function(...)
                self:SetupRow_Checkbox_CogButton(...)
            end
        },
        [20] = {
            name = "CBs_Settings_ListRow_Dropdown",
            height = 40,
            func = function(...)
                self:SetupRow_Dropdown(...)
            end
        },
        [30] = {
            name = "CBs_Settings_ListRow_Slider",
            height = 40,
            func = function(...)
                self:SetupRow_Slider(...)
            end
        },
        [40] = {
            name = "CBs_Settings_ListRow_EditBox",
            height = 40,
            func = function(...)
                self:SetupRow_EditBox(...)
            end
        },
        [50] = {
            name = "CBs_Settings_ListRow_Title",
            height = 40,
            func = function(...)
                self:SetupRow_Title(...)
            end
        },
        [60] = {
            name = "CBs_Settings_ListRow_Button",
            height = 40,
            func = function(...)
                self:SetupRow_Button(...)
            end
        },
        [100] = {
            name = "CBs_Settings_ListRow_Divider",
            height = 6,
            func = function(...)
                ZO_SortFilterList.SetupRow(self, ...)
            end
        }
    }

    for index, dataType in pairs(dataTypes) do
        ZO_ScrollList_AddDataType(self.list, index, dataType.name, dataType.height, dataType.func)
    end
end

-------------------------------------------------------------------------------------------------
-- FUNCTIONS - Append and Setup RowTypes --
-------------------------------------------------------------------------------------------------

function CBs_Settings_List:AppendRow_Checkbox(typeSelection, data)
    data.type = typeSelection
    data.dataTypeId = 10
    table.insert(self.masterList, data)
end

function CBs_Settings_List:SetupRow_Checkbox(control, data)
    control.data = data
    ZO_SortFilterList.SetupRow(self, control, data)

    control.checkbox = GetControl(control, "Checkbox")
    if control.checkbox then
        control.checkbox.tooltipText = data.tooltipText
        ZO_CheckButton_SetCheckState(control.checkbox, control.data.funcGet and control.data.funcGet())
        ZO_CheckButton_SetLabelText(control.checkbox, data.name)
        if control.checkbox.label then
            control.checkbox.label.defaultNormalColor = ZO_DEFAULT_ENABLED_COLOR
            control.checkbox.label:ClearAnchors()
            control.checkbox.label:SetAnchor(TOPLEFT, control.checkbox, TOPLEFT, -425)
            control.checkbox.label:SetAnchor(BOTTOMRIGHT, control.checkbox, BOTTOMLEFT)
        end
        ZO_CheckButton_SetTooltipAnchor(control.checkbox, TOP, control.checkbox.label)
        ZO_CheckButton_SetToggleFunction(control.checkbox, control.data.funcSet)
        ZO_CheckButton_SetEnableState(control.checkbox, not (control.data.disabledFunc and control.data.disabledFunc()))
    end
end

function CBs_Settings_List:AppendRow_Checkbox_CogButton(typeSelection, data)
    data.type = typeSelection
    data.dataTypeId = 15
    table.insert(self.masterList, data)
end

function CBs_Settings_List:SetupRow_Checkbox_CogButton(control, data)
    self:SetupRow_Checkbox(control, data)
    control.cogButton = GetControl(control, "CogButton")
    if control.cogButton then
        control.cogButton:SetHidden(false)
        local isEnabled = control.data.funcGet and control.data.funcGet()
        ZO_CheckButton_SetEnableState(control.cogButton, isEnabled)
        control.cogButton:SetAlpha(isEnabled and 1 or 0.5)
        control.cogButton:SetHandler("OnClicked", function()
            PlaySound(SOUNDS.SINGLE_SETTING_RESET_TO_DEFAULT)
            control.data.funcCog(control.slider, data.default)
        end)
    end
end

function CBs_Settings_List:AppendRow_Dropdown(typeSelection, data)
    data.type = typeSelection
    data.dataTypeId = 20
    table.insert(self.masterList, data)
end

function CBs_Settings_List:SetupRow_Dropdown(control, data)
    control.data = data
    ZO_SortFilterList.SetupRow(self, control, data)

    control.dropdown = GetControl(control, "Dropdown")
    control.comboBox = ZO_ComboBox_ObjectFromContainer(control.dropdown)
    control.comboBox:SetSortsItems(false)
    control.comboBox:SetFont("ZoFontWinT1")
    control.comboBox:SetSpacing(4)
    control.comboBox.tooltipText = data.tooltipText

    self.SetNameText(control, control.data.name)
    self.RepopulateDropdownOptions(control)
    self.SetActiveOrInactive(control)
end

function CBs_Settings_List:AppendRow_Slider(typeSelection, data)
    data.type = typeSelection
    data.dataTypeId = 30
    table.insert(self.masterList, data)
end

function CBs_Settings_List:SetupRow_Slider(control, data)
    control.data = data
    ZO_SortFilterList.SetupRow(self, control, control.data)

    control.slider = GetControl(control, "Slider")
    -- Need to override the existing value changed handler first so it doesn't run when we do the SetMinMax
    control.slider:SetHandler("OnValueChanged", nil)
    control.slider:SetMinMax(control.data.minValue, control.data.maxValue)
    control.slider:SetValueStep(control.data.valueStep or 1)
    control.slider:SetValue(data.funcGet())
    control.slider:SetHandler("OnValueChanged", control.data.funcSet)

    if data.default then
        if control.defaultMarkerControl == nil then
            control.defaultMarkerControl = CreateControlFromVirtual("$(parent)DefaultMarker", control.slider, "ZO_Options_DefaultMarker")
        end
        local offsetX = zo_clampedPercentBetween(data.minValue, data.maxValue, data.default) * control.slider:GetWidth()
        control.defaultMarkerControl:SetAnchor(TOP, control.slider, LEFT, offsetX + .25, 6)

        control.defaultMarkerControl:SetHandler("OnClicked", function()
            PlaySound(SOUNDS.SINGLE_SETTING_RESET_TO_DEFAULT)
            control.slider:SetValue(data.default)
            control.data.funcSet(control.slider, data.default)
        end)
    end

    local valueLabelControl = GetControl(control, "ValueLabel")
    if valueLabelControl and data.showValue then
        local shownVal = data.funcGet()
        if data.valueMin and data.valueMax and data.valueMax > data.valueMin then
            local range = data.maxValue - data.minValue
            local percentage = (shownVal - data.minValue) / range

            local shownRange = data.valueMax - data.valueMin
            shownVal = data.valueMin + percentage * shownRange
            shownVal = string.format("%d", shownVal)
        end
        valueLabelControl:SetText(shownVal)
    end

    self.SetNameText(control, control.data.name)
    self.SetActiveOrInactive(control)
end

function CBs_Settings_List:AppendRow_EditBox(typeSelection, data)
    data.type = typeSelection
    data.dataTypeId = 40
    table.insert(self.masterList, data)
end

function CBs_Settings_List:SetupRow_EditBox(control, data)
    control.data = data
    ZO_SortFilterList.SetupRow(self, control, control.data)

    control.editBox = GetControl(control, "EditBox")
    if control.editBox then
        ZO_EditDefaultText_Initialize(control.editBox)
        control.editBox:SetHandler("OnTextChanged", nil)
        control.editBox:SetText(data.funcGet())
        control.editBox:SetHandler("OnTextChanged", function()
            data.funcSet(control.editBox)
        end)
    end

    self.SetNameText(control, control.data.name)
    self.SetActiveOrInactive(control)
end

function CBs_Settings_List:AppendRow_Title(typeSelection, data)
    data.type = typeSelection
    data.dataTypeId = 50
    table.insert(self.masterList, data)
end

function CBs_Settings_List:SetupRow_Title(control, data)
    control.data = data
    ZO_SortFilterList.SetupRow(self, control, control.data)

    self.SetNameText(control, control.data.name)
    self.SetActiveOrInactive(control)
end

function CBs_Settings_List:AppendRow_Button(typeSelection, data)
    data.type = typeSelection
    data.dataTypeId = 60
    table.insert(self.masterList, data)
end

function CBs_Settings_List:SetupRow_Button(control, data)
    control.data = data
    ZO_SortFilterList.SetupRow(self, control, control.data)

    control.button = GetControl(control, "Button")
    if control.button then
        control.button:SetText(control.data.buttonName or "")
        control.button:SetHandler("OnClicked", function()
            control.data.funcSet()
        end)
    end

    self.SetNameText(control, control.data.name)
    self.SetActiveOrInactive(control)
end

function CBs_Settings_List:AppendRow_Divider(typeSelection, data)
    data.type = typeSelection
    data.dataTypeId = 100
    table.insert(self.masterList, data)
end

-------------------------------------------------------------------------------------------------
-- FUNCTIONS - SetupRowType - Helpers --
-------------------------------------------------------------------------------------------------
function CBs_Settings_List.RepopulateDropdownOptions(control)
    control.comboBox:ClearItems()

    local selectedValue = control.data.funcGet()
    local selectedEntry = nil
    for _, optionValue in pairs(control.data.choices or {}) do
        local entry = ZO_ComboBox:CreateItemEntry(optionValue, control.data.funcSet)
        control.comboBox:AddItem(entry)

        if optionValue == selectedValue then
            selectedEntry = entry
        end
    end
    control.comboBox:SelectItem(selectedEntry)
end

function CBs_Settings_List.SetNameText(control, text)
    local controlLabel = GetControl(control, "Name")
    if controlLabel then
        controlLabel:SetText(text or "")
    end
end

function CBs_Settings_List.SetActiveOrInactive(control)
    local disabled = control.data.disabledFunc and control.data.disabledFunc()

    local nameControl = GetControl(control, "Name")
    if nameControl then
        if disabled then
            nameControl:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
        else
            nameControl:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
        end
    end

    local valueLabelControl = GetControl(control, "ValueLabel")
    if valueLabelControl then
        if disabled then
            valueLabelControl:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA())
        else
            valueLabelControl:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA())
        end
    end

    if control.button then
        control.button:SetEnabled(not disabled)
    end

    if control.comboBox then
        control.comboBox:SetEnabled(not disabled)
    end

    if control.slider then
        control.slider:SetEnabled(not disabled)
    end

    if control.editBox then
        ZO_DefaultEdit_SetEnabled(control.editBox, not disabled)
    end
end

-------------------------------------------------------------------------------------------------
-- FUNCTIONS - MasterList --
-------------------------------------------------------------------------------------------------
function CBs_Settings_List:BuildMasterList()
    self.masterList = {}

    self.base.AppendMasterListTypeGeneral(self, "General")
    self.base.AppendMasterListTypeCollectionTypes(self, "CollectionTypes")
    self.base.AppendMasterListTypeCombined(self, "Combined")
    if self._type then
        self.base.AppendMasterListTypeSelection(self, "Selection")
        self.base.AppendMasterListTypeCollection(self, "Collection")
    else
        self.base.AppendMasterListTypeNoCollectionType(self, "Selection")
        self.base.AppendMasterListTypeNoCollectionType(self, "Collection")
    end
end

function CBs_Settings_List:FilterScrollList()
    local scrollData = ZO_ScrollList_GetDataList(self.list)
    ZO_ClearNumericallyIndexedTable(scrollData)

    for i = 1, #self.masterList do
        if self.masterListType == nil or self.masterListType == self.masterList[i].type then
            scrollData[#scrollData + 1] = ZO_ScrollList_CreateDataEntry(self.masterList[i].dataTypeId, self.masterList[i])
        end
    end
end

function CBs_Settings_List:SortScrollList()
end