changeset 13:1f68e8154947

New alpha build
author ShadowTheAge
date Thu, 12 Mar 2015 22:51:35 +0300
parents 0deef890ec99
children ce4069f85582
files .pkgmeta CrossRealmAssist.lua CrossRealmAssist.toc embeds.xml
diffstat 4 files changed, 387 insertions(+), 94 deletions(-) [+]
line wrap: on
line diff
--- a/.pkgmeta	Wed Mar 11 22:51:00 2015 +0300
+++ b/.pkgmeta	Thu Mar 12 22:51:35 2015 +0300
@@ -1,6 +1,8 @@
 package-as: CrossRealmAssist
 
 externals:
+ libs/CallbackHandler-1.0:
+  url: svn://svn.wowace.com/wow/ace3/mainline/trunk/CallbackHandler-1.0
  libs/AceAddon-3.0:
   url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceAddon-3.0
  libs/AceConsole-3.0:
@@ -12,9 +14,15 @@
   tag: latest
  libs/AceTimer-3.0:
   url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceTimer-3.0
+ libs/AceDB-3.0:
+  url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceDB-3.0
  libs/LibStub:
   url: svn://svn.wowace.com/wow/libstub/mainline/trunk
  libs/LibWho-2.0:
   url: svn://svn.wowace.com/wow/wholib/mainline/trunk
+ libs/LibDataBroker-1.1:
+  url: git://git.wowace.com/wow/libdatabroker-1-1/mainline.git
+ libs/LibDBIcon-1.0:
+  svn://svn.wowace.com/wow/libdbicon-1-0/mainline/trunk
   
 enable-nolib-creation: no
\ No newline at end of file
--- a/CrossRealmAssist.lua	Wed Mar 11 22:51:00 2015 +0300
+++ b/CrossRealmAssist.lua	Thu Mar 12 22:51:35 2015 +0300
@@ -2,21 +2,28 @@
 local addon = CrossRealmAssist;
 local wholib = LibStub:GetLibrary('LibWho-2.0'):Library()
 local ScrollingTable = LibStub("ScrollingTable");
+local ldb = LibStub("LibDataBroker-1.1")
+local minimapIcon = LibStub("LibDBIcon-1.0")
+local db
 
-local homeRealm, realmSep, gui, btRefresh, btQuick, btManual, lbRealm, lbStatus, playerName, lfgui, lfgTabSelected, lfgTable, lbThrottle
+local homeRealm, realmSep, gui, btRefresh, btSettings, btQuick, btManual, lbRealm, lbStatus, playerName, lfgui, lfgTabSelected, lfgTable, lbThrottle, curLfgGroup, sheduledScan, wasInGroup, inInstance
+local settingsMenu
+local hintShown
 
 local tabs = {}
 local curRealmStat
 local scanstate=0
 local recentRealms={}
 local recentgroups={}
+local autoScanGroups={}
 local active=false
 
 local lfgGroups={
     6, -- Custom
     10, -- Ashran
     1, -- Quests
-    3 -- Raids
+    3, -- Raids
+    8 -- BGs
 }
 
 local StatusTable = {
@@ -26,13 +33,18 @@
     ["applied"]="Applied",
     ["cancelled"]="Join cancelled",
     ["inviteaccepted"]="Joined",
-    ["_init"]="Join request"
+    ["_init"]="Join request",
+    ["_skip"]="Skipped"
 }
-
-local curLfgGroup
-local sheduledScan
-local wasInGroup
-local inInstance
+local DefaultWidgetPos = {x=0, y=200, to="CENTER"}
+local SettingsDefaults={
+    global={
+        minimap = {},
+        widgetPos=DefaultWidgetPos,
+        quickJoinHint = true,
+        quickJoin={[6]=1,[10]=1}
+    }
+}
 
 
 -- Utils functions
@@ -92,10 +104,14 @@
     widget:SetScript("OnLeave", HideTooltip)
 end
 
-local function SelectLfgTab(tab)
+local function TabClick(tab)
+    if tab == lfgTabSelected then return end
+    addon.LfgScan(tab.searchID)
+end
+
+local function changeTab(tab)
     PanelTemplates_DeselectTab(lfgTabSelected)
     lfgTabSelected = tab
-    addon.LfgScan(tab.searchID)
     PanelTemplates_SelectTab(lfgTabSelected)
 end
 
@@ -118,6 +134,12 @@
     end
 end
 
+local function ClearRealmHistory()
+    recentRealms = {}
+    addon:updateCurrentRealm()
+    if lfgTable then lfgTable:Refresh() end
+end
+
 
 
 
@@ -153,7 +175,12 @@
     end
 
     local leaderRealm = 3 -- recently visited realms
-    if (realm ~= "???") then leaderRealm = (5 - (recentRealms[realm] or 0)) end
+    local realmVis = recentRealms[realm]
+    local leaderRealm = 3;
+    if realmVis then
+        local ago = GetTime() - realmVis
+        leaderRealm = 1 + 2*math.min(1,ago/600);
+    end
 
     local countWeight = 4 -- count weight
     if pcount >= 39 or pcount <= 1 then countWeight = 1
@@ -168,33 +195,44 @@
     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 function AddLfgGroupInfo(id, short)
+    local _, action, caption, desc, voice, ilvl, time, bnetfr, charfr, guild, delisted, fullname, pcount, autoinv = C_LFGList.GetSearchResultInfo(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("Players:",pcount)
     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)
+    if recentRealms[realm] then
+        local ago = GetTime() - recentRealms[realm]
+        GameTooltip:AddDoubleLine("Realm visited",SecondsToTime(ago, false, false, 1, false).." ago",1,0.5,0,1,0.5,0)
+    else
+        GameTooltip:AddDoubleLine(" ","Realm not visited!",0,0,0,0,1,0)
+    end
+    if not short then
+        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
     end
     GameTooltip:Show()
 end
 
+local function ShowLfgInfo(rowFrame, cellFrame, data, cols, row, realrow, column, scrollingTable, ...)
+    if not realrow then return end
+    local rowdata = scrollingTable:GetRow(realrow);
+    GameTooltip:SetOwner(rowFrame, "ANCHOR_BOTTOMLEFT",-10,25)
+    AddLfgGroupInfo(rowdata.id);
+end
+
 local function updateTableData(rowFrame, cellFrame, data, cols, row, realrow, column, fShow, table, ...)
     if fShow then
         local rowdata = table:GetRow(realrow);
@@ -228,12 +266,21 @@
     return realm
 end
 
+local COLOR_YELLOW = {r=1,g=1,b=0,a=1}
+local COLOR_GREEN = {r=0,g=1,b=0,a=1}
+local function updateRealmColor(id)
+    local name = select(12, C_LFGList.GetSearchResultInfo(id))
+    local pname, realm = PlayerName(name);
+    return recentRealms[realm] and COLOR_YELLOW or COLOR_GREEN;
+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 not lfgTable then return end
     if select(11, C_LFGList.GetSearchResultInfo(result)) then
         lfgTable:SetFilter(filterTable)
     end
@@ -252,7 +299,7 @@
         local row = {rid}
         cols[1] = {value=updateGroupName,args=row}
         cols[2] = {value=updateGroupCount,args=row}
-        cols[3] = {value=updateGroupRealm,args=row}
+        cols[3] = {value=updateGroupRealm,args=row,color=updateRealmColor,colorargs=row}
         cols[4] = {}
         table.insert(tableData, {cols=cols,id=rid,weight=WeightLfgItem(rid)})
     end
@@ -260,12 +307,16 @@
     lfgTable:SetData(tableData)
 end
 
-local function JoinGroup(rowFrame, cellFrame, data, cols, row, realrow, column, scrollingTable, ...)
+local function JoinGroup(rid)
+    local tank, heal, dd = C_LFGList.GetAvailableRoles()
+    addon:SetGroupJoinStatus(rid, "_init")
+    C_LFGList.ApplyToGroup(rid, "", tank, heal, dd)
+end
+
+local function TableCellClick(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)
+    JoinGroup(rowdata.id)
 end
 
 
@@ -275,8 +326,32 @@
 
 -- Addon functions and gui constructors
 
+function addon.ShowMmTooltip(tooltip)
+    tooltip:AddLine("Cross Realm Assist",1,1,1)
+    tooltip:Show()
+end
+
+--[[function addon.MmClick(self, button)
+    if button == "RightButton" then
+        addon.ShowSettings(self)
+    else
+        addon:Activate()
+    end
+end]]
+
+function addon:OnInitialize()
+    db = LibStub("AceDB-3.0"):New("CrossRealmAssistDB", SettingsDefaults)
+    local minimapData = ldb:NewDataObject("CrossRealmAssistMinimapIcon",{
+        type = "data source",
+        text = "Cross Realm Assist",
+        icon = "Interface/Icons/INV_Misc_GroupNeedMore",
+        OnClick = addon.Activate,
+        OnTooltipShow = addon.ShowMmTooltip
+    })
+    minimapIcon:Register("CrossRealmAssistMinimapIcon", minimapData, db.global.minimap)
+end
+
 function addon:OnEnable()
-    local tabCount = table.getn(lfgGroups)
     realmSep = _G.REALM_SEPARATORS
     playerName = UnitName("player")
     homeRealm = GetRealmName()
@@ -296,16 +371,16 @@
     wasInGroup = IsInGroup()
     if not gui then addon:CreateUI() end
     addon:updateCurrentRealm();
-    addon:ForceRefreshZone();
+    addon:RefreshZoneAndClearHistory();
     gui:Show()
-    addon:RegisterEvent("ZONE_CHANGED_NEW_AREA", "ForceRefreshZone")
-    addon:RegisterEvent("SCENARIO_UPDATE", "ForceRefreshZone")
+    addon:RegisterEvent("ZONE_CHANGED_NEW_AREA", "RefreshZoneAndClearHistory")
+    addon:RegisterEvent("SCENARIO_UPDATE", "RefreshZoneAndClearHistory")
     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])
+    addon.LfgScan(addon.GetNextAutoScanCategory() or 1)
 end
 
 function addon:Deactivate()
@@ -328,15 +403,21 @@
     if status then
         lbStatus:SetText(status)
     else
-        lbStatus:SetText("") -- TODO
+        lbStatus:SetText("")
     end
 end
 
+local function stopMovingWidget()
+    gui:StopMovingOrSizing()
+    local point,_,_,x,y = gui:GetPoint(1);
+    db.global.widgetPos = {x=x,y=y,to=point}
+end
+
 function addon:CreateUI()
     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)
+    title:SetScript("OnDragStop", stopMovingWidget)
     gui:SetScript("OnHide", addon.Deactivate)
     setupTooltip(title, "ANCHOR_TOP", realmToolip)
 
@@ -344,17 +425,25 @@
     lbStatus = setupWidget(gui:CreateFontString(nil,"BACKGROUND", "GameFontHighlightSmallLeft"), {SetWidth=200,SetHeight=10}, 6, 23)
 
     btQuick = setupWidget(CreateFrame("Button",nil,gui,"UIMenuButtonStretchTemplate"),{SetWidth=90,SetHeight=20,SetText="Quick join"},4,36)
+    btQuick:RegisterForClicks("RightButtonUp","LeftButtonUp")
     btQuick:SetScript("OnClick",addon.DoAutoAction)
+    setupTooltip(btQuick, "ANCHOR_BOTTOM", addon.actionTooltip)
     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"),{SetWidth=20,SetHeight=20},184,36)
+    btRefresh = setupWidget(CreateFrame("Button",nil,gui,"UIPanelSquareButton"),{SetWidth=20,SetHeight=20},184,16)
     btRefresh.icon:SetTexture("Interface/BUTTONS/UI-RefreshButton")
     btRefresh.icon:SetTexCoord(0,1,0,1);
     btRefresh:SetScript("OnClick",addon.RefreshZone)
 
-    gui:SetPoint("CENTER",0,0)
+    btSettings = setupWidget(CreateFrame("Button",nil,gui,"UIPanelSquareButton"),{SetWidth=20,SetHeight=20},184,36)
+    btSettings.icon:SetTexture("Interface/Worldmap/Gear_64Grey")
+    btSettings.icon:SetTexCoord(0.1,0.9,0.1,0.9);
+    btSettings:SetScript("OnClick",addon.ShowSettings)
+
+    local savedPos = db.global.widgetPos
+    gui:SetPoint(savedPos.to,savedPos.x,savedPos.y)
     addon:UpdateAutoButtonStatus()
 end
 
@@ -385,7 +474,7 @@
         {name="",width=50,DoCellUpdate=updateTableData}
     },15,16,nil,lfgui);
 
-    lfgTable:RegisterEvents({OnEnter=ShowLfgInfo,OnLeave=HideTooltip,OnClick=JoinGroup})
+    lfgTable:RegisterEvents({OnEnter=ShowLfgInfo,OnLeave=HideTooltip,OnClick=TableCellClick})
 
     setupWidget(lfgTable.frame, nil, 10, 45);
     lfgTable.frame:SetBackdrop(nil)
@@ -406,18 +495,21 @@
     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.searchID = i;
         tab:SetID(i);
         PanelTemplates_TabResize(tab, 0)
         if i == 1 then
             tab:SetPoint("TOPLEFT", lfgui, "BOTTOMLEFT", 10, 7)
             lfgTabSelected = tab
+        else
+            tab:SetPoint("TOPLEFT", prevTab, "TOPRIGHT",-15,0)
+        end
+        if curLfgGroup == i then
             PanelTemplates_SelectTab(tab)
         else
-            tab:SetPoint("TOPLEFT", prevTab, "TOPRIGHT",-15,0)
             PanelTemplates_DeselectTab(tab)
         end
-        tab:SetScript("OnClick", SelectLfgTab)
+        tab:SetScript("OnClick", TabClick)
         tabs[i] = tab
         prevTab = tab
     end
@@ -429,25 +521,40 @@
     addon.LfgScan(curLfgGroup)
 end
 
+function addon.GetNextAutoScanCategory()
+    for i=1,#lfgGroups do
+        if not autoScanGroups[i] and db.global.quickJoin[lfgGroups[i]] and i ~= curLfgGroup then return i end
+    end
+    return nil
+end
+
 function addon.LfgScan(group)
-    if lfgTable then lfgTable:SetData({}) end
+    if lfgTable then
+        lfgTable:SetData({})
+        changeTab(tabs[group])
+    end
     lfgScanInProgress = true
     curLfgGroup = group
-    C_LFGList.Search(curLfgGroup,"")
+    C_LFGList.Search(lfgGroups[curLfgGroup],"")
 end
 
 function addon:LfgScanFailed(event, reason)
     if reason == "throttled" then
         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
-    lbThrottle:Show()
+    if lbThrottle then
+        if reason == "throttled" then
+            lbThrottle:SetText("LFG scan is delayed (throttled).\nThis page will update automatically...")
+        else
+            lbThrottle:SetText("Scan failed ("..reason..")")
+        end
+        lbThrottle:Show()
+    end
 end
 
 function addon:LfgResponseData()
     lfgScanInProgress = false;
+    addon:UpdateAutoButtonStatus()
     if lbThrottle then lbThrottle:Hide() end
     refreshLFGList()
 end
@@ -462,7 +569,13 @@
 
 function addon:SetGroupJoinStatus(id, status)
     local name = select(12, C_LFGList.GetSearchResultInfo(id))
-    recentgroups[name] = {status=status, time=GetTime()}
+    if name then
+        recentgroups[name] = {status=status, time=GetTime()}
+    end
+end
+
+function addon:RealmVisited(realm, head)
+    recentRealms[realm] = GetTime()
 end
 
 function addon:updatePartyInfo()
@@ -480,7 +593,7 @@
         end
     end
     if inGroup ~= wasInGroup  then
-        addon:ForceRefreshZone()
+        addon:RefreshZone(true)
         wasInGroup = inGroup
         addon:UpdateAutoButtonStatus()
     end
@@ -497,7 +610,8 @@
     addon:ScanRealm();
 end
 
-function addon:ForceRefreshZone()
+function addon:RefreshZoneAndClearHistory()
+    ClearRealmHistory()
     addon:RefreshZone(true)
 end
 
@@ -588,12 +702,14 @@
     end
 
     local bestRealm = curRealmStat[1]
+    addon:RealmVisited(bestRealm.realm, true)
     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
+            addon:RealmVisited(data.realm)
             prevThreshold = math.min(data.count/3,10)
         end
     end
@@ -613,54 +729,218 @@
 
 -- Auto action button
 
-local action;
+local action
 
-local function CancelJoin()
-    local apps = C_LFGList.GetApplications();
-    if apps[1] then
-        C_LFGList.CancelApplication(apps[1])
+local LeaveGroup = {
+    func = LeaveParty;
+    tooltip = "Leave current joined group",
+    text = "Leave group"
+}
+
+local CancelJoin = {
+    func = function()
+        local apps = C_LFGList.GetApplications();
+        if apps[1] then
+            C_LFGList.CancelApplication(apps[1])
+        end
+    end,
+    tooltip = "Cancel your current join application",
+    text = "Cancel join"
+}
+
+local QuickJoin = {
+    func = function(self, button)
+        if button == "RightButton" then
+            addon:SetGroupJoinStatus(self.groupToJoin, "_skip")
+        else
+            local delisted = select(11, C_LFGList.GetSearchResultInfo(self.groupToJoin))
+            if delisted == false then
+                JoinGroup(self.groupToJoin)
+            else
+                addon:SetStatus("Group just delisted")
+            end
+        end
+    end,
+    findGroup = function()
+        local count, list = C_LFGList.GetSearchResults()
+        local best
+        local bestvalue = 0
+        for i = 1,count do
+            local rid = list[i];
+            if not rid then break end
+            local value = WeightLfgItem(rid, true);
+            if value > bestvalue then
+                best = rid
+                bestvalue = value
+            end
+        end
+        return best
+    end,
+    tooltip = function(self)
+        AddLfgGroupInfo(self.groupToJoin, true)
+        GameTooltip:AddLine(" ")
+        GameTooltip:AddDoubleLine("Click to join","Right click to skip",0,1,0,1,0.5,0)
+    end,
+    text = "Quick join"
+}
+
+local ScanNext = {
+    func = function(self)
+        autoScanGroups[curLfgGroup] = 1
+        addon.LfgScan(self.category)
+    end,
+    tooltip = function(self)
+        GameTooltip:AddLine("Scan "..(C_LFGList.GetCategoryInfo(lfgGroups[self.category])))
+    end,
+    text = "Scan more"
+}
+
+local NeedReset = {
+    func = function()
+        wipe(autoScanGroups);
+        local categoryToScan = addon.GetNextAutoScanCategory()
+        if categoryToScan then
+            addon.LfgScan(categoryToScan)
+        end
+    end,
+    tooltip = "Scan again",
+    text = "Restart scan"
+}
+
+local Wait = {
+    tooltip = "Scan in progress",
+    text = "Wait..."
+}
+
+local ShowQuickHint = {
+    tooltip = "Quick Join",
+    text = "Quick Join",
+    func = function()
+        StaticPopupDialogs["CROSS_REALM_ASSIST"] = {
+            text = "Quick Join button will automatically join you to a random group with autoinvite and medium number of players. You never join same group twice, you need to clear join history to do so. This message can be disabled in options.",
+            button1 = OKAY,
+            hideOnEscape = true,
+            preferredIndex = 3,
+        }
+        StaticPopup_Show("CROSS_REALM_ASSIST")
+        hintShown = true;
+    end
+}
+
+function addon.DoAutoAction(widget, button)
+    addon:SetStatus()
+    if action and action.func then
+        action:func(button)
+    end
+    addon:UpdateAutoButtonStatus()
+end
+
+function addon.actionTooltip()
+    local tooltip = action.tooltip
+    if type(tooltip) == 'function' then
+        tooltip(action)
+    else
+        GameTooltip:AddLine(tooltip)
     end
 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})
-
+function addon:UpdateAutoButtonStatus()
+    if not btQuick then return end
+    btQuick:Enable()
+    if not hintShown and db.global.quickJoinHint then
+        action = ShowQuickHint;
+    elseif IsInGroup() then
+        action = LeaveGroup;
+    elseif C_LFGList.GetNumApplications() > 0 then
+        action = CancelJoin;
+    elseif lfgScanInProgress then
+        action = Wait
+    else
+        local group = QuickJoin.findGroup();
+        if group then
+            action = QuickJoin;
+            QuickJoin.groupToJoin = group
+        else
+            local categoryToScan = addon.GetNextAutoScanCategory()
+            if (categoryToScan) then
+                action = ScanNext;
+                ScanNext.category = categoryToScan
+            else
+                action = NeedReset;
+            end
+        end
+    end
+    btQuick:SetText(action.text)
+    if GameTooltip:GetOwner() == btQuick then
+        ShowTooltip(btQuick)
     end
 end
 
-local function QuickJoin()
 
+
+
+
+
+-- Settings
+
+local function toggleMinimapIcon(btn, arg1, arg2, checked)
+    local hidden = not checked;
+    db.global.minimap.hide = hidden;
+    if hidden then
+        DEFAULT_CHAT_FRAME:AddMessage("|cffff0000Type |cffffffff/cra |cffff0000in chat to open Cross Realm Assist without minimap button");
+        minimapIcon:Hide("CrossRealmAssistMinimapIcon")
+    else
+        minimapIcon:Show("CrossRealmAssistMinimapIcon")
+    end
 end
 
-function addon:DoAutoAction()
-    if action then action() end
-    addon:UpdateAutoButtonStatus()
+local function toggleQuickJoinHint(btn, arg1, arg2, checked)
+    db.global.quickJoinHint = checked
 end
 
-function addon:UpdateAutoButtonStatus()
-    btQuick:Enable()
-    if IsInGroup() then
-        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")
+local function toggleQuickJoin(btn, arg1, arg2, checked)
+    db.global.quickJoin[arg1] = checked
+end
+
+local function ClearJoinHistory()
+    recentgroups = {}
+    addon:UpdateAutoButtonStatus()
+    if lfgTable then lfgTable:Refresh() end
+end
+
+--[[local function resetPos()
+    db.global.widgetPos = DefaultWidgetPos
+    if gui then
+        gui:ClearAllPoints()
+        gui:SetPoint(DefaultWidgetPos.to,DefaultWidgetPos.x,DefaultWidgetPos.y)
     end
+end]]
+
+local function initMenu(self, level)
+    if not level then return end
+    if level == 1 then
+        UIDropDownMenu_AddButton({text="Clear realm history",notCheckable=1,func=ClearRealmHistory}, level)
+        UIDropDownMenu_AddButton({text="Clear join history",notCheckable=1,func=ClearJoinHistory}, level)
+        UIDropDownMenu_AddButton({disabled=1,notCheckable=1}, level)
+        UIDropDownMenu_AddButton({isTitle=1,text="Settings",notCheckable=1}, level)
+        UIDropDownMenu_AddButton({text="Show Minimap Button",checked=not db.global.minimap.hide, func=toggleMinimapIcon,keepShownOnClick=true,isNotRadio=true}, level)
+        UIDropDownMenu_AddButton({text="Show Quick Join Hint",checked=db.global.quickJoinHint, func=toggleQuickJoinHint,keepShownOnClick=true,isNotRadio=true}, level)
+        UIDropDownMenu_AddButton({text="Quick join categories",notCheckable=1,hasArrow=1,value="qjc",keepShownOnClick=true}, level)
+    elseif level == 2 then
+        if UIDROPDOWNMENU_MENU_VALUE == "qjc" then
+            for i=1,#lfgGroups do
+                local groupId = lfgGroups[i]
+                UIDropDownMenu_AddButton({text=(C_LFGList.GetCategoryInfo(groupId)),checked=db.global.quickJoin[groupId],arg1=groupId,func=toggleQuickJoin,keepShownOnClick=true,isNotRadio=true}, level)
+            end
+        end
+    end
+end
+
+function addon.ShowSettings(frame)
+    if not settingsMenu then
+        settingsMenu = CreateFrame("Frame", "CrossRealmAssistMenu")
+        settingsMenu.displayMode = "MENU"
+        settingsMenu.initialize = initMenu
+    end
+    ToggleDropDownMenu(1, nil, settingsMenu, frame, 10, 0)
 end
\ No newline at end of file
--- a/CrossRealmAssist.toc	Wed Mar 11 22:51:00 2015 +0300
+++ b/CrossRealmAssist.toc	Thu Mar 12 22:51:35 2015 +0300
@@ -2,7 +2,8 @@
 ## Title: Cross Realm Assist
 ## Notes: Easy tool for cross-realm hoping
 ## Author: ShadowTheAge
-## Version: 0.1
+## Version: 0.5
+## SavedVariables: CrossRealmAssistDB
 
 embeds.xml
 CrossRealmAssist.lua
\ No newline at end of file
--- a/embeds.xml	Wed Mar 11 22:51:00 2015 +0300
+++ b/embeds.xml	Thu Mar 12 22:51:35 2015 +0300
@@ -1,9 +1,13 @@
 <Ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd">
+	<Include file="Libs\CallbackHandler-1.0\CallbackHandler-1.0.xml"/>
 	<Script file="libs\LibStub\LibStub.lua"/>
+	<Script file="Libs\LibDataBroker-1.1\LibDataBroker-1.1.lua"/>
+	<Script file="Libs\LibDBIcon-1.0\LibDBIcon-1.0.lua"/>
+	<Script file="Libs\LibWho-2.0\LibWho-2.0.lua"/>
 	<Include file="Libs\AceAddon-3.0\AceAddon-3.0.xml"/>
-	<Include file="libs\AceGUI-3.0\AceGUI-3.0.xml"/>
 	<Include file="Libs\AceConsole-3.0\AceConsole-3.0.xml"/>
 	<Include file="Libs\AceEvent-3.0\AceEvent-3.0.xml"/>
+	<Include file="Libs\lib-st\lib-st.xml"/>
 	<Include file="Libs\AceTimer-3.0\AceTimer-3.0.xml"/>
-	<Script file="Libs\LibWho-2.0\LibWho-2.0\LibWho-2.0.lua"/>
+	<Include file="Libs\AceDB-3.0\AceDB-3.0.xml"/>
 </Ui>
\ No newline at end of file