changeset 12:0deef890ec99

Updated version
author ShadowTheAge
date Wed, 11 Mar 2015 22:51:00 +0300
parents 421508c17712
children 1f68e8154947
files .pkgmeta CrossRealmAssist.lua
diffstat 2 files changed, 399 insertions(+), 245 deletions(-) [+]
line wrap: on
line diff
--- a/.pkgmeta	Tue Mar 10 00:16:23 2015 +0300
+++ b/.pkgmeta	Wed Mar 11 22:51:00 2015 +0300
@@ -7,8 +7,9 @@
   url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceConsole-3.0
  libs/AceEvent-3.0:
   url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceEvent-3.0
- libs/AceGUI-3.0:
-  url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceGUI-3.0
+ libs/lib-st:
+  url: svn://svn.wowace.com/wow/lib-st/mainline/trunk
+  tag: latest
  libs/AceTimer-3.0:
   url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceTimer-3.0
  libs/LibStub:
--- a/CrossRealmAssist.lua	Tue Mar 10 00:16:23 2015 +0300
+++ b/CrossRealmAssist.lua	Wed Mar 11 22:51:00 2015 +0300
@@ -1,29 +1,68 @@
 CrossRealmAssist = LibStub("AceAddon-3.0"):NewAddon("CrossRealmAssist", "AceEvent-3.0", "AceConsole-3.0", "AceTimer-3.0")
-local AceGUI = LibStub("AceGUI-3.0")
 local addon = CrossRealmAssist;
 local wholib = LibStub:GetLibrary('LibWho-2.0'):Library()
+local ScrollingTable = LibStub("ScrollingTable");
 
-local homeRealm, realmSep, gui, btRefresh, btQuick, btManual, lbRealm, lbStatus, playerName
+local homeRealm, realmSep, gui, btRefresh, btQuick, btManual, lbRealm, lbStatus, playerName, lfgui, lfgTabSelected, lfgTable, lbThrottle
 
+local tabs = {}
 local curRealmStat
 local scanstate=0
 local recentRealms={}
+local recentgroups={}
 local active=false
 
 local lfgGroups={
     6, -- Custom
     10, -- Ashran
     1, -- Quests
-    3, -- Raids
-    8 -- BGs
+    3 -- Raids
 }
 
-local lfgTabs
+local StatusTable = {
+    ["invited"]="Invited",
+    ["declined"]="Declined",
+    ["timedout"]="Timed out",
+    ["applied"]="Applied",
+    ["cancelled"]="Join cancelled",
+    ["inviteaccepted"]="Joined",
+    ["_init"]="Join request"
+}
+
 local curLfgGroup
 local sheduledScan
 local wasInGroup
-local wasInInstance
-local lfgScanInProgress=false
+local inInstance
+
+
+-- Utils functions
+
+local function PlayerName(fullname)
+    fullname = fullname or "???-???"
+    local name, realm = strsplit(realmSep, fullname)
+    realm = realm or homeRealm;
+    return name, realm;
+end
+
+local function canJoinGroup()
+    return (not IsInGroup()) or (UnitIsGroupLeader('player') and not IsInRaid())
+end
+
+local function sortByWeight(a,b)
+    return b.weight < a.weight
+end
+
+
+-- UI functions
+
+local function createIcon(owner, icon, id)
+    local image = owner:CreateTexture(nil, "BACKGROUND")
+    image:SetWidth(16)
+    image:SetHeight(16)
+    image:SetTexture(icon)
+    image:SetPoint("TOPLEFT",owner,"TOPLEFT",id*16,0)
+    return image
+end
 
 local function setupWidget(widget, parameters, x, y)
     if parameters then
@@ -53,17 +92,191 @@
     widget:SetScript("OnLeave", HideTooltip)
 end
 
-function addon:OnInitialize()
+local function SelectLfgTab(tab)
+    PanelTemplates_DeselectTab(lfgTabSelected)
+    lfgTabSelected = tab
+    addon.LfgScan(tab.searchID)
+    PanelTemplates_SelectTab(lfgTabSelected)
+end
 
+local function realmToolip()
+    if not curRealmStat then return end
+    local players = curRealmStat.players;
+    local threshold = curRealmStat.threshold
+    GameTooltip:AddLine("Players in zone: "..players)
+    if not curRealmStat.complete then
+        GameTooltip:AppendText("+")
+    end
+    for i=1,curRealmStat.realms do
+        local data = curRealmStat[i]
+        local percent = math.ceil(100 * data.count / players - 0.5) .. "%";
+        if data.count >= threshold then
+            GameTooltip:AddDoubleLine(data.realm, percent, 0,1,0,0,1,0)
+        else
+            GameTooltip:AddDoubleLine(data.realm, percent, 0.5,0.5,0.5,0.5,0.5,0.5)
+        end
+    end
 end
 
+
+
+
+
+
+
+-- LFG list data providers, filters and tooltips
+
+local lfgScanInProgress=false
+local hasLfgListChanges=false
+
+local function addTooltipLineIcon(predicat, text, icon, r, g, b, wrap)
+    if predicat then
+        GameTooltip:AddLine(text, r, g, b, wrap)
+        if icon then GameTooltip:AddTexture(icon) end
+    end
+end
+
+local function WeightLfgItem(id, forAutoJoin)
+    local _, action, caption, desc, voice, ilvl, time, bnetfr, charfr, guild, delisted, fullname, pcount, autoinv = C_LFGList.GetSearchResultInfo(id)
+    if delisted then return 0 end
+    local name,realm = PlayerName(fullname);
+    if forAutoJoin then
+        if not autoinv or pcount >= 35 or pcount <= 5 or recentgroups[fullname] then return 0 end
+    end
+
+    local autoinvWeight = autoinv and 5 or 2
+
+    local visCoef = 1
+    if recentgroups[fullname] then
+        local ago = GetTime() - recentgroups[fullname].time;
+        visCoef = math.min(1,ago/600)
+    end
+
+    local leaderRealm = 3 -- recently visited realms
+    if (realm ~= "???") then leaderRealm = (5 - (recentRealms[realm] or 0)) end
+
+    local countWeight = 4 -- count weight
+    if pcount >= 39 or pcount <= 1 then countWeight = 1
+    elseif pcount >= 35 or pcount <= 4 then countWeight = 2
+    elseif pcount >= 30 or pcount <= 10 then countWeight = 3
+    else countWeight = 4 end
+
+    local ageWeight = 2
+    if time > 1200 then ageWeight = 4
+    elseif time > 300 then ageWeight = 3 end
+
+    return leaderRealm * countWeight * visCoef * autoinvWeight * ageWeight;
+end
+
+local function ShowLfgInfo(rowFrame, cellFrame, data, cols, row, realrow, column, scrollingTable, ...)
+    if not realrow then return end
+    local rowdata = scrollingTable:GetRow(realrow);
+    local _, action, caption, desc, voice, ilvl, time, bnetfr, charfr, guild, delisted, fullname, pcount, autoinv = C_LFGList.GetSearchResultInfo(rowdata.id)
+    local friends = bnetfr+charfr+guild
+    GameTooltip:SetOwner(rowFrame, "ANCHOR_BOTTOMLEFT",-10,25)
+    GameTooltip:ClearLines()
+    GameTooltip:AddLine(caption,1,1,1)
+    addTooltipLineIcon(desc ~= "", desc, nil, 0.5, 0.5, 0.5, true)
+    local name, realm = PlayerName(fullname)
+    GameTooltip:AddDoubleLine("Leader:",name)
+    GameTooltip:AddDoubleLine("Leader realm:",realm)
+    GameTooltip:AddLine(" ")
+    GameTooltip:AddDoubleLine("Players:",pcount)
+    addTooltipLineIcon(ilvl > 0, "Min. ilvl: "..ilvl, READY_CHECK_WAITING_TEXTURE, 1, 1, 0)
+    addTooltipLineIcon(voice ~= "", "Voice: "..voice, READY_CHECK_WAITING_TEXTURE, 1, 1, 0)
+    addTooltipLineIcon(friends > 0, "Friends: "..friends, READY_CHECK_WAITING_TEXTURE, 1, 1, 0)
+    addTooltipLineIcon(autoinv, "Autoinvite!", READY_CHECK_READY_TEXTURE, 0, 1, 0)
+    local visitinfo = recentgroups[fullname]
+    if visitinfo then
+        local ago = GetTime() - visitinfo.time;
+        GameTooltip:AddDoubleLine(StatusTable[visitinfo.status] or visitinfo.status,SecondsToTime(ago, false, false, 1, false).." ago",1,0,0,1,0,0)
+        GameTooltip:AddTexture(READY_CHECK_NOT_READY_TEXTURE)
+    end
+    GameTooltip:Show()
+end
+
+local function updateTableData(rowFrame, cellFrame, data, cols, row, realrow, column, fShow, table, ...)
+    if fShow then
+        local rowdata = table:GetRow(realrow);
+        local icons = cellFrame.icons
+        local _, action, caption, desc, voice, ilvl, time, bnetfr, charfr, guild, delisted, fullname, pcount, autoinv = C_LFGList.GetSearchResultInfo(rowdata.id)
+        if not icons then
+            local miscdata = createIcon(cellFrame,READY_CHECK_WAITING_TEXTURE,0)
+            local autoinv = createIcon(cellFrame,READY_CHECK_READY_TEXTURE, 1)
+            local visited = createIcon(cellFrame,READY_CHECK_NOT_READY_TEXTURE, 2)
+            icons = {misc=miscdata, autoinv=autoinv, visited=visited}
+            cellFrame.icons = icons
+        end
+        icons.misc:SetShown(voice ~= "" or bnetfr > 0 or charfr > 0 or guild > 0 or ilvl > 0)
+        icons.autoinv:SetShown(autoinv)
+        icons.visited:SetShown(recentgroups[fullname])
+        if GameTooltip:GetOwner() == rowFrame then ShowLfgInfo(rowFrame, cellFrame, data, cols, row, realrow, column, table) end
+    end
+end
+
+local function updateGroupName(id)
+    return select(3, C_LFGList.GetSearchResultInfo(id))
+end
+
+local function updateGroupCount(id)
+    return select(13, C_LFGList.GetSearchResultInfo(id))
+end
+
+local function updateGroupRealm(id)
+    local name = select(12, C_LFGList.GetSearchResultInfo(id))
+    local pname, realm = PlayerName(name);
+    return realm
+end
+
+local function filterTable(self, row)
+    local delisted = select(11, C_LFGList.GetSearchResultInfo(row.id))
+    return not delisted;
+end
+
+function addon:UpdateResponseData(event, result)
+    if select(11, C_LFGList.GetSearchResultInfo(result)) then
+        lfgTable:SetFilter(filterTable)
+    end
+    hasLfgListChanges = true
+end
+
+local function refreshLFGList()
+    if lfgScanInProgress or not lfgTable then return end
+    local count, list = C_LFGList.GetSearchResults()
+    local tableData = {}
+    for i = 1,count do
+        local rid = list[i];
+        if not rid then break end
+        local data = list[i];
+        local cols = {}
+        local row = {rid}
+        cols[1] = {value=updateGroupName,args=row}
+        cols[2] = {value=updateGroupCount,args=row}
+        cols[3] = {value=updateGroupRealm,args=row}
+        cols[4] = {}
+        table.insert(tableData, {cols=cols,id=rid,weight=WeightLfgItem(rid)})
+    end
+    table.sort(tableData, sortByWeight);
+    lfgTable:SetData(tableData)
+end
+
+local function JoinGroup(rowFrame, cellFrame, data, cols, row, realrow, column, scrollingTable, ...)
+    if not realrow or not canJoinGroup() then return end
+    local rowdata = scrollingTable:GetRow(realrow);
+    local tank, heal, dd = C_LFGList.GetAvailableRoles()
+    addon:SetGroupJoinStatus(rowdata.id, "_init")
+    C_LFGList.ApplyToGroup(rowdata.id, "", tank, heal, dd)
+end
+
+
+
+
+
+
+-- Addon functions and gui constructors
+
 function addon:OnEnable()
     local tabCount = table.getn(lfgGroups)
-    lfgTabs = {}
-    for i=1,tabCount do
-        local cat = lfgGroups[i]
-        table.insert(lfgTabs,{value=cat,text=(C_LFGList.GetCategoryInfo(cat))})
-    end
     realmSep = _G.REALM_SEPARATORS
     playerName = UnitName("player")
     homeRealm = GetRealmName()
@@ -87,20 +300,25 @@
     gui:Show()
     addon:RegisterEvent("ZONE_CHANGED_NEW_AREA", "ForceRefreshZone")
     addon:RegisterEvent("SCENARIO_UPDATE", "ForceRefreshZone")
-    --addon:RegisterEvent("LFG_LIST_SEARCH_RESULTS_RECEIVED", "LfgResponseData")
-    --addon:RegisterEvent("LFG_LIST_SEARCH_FAILED", "LfgScanFailed")
-    --addon:RegisterEvent("GROUP_ROSTER_UPDATE", "updatePartyInfo")
-    --addon:RegisterEvent("LFG_LIST_APPLICATION_STATUS_UPDATED", "updateAppStatus")
+    addon:RegisterEvent("LFG_LIST_SEARCH_RESULTS_RECEIVED", "LfgResponseData")
+    addon:RegisterEvent("LFG_LIST_SEARCH_RESULT_UPDATED", "UpdateResponseData")
+    addon:RegisterEvent("LFG_LIST_SEARCH_FAILED", "LfgScanFailed")
+    addon:RegisterEvent("GROUP_ROSTER_UPDATE", "updatePartyInfo")
+    addon:RegisterEvent("LFG_LIST_APPLICATION_STATUS_UPDATED", "updateAppStatus")
+    addon.LfgScan(lfgGroups[1])
 end
 
 function addon:Deactivate()
     if not active then return end
     active = false
+    gui:Hide()
+    if lfgui then lfgui:Hide() end
     scanstate = 0
     lfgScanInProgress = false
     addon:UnregisterEvent("ZONE_CHANGED_NEW_AREA")
     addon:UnregisterEvent("PLAYER_REGEN_ENABLED")
     addon:UnregisterEvent("LFG_LIST_SEARCH_RESULTS_RECEIVED")
+    addon:UnregisterEvent("LFG_LIST_SEARCH_RESULT_UPDATED")
     addon:UnregisterEvent("LFG_LIST_SEARCH_FAILED")
     addon:UnregisterEvent("GROUP_ROSTER_UPDATE")
     addon:UnregisterEvent("LFG_LIST_APPLICATION_STATUS_UPDATED")
@@ -115,198 +333,161 @@
 end
 
 function addon:CreateUI()
-    gui = setupWidget(CreateFrame("Frame",nil,nil,"InsetFrameTemplate3"), {SetFrameStrata="DIALOG",SetWidth=208,SetHeight=60,EnableMouse=true,SetMovable=true})
+    gui = setupWidget(CreateFrame("Frame","CrossRealmAssistMainUI",nil,"InsetFrameTemplate3"), {SetFrameStrata="LOW",SetWidth=208,SetHeight=60,EnableMouse=true,SetMovable=true})
     local title = setupWidget(CreateFrame("Frame",nil,gui), {SetWidth=190,SetHeight=18,EnableMouse=true,RegisterForDrag="LeftButton"}, 0, 6);
     title:SetScript("OnDragStart", function() gui:StartMoving() end)
     title:SetScript("OnDragStop", function() gui:StopMovingOrSizing() end)
     gui:SetScript("OnHide", addon.Deactivate)
-    setupTooltip(title, "ANCHOR_TOP", addon.realmToolip)
+    setupTooltip(title, "ANCHOR_TOP", realmToolip)
 
     lbRealm = setupWidget(gui:CreateFontString(nil,"BACKGROUND", "GameFontNormal"), {SetWidth=200,SetHeight=18}, 0, 6)
     lbStatus = setupWidget(gui:CreateFontString(nil,"BACKGROUND", "GameFontHighlightSmallLeft"), {SetWidth=200,SetHeight=10}, 6, 23)
 
-    btQuick = setupWidget(CreateFrame("Button",nil,gui,"UIMenuButtonStretchTemplate"),{EnableMouse=true,SetWidth=90,SetHeight=20,SetText="Quick join"},4,36)
-    btManual = setupWidget(CreateFrame("Button",nil,gui,"UIMenuButtonStretchTemplate"),{EnableMouse=true,SetWidth=90,SetHeight=20,SetText="Manual join"},94,36)
+    btQuick = setupWidget(CreateFrame("Button",nil,gui,"UIMenuButtonStretchTemplate"),{SetWidth=90,SetHeight=20,SetText="Quick join"},4,36)
+    btQuick:SetScript("OnClick",addon.DoAutoAction)
+    btManual = setupWidget(CreateFrame("Button",nil,gui,"UIMenuButtonStretchTemplate"),{SetWidth=90,SetHeight=20,SetText="Manual join"},94,36)
+    btManual:SetScript("OnClick",addon.ShowManualLfg)
     setupWidget(CreateFrame("Button",nil,gui,"UIPanelCloseButton"),{EnableMouse=true,SetWidth=20,SetHeight=20},188,0)
 
-    btRefresh = setupWidget(CreateFrame("Button",nil,gui,"UIPanelSquareButton"),{EnableMouse=true,SetWidth=20,SetHeight=20},184,36)
+    btRefresh = setupWidget(CreateFrame("Button",nil,gui,"UIPanelSquareButton"),{SetWidth=20,SetHeight=20},184,36)
     btRefresh.icon:SetTexture("Interface/BUTTONS/UI-RefreshButton")
     btRefresh.icon:SetTexCoord(0,1,0,1);
     btRefresh:SetScript("OnClick",addon.RefreshZone)
 
     gui:SetPoint("CENTER",0,0)
+    addon:UpdateAutoButtonStatus()
+end
 
-    --[[gui = addon:AddUI(nil,"Window",{SetTitle="Cross Realm Assist",EnableResize=false,SetLayout="Flow"},true,{OnClose=addon.Deactivate})
+function addon:ShowManualLfg()
+    if not lfgui then addon:CreateLFGUI() end
+    lfgui:Show()
+end
 
-    local tabgroup = addon:AddUI(gui,"TabGroup",{SetFullHeight=true,SetTabs=lfgTabs,SetLayout="Fill"},true,{OnGroupSelected=addon.LfgScan})
-    tabgroup:SelectTab(lfgGroups[1])
-    lfgContainer = addon:AddUI(tabgroup,"ScrollFrame")
+function addon.lfgUpdate()
+    if hasLfgListChanges then
+        lfgTable:Refresh()
+        hasLfgListChanges = false
+    end
+end
 
-    local hgroupc = addon:AddUI(gui,"InlineGroup",{SetLayout="Fill",SetFullHeight=true,SetTitle="Realm info"},true)
-    hgroup = addon:AddUI(hgroupc,"ScrollFrame")
+function addon:CreateLFGUI()
+    lfgui = setupWidget(CreateFrame("Frame","CrossRealmAssistJoinUI",nil,"UIPanelDialogTemplate"), {SetFrameStrata="DIALOG",SetWidth=405,SetHeight=300,EnableMouse=true,SetMovable=true})
+    lfgui.title:SetText("Click to join group")
+    lfgui:SetScript("OnUpdate",addon.lfgUpdate)
+    local titlereg = lfgui:CreateTitleRegion()
+    titlereg:SetAllPoints(lfgui.title)
+    addon:CreateTabs()
 
-    addon:AddUI(hgroup,"Heading",{SetText="Current realm"})
-    currealm = addon:AddUI(hgroup,"SimpleGroup");
-    addon:AddUI(hgroup,"Button",{SetText="Refresh",SetRelativeWidth=0.5,SetHeight=20},true,{OnClick=addon.ScanRealm})
+    lfgTable = ScrollingTable:CreateST({
+        {name="Title",width=160},
+        {name="#",width=30,align="CENTER"},
+        {name="Realm",width=120,align="RIGHT"},
+        {name="",width=50,DoCellUpdate=updateTableData}
+    },15,16,nil,lfgui);
 
-    addon:AddUI(hgroup,"Heading",{SetText="Party statistics"})
-    partyrealm = addon:AddUI(hgroup,"SimpleGroup");
-    leavebtn = addon:AddUI(hgroup,"Button",{SetText="Leave",SetRelativeWidth=0.5,SetHeight=20,SetDisabled=not IsInGroup()},true,{OnClick=LeaveParty})
+    lfgTable:RegisterEvents({OnEnter=ShowLfgInfo,OnLeave=HideTooltip,OnClick=JoinGroup})
 
-    addon:AddUI(hgroup,"Heading",{SetText="Recent realms"})
-    recrealm = addon:AddUI(hgroup,"SimpleGroup");
-    addon:AddUI(hgroup,"Button",{SetText="Clear",SetRelativeWidth=0.5,SetHeight=20},true,{OnClick=addon.ClearRecentRealms})
+    setupWidget(lfgTable.frame, nil, 10, 45);
+    lfgTable.frame:SetBackdrop(nil)
+    lfgui:SetPoint("CENTER",0,0)
+    refreshLFGList()
 
-    gui:DoLayout()
-    gui:PauseLayout()
+    lbThrottle = setupWidget(lfgui:CreateFontString(nil,"BACKGROUND", "GameFontHighlightSmall"), {SetWidth=300}, 50, 100)
+    lbThrottle:Hide();
 
-    tabgroup:SetPoint("BOTTOMRIGHT", gui.content, "BOTTOMRIGHT", -200, 0)
-    hgroupc:SetPoint("TOPLEFT", gui.content, "TOPRIGHT", -200, 0)
-    hgroupc:SetPoint("BOTTOMRIGHT", gui.content, "BOTTOMRIGHT")
+    local btRefresh = setupWidget(CreateFrame("Button",nil,lfgui,"UIPanelSquareButton"),{SetWidth=22,SetHeight=22},379,27)
+    btRefresh.icon:SetTexture("Interface/BUTTONS/UI-RefreshButton")
+    btRefresh.icon:SetTexCoord(0,1,0,1);
+    btRefresh:SetScript("OnClick",addon.refreshLfgCurrent)
+end
 
-    if curRealmStat then addon:updateCurrentRealm() end
-    addon:updatePartyInfo()
-    addon:updateRecentRealms()]]
+function addon:CreateTabs()
+    local prevTab
+    for i=1,#lfgGroups do
+        local tab = CreateFrame("Button","$parentTab"..i,lfgui,"CharacterFrameTabButtonTemplate")
+        tab:SetText((C_LFGList.GetCategoryInfo(lfgGroups[i])));
+        tab.searchID = lfgGroups[i];
+        tab:SetID(i);
+        PanelTemplates_TabResize(tab, 0)
+        if i == 1 then
+            tab:SetPoint("TOPLEFT", lfgui, "BOTTOMLEFT", 10, 7)
+            lfgTabSelected = tab
+            PanelTemplates_SelectTab(tab)
+        else
+            tab:SetPoint("TOPLEFT", prevTab, "TOPRIGHT",-15,0)
+            PanelTemplates_DeselectTab(tab)
+        end
+        tab:SetScript("OnClick", SelectLfgTab)
+        tabs[i] = tab
+        prevTab = tab
+    end
 end
 
 -- LFG scanning routine
 
---[[function addon.refreshLfgCurrent()
-    addon.LfgScan(nil,nil,curLfgGroup)
+function addon.refreshLfgCurrent()
+    addon.LfgScan(curLfgGroup)
 end
 
-function addon.LfgScan(widget, callback, tab)
-    if not tab then return end
+function addon.LfgScan(group)
+    if lfgTable then lfgTable:SetData({}) end
     lfgScanInProgress = true
-    if lfgContainer then lfgContainer:ReleaseChildren() end
-    curLfgGroup = tab
+    curLfgGroup = group
     C_LFGList.Search(curLfgGroup,"")
 end
 
 function addon:LfgScanFailed(event, reason)
-    print("scan failed "..reason)
     if reason == "throttled" then
-        addon:ScheduleTimer(addon.LfgScan, 2, nil, nil, curLfgGroup)
+        addon:ScheduleTimer(addon.LfgScan, 2, curLfgGroup)
+        lbThrottle:SetText("LFG scan is delayed (throttled).\nThis page will update automatically...")
+    else
+        lbThrottle:SetText("Scan failed ("..reason..")")
     end
-end
-
-local function WeightLfgItem(item)
-    local leaderRealm = 3
-    if (item.realm ~= "???") then leaderRealm = (5 - (recentRealms[item.realm] or 0)) end
-    local weight =
-        (item.autoinv and 5 or 2) *
-                ((item.friends > 0) and 2 or 3) *
-                ((item.ilvl > 0) and 2 or 3) *
-                ((item.voice ~= "") and 2 or 4)
-    local count = item.pcount;
-    local countWeight
-    if count >= 39 or count <= 1 then countWeight = 1
-    elseif count >= 35 or count <= 4 then countWeight = 2
-    elseif count >= 30 or count <= 10 then countWeight = 3
-    else countWeight = 4 end
-    return weight * leaderRealm * countWeight;
+    lbThrottle:Show()
 end
 
 function addon:LfgResponseData()
     lfgScanInProgress = false;
-    addon:UpdateCurrentLfgInfo()
-end
-
-function addon:UpdateCurrentLfgInfo(repeated)
-    if lfgScanInProgress then return end
-    local count, list = C_LFGList.GetSearchResults()
-    local lfgList = {}
-    local lfgEntries = 0
-    local hasUnknowns = false
-    for i = 1,count do
-        local rid = list[i];
-        if not rid then break end
-        local _, action, caption, desc, voice, ilvl, time, bnetfr, charfr, guild, delisted, fullname, pcount, autoinv = C_LFGList.GetSearchResultInfo(rid)
-        if not fullname then
-            fullname = "???-???"
-            hasUnknowns = true
-        end
-        if not delisted then
-            local pname, realm = strsplit(realmSep, fullname)
-            realm = realm or homeRealm
-            local item = {
-                rid=rid,
-                action=action,
-                caption=caption,
-                desc=desc,
-                ilvl=ilvl,
-                voice=voice,
-                time=time,
-                friends=bnetfr+charfr+guild,
-                name=pname,
-                realm = realm,
-                pcount=pcount,
-                autoinv=autoinv
-            }
-            item.weight = WeightLfgItem(item)
-            table.insert(lfgList, item)
-            lfgEntries = lfgEntries + 1
-        end
-    end
-    addon:refreshLFGList(lfgList, lfgEntries);
-    if hasUnknowns and repeated ~= true then addon:ScheduleTimer("UpdateCurrentLfgInfo", 1, true) end
-end
-
-function addon:refreshLFGList(list, count)
-    if not lfgContainer then return end
-    lfgContainer:PauseLayout()
-    lfgContainer:ReleaseChildren()
-    table.sort(list, addon.SortLfgItems)
-
-    local canJoin = addon.canJoinGroup()
-
-    for i=1,count do
-        local data = list[i];
-        local renderer = addon:AddUI(lfgContainer,"SimpleGroup",{SetLayout="Flow",SetHeight=20,SetAutoAdjustHeight=false});
-
-        addon:AddUI(renderer,"Label",{SetText=data.caption,SetRelativeWidth=0.4},true)
-        addon:AddUI(renderer,"Label",{SetText=data.pcount,SetRelativeWidth=0.05},true)
-        local realm = addon:AddUI(renderer,"Label",{SetText=data.realm,SetRelativeWidth=0.25},true)
-        if recentRealms[data.realm] then
-            local r,g,b = GetItemQualityColor(recentRealms[data.realm]);
-            realm:SetColor(r,g,b)
-        end
-
-        local tooltip = {}
-        if data.voice ~= "" then table.insert(tooltip,"Voice: "..data.voice) end
-        if data.friends > 0 then table.insert(tooltip,"Friends: "..data.friends) end
-        if data.ilvl > 0 then table.insert(tooltip,"Min. Ilvl: "..data.ilvl) end
-        addon:AddIcon(renderer, "Interface/GossipFrame/ActiveQuestIcon", 16, tooltip[1] ~= nil, tooltip)
-        addon:AddIcon(renderer, READY_CHECK_READY_TEXTURE, 16, data.autoinv, {"Auto invite!"})
-        local btn = addon:AddUI(renderer,"Button",{SetText="Join",SetRelativeWidth=0.2,SetHeight=20,SetDisabled=not canJoin},true,{OnClick=addon.joinGroup})
-        btn:SetUserData('rid',data.rid)
-    end
-    addon:AddUI(lfgContainer,"Button",{SetText="Refresh",SetWidth=100,SetHeight=20},true,{OnClick=addon.refreshLfgCurrent})
-
-    lfgContainer:ResumeLayout()
-    lfgContainer:DoLayout()
-end
-
-function addon.SortLfgItems(a,b)
-    return a.weight > b.weight
-end
-
-function addon.canJoinGroup()
-    return (not IsInGroup()) or (UnitIsGroupLeader('player') and not IsInRaid())
-end
-
-function addon.joinGroup(widget)
-    if not addon.canJoinGroup() then return end
-    local rid = widget:GetUserData('rid');
-    widget:SetDisabled(true)
-    C_LFGList.ApplyToGroup(rid, "", C_LFGList.GetAvailableRoles())
+    if lbThrottle then lbThrottle:Hide() end
+    refreshLFGList()
 end
 
 function addon:updateAppStatus(event, id, status, oldstatus)
     if status == "invited" then
         LFGListInviteDialog_Accept(LFGListInviteDialog)
     end
-end]]
+    addon:UpdateAutoButtonStatus()
+    addon:SetGroupJoinStatus(id, status)
+end
+
+function addon:SetGroupJoinStatus(id, status)
+    local name = select(12, C_LFGList.GetSearchResultInfo(id))
+    recentgroups[name] = {status=status, time=GetTime()}
+end
+
+function addon:updatePartyInfo()
+    local realms = {}
+    local inGroup = IsInGroup()
+    if inGroup then
+        if IsInRaid() then
+            for i=1, MAX_RAID_MEMBERS do
+                addon:AddUnitIdStat("raid"..i, realms)
+            end
+        else
+            for i=1, MAX_PARTY_MEMBERS do
+                addon:AddUnitIdStat("party"..i, realms)
+            end
+        end
+    end
+    if inGroup ~= wasInGroup  then
+        addon:ForceRefreshZone()
+        wasInGroup = inGroup
+        addon:UpdateAutoButtonStatus()
+    end
+end
+
+
+
 
 -- Zone scanning routine
 
@@ -322,12 +503,13 @@
 
 function addon:RefreshZone(shedule)
     local inst, instType = IsInInstance()
-    if (inst or instType ~= "none") then
+    inInstance = (inst or instType ~= "none")
+    if inInstance then
         lbRealm:SetText("Instanced zone")
         curRealmStat = nil
-        btQuick:Disable()
+        inInstance = true
     else
-        btQuick:Enable()
+        inInstance = false;
         if scanstate == 0 then
             addon:ScanRealm()
         elseif shedule == true and scanstate == 2 then
@@ -335,6 +517,7 @@
             scanstate = 3
         end
     end
+    addon:UpdateAutoButtonStatus()
 end
 
 function addon:ScanRealm()
@@ -405,13 +588,13 @@
     end
 
     local bestRealm = curRealmStat[1]
-    local prevThreshold = math.min(bestRealm.count/3,5)
+    local prevThreshold = math.min(bestRealm.count/3,10)
     local mixCount = 0
     for i=2,curRealmStat.realms do
         local data = curRealmStat[i]
         if data.count >= prevThreshold then
             mixCount = mixCount + 1
-            prevThreshold = math.min(data.count/3,5)
+            prevThreshold = math.min(data.count/3,10)
         end
     end
     curRealmStat.threshold = prevThreshold
@@ -423,91 +606,61 @@
     end
 end
 
-function addon:realmToolip()
-    if not curRealmStat then return end
-    local players = curRealmStat.players;
-    local threshold = curRealmStat.threshold
-    GameTooltip:AddLine("Players in zone: "..players)
-    if not curRealmStat.complete then
-        GameTooltip:AppendText("+")
-    end
-    for i=1,curRealmStat.realms do
-        local data = curRealmStat[i]
-        local percent = math.ceil(100 * data.count / players - 0.5) .. "%";
-        if data.count >= threshold then
-            GameTooltip:AddDoubleLine(data.realm, percent, 0,1,0,0,1,0)
-        else
-            GameTooltip:AddDoubleLine(data.realm, percent, 0.5,0.5,0.5,0.5,0.5,0.5)
-        end
+
+
+
+
+
+-- Auto action button
+
+local action;
+
+local function CancelJoin()
+    local apps = C_LFGList.GetApplications();
+    if apps[1] then
+        C_LFGList.CancelApplication(apps[1])
     end
 end
 
---[[function addon:addLabels(container, stats, epict, whitet, grayt, emptytext)
-    if stats.realms == 0 then
-        addon:AddLabel(container, emptytext)
-    else
-        local players = stats.players
-        local pleft = players;
-        for i=1,stats.realms do
-            local data = stats[i]
-            local count = data.count;
-            local percent = math.ceil(100 * count / players - 0.5)
-            local label = data.realm .. " (" .. percent .. "%)";
-            local color
-            if count < grayt then break
-            elseif count < whitet then color = 1
-            elseif count < epict then color = 2
-            else color = 4 end
-            pleft = pleft - count
-            addon:AddLabel(container, label, color);
-        end
-        if pleft > 0 then
-            addon:AddLabel(container, "Other" .. " (" .. math.ceil(100 * pleft / players - 0.5) .. "%)", 0);
-        end
+local function findGroupToJoin()
+    local count, list = C_LFGList.GetSearchResults()
+    local tableData = {}
+    for i = 1,count do
+        local rid = list[i];
+        if not rid then break end
+        local _, action, caption, desc, voice, ilvl, time, bnetfr, charfr, guild, delisted, fullname, pcount, autoinv = C_LFGList.GetSearchResultInfo(rid)
+
+        local data = list[i];
+        local cols = {}
+        local row = {rid}
+        cols[1] = {value=updateGroupName,args=row}
+        cols[2] = {value=updateGroupCount,args=row}
+        cols[3] = {value=updateGroupRealm,args=row}
+        cols[4] = {}
+        table.insert(tableData, {cols=cols,id=rid})
+
     end
 end
 
-function addon:updateRecentRealms()
-    if not recrealm then return end
-    recrealm:ReleaseChildren()
-    local nothing = true;
-    for realm,color in pairs(recentRealms) do
-        addon:AddLabel(recrealm, realm,color);
-        nothing = false;
-    end
-    if nothing then
-        addon:AddLabel(recrealm, "No recent realms");
-    end
+local function QuickJoin()
+
 end
 
-function addon:ClearRecentRealms()
-    recentRealms = {}
-    addon:UpdateCurrentLfgInfo()
-    addon:updateRecentRealms()
+function addon:DoAutoAction()
+    if action then action() end
+    addon:UpdateAutoButtonStatus()
 end
 
-function addon:updatePartyInfo()
-    if not partyrealm then return end
-    partyrealm:ReleaseChildren()
-    local realms = {}
-    local inGroup = IsInGroup()
+function addon:UpdateAutoButtonStatus()
+    btQuick:Enable()
     if IsInGroup() then
-        if IsInRaid() then
-            for i=1, MAX_RAID_MEMBERS do
-                addon:AddUnitIdStat("raid"..i, realms)
-            end
-        else
-            for i=1, MAX_PARTY_MEMBERS do
-                addon:AddUnitIdStat("party"..i, realms)
-            end
-        end
+        action = LeaveParty;
+        btQuick:SetText("Leave group")
+    elseif C_LFGList.GetNumApplications() > 0 then
+        action = CancelJoin;
+        btQuick:SetText("Cancel join")
+    else
+        if inInstance then btQuick:Disable() end
+        btQuick:SetText("Quick join")
     end
-    if inGroup ~= wasInGroup  then
-        addon:SheduleScan()
-        wasInGroup = inGroup
-        addon:UpdateCurrentLfgInfo()
-        leavebtn:SetDisabled(not inGroup)
-    end
-    local partyStat = addon:GetRealmStat(realms);
-    addon:addLabels(partyrealm, partyStat, partyStat.players/2, 2, 0, "Not in party");
-end]]
\ No newline at end of file
+end
\ No newline at end of file