Merfin = Merfin or {}
local Merfin = Merfin

local screenWidth, screenHeight = GetPhysicalScreenSize()
local resolution = screenWidth >= 2560 and 'QUAD_HD' or 'FULL_HD'

local function GetProfileResolution()
    return resolution
end

Merfin.CenteredHorizontal = function(newPositions, activeRegions, spacing, sizes, maxIcons)
    local iconSize = (GetProfileResolution() == 'QUAD_HD' and sizes[2]) or sizes[1]
    
    if not activeRegions or #activeRegions == 0 then
        return
    end
    
    local totalIcons = #activeRegions
    
    if WeakAuras.IsOptionsOpen() and maxIcons then
        totalIcons = math.min(totalIcons, maxIcons)
    end

    local totalWidth = totalIcons * iconSize + (totalIcons - 1) * spacing
    local startX = -totalWidth / 2 + iconSize / 2
    
    for i = 1, totalIcons do
        local region = activeRegions[i]
        local xPos = startX + (i - 1) * (iconSize + spacing)
        
        region.region:SetRegionWidth(iconSize)
        region.region:SetRegionHeight(iconSize)
        
        newPositions[i] = {xPos, 0}
    end
end

Merfin.GridDown = function(newPositions, activeRegions, spacing, maxIconsPerRow, iconSizeFirstRow, iconSizeSecondRow, maxIcons)

    local iconSizeFirstRow = (GetProfileResolution() == 'QUAD_HD' and iconSizeFirstRow[2]) or iconSizeFirstRow[1]
    local iconSizeSecondRow = (GetProfileResolution() == 'QUAD_HD' and iconSizeSecondRow[2]) or iconSizeSecondRow[1]

    local totalIcons = math.min(#activeRegions, maxIcons)
    local iconsInFirstRow = math.min(maxIconsPerRow, totalIcons)
    local iconsInSecondRow = math.min(maxIconsPerRow, totalIcons - iconsInFirstRow)
    
    local offsetFirstRow = (iconsInFirstRow * (iconSizeFirstRow + spacing)) / 2 - (iconSizeFirstRow + spacing) / 2
    local offsetSecondRow = (iconsInSecondRow * (iconSizeSecondRow + spacing)) / 2 - (iconSizeSecondRow + spacing) / 2
    
    for i, region in ipairs(activeRegions) do
        if i > maxIcons then
            break
        end
        
        local row = math.floor((i - 1) / maxIconsPerRow)
        local col = (i - 1) % maxIconsPerRow
        
        if row == 0 then
            region.region:SetRegionWidth(iconSizeFirstRow)
            region.region:SetRegionHeight(iconSizeFirstRow)
            newPositions[i] = {col * (iconSizeFirstRow + spacing) - offsetFirstRow, 0}
        else
            region.region:SetRegionWidth(iconSizeSecondRow)
            region.region:SetRegionHeight(iconSizeSecondRow)
            newPositions[i] = {col * (iconSizeSecondRow + spacing) - offsetSecondRow, -(iconSizeFirstRow + spacing)}
        end
    end
end

Merfin.GridUp = function(newPositions, activeRegions, spacing, maxIconsPerRow, iconSize, maxIcons)
    local iconSize = (GetProfileResolution() == 'QUAD_HD' and iconSize[2]) or iconSize[1]

    local totalIcons = math.min(#activeRegions, maxIcons)

    for i, region in ipairs(activeRegions) do
        if i > maxIcons then
            break
        end

        -- Determine row and column for each icon
        local row = math.floor((i - 1) / maxIconsPerRow)
        local col = (i - 1) % maxIconsPerRow

        -- Calculate the number of icons in the current row
        local iconsInRow = math.min(maxIconsPerRow, totalIcons - row * maxIconsPerRow)

        -- Horizontal offset to center the current row
        local horizontalOffset = (iconsInRow * (iconSize + spacing)) / 2 - (iconSize + spacing) / 2

        -- Calculate positions
        local x = col * (iconSize + spacing) - horizontalOffset
        local y = row * (iconSize + spacing) -- Rows grow upwards without vertical centering

        region.region:SetRegionWidth(iconSize)
        region.region:SetRegionHeight(iconSize)
        newPositions[i] = {x, y}
    end
end

Merfin.GridFlexible = function(newPositions, activeRegions, settings)
    local direction = settings.direction or "HD" -- Growth direction
    local maxIcons = settings.maxIcons or #activeRegions
    local maxIconsPerRow = settings.maxIconsPerRow or maxIcons
    local iconSizes = settings.iconSizes or {{40, 40}, {40, 40}} -- Icon sizes per row (width, height)
    local spacing = settings.spacing or 5 -- Spacing between icons
    local anchor = settings.anchor or "TOPLEFT" -- Anchor point of the group

    -- Function to get the size of icons for a specific row
    local function getIconSize(rowIndex)
        local size = iconSizes[rowIndex] or iconSizes[#iconSizes]
        return size[1], size[2] -- Return width and height
    end

    -- Adjust positions based on anchor
    local function adjustAnchor(x, y, totalWidth, totalHeight)
        if anchor == "TOPLEFT" then
            return x, y
        elseif anchor == "TOPRIGHT" then
            return -x, y
        elseif anchor == "BOTTOMLEFT" then
            return x, -y
        elseif anchor == "BOTTOMRIGHT" then
            return -x, -y
        elseif anchor == "CENTER" then
            return x - totalWidth / 2, y - totalHeight / 2
        end
        return x, y
    end

    -- Calculate total width and height for proper alignment
    local totalRows = math.ceil(maxIcons / maxIconsPerRow)
    local totalColumns = math.min(maxIconsPerRow, maxIcons)
    local maxWidth = 0
    local maxHeight = 0

    for i = 1, totalRows do
        local rowWidth = totalColumns * (getIconSize(i) + spacing) - spacing
        local rowHeight = getIconSize(i)
        maxWidth = math.max(maxWidth, rowWidth)
        maxHeight = maxHeight + rowHeight
    end
    maxHeight = maxHeight + ((totalRows - 1) * spacing) -- Adjust for spacing between rows

    -- Generate positions and set sizes
    for i, region in ipairs(activeRegions) do
        if i > maxIcons then
            break
        end

        -- Determine the row and column of the current icon
        local row = math.floor((i - 1) / maxIconsPerRow)
        local col = (i - 1) % maxIconsPerRow

        local iconWidth, iconHeight = getIconSize(row + 1)
        region.region:SetRegionWidth(iconWidth)
        region.region:SetRegionHeight(iconHeight)

        -- Calculate icon position based on direction
        local x, y = 0, 0

        if direction == "DL" then
            -- Growth Down, then Left
            x = -(col * (iconWidth + spacing))
            y = -(row * (iconHeight + spacing))
        elseif direction == "DR" then
            -- Growth Down, then Right
            x = col * (iconWidth + spacing)
            y = -(row * (iconHeight + spacing))
        elseif direction == "HD" then
            x = (col * (iconWidth + spacing)) - ((totalColumns - 1) * (iconWidth + spacing) / 2)
            y = -(row * (iconHeight + spacing))
        elseif direction == "HU" then
            x = (col * (iconWidth + spacing)) - ((totalColumns - 1) * (iconWidth + spacing) / 2)
            y = (row * (iconHeight + spacing))
        elseif direction == "RU" then
            x = (col * (iconWidth + spacing))
            y = (row * (iconHeight + spacing))
        elseif direction == "RD" then
            x = (col * (iconWidth + spacing))
            y = -(row * (iconHeight + spacing))
        elseif direction == "LU" then
            x = -(col * (iconWidth + spacing))
            y = (row * (iconHeight + spacing))
        elseif direction == "LD" then
            x = -(col * (iconWidth + spacing))
            y = -(row * (iconHeight + spacing))
        end

        -- Adjust based on anchor
        x, y = adjustAnchor(x, y, maxWidth, maxHeight)

        -- Save the calculated positions
        newPositions[i] = {x, y}
    end
end
