-- Copyright © 2024 @Groick (Twitch). All rights reserved.
local function L(key, ...) return EasyOptions:Localize(key, ...) end
function EasyOptions:CreateGroupBoxBase(typeName, baseTypeName, parent, customControlName, text, tooltipTitleText, tooltipText, positionInfo, customSize, defaultSize, showBackgroundAndBorder, allowFillWidthByDefault, fontObjectName, customFontInfo, customTextColor)
  -- Create the control and set properties.
  local controlNameDefault = typeName
  local controlName = EasyOptions:GetControlName(controlNameDefault, customControlName)

  local addHideGameTooltipScripts = true
  local control = EasyOptions:CreateContainerFrame(controlName, parent, showBackgroundAndBorder, showBackgroundAndBorder, addHideGameTooltipScripts)

  control.Name = controlName
  control.Type = typeName
  control.BaseType = baseTypeName
  -- control:SetMotionScriptsWhileDisabled(true)
  -- control:EnableMouse(true)
  --
  if (text == nil) or (text == "") then -- NOTE: We only assign the tooltip to the GroupBox if the GroupBox does not have a label. Otherwise, we assume that it is preferable to only show the tooltip for the GroupBox when cursor is over the GroupBox's label.
    EasyOptions:SetTooltip(control, control, tooltipTitleText, tooltipText)
  end
  
  -- Create the label for the control.
  local labelOffsetX = 0
  local labelOffsetY = 4
  local labelPositionInfo = {"BOTTOMLEFT", "TOPLEFT", labelOffsetX, labelOffsetY} -- "LEFT", "RIGHT", "TOP", "BOTTOM", "TOPLEFT", "TOPRIGHT", "BOTTOMLEFT", "BOTTOMRIGHT", "CENTER"
  local fontObjectNameLocal = fontObjectName or EasyOptions.Fields.DefaultGroupLabelFontObjectName
  local labelControl, label, labelControlRegionWidth, labelControlRegionHeight = EasyOptions:CreateLabelForControl(parent, control, control, controlName, text, tooltipTitleText, tooltipText, labelPositionInfo, fontObjectNameLocal, customFontInfo, customTextColor)
  label:SetJustifyH("LEFT") -- "LEFT", "RIGHT", "CENTER"
  label:SetJustifyV("MIDDLE") -- "TOP", "BOTTOM", "MIDDLE"
  local labelRegionWidth = 0 -- init
  local labelRegionHeight = 0 -- init
  local hasLabelText = (text ~= nil) and (text ~= "")
  if (hasLabelText) then
    labelRegionWidth = labelControlRegionWidth - 5 -- + labelOffsetX
    labelRegionHeight = labelControlRegionHeight + labelOffsetY - 1
  end
  control.LabelRegionWidth = labelRegionWidth
  control.LabelRegionHeight = labelRegionHeight
  
  -- Set the bounds of the control.
  local width, height, hasWidth, hasHeight, shouldFillWidth = EasyOptions:GetGroupBoxSizeFromCustomSize(customSize, defaultSize)
  local offsetX = 2 -- Offset the x-position of this control type to help it align better with the other controls.
  local offsetY = 3 + labelRegionHeight + EasyOptions:IIF(hasLabelText, 1, 0) -- Offset the y-position of this control type to help it align better with the other controls.
  -- control:ClearAllPoints()
  control:SetPoint(positionInfo[1], parent, positionInfo[2], positionInfo[3] + offsetX, positionInfo[4] - offsetY)
  if (shouldFillWidth) or ((allowFillWidthByDefault) and (customSize == nil)) then
    EasyOptions:SetControlPointToFillWidth(control, parent, positionInfo, offsetX, 2)
  end
  control:SetSize(width, height)
  
  -- control:SetScript("OnClick", onClickHandler)
  control.OnEnabledChangedHandler = function(self)
    -- Reserved.
  end
  EasyOptions:AddSupportForEnabledState(control)
  
  -- Modify height to help make the control align with other controls.
  control.GetSizeEffective = function(self)
    -- Description: Returns the width of the visual bounds of the control, excluding the label.
    local control = self
    local hasLabel = (control.LabelRegionHeight > 0)
    local widthEffective = math.max(control:GetWidth() - 2, 0)
    local heightEffective = math.max((control:GetHeight() - 2) + EasyOptions:IIF(hasLabel, 1, 0), 0)
    return widthEffective, heightEffective
  end
  control.GetWidthEffective = function(self)
    -- Description: Returns the width of the visual bounds of the control, excluding the label.
    local control = self
    local widthEffective, heightEffective = control:GetSizeEffective()
    return widthEffective
  end
  control.GetHeightEffective = function(self)
    -- Description: Returns the height of the visual bounds of the control, excluding the label.
    local control = self
    local widthEffective, heightEffective = control:GetSizeEffective()
    return heightEffective
  end
  local widthEffective, heightEffective = control:GetSizeEffective()
  local controlRegionWidth = math.max(widthEffective, labelRegionWidth)
  local controlRegionHeight = heightEffective + labelRegionHeight -- NOTE: We don't use control:GetHeight() because some controls don't implement that method and most controls that support that method return a value that is larger than desired.
  control.ControlRegionWidth = controlRegionWidth
  control.ControlRegionHeight = controlRegionHeight
  return control, controlRegionWidth, controlRegionHeight
end
function EasyOptions:CreateGroupBox(parent, customControlName, text, tooltipTitleText, tooltipText, positionInfo, customSize, allowFillWidthByDefault, fontObjectName, customFontInfo, customTextColor)
  local typeName = "GroupBox"
  local baseTypeName = "GroupBox"
  local defaultSize = EasyOptions:GetDefaultGroupBoxSize()
  local showBackgroundAndBorder = true
  local control, controlRegionWidth, controlRegionHeight = EasyOptions:CreateGroupBoxBase(typeName, baseTypeName, parent, customControlName, text, tooltipTitleText, tooltipText, positionInfo, customSize, defaultSize, showBackgroundAndBorder, allowFillWidthByDefault, fontObjectName, customFontInfo, customTextColor)
  return control, controlRegionWidth, controlRegionHeight
end
function EasyOptions:CreateOptionGroupBox(parent, positionInfo, optionItem)
  local optionName = optionItem.Name
  local text = EasyOptions:GetControlText(optionItem)
  local tooltipTitleText = optionItem.TooltipTitleText or text
  local tooltipText = optionItem.TooltipText
  local customSize = optionItem.Size
  local allowFillWidthByDefault = true
  local fontObjectName = nil
  local customFontInfo = optionItem.FontInfo
  local customTextColor = optionItem.TextColor
  
  local control, controlRegionWidth, controlRegionHeight = EasyOptions:CreateGroupBox(parent, nil, text, tooltipTitleText, tooltipText, positionInfo, customSize, allowFillWidthByDefault, fontObjectName, customFontInfo, customTextColor)
  -- EasyOptions:AddRightButtonDownHandlerForOptionControl(control)
  
  optionItem.Control = control
  control.OptionItem = optionItem
  if (optionName ~= nil) and (optionName ~= "") then
    EasyOptions.Current.OptionControls[optionName] = control
  end
  
  return control, controlRegionWidth, controlRegionHeight
end
function EasyOptions:CreateOptionGroupBoxGroup(parent, positionInfo, optionItem)
  local optionName = optionItem.Name
  local text = EasyOptions:GetControlText(optionItem)
  local tooltipTitleText = optionItem.TooltipTitleText or text
  local tooltipText = optionItem.TooltipText
  local customSize = optionItem.Size
  local allowFillWidthByDefault = (optionItem.AutoFitWidth == false)
  local fontObjectName = nil
  local customFontInfo = optionItem.FontInfo
  local customTextColor = optionItem.TextColor
  
  local control, controlRegionWidth, controlRegionHeight = EasyOptions:CreateGroupBox(parent, nil, text, tooltipTitleText, tooltipText, positionInfo, customSize, allowFillWidthByDefault, fontObjectName, customFontInfo, customTextColor)
  -- EasyOptions:AddRightButtonDownHandlerForOptionControl(control)
  
  optionItem.Control = control
  control.OptionItem = optionItem
  if (optionName ~= nil) and (optionName ~= "") then
    EasyOptions.Current.OptionControls[optionName] = control
  end
  
  return control, controlRegionWidth, controlRegionHeight
end
function EasyOptions:GetGroupBoxSizeFromCustomSize(customSize, defaultSize) -- width, height, hasWidth, hasHeight, shouldFillWidth
  local ignoreCustomHeight = false
  local defaultWidth = defaultSize[1]
  local defaultHeight = defaultSize[2]
  local widthMaxAllowed = EasyOptions.Fields.ControlSizeMaxAllowed_Large
  local heightMaxAllowed = EasyOptions.Fields.ControlSizeMaxAllowed_Large
  local allowFillWidthFlag = true
  local assumeSingleValueIsHeight = false
  return EasyOptions:GetSizeFromCustomSize(customSize, ignoreCustomHeight, defaultWidth, defaultHeight, widthMaxAllowed, heightMaxAllowed, allowFillWidthFlag, assumeSingleValueIsHeight)
end
function EasyOptions:GetDefaultGroupBoxSize()
  local width = (0.5 * EasyOptions.Fields.DefaultWidthMaxAvailable_NoScrollBars) - EasyOptions:GetDefaultControlPaddingX() -- Allow room for two adjacent controls including the default gap between the two controls.
  local height = 10 * 16 -- This value is arbitrary.
  return {width, height}
end
