-- Copyright © 2024 @Groick (Twitch). All rights reserved.
local function L(key, ...) return EasyOptions:Localize(key, ...) end
function EasyOptions:CreateLabel(parent, labelAnchorControl, controlTypeName, customControlName, text, tooltipTitleText, tooltipText, fontObjectName, positionInfo, customSize, wordWrap, customFontInfo, customTextColor, includeUnderline, customUnderlineWidth, frameTemplate)
  local controlName = EasyOptions:GetControlName(controlTypeName, customControlName)
  local control = CreateFrame("Frame", controlName, parent, frameTemplate)
  control.Name = controlName
  control.Type = controlTypeName
  control.BaseType = "Label"
  EasyOptions:SetTooltip(control, control, tooltipTitleText, tooltipText)
  -- control:EnableMouse(true)
  
  local label = control:CreateFontString(controlName..".Label", "ARTWORK", fontObjectName)
  label:SetJustifyH("LEFT") -- "LEFT", "RIGHT", "CENTER"
  label:SetJustifyV("MIDDLE") -- "TOP", "BOTTOM", "MIDDLE"
  label:SetText(text)
  label:SetWordWrap(EasyOptions:IIF(wordWrap ~= nil, wordWrap, true)) -- We use true by default because the \n (i.e., new line) control character is ignored if WordWrap is false.
  EasyOptions:SetFontFromCustomFontInfo(label, customFontInfo, customTextColor) -- IMPORTANT: We must call EasyOptions:SetFontFromCustomFontInfo before we determine the size of the string that is shown in the label.
  -- label:SetNonSpaceWrap(false)
  -- label:SetShadowOffset(1, -1)
  control.Label = label
  label.LabelControl = control
  label.Owner = control
  -- EasyOptions:AddControlToOwner(label, control)
  
  local positionInfo_Label = {"TOPLEFT", "TOPLEFT", EasyOptions:GetLabelOffsetX(), EasyOptions:GetLabelOffsetY()}
  local ignoreCustomHeight = false
  local defaultWidth = 1
  local defaultHeight = 1
  local allowFillWidthFlag = false
  local width, height, hasWidth, hasHeight, shouldFillWidth = EasyOptions:GetSizeFromCustomSize(customSize, ignoreCustomHeight, defaultWidth, defaultHeight, EasyOptions.Fields.ControlSizeMaxAllowed_Large, EasyOptions.Fields.ControlSizeMaxAllowed_Large, allowFillWidthFlag, false)
  label:SetPoint(positionInfo_Label[1], control, positionInfo_Label[2], positionInfo_Label[3], positionInfo_Label[4])
  if (hasWidth) then
    control.Label:SetWidth(width)
  end
  if (hasHeight) then
    control.Label:SetHeight(height)
  end
  if (shouldFillWidth) then
    EasyOptions:SetControlPointToFillWidth(label, control, positionInfo_Label, 0, 0)
  end

  local stringWidth = EasyOptions:GetLabelStringWidth(label, true)
  local stringHeight, stringHeightFromAPI, stringHeightScaleFactor, stringHeightOffset = EasyOptions:GetLabelStringHeight(label)
  local sizeMinAllowed = EasyOptions:IIF((includeUnderline) and (customUnderlineWidth ~= nil) and ((EasyOptions:IsFillWidthFlag(customUnderlineWidth, true)) or (customUnderlineWidth > 0)), 1, 0) -- IMPORTANT: We must not allow the label's size to be 0 if we want to show an underline because the underline will not be shown if the control's size is 0.
  defaultWidth = math.max(stringWidth, sizeMinAllowed)
  defaultHeight = math.max(stringHeight, sizeMinAllowed)
  width, height, hasWidth, hasHeight, shouldFillWidth = EasyOptions:GetSizeFromCustomSize(customSize, ignoreCustomHeight, defaultWidth, defaultHeight, EasyOptions.Fields.ControlSizeMaxAllowed_Large, EasyOptions.Fields.ControlSizeMaxAllowed_Large, allowFillWidthFlag, false)
  control:SetSize(width, height) -- Set the size of the frame to fit the text. Note that this is only to assist with determining the bounds of the label's text since the frame is not visible.
  local controlRegionWidth = width
  local controlRegionHeight = height

  if (includeUnderline) then
    local underlineTexture = control:CreateTexture(controlName..".Underline", "ARTWORK")
    underlineTexture:SetTexture("Interface\\AddOns\\EasyOptions\\Textures\\LineThin1.tga")
    --
    local defaultWidth = EasyOptions:IIF(width > 0, width - 2, 0)
    local defaultHeight = 1.0
    local ignoreCustomHeight_Underline = true
    local underlineWidth, underlineHeight, underlineHasWidth, underlineHasHeight, underlineShouldFillWidth = EasyOptions:GetSizeFromCustomSize(customUnderlineWidth, ignoreCustomHeight_Underline, defaultWidth, defaultHeight, EasyOptions.Fields.ControlSizeMaxAllowed_Large, EasyOptions.Fields.ControlSizeMaxAllowed_Large, true, false)
    --
    local yOffset_Underline = 2 + math.max(1.0 * ((stringHeightFromAPI / EasyOptions:GetLabelStringHeightBase()) - 1.0), 0.0) -- * (stringHeightFromAPI / EasyOptions:GetLabelStringHeightBase()) -- - (1.0 - stringHeightScaleFactor) * (stringHeightFromAPI - EasyOptions:GetLabelStringHeightBase())
    underlineTexture:SetSize(underlineWidth, underlineHeight)
    underlineTexture:ClearAllPoints()
    underlineTexture:SetPoint("TOPLEFT", label, "BOTTOMLEFT", 0, -yOffset_Underline)
    if (not underlineShouldFillWidth) then
      underlineTexture:SetPoint("TOPRIGHT", label, "BOTTOMLEFT", underlineWidth, -yOffset_Underline)
    else
      EasyOptions:SetControlPointToFillWidth(underlineTexture, parent, positionInfo, 0, 5)
    end
    control.UnderlineTexture = underlineTexture
    --
    controlRegionWidth = math.max(underlineWidth, controlRegionWidth)
    controlRegionHeight = controlRegionHeight + yOffset_Underline -- + 3 * (stringHeightFromAPI / EasyOptions:GetLabelStringHeightBase())
  end

  local offsetX = 4 -- Offset the x-position of this control type to help it align better with the other controls.
  local offsetY = 0 -- Offset the y-position of this control type to help it align better with the other controls.
  control:ClearAllPoints()
  control:SetPoint(positionInfo[1], labelAnchorControl, positionInfo[2], positionInfo[3] + offsetX, positionInfo[4] - offsetY)
  if (shouldFillWidth) then
    EasyOptions:SetControlPointToFillWidth(control, parent, positionInfo, offsetX, 2)
  end
  
  -- control:SetScript("OnClick", onClickHandler)
  control.OnEnabledChangedHandler = function(self)
    local control = self
    control:EnableMouse(control:IsEnabled())
  end
  EasyOptions:AddSupportForEnabledState(control)
  control:EnableMouse(control:IsEnabled())
  
  control.ControlRegionWidth = controlRegionWidth
  control.ControlRegionHeight = controlRegionHeight
  return control, controlRegionWidth, controlRegionHeight
end
function EasyOptions:CreateOptionGroupTitle(parent, positionInfo, optionItem)
  local labelAnchorControl = parent
  local controlTypeName = "GroupTitle"
  local text = EasyOptions:GetControlText(optionItem)
  local tooltipTitleText = optionItem.TooltipTitleText or text
  local tooltipText = optionItem.TooltipText
  local fontObjectName = EasyOptions.Fields.DefaultGroupLabelFontObjectName
  local customSize = optionItem.Size
  local wordWrap = optionItem.WordWrap
  local customFontInfo = optionItem.FontInfo
  local customTextColor = optionItem.TextColor
  local includeUnderline = EasyOptions:IIF(optionItem.IncludeUnderline ~= nil, optionItem.IncludeUnderline, true) -- Include the underline by default.
  local customUnderlineWidth = optionItem.UnderlineWidth
  local frameTemplate = nil
  local control, controlRegionWidth, controlRegionHeight = EasyOptions:CreateLabel(parent, labelAnchorControl, controlTypeName, nil, text, tooltipTitleText, tooltipText, fontObjectName, positionInfo, customSize, wordWrap, customFontInfo, customTextColor, includeUnderline, customUnderlineWidth, frameTemplate)
  
  optionItem.Control = control
  control.OptionItem = optionItem
  
  return control, controlRegionWidth, controlRegionHeight
end
function EasyOptions:CreateOptionLabel(parent, positionInfo, optionItem)
  local labelAnchorControl = parent
  local controlTypeName = "Label"
  local text = EasyOptions:GetControlText(optionItem)
  local tooltipTitleText = optionItem.TooltipTitleText or text
  local tooltipText = optionItem.TooltipText
  local fontObjectName = EasyOptions.Fields.DefaultLabelFontObjectName
  local customSize = optionItem.Size
  local wordWrap = optionItem.WordWrap
  local customFontInfo = optionItem.FontInfo
  local customTextColor = optionItem.TextColor
  local includeUnderline = EasyOptions:IIF(optionItem.IncludeUnderline ~= nil, optionItem.IncludeUnderline, false) -- Don't include the underline by default.
  local customUnderlineWidth = optionItem.UnderlineWidth
  local frameTemplate = nil
  local control, controlRegionWidth, controlRegionHeight = EasyOptions:CreateLabel(parent, labelAnchorControl, controlTypeName, nil, text, tooltipTitleText, tooltipText, fontObjectName, positionInfo, customSize, wordWrap, customFontInfo, customTextColor, includeUnderline, customUnderlineWidth, frameTemplate)
  
  optionItem.Control = control
  control.OptionItem = optionItem
  
  return control, controlRegionWidth, controlRegionHeight
end
function EasyOptions:CreateOptionSeparator(parent, positionInfo, optionItem)
  local labelAnchorControl = parent
  local controlTypeName = "Separator"
  local text = ""
  local tooltipTitleText = optionItem.TooltipTitleText or text
  local tooltipText = optionItem.TooltipText
  local fontObjectName = EasyOptions.Fields.DefaultLabelFontObjectName
  local customSize = nil
  local wordWrap = nil
  local customFontInfo = nil
  local customTextColor = nil
  local includeUnderline = true
  local defaultWidth = EasyOptions.Fields.FillWidthFlag -- (0.5 * EasyOptions.Fields.DefaultWidthMaxAvailable_NoScrollBars) - EasyOptions:GetDefaultControlPaddingX() -- Allow room for two adjacent controls including the default gap between the two controls.
  local customUnderlineWidth = EasyOptions:IIF(optionItem.Width ~= nil, optionItem.Width, defaultWidth)
  local frameTemplate = nil
  local control, controlRegionWidth, controlRegionHeight = EasyOptions:CreateLabel(parent, labelAnchorControl, controlTypeName, nil, text, tooltipTitleText, tooltipText, fontObjectName, positionInfo, customSize, wordWrap, customFontInfo, customTextColor, includeUnderline, customUnderlineWidth, frameTemplate)
  
  optionItem.Control = control
  control.OptionItem = optionItem
  
  return control, controlRegionWidth, controlRegionHeight
end
function EasyOptions:CreateLabelForControl(parent, ownerControl, labelAnchorControl, controlName, text, tooltipTitleText, tooltipText, positionInfo, fontObjectName, customFontInfo, customTextColor)
  local controlTypeName = "Label"
  local customControlName = EasyOptions:IIF(controlName ~= nil, controlName.."."..controlTypeName, nil)
  local customSize = nil
  local wordWrap = nil
  local includeUnderline = false
  local customUnderlineWidth = nil
  local frameTemplate = nil
  local labelControl, controlRegionWidth, controlRegionHeight = EasyOptions:CreateLabel(parent, labelAnchorControl, controlTypeName, customControlName, text, tooltipTitleText, tooltipText, fontObjectName, positionInfo, customSize, wordWrap, customFontInfo, customTextColor, includeUnderline, customUnderlineWidth, frameTemplate)
  
  if (ownerControl ~= nil) then
    if (ownerControl.LabelControl ~= nil) then
      EasyOptions:PrintErrorMessage(L("The LabelControl property for the control \"{1}\" is being changed from \"{2}\" to \"{3}\".", EasyOptions:FormatName(ownerControl.Name), EasyOptions:FormatName(ownerControl.LabelControl.Name), EasyOptions:FormatName(labelControl.Name)))
    elseif (ownerControl.Label ~= nil) then
      EasyOptions:PrintErrorMessage(L("The Label property for the control \"{1}\" is being changed.", EasyOptions:FormatName(ownerControl.Name)))
    end
    ownerControl.Label = labelControl.Label
    ownerControl.LabelControl = labelControl
    EasyOptions:AddControlToOwner(labelControl, ownerControl)
    -- labelControl.OptionItem = ownerControl.OptionItem
    -- labelControl.Label.OptionItem = ownerControl.OptionItem
  end
  
  return labelControl, labelControl.Label, controlRegionWidth, controlRegionHeight
end
function EasyOptions:GetLabelOffsetX()
  return 0
end
function EasyOptions:GetLabelOffsetY()
  return -3
end
function EasyOptions:GetLabelStringWidth(label, useUnboundedWidth) -- stringWidth, stringWidthFromAPI, scaleFactor, offset
  if (label == nil) then
    return 0, 0, 1.0, 0
  end

  local text = label:GetText()
  if (text == nil) or (text == "") then
    return 0, 0, 1.0, 0
  end

  local scaleFactor = 1.02
  local offset = 2
  local stringWidthFromAPI
  if (not useUnboundedWidth) then
    stringWidthFromAPI = label:GetStringWidth()
  else
    stringWidthFromAPI = label:GetUnboundedStringWidth()
  end
  -- stringWidthFromAPI = math.floor(stringWidthFromAPI + 0.5) -- Use math.floor to round to the nearest integer.
  local stringWidth = scaleFactor * stringWidthFromAPI + offset -- Modify the result so it is consistent with the visual appearance of the string. IMPORTANT: This is required by some controls in order to prevent text from wrapping.
  -- stringWidth = math.ceil(stringWidth) -- math.ceiling
  return stringWidth, stringWidthFromAPI, scaleFactor, offset
end
function EasyOptions:GetLabelStringHeight(label) -- stringHeight, stringHeightFromAPI, scaleFactor, offset
  if (label == nil) then
    return 0, 0, 1.0, 0
  end

  local text = label:GetText()
  if (text == nil) or (text == "") then
    return 0, 0, 1.0, 0
  end

  local scaleFactor = 1.0 -- 0.98
  local offset = 0
  local stringHeightFromAPI = label:GetStringHeight() -- math.floor(label:GetStringHeight() + 0.5) -- Use math.floor to round to the nearest integer because the returned value from the WoW API can have rounding errors.
  -- stringHeightFromAPI = math.floor(stringHeightFromAPI + 0.5) -- Use math.floor to round to the nearest integer.
  local stringHeight = scaleFactor * stringHeightFromAPI + offset -- Modify the result so it is consistent with the visual appearance of the string.
  -- stringHeight = math.ceil(stringHeight) -- math.ceiling
  return stringHeight, stringHeightFromAPI, scaleFactor, offset
end
function EasyOptions:GetLabelStringHeightBase()
  -- Returns the result of label:GetStringHeight() when the label is using the default font.
  return 12.088889
end
