local TempMaxH=0;
local bwidth=nil
local bheight=nil
local bcspace=nil
local brspace=nil
local left=nil
local right=nil
local bottom=nil
local top=nil
local hheight=nil
local hrspace=nil
local hwidth=nil
local hwidthadj=nil
local cols=nil
local nraid=nil
local tBars=nil
local b=nil
local bar=nil
local hdr=nil
local HealBot_TrackNames={};
local i=nil
local h=nil
local z=nil
local t=nil
local x=nil
local xButton=nil
local curcol=nil
local xUnit=nil
local tUnit=nil
local getUnitID=nil
local pUnit=nil
local header=nil
local order = {};
local units = {};
local HealBot_CheckedTargets={};
local name=nil
local subgroup=nil
local online=nil
local class=nil
local TempSort=nil
local MyGroup=0
local numHeaders = 0
local HealBot_headerno=0
local GroupValid=nil
local TargetValid=nil
local HeaderPos={}
local OffsetY = 10;
local OffsetX = 10;
local MaxOffsetY=0;
local HealBot_HeadX={};
local HealBot_HeadY={};
local HealBot_BarX={};
local HealBot_BarY={};
local HealBot_MultiColHoToffset=0;
local HealBot_TrackUnitNames={};
local HealBot_TrackButtons={};
local HealBot_TrackHButtons={};
local HealBot_TrackButtonsH={};
local HealBot_Panel_BlackList={};
local HealBot_UnitGroup={}
local format=format
local ceil=ceil;
local HealBot_AddHeight=4
local HealBot_MyHealTargets={}
local MyHealTargets=nil
local mti=0
local classEN=nil
local uName=nil
local HealBot_MainTanks={};
local HealBot_TempTanks={};
local HealBot_GroupGUID={}
local xGUID = nil
local maxHealDiv=2500

local HealBot_Action_HealGroup = {
    "player",
    "party1",
    "party2",
    "party3",
    "party4",
};

local HealBot_Action_HealButtons = {};

function HealBot_GetMyHealTargets()
    return HealBot_MyHealTargets;
end

function HealBot_Panel_SetBarArrays(bx)
    HealBot_BarX[bx]=0;
    HealBot_BarY[bx]=0;
end

function HealBot_Panel_SetHeadArrays(bx)
    HealBot_HeadX[bx]=0;
    HealBot_HeadY[bx]=0;
end

function HealBot_Panel_SetmaxHealDiv(lvl)
    maxHealDiv=500
    if lvl>76 then
        maxHealDiv=5000
    elseif lvl>70 then
        maxHealDiv=4000
    elseif lvl>60 then
        maxHealDiv=2500
    elseif lvl>45 then
        maxHealDiv=2000
    elseif lvl>30 then
        maxHealDiv=1000
    end
end

function HealBot_Panel_ClearBlackList()
    for x,_ in pairs(HealBot_Panel_BlackList) do
        HealBot_Panel_BlackList[x]=nil;
    end
end

function HealBot_Panel_AddBlackList(hbGUID)
    HealBot_Panel_BlackList[hbGUID]=true;
end

function HealBot_Panel_ClearHealTarget()
    HealBot_MyHealTargets = {}
end

local myGUID=nil
function HealBot_Panel_ToggelHealTarget(hbGUID)
    mti=0
    table.foreach(HealBot_MyHealTargets, function (i,myGUID)
        if myGUID==hbGUID then
            mti=i
        end  
    end)
    if mti>0 then
        table.remove(HealBot_MyHealTargets,mti)
    else
        table.insert(HealBot_MyHealTargets,hbGUID)
    end
end

function HealBot_Panel_RetMyHealTarget(hbGUID)
    mti=0
    table.foreach(HealBot_MyHealTargets, function (i,myGUID)
        if myGUID==hbGUID then
            mti=i
        end  
    end)
    if mti>0 then
        return true
    else
        return false
    end
end
  
function HealBot_Panel_SetMultiColHoToffset(nx)
    HealBot_MultiColHoToffset=nx
end

local thisX=nil

function HealBot_Action_PositionButton(button,OsetX,OsetY,bWidth,bHeight,xHeader)
    brspace=Healbot_Config_Skins.brspace[Healbot_Config_Skins.Current_Skin];
    if xHeader then
        HealBot_headerno=HealBot_headerno+1;
        hheight = ceil(bHeight*0.8)
        hrspace = ceil(brspace*1.4)+3
        hdr=getglobal("HealBot_Action_Header"..HealBot_headerno);
        bar = HealBot_Action_HealthBar(hdr);
        hwidth = bWidth*Healbot_Config_Skins.headwidth[Healbot_Config_Skins.Current_Skin]
        hwidthadj = ceil((bWidth-hwidth)/2);
        thisX=OsetX+hwidthadj+(HealBot_MultiColHoToffset*curcol)
        if HealBot_HeadX[hdr]~=thisX or HealBot_HeadY[hdr]~=format("%s",OsetY)..xHeader then
            HealBot_HeadX[hdr]=thisX
            HealBot_HeadY[hdr]=format("%s",OsetY)..xHeader;
            hdr:ClearAllPoints();
            if HealBot_Config.Panel_Anchor<3 then
                hdr:SetPoint("TOPLEFT","HealBot_Action","TOPLEFT",thisX,-OsetY);
            else
                hdr:SetPoint("TOPRIGHT","HealBot_Action","TOPRIGHT",-thisX,-OsetY);
            end
            bar.txt = getglobal(bar:GetName().."_text");
            bar.txt:SetText(xHeader);
            hdr:Show();
        end
        HealBot_TrackButtonsH[hdr]=nil;
        HealBot_TrackHButtons[hdr]=true;
        OsetY = OsetY+hheight+hrspace;
    else
        thisX=OsetX+(HealBot_MultiColHoToffset*curcol)
        if HealBot_BarX[button]~=thisX or HealBot_BarY[button]~=OsetY then
            HealBot_BarX[button]=thisX
            HealBot_BarY[button]=OsetY;
            button:ClearAllPoints();
            button:SetWidth(bWidth);
            if HealBot_Config.Panel_Anchor<3 then
                button:SetPoint("TOPLEFT","HealBot_Action","TOPLEFT",thisX,-OsetY)
            else
                button:SetPoint("TOPRIGHT","HealBot_Action","TOPRIGHT",-thisX,-OsetY)
            end
            button:Show();
        end
        OsetY = OsetY+bHeight+brspace+HealBot_AddHeight
    end
    return OsetY;
end

local HealBot_AggroBarSize=0
function HealBot_Action_SetAddHeight()
    if Healbot_Config_Skins.ShowAggro[Healbot_Config_Skins.Current_Skin]==0 or Healbot_Config_Skins.ShowAggroBars[Healbot_Config_Skins.Current_Skin]==0 then 
        HealBot_AggroBarSize=0
    else
        HealBot_AggroBarSize=Healbot_Config_Skins.AggroBarSize[Healbot_Config_Skins.Current_Skin]
    end
    if Healbot_Config_Skins.bar2size[Healbot_Config_Skins.Current_Skin]==0 then
        if Healbot_Config_Skins.ShowAggroBars[Healbot_Config_Skins.Current_Skin]==0 then
            HealBot_AddHeight=0
        else
            HealBot_AddHeight=(HealBot_AggroBarSize*2)
        end
    else
        if Healbot_Config_Skins.ShowAggroBars[Healbot_Config_Skins.Current_Skin]==0 then
            HealBot_AddHeight=Healbot_Config_Skins.bar2size[Healbot_Config_Skins.Current_Skin]
        else
            HealBot_AddHeight=Healbot_Config_Skins.bar2size[Healbot_Config_Skins.Current_Skin]+(HealBot_AggroBarSize*2)
        end
    end
end

function HealBot_Action_SetHeightWidth(width,height,bWidth)
    if HealBot_Config.Panel_Anchor==1 then
        if HealBot_Config.PanelAnchorY==-1 or HealBot_Config.PanelAnchorX==-1 then
            left,top = HealBot_Action:GetLeft(),HealBot_Action:GetTop();
            HealBot_Config.PanelAnchorY=top;
            HealBot_Config.PanelAnchorX=left; 
        end
        HealBot_Action:ClearAllPoints();
        HealBot_Action:SetPoint("TOPLEFT","UIParent","BOTTOMLEFT",HealBot_Config.PanelAnchorX,HealBot_Config.PanelAnchorY);
    elseif HealBot_Config.Panel_Anchor==2 then
        if HealBot_Config.PanelAnchorY==-1 or HealBot_Config.PanelAnchorX==-1 then
            left,bottom = HealBot_Action:GetLeft(),HealBot_Action:GetBottom();
            HealBot_Config.PanelAnchorY=bottom
            HealBot_Config.PanelAnchorX=left
        end
        HealBot_Action:ClearAllPoints();
        HealBot_Action:SetPoint("BOTTOMLEFT","UIParent","BOTTOMLEFT",HealBot_Config.PanelAnchorX,HealBot_Config.PanelAnchorY);
    elseif HealBot_Config.Panel_Anchor==3 then
        if HealBot_Config.PanelAnchorY==-1 or HealBot_Config.PanelAnchorX==-1 then
            right,top = HealBot_Action:GetLeft(),HealBot_Action:GetBottom();
            HealBot_Config.PanelAnchorY=top;
            HealBot_Config.PanelAnchorX=right; 
        end
        HealBot_Action:ClearAllPoints();
        HealBot_Action:SetPoint("TOPRIGHT","UIParent","BOTTOMLEFT",HealBot_Config.PanelAnchorX,HealBot_Config.PanelAnchorY);
    elseif HealBot_Config.Panel_Anchor==4 then
        if HealBot_Config.PanelAnchorY==-1 or HealBot_Config.PanelAnchorX==-1 then
            right,bottom = HealBot_Action:GetLeft(),HealBot_Action:GetBottom();
            HealBot_Config.PanelAnchorY=bottom;
            HealBot_Config.PanelAnchorX=right; 
        end
        HealBot_Action:ClearAllPoints();
        HealBot_Action:SetPoint("BOTTOMRIGHT","UIParent","BOTTOMLEFT",HealBot_Config.PanelAnchorX,HealBot_Config.PanelAnchorY);
    end
    HealBot_Action:SetHeight(height);
    if (HealBot_Config.Panel_Anchor<3 and Healbot_Config_Skins.HoTposBar[Healbot_Config_Skins.Current_Skin]==2) or (HealBot_Config.Panel_Anchor>2 and Healbot_Config_Skins.HoTposBar[Healbot_Config_Skins.Current_Skin]==1) then curcol=curcol+1; end;
    HealBot_Action:SetWidth(width+bWidth+10+(HealBot_MultiColHoToffset*curcol))
end

function HealBot_Panel_PartyChanged(showHeaders)

    nraid=GetNumRaidMembers();
    MyHealTargets=nil
    numHeaders = 0
    TempMaxH=0;
    bwidth = Healbot_Config_Skins.bwidth[Healbot_Config_Skins.Current_Skin];
    bheight=Healbot_Config_Skins.bheight[Healbot_Config_Skins.Current_Skin];
    bcspace=Healbot_Config_Skins.bcspace[Healbot_Config_Skins.Current_Skin];
    cols=Healbot_Config_Skins.numcols[Healbot_Config_Skins.Current_Skin];

    for x,_ in pairs(HeaderPos) do
        HeaderPos[x]=nil;
    end
    for x,_ in pairs(HealBot_Action_HealButtons) do
        HealBot_Action_HealButtons[x]=nil;
    end
  
    for x,_ in pairs(HealBot_TrackNames) do
        HealBot_TrackNames[x]=nil;
    end
  
    for x,_ in pairs(HealBot_MainTanks) do
        HealBot_MainTanks[x]=nil;
    end
  
    for x,_ in pairs(HealBot_TempTanks) do
        HealBot_TempTanks[x]=nil;
    end
  
    for xGUID,_ in pairs(HealBot_Panel_BlackList) do
        HealBot_TrackNames[xGUID]=true
    end 
  
    table.foreach(HealBot_MyHealTargets, function (i,xGUID)
        HealBot_TrackNames[xGUID]=true
        MyHealTargets=true
    end)
  
    HealBot_headerno=0;
    i=0;
    h=1;
    z=1;
    
    if HealBot_Config.SelfHeals==1 then
        if showHeaders then 
            HeaderPos[i+1] = HEALBOT_OPTIONS_SELFHEALS 
            GroupValid=i
        end
        xUnit="player";
        uName=UnitName(xUnit);
        if not HealBot_TrackNames[HealBot_PlayerGUID] and uName and uName~=HEALBOT_WORDS_UNKNOWN then
            i = i+1;
            HealBot_UnitName[HealBot_PlayerGUID] = uName;
            HealBot_TrackNames[HealBot_PlayerGUID]=true;
            b=HealBot_Action_SetHealButton(i,xUnit,HealBot_PlayerGUID);
            if b then
                HealBot_TrackButtons[b]=nil
                HealBot_TrackUnitNames[HealBot_PlayerGUID]=nil
                table.insert(HealBot_Action_HealButtons,b)
            end
        end
        if HealBot_Config.SelfPet==1 then
            xUnit="pet";
            xGUID=HealBot_UnitGUID(xUnit)
            uName=UnitName(xUnit);
            if xGUID and not HealBot_TrackNames[xGUID] and uName and not HealBot_retIsInVehicle("player") and uName~=HEALBOT_WORDS_UNKNOWN then
                i = i+1;
                HealBot_UnitName[xGUID] = uName;
                HealBot_TrackNames[xGUID]=true;
                b=HealBot_Action_SetHealButton(i,xUnit,xGUID);
                if b then
                    HealBot_TrackButtons[b]=nil
                    HealBot_TrackUnitNames[xGUID]=nil
                    table.insert(HealBot_Action_HealButtons,b)
                end
            end
        end
        if showHeaders and i>GroupValid then numHeaders=numHeaders+1 end
    end
    
    if HealBot_Config.TankHeals==1 and nraid>0 then
        if showHeaders then 
            HeaderPos[i+1] = HEALBOT_OPTIONS_TANKHEALS 
            GroupValid=i
        end
        for j=1,10 do
            xGUID = HealBot_retHealBot_MainTanks(j);
            if xGUID then 
                HealBot_MainTanks[xGUID]=true 
                HealBot_TempTanks[xGUID]=true 
            end
        end
        for k=1,40 do
            xGUID=UnitGUID("raid"..k);
            if xGUID and HealBot_MainTanks[xGUID] then
                HealBot_MainTanks[xGUID]="raid"..k
                HealBot_TempTanks[xGUID]=nil 
            end
        end
        for xGUID,_ in pairs(HealBot_TempTanks) do
            HealBot_MainTanks[xGUID]=nil
        end
        for xGUID,xUnit in pairs(HealBot_MainTanks) do
            i = i+1;
            HealBot_UnitName[xGUID] = UnitName(xUnit);
            HealBot_TrackNames[xGUID]=true;
            b=HealBot_Action_SetHealButton(i,xUnit,xGUID);
            if b then
                HealBot_TrackButtons[b]=nil
                HealBot_TrackUnitNames[xGUID]=nil
                table.insert(HealBot_Action_HealButtons,b)
            end
        end
        if showHeaders and i>GroupValid then numHeaders=numHeaders+1 end
    end
    
    MyGroup=0
    if HealBot_Config.GroupHeals==1 then
        if showHeaders then 
            MyGroup=i+1
            HeaderPos[MyGroup] = HEALBOT_OPTIONS_GROUPHEALS 
            GroupValid=i
        end
        for _,xUnit in ipairs(HealBot_Action_HealGroup) do
            uName=UnitName(xUnit);
            xGUID=HealBot_UnitGUID(xUnit)
            if xGUID and uName and not HealBot_TrackNames[xGUID] and uName~=HEALBOT_WORDS_UNKNOWN then
                if nraid>0 and uName~=HealBot_PlayerName then 
                    xUnit=HealBot_RaidUnit(xUnit,xGUID) 
                end
                i = i+1;
                HealBot_UnitName[xGUID] = uName;
                HealBot_TrackNames[xGUID]=true;
                b=HealBot_Action_SetHealButton(i,xUnit,xGUID);
                if b then
                    HealBot_TrackButtons[b]=nil
                    HealBot_TrackUnitNames[xGUID]=nil
                    table.insert(HealBot_Action_HealButtons,b)
                end
            end
        end
        if HealBot_Config.SelfPet==1 then
            xUnit="pet";
            xGUID=HealBot_UnitGUID(xUnit)
            uName=UnitName(xUnit);
            if xGUID and not HealBot_TrackNames[xGUID] and uName and not HealBot_retIsInVehicle("player") and uName~=HEALBOT_WORDS_UNKNOWN then
                i = i+1;
                HealBot_UnitName[xGUID] = uName;
                HealBot_TrackNames[xGUID]=true;
                b=HealBot_Action_SetHealButton(i,xUnit,xGUID);
                if b then
                    HealBot_TrackButtons[b]=nil
                    HealBot_TrackUnitNames[xGUID]=nil
                    table.insert(HealBot_Action_HealButtons,b)
                end
            end
        end
        if showHeaders and i>GroupValid then 
            numHeaders=numHeaders+1 
        else
            MyGroup=0
        end
    end
    
    if HealBot_Config.SetFocusBar==1 and UnitExists("focus") and not UnitIsEnemy("focus", "player") then
        xGUID=HealBot_UnitGUID("focus")
        if xGUID and not HealBot_Panel_RetMyHealTarget(xGUID) and not HealBot_TrackNames[xGUID] then 
            HealBot_TrackNames[xGUID]=true;
            table.insert(HealBot_MyHealTargets,xGUID)
            MyHealTargets=true
        end
    end
  
    if MyHealTargets then
        if showHeaders and (HealBot_Config.ShowMyTargetsList==1 or MyGroup==0) then 
            HeaderPos[i+1] = HEALBOT_OPTIONS_MYTARGET 
            GroupValid=i
        end
        table.foreach(HealBot_MyHealTargets, function (index,xGUID)
        --  HealBot_AddDebug("In MyHealTargets - uName="..uName)
            xUnit=HealBot_RaidUnit("unknown",xGUID) 
            if UnitExists(xUnit) then
                i = i+1;
                HealBot_UnitName[xGUID] = UnitName(xUnit);
                b=HealBot_Action_SetHealButton(i,xUnit,xGUID);
                if b then
                    HealBot_TrackButtons[b]=nil
                    HealBot_TrackUnitNames[xGUID]=nil
                    table.insert(HealBot_Action_HealButtons,b)
                end
            else
                HealBot_Panel_ToggelHealTarget(xGUID)
            end
        end)
        if showHeaders and i>GroupValid then numHeaders=numHeaders+1 end
    end

    if HealBot_Config.EmergencyHeals==1 then
        for x,_ in pairs(order) do
            order[x]=nil;
        end
        for x,_ in pairs(units) do
            units[x]=nil;
        end
        if showHeaders then
            GroupValid=i
            if HealBot_Config.ExtraOrder==1 then
                HeaderPos[i+1] = HEALBOT_OPTIONS_EMERGENCYHEALS
                numHeaders=numHeaders+1;
            end
        end
        if HealBot_Config.EmergIncMonitor==1 then
            if nraid>0 then
                for j=1,40 do
                    xUnit = "raid"..j;
                    xGUID=UnitGUID(xUnit)
                    uName=UnitName(xUnit);
                    name, _, subgroup, _, class, _, _, online, _, _, _ = GetRaidRosterInfo(j);
                    if xGUID then
                        HealBot_GroupGUID[xGUID]=subgroup
                        if (not online and not HealBot_Action_retUnitOffline(xGUID)) or HealBot_Action_retUnitOffline(xGUID) then
                            HealBot_Action_UnitIsOffline(xGUID)
                        end
                        if uName==HealBot_PlayerName then
                            xUnit="player"
                            if MyGroup>0 then
                                HeaderPos[MyGroup] = HEALBOT_OPTIONS_GROUPHEALS.." "..subgroup;
                            end
                        end
                    end
                    if xGUID and uName and not HealBot_TrackNames[xGUID] and uName~=HEALBOT_WORDS_UNKNOWN then
                        if HealBot_Config.ExtraIncGroup[subgroup] and class then
                            if HealBot_Config.ExtraOrder==1 then
                                order[xUnit] = name;
                            elseif HealBot_Config.ExtraOrder==2 then
                                order[xUnit] = class;
                            elseif HealBot_Config.ExtraOrder==3 then
                                order[xUnit] = subgroup;
                            else
                                order[xUnit] = 0-UnitHealthMax(xUnit);
                                if UnitHealthMax(xUnit)>TempMaxH then TempMaxH=UnitHealthMax(xUnit); end
                            end
                            table.insert(units,xUnit);
                            HealBot_UnitGroup[xUnit]=subgroup
                            HealBot_UnitName[xGUID] = uName;
                            HealBot_TrackNames[xGUID]=true;
                        end
                    end
                end
            else
                for _,xUnit in ipairs(HealBot_Action_HealGroup) do
                    uName=UnitName(xUnit);
                    xGUID=HealBot_UnitGUID(xUnit)
                    if xGUID then
                        HealBot_GroupGUID[xGUID]=1
                        if (not UnitIsConnected(xUnit) and not HealBot_Action_retUnitOffline(xGUID)) or HealBot_Action_retUnitOffline(xGUID) then
                            HealBot_Action_UnitIsOffline(xGUID)
                        end
                    end
                    if xGUID and uName and not HealBot_TrackNames[xGUID] and uName~=HEALBOT_WORDS_UNKNOWN then
                        class,_=UnitClass(xUnit)
                        name = uName;
                        subgroup = 1
                        if HealBot_Config.ExtraIncGroup[subgroup] and class then
                            if HealBot_Config.ExtraOrder==1 then
                                order[xUnit] = name;
                            elseif HealBot_Config.ExtraOrder==2 then
                                order[xUnit] = class;
                            elseif HealBot_Config.ExtraOrder==3 then
                                order[xUnit] = subgroup;
                            else
                                order[xUnit] = 0-UnitHealthMax(xUnit);
                                if UnitHealthMax(xUnit)>TempMaxH then TempMaxH=UnitHealthMax(xUnit); end
                            end
                            table.insert(units,xUnit);
                            HealBot_UnitGroup[xUnit]=subgroup
                            HealBot_UnitName[xGUID] = uName;
                            HealBot_TrackNames[xGUID]=true;
                        end
                    end
                end
            end
        else
            if nraid>0 then
                for j=1,40 do
                    xUnit = "raid"..j;
                    xGUID=UnitGUID(xUnit)
                    uName=UnitName(xUnit);
                    name, _, subgroup, _, class, _, _, online, _, _, _ = GetRaidRosterInfo(j);
                    if xGUID then
                        HealBot_GroupGUID[xGUID]=subgroup
                        if (not online and not HealBot_Action_retUnitOffline(xGUID)) or HealBot_Action_retUnitOffline(xGUID) then
                            HealBot_Action_UnitIsOffline(xGUID)
                        end
                        if uName==HealBot_PlayerName then
                            xUnit="player"
                            if MyGroup>0 then
                                HeaderPos[MyGroup] = HEALBOT_OPTIONS_GROUPHEALS.." "..subgroup;
                            end
                        end
                    end
                    if xGUID and uName and not HealBot_TrackNames[xGUID] and uName~=HEALBOT_WORDS_UNKNOWN then
                        _,classEN=UnitClass(xUnit)
                        if HealBot_Config.ExtraIncGroup[subgroup] and class and HealBot_EmergInc[strsub(classEN,1,4)]==1 then
                            if HealBot_Config.ExtraOrder==1 then
                                order[xUnit] = name;
                            elseif HealBot_Config.ExtraOrder==2 then
                                order[xUnit] = class;
                            elseif HealBot_Config.ExtraOrder==3 then
                                order[xUnit] = subgroup;
                            else
                                order[xUnit] = 0-UnitHealthMax(xUnit);
                                if UnitHealthMax(xUnit)>TempMaxH then TempMaxH=UnitHealthMax(xUnit); end
                            end
                            table.insert(units,xUnit);
                            HealBot_UnitGroup[xUnit]=subgroup
                            HealBot_UnitName[xGUID] = uName;
                            HealBot_TrackNames[xGUID]=true;
                        end
                    end
                end
            else
                for _,xUnit in ipairs(HealBot_Action_HealGroup) do
                    class,classEN = UnitClass(xUnit);
                    xGUID=HealBot_UnitGUID(xUnit)
                    uName=UnitName(xUnit);
                    if xGUID then
                        HealBot_GroupGUID[xGUID]=1
                        if (not UnitIsConnected(xUnit) and not HealBot_Action_retUnitOffline(xGUID)) or HealBot_Action_retUnitOffline(xGUID) then
                            HealBot_Action_UnitIsOffline(xGUID)
                        end
                    end
                    if xGUID and uName and class and not HealBot_TrackNames[xGUID] and uName~=HEALBOT_WORDS_UNKNOWN then
                        name = uName;
                        subgroup = 1;
                        if HealBot_Config.ExtraIncGroup[subgroup] and HealBot_EmergInc[strsub(classEN,1,4)]==1 then
                            if HealBot_Config.ExtraOrder==1 then
                                order[xUnit] = name;
                            elseif HealBot_Config.ExtraOrder==2 then
                                order[xUnit] = class;
                            elseif HealBot_Config.ExtraOrder==3 then
                                order[xUnit] = subgroup;
                            else
                                order[xUnit] = 0-UnitHealthMax(xUnit);
                                if UnitHealthMax(xUnit)>TempMaxH then TempMaxH=UnitHealthMax(xUnit); end
                            end
                            table.insert(units,xUnit);
                            HealBot_UnitGroup[xUnit]=subgroup
                            HealBot_UnitName[xGUID] = uName;
                            HealBot_TrackNames[xGUID]=true;
                        end
                    end
                end
            end
        end
        table.sort(units,function (a,b)
            if order[a]<order[b] then return true end
            if order[a]>order[b] then return false end
            return a<b
        end)
        TempMaxH=ceil(TempMaxH/maxHealDiv)*maxHealDiv;
        TempSort="init"

        for j=1,40 do
            if not units[j] then break end
            xUnit=units[j];
            xGUID=UnitGUID(xUnit)
            uName = HealBot_UnitName[xGUID];
            if showHeaders then
                _,classEN = UnitClass(xUnit);
                if HealBot_Config.ExtraOrder==2 and TempSort~=classEN then 
                    TempSort=classEN
                    HeaderPos[i+1] = classEN
                    numHeaders=numHeaders+1;
                end
                if HealBot_Config.ExtraOrder==3 and TempSort~=HealBot_UnitGroup[xUnit] then
                    TempSort=HealBot_UnitGroup[xUnit]
                    HeaderPos[i+1] = HEALBOT_OPTIONS_GROUPHEALS.." "..TempSort
                    numHeaders=numHeaders+1;
                end
                if HealBot_Config.ExtraOrder==4 and TempMaxH>UnitHealthMax(xUnit) then
                    TempMaxH=TempMaxH-maxHealDiv
                    HeaderPos[i+1] = ">"..format("%s",(TempMaxH/1000)).."k"
                    numHeaders=numHeaders+1;
                end
            end
            i = i+1;
            b=HealBot_Action_SetHealButton(i,xUnit,xGUID);
            if b then
                HealBot_TrackButtons[b]=nil
                HealBot_TrackUnitNames[xGUID]=nil
                table.insert(HealBot_Action_HealButtons,b)
            end
        end
        if showHeaders and i==GroupValid+1 then HeaderPos[i+1] = nil end
    else
        if nraid>0 then
            for j=1,40 do
                xUnit = "raid"..j;
                xGUID=UnitGUID(xUnit)
                if xGUID then
                    _, _, subgroup, _, _, _, _, online, _, _, _ = GetRaidRosterInfo(j);
                    HealBot_GroupGUID[xGUID]=subgroup
                    if (not online and not HealBot_Action_retUnitOffline(xGUID)) or HealBot_Action_retUnitOffline(xGUID) then
                        HealBot_Action_UnitIsOffline(xGUID)
                    end
                end
            end
        else
            for _,xUnit in ipairs(HealBot_Action_HealGroup) do
                xGUID=HealBot_UnitGUID(xUnit)
                if xGUID then
                    if (not UnitIsConnected(xUnit) and not HealBot_Action_retUnitOffline(xGUID)) or HealBot_Action_retUnitOffline(xGUID) then
                        HealBot_Action_UnitIsOffline(xGUID)
                    end
                    HealBot_GroupGUID[xGUID]=1
                end
            end
        end
    end
    
    if HealBot_Config.PetHeals==1 then
        for x,_ in pairs(HealBot_CheckedTargets) do
            HealBot_CheckedTargets[x]=nil;
        end
        if showHeaders then 
            HeaderPos[i+1] = HEALBOT_OPTIONS_PETHEALS 
            GroupValid=i
        end
        xUnit="pet"
        pUnit="player"
        xGUID=HealBot_UnitGUID(xUnit)
        uName=UnitName(xUnit);
        if xGUID and not HealBot_TrackNames[xGUID] and not HealBot_CheckedTargets[xGUID] and not HealBot_retIsInVehicle(pUnit) and uName and uName~=HEALBOT_WORDS_UNKNOWN then
            i = i+1;
            HealBot_UnitName[xGUID] = uName;
            b=HealBot_Action_SetHealButton(i,xUnit,xGUID);
            if b then
                HealBot_TrackButtons[b]=nil
                HealBot_TrackUnitNames[xGUID]=nil
                table.insert(HealBot_Action_HealButtons,b)
                HealBot_GroupGUID[xGUID]=HealBot_GroupGUID[HealBot_PlayerGUID]
            end
            HealBot_CheckedTargets[xGUID]=true;
        end
        if nraid>0 then
            for j=1,40 do
                xUnit="raidpet"..j;
                xGUID=HealBot_UnitGUID(xUnit)
                pUnit="raid"..j;
                uName=UnitName(xUnit);
                if xGUID and not HealBot_TrackNames[xGUID] and not HealBot_CheckedTargets[xGUID] and HealBot_TrackNames[UnitGUID(pUnit)] and not HealBot_retIsInVehicle(pUnit) and uName and uName~=HEALBOT_WORDS_UNKNOWN then
                    i = i+1;
                    HealBot_UnitName[xGUID] = uName;
                    b=HealBot_Action_SetHealButton(i,xUnit,xGUID);
                    if b then
                        HealBot_TrackButtons[b]=nil
                        HealBot_TrackUnitNames[xGUID]=nil
                        table.insert(HealBot_Action_HealButtons,b)
                        HealBot_GroupGUID[xGUID]=HealBot_GroupGUID[HealBot_UnitGUID(pUnit)]
                    else
                        i=i-1
                    end
                    HealBot_CheckedTargets[xGUID]=true;
                end
                if i>56 then break end
            end
        else
            for j=1,4 do
                xUnit="partypet"..j;
                xGUID=HealBot_UnitGUID(xUnit)
                pUnit="party"..j;
                uName=UnitName(xUnit);
                if xGUID and not HealBot_TrackNames[xGUID] and not HealBot_CheckedTargets[xGUID] and HealBot_TrackNames[UnitGUID(pUnit)] and not HealBot_retIsInVehicle(pUnit) and uName and uName~=HEALBOT_WORDS_UNKNOWN then
                    i = i+1;
                    HealBot_UnitName[xGUID] = uName;
                    b=HealBot_Action_SetHealButton(i,xUnit,xGUID);
                    if b then
                        HealBot_TrackButtons[b]=nil
                        HealBot_TrackUnitNames[xGUID]=nil
                        table.insert(HealBot_Action_HealButtons,b)
                        HealBot_GroupGUID[xGUID]=HealBot_GroupGUID[HealBot_UnitGUID(pUnit)]
                    else
                        i=i-1
                    end
                    HealBot_CheckedTargets[xGUID]=true;
                end
            end
        end
        if showHeaders and i>GroupValid then numHeaders=numHeaders+1 end
    end

    
    if HealBot_Config.VehicleHeals==1 then
        for x,_ in pairs(HealBot_CheckedTargets) do
            HealBot_CheckedTargets[x]=nil;
        end
        if showHeaders then 
            HeaderPos[i+1] = HEALBOT_VEHICLE 
            GroupValid=i
        end
        xUnit="pet"
        pUnit="player"
        xGUID=HealBot_UnitGUID(xUnit)
        uName=UnitName(xUnit);
        if xGUID and not HealBot_TrackNames[xGUID] and not HealBot_CheckedTargets[xGUID] and HealBot_retIsInVehicle(pUnit) and uName and uName~=HEALBOT_WORDS_UNKNOWN then
            i = i+1;
            HealBot_UnitName[xGUID] = uName;
            b=HealBot_Action_SetHealButton(i,xUnit,xGUID);
            if b then
                HealBot_TrackButtons[b]=nil
                HealBot_TrackUnitNames[xGUID]=nil
                table.insert(HealBot_Action_HealButtons,b)
            end
            HealBot_CheckedTargets[xGUID]=true;
        end
        if nraid>0 then
            for j=1,40 do
                xUnit="raidpet"..j;
                xGUID=HealBot_UnitGUID(xUnit)
                pUnit="raid"..j;
                uName=UnitName(xUnit);
                if xGUID and not HealBot_TrackNames[xGUID] and not HealBot_CheckedTargets[xGUID] and HealBot_TrackNames[UnitGUID(pUnit)] and HealBot_retIsInVehicle(pUnit) and uName and uName~=HEALBOT_WORDS_UNKNOWN then
                    i = i+1;
                    HealBot_UnitName[xGUID] = uName;
                    b=HealBot_Action_SetHealButton(i,xUnit,xGUID);
                    if b then
                        HealBot_TrackButtons[b]=nil
                        HealBot_TrackUnitNames[xGUID]=nil
                        table.insert(HealBot_Action_HealButtons,b)
                    else
                        i=i-1
                    end
                    HealBot_CheckedTargets[xGUID]=true;
                end
                if i>56 then break end
            end
        else
            for j=1,4 do
                xUnit="partypet"..j;
                xGUID=HealBot_UnitGUID(xUnit)
                pUnit="party"..j;
                uName=UnitName(xUnit);
                if xGUID and not HealBot_TrackNames[xGUID] and not HealBot_CheckedTargets[xGUID] and HealBot_TrackNames[UnitGUID(pUnit)] and HealBot_retIsInVehicle(pUnit) and uName and uName~=HEALBOT_WORDS_UNKNOWN then
                    i = i+1;
                    HealBot_UnitName[xGUID] = uName;
                    b=HealBot_Action_SetHealButton(i,xUnit,xGUID);
                    if b then
                        HealBot_TrackButtons[b]=nil
                        HealBot_TrackUnitNames[xGUID]=nil
                        table.insert(HealBot_Action_HealButtons,b)
                    else
                        i=i-1
                    end
                    HealBot_CheckedTargets[xGUID]=true;
                end
            end
        end
        if showHeaders and i>GroupValid then numHeaders=numHeaders+1 end
    end
    
    
    if HealBot_Config.TargetHeals==1 and not HealBot_IsFighting then
        if (UnitIsFriend("player","target")) then
            uName=UnitName("target")
            TargetValid=false
            if uName==HealBot_PlayerName then 
                if HealBot_Config.TargetIncSelf==1 then TargetValid=true end
            elseif UnitInParty("target") then
                if HealBot_Config.TargetIncGroup==1 then TargetValid=true end
            elseif UnitInRaid("target") then 
                if HealBot_Config.TargetIncRaid==1 then TargetValid=true end
            elseif UnitPlayerOrPetInParty("target") or UnitPlayerOrPetInRaid("target") then
                if HealBot_Config.TargetIncPet==1 then TargetValid=true end
            else
                TargetValid=true
            end
            if TargetValid and not HealBot_Panel_BlackList[HealBot_UnitGUID("target")] then

                if showHeaders then HeaderPos[i+1] = HEALBOT_OPTIONS_TARGETHEALS end
                xUnit="target";
                xGUID=HealBot_UnitGUID(xUnit)
                if xGUID and HealBot_MayHeal(xUnit, uName) then
                    HealBot_UnitName[xGUID] = uName;    
                    b=HealBot_Action_SetTargetHealButton(xUnit,xGUID);
                    if b then
                        HealBot_TrackButtons[b]=nil
                        HealBot_TrackUnitNames[HealBot_UnitGUID("target")]=nil
                        table.insert(HealBot_Action_HealButtons,b)
                        if showHeaders then numHeaders=numHeaders+1 end
                    end
                end
            end
        end
    end
    
    for xGUID,xUnit in pairs(HealBot_TrackUnitNames) do
        if HealBot_Action_retAggro(xGUID) then HealBot_Action_UpdateAggro(xUnit,false,nil,xGUID) end
        HealBot_TrackUnitNames[xGUID]=nil
        HealBot_Action_RemoveMember(xGUID)
    end
  
    i=0
    if HealBot_Config.Panel_Anchor<3 then
        curcol=2-Healbot_Config_Skins.HoTposBar[Healbot_Config_Skins.Current_Skin]
    else
        curcol=2-(3-Healbot_Config_Skins.HoTposBar[Healbot_Config_Skins.Current_Skin])
    end
    z=1;
    OffsetY = 10 + HealBot_AggroBarSize;
    OffsetX = 10;
    MaxOffsetY=0;
  
    if showHeaders then 
        h=0
        table.foreach(HealBot_Action_HealButtons, function (x,xButton)
            uName=UnitName(xButton.unit);
            if uName then
                i=i+1
                if HeaderPos[i] then
                    h=h+1;
                    header=HeaderPos[i];
                    if h>cols then
                        if MaxOffsetY<OffsetY then MaxOffsetY = OffsetY; end
                        OffsetY = 10 + HealBot_AggroBarSize;
                        OffsetX = OffsetX + bwidth+bcspace; 
                        h=1;
                        curcol=curcol+1
                    end
                    OffsetY = HealBot_Action_PositionButton(nil,OffsetX,OffsetY,bwidth,bheight,header,curcol);
                end
                OffsetY = HealBot_Action_PositionButton(xButton,OffsetX,OffsetY,bwidth,bheight,nil,curcol);
            end
        end)
    else
        h=1
            tBars=table.getn(HealBot_Action_HealButtons)
            table.foreach(HealBot_Action_HealButtons, function (x,xButton)
            uName=UnitName(xButton.unit);
            if uName then
                i=i+1
                OffsetY = HealBot_Action_PositionButton(xButton,OffsetX,OffsetY,bwidth,bheight,nil,curcol)
                if h==ceil((tBars)/cols) and z<tBars then
                    h=0;
                    if MaxOffsetY<OffsetY then MaxOffsetY = OffsetY; end
                    OffsetY = 10 + HealBot_AggroBarSize;
                    OffsetX = OffsetX + bwidth+bcspace; 
                    curcol=curcol+1;
                end
        
                z=z+1
                h=h+1;
            end
        end)
    end

    for xButton,_ in pairs(HealBot_TrackButtonsH) do
        xButton:Hide();
        HealBot_HeadY[xButton]="0"
        HealBot_TrackButtonsH[xButton]=nil;
    end
    for xButton,_ in pairs(HealBot_TrackButtons) do
        xButton:Hide();
        HealBot_Panel_SetBarArrays(xButton)
        HealBot_TrackButtons[xButton]=nil;
    end
    for xUnit,xButton in pairs(HealBot_Unit_Button) do
        if UnitExists(xUnit) then
            xGUID=HealBot_UnitGUID(xUnit)
            HealBot_TrackButtons[xButton]=true;
            HealBot_TrackUnitNames[xGUID]=xUnit;
            if HealBot_HoT_Active_Button[xGUID] then
                if HealBot_HoT_Active_Button[xGUID]~=xButton then
                    HealBot_HoT_MoveIcon(HealBot_HoT_Active_Button[xGUID], xButton, xGUID)
                    HealBot_HoT_Active_Button[xGUID]=xButton  
                end
            end
        else
            HealBot_Unit_Button[xUnit]=nil
        end
    end
  
    for xButton,_ in pairs(HealBot_TrackHButtons) do
        HealBot_TrackButtonsH[xButton]=true;
    end

    if MaxOffsetY<OffsetY then MaxOffsetY = OffsetY; end

    if HealBot_Config.HideOptions==1 then
        HealBot_Action_OptionsButton:Hide();
    else
        HealBot_Action_OptionsButton:SetPoint("BOTTOM","HealBot_Action","BOTTOM",0,10);
        HealBot_Action_OptionsButton:Show();
        MaxOffsetY = MaxOffsetY+30;
    end  

    HealBot_Action_SetHeightWidth(OffsetX, MaxOffsetY+10, bwidth,curcol);
    HealBot_Action_RefreshButtons();
    if Healbot_Config_Skins.ShowRaidIcon[Healbot_Config_Skins.Current_Skin]==1 then HealBot_OnEvent_RaidTargetUpdate(nil) end
  
end

function HealBot_Action_RemoveMember(hbGUID)
    HealBot_ClearHealsIn(hbGUID)
    HealBot_Action_LocalArrays(hbGUID)
    if HealBot_GroupGUID[hbGUID] then HealBot_GroupGUID[hbGUID]=nil end
end

function HealBot_RetGroupGUIDs(hbGUID)
    if not HealBot_GroupGUID[hbGUID] then 
        z=1
    else
        z=HealBot_GroupGUID[hbGUID]
    end
    y=hbGUID
    for xGUID,group in pairs(HealBot_GroupGUID) do
        if group==z and xGUID~=hbGUID then
            y=y..":"..xGUID
        end
    end
    return y
end
