-- This file is a private addition by Portalz - officialportalz@gmail.com.
-- its an absolute monstrosity of a mess, but its my mess i coded quickly but carefully
-- It is not part of the GuildMap MPL 2.0 codebase.
-- All rights reserved.

-- local GuildMapUI = {}
-- _G["GuildMapTest"] = GuildMapTest

-- working on getting cross guild working but its painful

local AceGUI = LibStub("AceGUI-3.0")
GMMW= GMMW or {}
GuildMapDB=GuildMapDB or {}
GuildMapDB.GMMW=GuildMapDB.GMMW or {}
local lastHealth=UnitHealth("player")
local deadPlayers={}
local groupList={}
guild_map_folder_name="GuildMap"
guild_map_clusterIcon_distance=1500
guild_map_is_dueling=0
local currentlyDueling={}
local finishedDuel={}
local duelingCooldownTime=30
local MAX_LEVEL_POSSIBLE=GetMaxPlayerLevel()
local version, build, date, toc = GetBuildInfo()

local pinGrid={}

local isDuelingFrameCheck = CreateFrame("Frame")

isDuelingFrameCheck:RegisterEvent("DUEL_FINISHED")
isDuelingFrameCheck:RegisterEvent("CHAT_MSG_SYSTEM")

isDuelingFrameCheck:SetScript("OnEvent", function(self, event, message)
    if toc~=120000 then
        if event=="CHAT_MSG_SYSTEM" then
            if message=="Duel starting: 1" then
                guild_map_is_dueling=1
                --print("DUEL STARTING 1")
            end
        elseif event == "DUEL_FINISHED" then
            guild_map_is_dueling=0
            --print("DUEL FINISHED") 
        end
    end
end)

local function GetMaxPlayerLevel()
    -- Try the modern API
    if type(MAX_PLAYER_LEVEL_TABLE) == "table" and type(GetExpansionLevel) == "function" then
        local level = MAX_PLAYER_LEVEL_TABLE[GetExpansionLevel() + 1]
        if level then return level end
    end

    -- Try the legacy global
    if type(MAX_PLAYER_LEVEL) == "number" then
        return MAX_PLAYER_LEVEL
    end

    -- Fallbacks by client version if all else fails
    local version = select(4, GetBuildInfo()) -- returns something like 40402 for Cataclysm
    if version >= 40000 and version < 50000 then
        return 85 -- Cataclysm
    elseif version >= 30000 and version < 40000 then
        return 80 -- WotLK
    elseif version >= 20000 and version < 30000 then
        return 70 -- TBC
    elseif version >= 10000 and version < 20000 then
        return 60 -- Vanilla/Classic
    end

    return 60 -- Final fallback
end



function guild_map_duel_signal_process(playerName,isDueling)
    if isDueling then
        --player is actually currently dueling
        --print("player is actually currently dueling")
        currentlyDueling[playerName]=1
    elseif currentlyDueling[playerName] then
        -- player is no longer dueling for the first time since dueled before
        --print("player is no longer dueling for the first time since dueled before")
        finishedDuel[playerName]=time()
        currentlyDueling[playerName]=nil
    end
end

function guild_map_post_duel_timer(playerName,health)
    if finishedDuel[playerName] then
        -- player is no longer dueling for a few seconds after duel
        --print("player is no longer dueling for a few seconds after duel")
        --print(health,GuildMapDB.healthAlertThreshold)
        if time()-finishedDuel[playerName]>=duelingCooldownTime then
            --print("Clearing timer",playerName)
            finishedDuel[playerName]=nil 
        end
    end
    
end

function guild_map_post_duel_threshold(playerName,health)
    if tonumber(health)>GuildMapDB.healthAlertThreshold then
        --print("Clearing hp",playerName,health,GuildMapDB.healthAlertThreshold)
        finishedDuel[playerName]=nil 
    end
end

function guild_map_not_dueling_clearance(name,isDueling)
    if isDueling or currentlyDueling[name] or finishedDuel[name] then
        return false
    end
    return true
end

function printPinGrid()
    local grid = pinGrid
    local dupeTracker={}
    local dupeAlert=nil
    for x, yTable in pairs(grid) do
        print("x = " .. tostring(x)) -- Print the first-level key (x)

        for y, pinTable in pairs(yTable) do
            print("  y = " .. tostring(y)) -- Print the second-level key (y)

            for title, pin in pairs(pinTable) do
                print("    pin.title = " .. tostring(title)) -- Print the third-level key (pin title)
                if dupeTracker[title] then
                    dupeAlert="ERROR THERE IS A DUPE "..title
                end
                dupeTracker[title]=title
            end
        end
    end
    if dupeAlert then
        print(dupeAlert)
    end
end

function guild_map_insertIntoPinGrid(pin)
    local x=pin.remainingData.clusterGrid_x
    local y=pin.remainingData.clusterGrid_y
    if not pinGrid[x] then
        pinGrid[x]={}
    end

    if not pinGrid[x][y] then
        pinGrid[x][y]={}
    end
    pinGrid[x][y][pin.title]=pin
end

function guild_map_removeFromPinGrid(pin)
    if pinGrid[pin.remainingData.clusterGrid_x] and pinGrid[pin.remainingData.clusterGrid_x][pin.remainingData.clusterGrid_y] and pinGrid[pin.remainingData.clusterGrid_x][pin.remainingData.clusterGrid_y][pin.title]then
        pinGrid[pin.remainingData.clusterGrid_x][pin.remainingData.clusterGrid_y][pin.title]=nil
    end
end

function guild_map_getPinGrid(x,y)
    return pinGrid[x][y]
end

function guild_map_clearPinGrid()
    pinGrid={}
end

function guild_map_gather_pin_neighbors(pin,pinType)
    local collectedPinsTables={}
    local cornerx=pin.remainingData.clusterGrid_x-1500
    local cornery=pin.remainingData.clusterGrid_y-1500
    for i=0,2 do
        for j=0, 2 do
            if pinGrid[cornerx+j*1500] and pinGrid[cornerx+j*1500][cornery+i*1500] then
                for index, value in pairs(guild_map_getTouchingPins(pin,pinGrid[cornerx+j*1500][cornery+i*1500],pinType)) do
                    table.insert(collectedPinsTables,value)
                end
            end
        end
    end
    return collectedPinsTables
end

function guild_map_getTouchingPins(pin, pinPool,pinType)
    local touchingIcons = {}
    local pinSpecific=nil
    if pinType==0 then
        pinSpecific=pin.world
    end
    -- Get bounds of the target icon
    local leftT, bottomT, widthT, heightT = pinSpecific:GetLeft(), pinSpecific:GetBottom(), pinSpecific:GetWidth(), pinSpecific:GetHeight()
    local rightT, topT = leftT + widthT, bottomT + heightT
    for _, icon in pairs(pinPool) do
        if icon ~= pin then
            local iconSpecific=nil
            if pinType==0 then
                iconSpecific=icon.world
            end
            local left, bottom, width, height = iconSpecific:GetLeft(), iconSpecific:GetBottom(), iconSpecific:GetWidth(), iconSpecific:GetHeight()
            if left then 
                local right, top = left + width, bottom + height
                -- Check for overlap
                if not (rightT < left or leftT > right or topT < bottom or bottomT > top) then
                    table.insert(touchingIcons, icon)
                end
            end
        end
    end

    return touchingIcons
end



function guild_map_layer_texture_path_modifier(layer,path)
    commonLayer=( NWB_CurrentLayer~=0 and layer == NWB_CurrentLayer)
    if commonLayer then
        path=path.."LAYER"
    end
    return path
end

function guild_map_check_level_filter_range(level)
    return level > GuildMapDB.max_level_filter or level < GuildMapDB.min_level_filter
end

function guild_map_redraw_curr_pins()
    for waypoint,pin in pairs(guild_map_pins) do
        GuildMap:RemovePinsByTitle(pin.wp.title)
        GuildMap:CreateMapPin(waypoint, pin.wp.healthPercent, pin.remainingData.rank, pin.remainingData.targetLevel, pin.remainingData.className, pin.wp.layer)
    end
end



function guild_map_clear_all_dbm()
    for _, pinSet in pairs(guild_map_pins) do
        if pinSet.title then
            guild_map_remove_dbm_waypoint(pinSet.title)
        end
    end
end

function guild_map_onlyfangs_check()
    local guildName, guildRank, guildRankIndex, guildID = GetGuildInfo("player")
    if guildName=="OnlyFangs" then
        guild_map_addon_onlyfangs_warning_frame()
end
end

function guild_map_addon_onlyfangs_warning_frame()
    local addon_warning_frame = AceGUI:Create("Frame")
    addon_warning_frame:SetLayout("Flow")
    addon_warning_frame:SetTitle("GUILDMAP  "..guild_map_version.."  WARNING")
    addon_warning_frame:SetWidth(800)
    addon_warning_frame:SetHeight(300)

    local warning_text_label = AceGUI:Create("Label")
    warning_text_label:SetText("You have the public version of GuildMap installed\n as an OnlyFangs member.\n\n Delete this addon folder ('GuildMap') and go install:\n Then /reload somewhere safe.")
    warning_text_label:SetColor(1, .16, .16) 
    warning_text_label:SetWidth(800)
    warning_text_label:SetHeight(175)
    local fontName, fontHeight, fontFlags = GameFontNormal:GetFont()
    local newFontHeight = 30
    warning_text_label.label:SetFont(fontName, newFontHeight, fontFlags)
    addon_warning_frame:AddChild(warning_text_label)

    local guildMapOFURL = AceGUI:Create("EditBox")
    guildMapOFURL:SetText("https://www.curseforge.com/wow/addons/guildmapof")
    guildMapOFURL:SetWidth(350)
    addon_warning_frame:AddChild(guildMapOFURL)
end

function guild_map_draw_dbm_pins()
    for _, pinSet in pairs(guild_map_pins) do
        local player_mapID = C_Map.GetBestMapForUnit("player")
        if GuildMapDB.guild_map_DBM_menu_render and DBM and DBM.HudMap and not DBM:HasMapRestrictions() then
            if pinSet.title and player_mapID == pinSet.wp.mapID then
                if pinSet.remainingData.className and RAID_CLASS_COLORS[pinSet.remainingData.className] then
                    local r, g, b = RAID_CLASS_COLORS[pinSet.remainingData.className].r, RAID_CLASS_COLORS[pinSet.remainingData.className].g, RAID_CLASS_COLORS[pinSet.remainingData.className].b
                    -- DBM.HudMap:FreeEncounterMarkerByTarget(pinSet.title, "GuildMap")--Basically equiv of GuildMap:RemovePinsByTitle(title)
                    DBM.HudMap:RegisterPositionMarker(pinSet.title, "GuildMap", "party", pinSet.wp.x * 100, pinSet.wp.y * 100, 1.5, nil, r, g, b, 1, nil, true, pinSet.wp.mapID):Appear():RegisterForAlerts()
                end
            end
        end
    end
end



function guild_map_remove_dbm_waypoint(title)
    if DBM and DBM.HudMap then
        DBM.HudMap:FreeEncounterMarkerByTarget(title, "GuildMap")--Basically equiv of GuildMap:RemovePinsByTitle(title)
    end
end


function guild_map_check_group_member(name)
    return groupList[name]
end

local function updateGroupList()
    groupList={}
    local raidModifier=1
    local unitPrefix="party"
    if IsInRaid() then
        raidModifier=0
        unitPrefix="raid"
    end
    for i = 1, GetNumGroupMembers() - raidModifier do
        local unitID= unitPrefix .. i
        local name = UnitName(unitID)
        groupList[name]=true
        GuildMap:RemovePinsByTitle(name)
    end
end

local groupUpdate = CreateFrame("Frame")
groupUpdate:RegisterEvent("GROUP_ROSTER_UPDATE")

groupUpdate:SetScript("OnEvent", function(self, event, ...)
    if event == "GROUP_ROSTER_UPDATE" then
        if IsInGroup() then
            updateGroupList()
        else
            groupList={}
        end
    end
end)
-- UnitAffectingCombat('player')
-- UnitIsFeignDeath("player")
-- UnitIsDeadOrGhost("player")

-- function guild_map_feign_death_handle(class)
--     if class=="HUNTER" and UnitIsFeignDeath("player") then
--         return lastHealth
--     else
--         return nil
--     end
-- end

function guild_map_V1GreaterThanV2(v1,v2)
    -- print(v1.." "..tostring(v2))
    if v1==v2 then
        -- print("A")
        return false
    end
    if v2 then
        -- print("A0")
        local v1Split={strsplit(".", v1)}
        local v2Split={strsplit(".", v2)}

        if #v1Split>#v2Split then
            -- print("B")
            return true
        end

        for i=1, math.min(#v1Split,#v2Split) do
            if v1Split[i] < v2Split[i] then
                -- print("C")
                return false
            elseif v1Split[i]>v2Split[i] then
                -- print("D")
                return true
            end
        end
        -- print("E")
        return false
    else
        -- print("F")
        return true -- v1 greater
    end
    -- print("G")
end

function guild_map_check_received_healthPercent(name,healthPercent)
    if healthPercent==0 then
        deadPlayers[name]=1
    end
end

function guild_map_get_deadPlayer(name)
    return deadPlayers[name]
end

function guild_map_fix_healthpercent(healthPercent,class)
    if UnitIsDeadOrGhost("player") then
        if class~="HUNTER" or (not UnitIsFeignDeath("player") and not UnitAffectingCombat('player')) then
            return 0
        else
            return math.floor(lastHealth / UnitHealthMax("player") * 100)
        end
    end
    if healthPercent==0 then
        return 1
    end
    return healthPercent
end

function GuildMapOnAddonMessageWrap(prefix, text, channel, sender)
    GuildMapOnAddonMessage(prefix, text, channel, sender)
end

function sendPositionWrap(x)
    if GuildMapDB.dynamic_level_filter then
        gm_ValidateAndLinkDynamic_automation()
    end
    message=GuildMap:SendGuildPosition(x)
    if message then
        C_ChatInfo.SendAddonMessage(ADDON_PREFIX, message, "GUILD")
    end
    timeSinceLastUpdate=0
    if not UnitIsDeadOrGhost('player') then
        lastHealth=UnitHealth("player")
    end
end

function sendPositionChat()
    message=GuildMap:SendGuildPosition(x)
    timeSinceLastUpdate=timeSinceLastUpdateExternal
    if message then
        C_ChatInfo.SendAddonMessage(ADDON_PREFIX, message, "GUILD")
        if GuildMapDB.crossBroadCast then
            SendChatMessage(message, "CHANNEL", nil, GetChannelName(GuildMapDB.crossMyGuild))
            timeSinceLastUpdate=0
            timeSinceLastUpdateExternal = 0
        end
    end
end

function checkChannels()
    channelStatus={}
    local channels = { GetChannelList() }
    if #channels == 0 then
        return
    end

    for i = 1, #channels, 3 do
        local channelNumber = channels[i]
        local channelName = channels[i + 1]
        local isPasswordProtected = channels[i + 2]
        local protectionStatus = isPasswordProtected and "Password Protected" or "No Password"
        if GuildMapDB.GMMW[channelName] then
            channelStatus[channelName]=true
            if not GuildMapDB.GMMW[channelName].setBroadcast then
                LeaveChannelByName(channelName)
            end
        end

        if GuildMapDB.crossMyGuild==channelName and not GuildMapDB.crossBroadCast then
            LeaveChannelByName(channelName)
        end
        -- print(string.format("%d: %s (%s)", channelNumber, channelName, protectionStatus))
    end

    for channeName,channel in pairs(GuildMapDB.GMMW) do
        local myGuild=false

        if not channelStatus[channeName] and  GuildMapDB.GMMW[channeName].setBroadcast then
            -- print("Attempting Connection to Connect to"..channeName)
            JoinChannelByName(channeName, channel.setEditPassword)
        end

        if channelName==GuildMapDB.crossMyGuild then
            myGuild=true
        end
    end

    if not myGuild and GuildMapDB.crossBroadCast then
        -- print("Attempting Connection to Connect to"..GuildMapDB.crossMyGuild)
        JoinChannelByName(GuildMapDB.crossMyGuild, GuildMapDB.crossMyPassword)
    end
end

function guild_map_check_stealth_render(x,y,mapID)
    return x==0 and y==0 and mapID==1458
end


function addDefaults(defaults)
    defaults.crossBroadCast=false
    defaults.crossMyGuild=nil
    defaults.crossMyPassword=nil
    defaults.otherGuilds=nil
    defaults.DBM_enabled=false
    defaults.min_level_filter=1
    defaults.max_level_filter=MAX_LEVEL_POSSIBLE
    defaults.dynamic_min_filter=0
    defaults.dynamic_max_filter=0
    defaults.dynamic_level_filter=false
    defaults.ignoreDuelHealthAlerts=false
end

function isStealth()
    local stealthOption=false
    -- local _, class = UnitClass("player")
    --   if class=="DRUID" or class=="ROGUE" then
        stealthOption=true
    --   end
    return stealthOption
end

function guild_map_DBM_menu_render(container)
    local enable_dbm_hudmap = AceGUI:Create("CheckBox")
    enable_dbm_hudmap:SetLabel("Enable DBM Hudmap")
    enable_dbm_hudmap:SetWidth(300)
    enable_dbm_hudmap:SetValue(GuildMapDB.guild_map_DBM_menu_render)
    enable_dbm_hudmap:SetCallback("OnValueChanged", function(_, _, value)
        GuildMapDB.guild_map_DBM_menu_render = value
        enable_dbm_hudmap:SetValue(value)
        if value then
            guild_map_draw_dbm_pins()
        else
            guild_map_clear_all_dbm()
        end
    end)
    container:AddChild(enable_dbm_hudmap)
end

function gm_ValidateAndLinkDynamic_automation()
    local minVal=tonumber(GuildMapDB.dynamic_min_filter)
    local maxVal=tonumber(GuildMapDB.dynamic_max_filter)
    local playerLevel=UnitLevel("player")

    if playerLevel-minVal<1 then
        GuildMapDB.dynamic_min_filter=playerLevel-1
        GuildMapDB.min_level_filter=playerLevel-GuildMapDB.dynamic_min_filter
        GuildMap:ClearAllWaypoints()
    end

    if playerLevel+maxVal>MAX_LEVEL_POSSIBLE then
        GuildMapDB.dynamic_max_filter=MAX_LEVEL_POSSIBLE-playerLevel
        GuildMapDB.max_level_filter=playerLevel+GuildMapDB.dynamic_max_filter
        GuildMap:ClearAllWaypoints()
    end
end

function extra_settings_menu_render(container)
    -- Create a frame
    local level_filter_info = AceGUI:Create("Label")
    if level_filter_info then
        level_filter_info:SetText(GuildMap_Localize("Filter level ranges to be shown on the Map and Minimap"))
        level_filter_info:SetFullWidth(true)
        level_filter_info:SetColor(1, 1, 0)
        container:AddChild(level_filter_info)
    end

    local dynamic_level_filter_option_frame = AceGUI:Create("CheckBox")
    dynamic_level_filter_option_frame:SetLabel(GuildMap_Localize("Dynamically change around my level"))
    dynamic_level_filter_option_frame:SetFullWidth(true)
    dynamic_level_filter_option_frame:SetValue(GuildMapDB.dynamic_level_filter)
    container:AddChild(dynamic_level_filter_option_frame)

    local dynamicMinBox = AceGUI:Create("EditBox")
    dynamicMinBox:SetLabel(GuildMap_Localize("Levels below mine"))
    dynamicMinBox:SetDisabled(not GuildMapDB.dynamic_level_filter)
    dynamicMinBox:SetText(tostring(GuildMapDB.dynamic_min_filter)) -- Default Min Value
    dynamicMinBox:SetWidth(120)
    container:AddChild(dynamicMinBox)

    local dynamicMaxBox = AceGUI:Create("EditBox")
    dynamicMaxBox:SetLabel(GuildMap_Localize("Levels above mine"))
    dynamicMaxBox:SetDisabled(not GuildMapDB.dynamic_level_filter)
    dynamicMaxBox:SetText(tostring(GuildMapDB.dynamic_max_filter)) -- Default Max Value
    dynamicMaxBox:SetWidth(120)
    container:AddChild(dynamicMaxBox)

    local level_filter_spacer = AceGUI:Create("Label")
    if level_filter_spacer then
        level_filter_spacer:SetText("")
        level_filter_spacer:SetHeight(1)
        level_filter_spacer:SetFullWidth(true)
        container:AddChild(level_filter_spacer)
    end

    -- Create text boxes for min and max values
    local minBox = AceGUI:Create("EditBox")
    minBox:SetLabel(GuildMap_Localize("Min Level"))
    minBox:SetDisabled(GuildMapDB.dynamic_level_filter)
    minBox:SetText(tostring(GuildMapDB.min_level_filter)) 
    minBox:SetWidth(120)
    container:AddChild(minBox)

    local maxBox = AceGUI:Create("EditBox")
    maxBox:SetLabel(GuildMap_Localize("Max Level"))
    maxBox:SetDisabled(GuildMapDB.dynamic_level_filter)
    maxBox:SetText(tostring(GuildMapDB.max_level_filter)) 
    maxBox:SetWidth(120)
    container:AddChild(maxBox)

    -- Link values to prevent overlap
    local function ValidateAndLink(type)
        
        local minVal=nil
        local maxVal=nil
        
        if type==0 then
            minVal = tonumber(minBox:GetText())
            maxVal = tonumber(GuildMapDB.max_level_filter)
        else
            maxVal = tonumber(maxBox:GetText())
            minVal = tonumber(GuildMapDB.min_level_filter)
        end

        -- Ensure inputs are valid numbers
        if type==0 then
            if not minVal or minVal < 1 or (not (minVal <= maxVal)) then
                minBox:SetText(tostring(GuildMapDB.min_level_filter))
                return
            else
                GuildMap:ClearAllWaypoints()
                GuildMapDB.min_level_filter=minVal
            end
        else
            if not maxVal or maxVal>MAX_LEVEL_POSSIBLE or (not (maxVal >= minVal)) then
                maxBox:SetText(tostring(GuildMapDB.max_level_filter)) 
                return
            else
                GuildMap:ClearAllWaypoints()
                GuildMapDB.max_level_filter=maxVal
            end
        end
    end

    local function ValidateAndLinkDynamic(type)
        local minVal=tonumber(dynamicMinBox:GetText())
        local maxVal=tonumber(dynamicMaxBox:GetText())
        local playerLevel=UnitLevel("player")

        local acceptedEntry=true

        -- Ensure inputs are valid numbers
        if type==0 then
            if (minVal and minVal>=0) then
                if playerLevel-minVal<1 then
                    minVal=playerLevel-1
                end
                GuildMapDB.dynamic_min_filter=minVal
                GuildMapDB.min_level_filter=playerLevel-minVal
                if minBox then
                    minBox:SetDisabled(false)
                    minBox:SetText(tostring(GuildMapDB.min_level_filter))
                    minBox:SetDisabled(true)
                end
            else
                acceptedEntry=false
            end
            if dynamicMinBox then
                dynamicMinBox:SetText(tostring(GuildMapDB.dynamic_min_filter))
            end
        else
            if ( maxVal and maxVal>=0) then
                if playerLevel+maxVal>MAX_LEVEL_POSSIBLE then
                    maxVal=MAX_LEVEL_POSSIBLE-playerLevel
                end
                GuildMapDB.dynamic_max_filter=maxVal
                GuildMapDB.max_level_filter=playerLevel+maxVal
                if maxBox then
                    maxBox:SetDisabled(false)
                    maxBox:SetText(tostring(GuildMapDB.max_level_filter))
                    maxBox:SetDisabled(true)
                end
            else
                acceptedEntry=false
            end
            if dynamicMaxBox then
                dynamicMaxBox:SetText(tostring(GuildMapDB.dynamic_max_filter))
            end
        end
        if acceptedEntry then
            GuildMap:ClearAllWaypoints()
        end
    end

    dynamic_level_filter_option_frame:SetCallback("OnValueChanged", function(_, _, value)
        minBox:SetDisabled(value)
        maxBox:SetDisabled(value)
        dynamicMaxBox:SetDisabled(not value)
        dynamicMinBox:SetDisabled(not value)
        GuildMapDB.dynamic_level_filter = value
        dynamic_level_filter_option_frame:SetValue(value)
        if value then
            ValidateAndLinkDynamic(0)
            ValidateAndLinkDynamic(1)
        end
        GuildMap:ClearAllWaypoints()
    end)

    -- Call validation on text change
    minBox:SetCallback("OnEnterPressed", function(widget, event, text)
        ValidateAndLink(0)
    end)
    maxBox:SetCallback("OnEnterPressed", function(widget, event, text)
        ValidateAndLink(1)
    end)
    dynamicMinBox:SetCallback("OnEnterPressed", function(widget, event, text)
        ValidateAndLinkDynamic(0)
    end)
    dynamicMaxBox:SetCallback("OnEnterPressed", function(widget, event, text)
        ValidateAndLinkDynamic(1)
    end)

    -- ValidateAndLinkDynamic(0)
    -- ValidateAndLinkDynamic(1)

    -- -- Debugging button to print values
    -- local printButton = AceGUI:Create("Button")
    -- printButton:SetText("Print Values")
    -- printButton:SetCallback("OnClick", function()
    --     print("Min:",GuildMapDB.min_level_filter, "Max:",GuildMapDB.max_level_filter)
    -- end)
    -- container:AddChild(printButton)
end

function crossGuildMyTab(container)
    local desc = AceGUI:Create("Label")
    desc:SetText("This is Tab 1")
    desc:SetFullWidth(true)
    container:AddChild(desc)
    
    local broadcastLocationOp = AceGUI:Create("CheckBox")
    broadcastLocationOp:SetLabel("Broadcast to other Guilds")
    broadcastLocationOp:SetWidth(300)
    broadcastLocationOp:SetValue(GuildMapDB.crossBroadCast)
    broadcastLocationOp:SetCallback("OnValueChanged", function(_, _, value)
        GuildMapDB.crossBroadCast = value
        broadcastLocationOp:SetValue(value)
        if not value then
            LeaveChannelByName(GuildMapDB.crossMyGuild)
        else
            JoinChannelByName(GuildMapDB.crossMyGuild, GuildMapDB.crossMyPassword)
        end
        sendPositionWrap(true)
    end)
    container:AddChild(broadcastLocationOp)
    
    -- local frame = AceGUI:Create("Frame")
    -- container.SetLayout("Flow")
    -- Add content to the frame
    local label1 = AceGUI:Create("Label")
    label1:SetText("Guild Channel")
    label1:SetWidth(350)
    container:AddChild(label1)

    local editBoxName = AceGUI:Create("EditBox")
    editBoxName:SetWidth(350)
    editBoxName:SetText(GuildMapDB.crossMyGuild or "Channel")
    prevEditBoxNameMy=GuildMapDB.crossMyGuild
    editBoxName:SetCallback("OnEnterPressed", function(_, _, value)
        if value then
            editBoxName:SetText(value:lower())
            GuildMapDB.crossMyGuild = value:lower()
            LeaveChannelByName(prevEditBoxNameMy)
            prevEditBoxNameMy=GuildMapDB.crossMyGuild
        end
        checkChannels()
    end)
    container:AddChild(editBoxName)

    local label2 = AceGUI:Create("Label")
    label2:SetText("Guild Password Case Sensitive")
    label2:SetWidth(350)
    container:AddChild(label2)

    local editBoxPassword = AceGUI:Create("EditBox")
    editBoxPassword:SetWidth(350)
    editBoxPassword:SetText(GuildMapDB.crossMyPassword or "Password")
    prevEditBoxName=GuildMapDB.crossMyPassword
    editBoxPassword:SetCallback("OnEnterPressed", function(_, _, value)
        GuildMapDB.crossMyPassword = value
        prevEditBoxName=GuildMapDB.crossMyPassword
        checkChannels()
    end)
    container:AddChild(editBoxPassword)
end

--add function to refresh channels --channels need prefix?

function crossGuildScrolLTab(container)
    local desc = AceGUI:Create("Label")
    desc:SetText("This is Tab 1")
    desc:SetFullWidth(true)
    container:AddChild(desc)


    local button = AceGUI:Create("Button")
    button:SetText("Add Guild")
    button:SetWidth(200)
    
    container:AddChild(button)

    
    local scrollFrame = AceGUI:Create("ScrollFrame")
    -- scrollFrame.SetLayout("Flow")
    scrollFrame:SetWidth(400)
    scrollFrame:SetHeight(350)
    button:SetCallback("OnClick", function(widget, event)
        --refresh tab
        container:ReleaseChildren()
        crossGuildScrolLTab(container)

        -- for key,block in pairs(GMMW) do
        --     block.setEditChannel=key
        --     local newBlock=createCrossGuildBlock(scrollFrame,container,block)
        --     scrollFrame:AddChild(newBlock)
            
        -- end

        local newBlock=createCrossGuildBlock(scrollFrame,container)
        scrollFrame:AddChild(newBlock)
    end)

    for key,block in pairs(GuildMapDB.GMMW) do
        block.setEditChannel=key
        local newBlock=createCrossGuildBlock(scrollFrame,container,block)
        scrollFrame:AddChild(newBlock)
        
    end

    container:AddChild(scrollFrame)
end

function createCrossGuildBlock(xfr,tabContainer,settings)
    local scrollFrame = AceGUI:Create("SimpleGroup")

    if not settings then
        settings= {
            setBroadcast=false,
            setEditChannel="Guild Channel",
            setEditPassword="Password"
        }
    end
    
    local broadcastLocationOp = AceGUI:Create("CheckBox")
    broadcastLocationOp:SetLabel("Enabled")
    broadcastLocationOp:SetWidth(200)
    broadcastLocationOp:SetValue(settings.setBroadcast)
    scrollFrame:AddChild(broadcastLocationOp)
    local label1 = AceGUI:Create("Label")
    label1:SetText("Guild Channel")
    label1:SetWidth(350)
    scrollFrame:AddChild(label1)

    
    local editBoxName = AceGUI:Create("EditBox")
    editBoxName:SetText(settings.setEditChannel)
    prevEditBoxName=settings.setEditChannel
    editBoxName:SetWidth(350)
    
    scrollFrame:AddChild(editBoxName)

    local label2 = AceGUI:Create("Label")
    label2:SetText("Guild Password Case Sensitive")
    label2:SetWidth(350)
    scrollFrame:AddChild(label2)

    local editBoxPassword = AceGUI:Create("EditBox")
    editBoxPassword:SetText(settings.setEditPassword)
    prevEditPassword=settings.setEditPassword
  
    editBoxPassword:SetWidth(350)
    scrollFrame:AddChild(editBoxPassword)


    broadcastLocationOp:SetCallback("OnValueChanged", function(_, _, value)
        broadcastLocationOp:SetValue(value)
        GuildMapDB.GMMW[editBoxName:GetText()]={
            setEditPassword=editBoxPassword:GetText(),
            setBroadcast=broadcastLocationOp:GetValue()
        }
        if not value then
            LeaveChannelByName(editBoxName:GetText())
            GuildMap:ClearAllWaypoints()
        else
            JoinChannelByName(editBoxName:GetText(), editBoxPassword:GetText())
        end
    end)

    editBoxPassword:SetCallback("OnEnterPressed", function(_, _, value)
        GuildMapDB.GMMW[editBoxName:GetText()]={
            setEditPassword=editBoxPassword:GetText(),
            setBroadcast=broadcastLocationOp:GetValue()
        }
        checkChannels()
    end)

    editBoxName:SetCallback("OnEnterPressed", function(_, _, value)
        if value then
            GuildMapDB.GMMW[prevEditBoxName]=nil
            editBoxName:SetText(value:lower())
            GuildMapDB.GMMW[value:lower()]={
                setEditPassword=editBoxPassword:GetText(),
                setBroadcast=broadcastLocationOp:GetValue()
            }
            LeaveChannelByName(prevEditBoxName)
            prevEditBoxName=value:lower()
            checkChannels()
        end
        
    end)
    
    local delete = AceGUI:Create("Button")
    delete:SetText("Delete")
    delete:SetWidth(200)
    delete:SetCallback("OnClick", function(widget, event)
        -- GMMW[editBoxName:GetText()]=nil
        tabContainer:ReleaseChildren()
        GuildMapDB.GMMW[editBoxName:GetText()]=nil
        crossGuildScrolLTab(tabContainer)
        LeaveChannelByName(editBoxName:GetText())
        -- for _,block in pairs(GuildMapDB.GMMW) do
        --     block.setEditChannel=_
        --     local newBlock=createCrossGuildBlock(xfr,tabContainer,block)
        --     xfr:AddChild(newBlock)
        -- end
    end)
    scrollFrame:AddChild(delete)
    local label3 = AceGUI:Create("Label")
    label3:SetText("    ")
    label3:SetWidth(350)
    scrollFrame:AddChild(label3)

    local separator = AceGUI:Create("Heading")
    -- separator:SetText("Button " .. i)
    separator:SetWidth(350)
    scrollFrame:AddChild(separator)

    scrollFrame:SetFullWidth(true)
    scrollFrame:SetFullHeight(true)
    -- scrollFrame:SetLayout("Fill")
    -- xfr:AddChild(scrollFrame)

    return scrollFrame
    
end

function GuildMapTabOptions(configFrame)
  -- function that draws the widgets for the first tab
  local function DrawGroup1(container)
    
  end
  
  -- function that draws the widgets for the second tab
  local function DrawGroup2(container)
    GuildMapUI:ShowConfigWindow(container)
  end
  
  -- Callback function for OnGroupSelected
  local function SelectGroup(container, event, group)
     container:ReleaseChildren()
     if group == "core" then
        DrawGroup2(container,isStealth())
    elseif group =="extra" then
        extra_settings_menu_render(container)
    elseif group=="dbm" then
        guild_map_DBM_menu_render(container)
    elseif group == "tab2" then
        crossGuildMyTab(container)
     elseif group == "tab3" then
        crossGuildScrolLTab(container)
     end
  end
  
  -- Create the frame container
  local frame = AceGUI:Create("Frame")

--   Add the frame as a global variable under the name `MyGlobalFrameName`
    _G["GuildMapGFrameX"] = frame.frame
    -- Register the global variable `MyGlobalFrameName` as a "special frame"
    -- so that it is closed when the escape key is pressed.
    tinsert(UISpecialFrames, "GuildMapGFrameX")


    local frameHeight=565

    if toc==120000 then
        frameHeight=425
    end
    
    if isStealth() then
        frameHeight=frameHeight+45
    end
 
  frame:SetWidth(495)
  frame:SetHeight(frameHeight)



  frame:SetTitle(GuildMap_Localize("GuildMap Options"))
  frame:SetStatusText(GuildMap_Localize("Discord: `portallz` for bugs"))
  frame:SetCallback("OnClose", function(widget) AceGUI:Release(widget) end)
  -- Fill Layout - the TabGroup widget will fill the whole frame
  frame:SetLayout("Fill")
  
  -- Create the TabGroup
  local tab =  AceGUI:Create("TabGroup")
  tab:SetLayout("Flow")
  -- Setup which tabs to show
--   tab:SetTabs({{text="Core", value="core"}, {text="My Guild", value="tab2"},{text="Other Guilds", value="tab3"}})
-- if DBM then
    -- tab:SetTabs({{text="Core", value="core"}, {text="DBM", value="dbm"}})
-- else
  tab:SetTabs({{text=GuildMap_Localize("Core"), value="core"},{text=GuildMap_Localize("Extra"), value="extra"}})
-- end
  -- Register callback
  tab:SetCallback("OnGroupSelected", SelectGroup)
  -- Set initial Tab (this will fire the OnGroupSelected callback)
  tab:SelectTab("core")
  
  -- add to the frame container
  frame:AddChild(tab)

  return frame

end
