Advertisement
DreadfulSanity

Broker_Currencyflow.lua - Dragon Isles Supplies, Elemental Overflow

Dec 17th, 2022 (edited)
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 64.14 KB | None | 0 0
  1. --[[ *******************************************************************
  2. Project                 : Broker_Currencyflow
  3. Author                  : Aledara (wowi AT jocosoft DOT com), masi (mfourtytwoi@gmail.com)
  4. ********************************************************************* ]]
  5.  
  6. local MODNAME = "Currencyflow"
  7. local FULLNAME = "Broker: "..MODNAME
  8.  
  9. local Currencyflow  = LibStub( "AceAddon-3.0" ):NewAddon( MODNAME, "AceEvent-3.0" )
  10. local QT  = LibStub:GetLibrary( "LibQTip-1.0" )
  11. local L   = LibStub:GetLibrary( "AceLocale-3.0" ):GetLocale( MODNAME )
  12. local Config  = LibStub( "AceConfig-3.0" )
  13. local ConfigReg = LibStub( "AceConfigRegistry-3.0" )
  14. local ConfigDlg = LibStub( "AceConfigDialog-3.0" )
  15.  
  16. _G["Currencyflow"] = Currencyflow
  17.  
  18. local tooltip
  19. local RAID_CLASS_COLORS = CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS
  20. local ICON_QM = "Interface\\Icons\\INV_Misc_QuestionMark"
  21.  
  22. local fmt_yellow = "|cffffff00%s|r"
  23. local fmt_white = "|cffffffff%s|r"
  24. local COLOR_MAXREACHED = "ff8800"
  25. local HISTORY_DAYS = 30
  26.  
  27. local TYPE_MONEY = 1
  28. local TYPE_CURRENCY = 2
  29. local TYPE_FRAGMENT = 3
  30. local TYPE_ITEM = 4
  31.  
  32. local charToDelete = nil
  33.  
  34. -- These are the currencies we can keep track of
  35. local currencies = {
  36.   ["current"] = {
  37.     -- Dragonflight
  38.     ["pve"] = {
  39.       [2003] = {["type"] = TYPE_CURRENCY, ["name"] = L["DRAGON_ISLES_SUPPLIES"]},           -- Dragonflight Dragon Isles Supplies
  40.       [2118] = {["type"] = TYPE_CURRENCY, ["name"] = L["ELEMENTAL_OVERFLOW"]},              -- Dragonflight Elemental Overflow
  41.     },
  42.     ["pvp"] = {
  43.       [1602] = {["type"] = TYPE_CURRENCY, ["name"] = L["CONQUEST"]},                        -- Dragonflight Conquest
  44.       [1792] = {["type"] = TYPE_CURRENCY, ["name"] = L["Honor"]},                           -- Dragonflight Honor
  45.     }
  46.   },
  47.   ["legacy"] = {
  48.     ["pve"] = {
  49.         -- Shadowlands
  50.       [1191] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_VALOR"]},                      -- Shadowlands Valor   
  51.       [1728] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_PHANTASMA"]},                  -- Shadowlands Phantasma
  52.       [1767] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_STYGIA"]},                     -- Shadowlands Stygia
  53.       [1810] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_WILLING_SOUL"]},               -- Shadowlands Willing Soul
  54.       [1813] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_RESERVOIR_ANIMA"]},            -- Shadowlands Reservoir Anima
  55.       [1816] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_SINSTONE_FRAGMENTS"]},         -- Shadowlands Sinstone Fragments
  56.       [1819] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_MEDALLION_OF_SERVICE"]},       -- Shadowlands Medallion of Service
  57.       [1820] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_INFUSED_RUBY"]},               -- Shadowlands Infused Ruby
  58.       [1822] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_RENOWN"]},                     -- Shadowlands Renown
  59.       [1828] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_SOUL_ASH"]},                   -- Shadowlands Soul Ash
  60.       [1885] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_GRATEFUL_OFFERING"]},          -- Shadowlands Grateful Offering
  61.       [1904] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_TOWER_KNOWLEDGE"]},            -- Shadowlands Tower Knowledge
  62.       [1906] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_SOUL_CINDERS"]},               -- Shadowlands Soul Cinders
  63.       [1931] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_CATALOGED_RESEARCH"]},         -- Shadowlands Cataloged Research
  64.       [1977] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_STYGIAN_EMBER"]},              -- Shadowlands Stygian Ember
  65.       [2009] = {["type"] = TYPE_CURRENCY, ["name"] = L["COSMIC_FLUX"]},                     -- Shadowlands Cosmic Flux
  66.       [1979] = {["type"] = TYPE_CURRENCY, ["name"] = L["CYPHERS_OF_THE_FIRST_ONES"]},       -- Shadowlands Cyphers of the First Ones
  67.       -- BfA
  68.       [1560] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_WAR_RESOURCES"]},              -- BfA War Resources
  69.       [1580] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_SEAL_OF_WARTORN_FATE"]},       -- BfA Seal of Wartorn Fate
  70.       [1710] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_SEAFARERS_DUBLOON"]},          -- BfA Seafarer's Dubloon
  71.       [1716] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_HONORBOUND_SERVICE_MEDAL"]},   -- BfA Honorbound Service Medal
  72.       [1717] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_7TH_LEGION_SERVICE_MEDAL"]},   -- BfA 7th Legion Service Medal
  73.       [1718] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_TITAN_RESIDUUM"]},             -- BfA Titan Residuum
  74.       [1721] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_PRISMATIC_MANAPEARL"]},        -- BfA Prismatic Manapearl
  75.       [1755] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_COALESCING_VISIONS"]},         -- BfA Coalescing Visions
  76.       [1719] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_CORRUPTED_MEMENTOS"]},         -- BfA Corrupted Mementos
  77.       [1803] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_ECHOES_OF_NYALOTHA"]},         -- BfA Echoes of Ny'alotha
  78.       -- Legion
  79.       [1220] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_ORDER_RESOURCES"]},            -- Legion Order Resources
  80.       [1226] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_NETHERSHARD"]},                -- Legion Nethershard
  81.       [1268] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_TIMEWORN_ARTIFACT"]},          -- Legion Timeworn Artifact
  82.       [1273] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_SEAL_OF_BROKEN_FATE"]},        -- Legion Seal of Broken Fate
  83.       [1275] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_CURIOUS_COINS"]},              -- Legion Curious Coins
  84.       [1342] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_LEGIONFALL_WAR_SUPPLIES"]},    -- Legion Legionfall War Supplies
  85.       [1501] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_WRITHING_ESSENCE"]},           -- Legion Writhing Essence
  86.       [1508] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_VEILED_ARGUNITE"]},            -- Legion Veiled Argunite
  87.       [1533] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_WAKENING_ESSENCE"]},           -- Legion Wakening Essence
  88.       [1149] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_SIGHTLESS_EYE"]},              -- Legion Sightless Eye
  89.       [1154] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_SHADOWY_COINS"]},              -- Legion Shadowy Coins
  90.       [1155] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_ANCIENT_MANA"]},               -- Legion Ancient Mana
  91.       [1356] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_ECHOES_OF_BATTLE"]},           -- Legion Echoes of Battle
  92.       [1357] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_ECHOES_OF_DOMINATION"]},       -- Legion Echoes of Domination
  93.       -- WoD
  94.       [823] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_APEXIS_CRYSTAL"]},              -- WoD Apexis Crystal
  95.       [824] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_GARRISON_RESOURCES"]},          -- WoD Garrison Resources
  96.       [944] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_ARTIFACT_FRAGMENT"]},           -- WoD Artifact Fragment
  97.       [980] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_DINGY_IRON_COINS"]},            -- WoD Dingy Iron Coins
  98.       [994] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_SEAL_OF_TEMPERED_FATE"]},       -- WoD Seal of Tempered Fate
  99.       [1101] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_OIL"]},                        -- WoD Oil
  100.       [1129] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_SEAL_OF_INEVITABLE_FATE"]},    -- WoD Seal of Inevitable Fate
  101.       [1166] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_TIMEWARPED_BADGE"]},           -- WoD Timewarped Badge
  102.       -- MoP
  103.       [697] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_ELDERCHARMOFGOODFORTUNE"]},     -- MoP  Elder Charm of Good Fortune
  104.       [738] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_LESSERGOODFORTUNE"]},           -- MoP  Lesser Charm of Good Fortune
  105.       [752] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_MOGORUNEOFFATE"]},              -- MoP 5.2 Mogu Rune of Fate
  106.       [776] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_WARFORGEDSEAL"]},               -- MoP 5.4 Warforged Seal
  107.       [777] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_TIMELESSCOIN"]},                -- MoP 5.4 Timeless Coin
  108.       -- Cata
  109.       [416] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_MARKOFTHEWORLDTREE"]},
  110.       [614] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_MOTEDARKNESS"]},                -- T13 (Dragonsoul) currency
  111.       [615] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_ESSENCEDEATHWING"]},            -- T13 (Dragonsoul) currency
  112.       -- Wrath
  113.       [241] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_CHAMPIONSEAL"]},
  114.       -- TBC
  115.       -- WoW
  116.     },
  117.     ["pvp"] = {
  118.       -- MoP
  119.       [789] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_BLOODYCOIN"]},                  -- MoP 5.4 Bloody Coin
  120.       -- Cata
  121.       [391] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_TOLBARADCOMMENDATION"]},        -- Tol Barad
  122.     }
  123.   },
  124.   ["archaeology"] = {
  125.     -- Archaeology Fragments
  126.     [384] = {["type"] = TYPE_FRAGMENT, ["index"] = 1, ["name"] = L["NAME_AF_DWARF"]},
  127.     [385] = {["type"] = TYPE_FRAGMENT, ["index"] = 8, ["name"] = L["NAME_AF_TROLL"]},
  128.     [393] = {["type"] = TYPE_FRAGMENT, ["index"] = 3, ["name"] = L["NAME_AF_FOSSIL"]},
  129.     [394] = {["type"] = TYPE_FRAGMENT, ["index"] = 4, ["name"] = L["NAME_AF_NIGHTELF"]},
  130.     [397] = {["type"] = TYPE_FRAGMENT, ["index"] = 6, ["name"] = L["NAME_AF_ORC"]},
  131.     [398] = {["type"] = TYPE_FRAGMENT, ["index"] = 2, ["name"] = L["NAME_AF_DRAENEI"]},
  132.     [399] = {["type"] = TYPE_FRAGMENT, ["index"] = 9, ["name"] = L["NAME_AF_VRYKULL"]},
  133.     [400] = {["type"] = TYPE_FRAGMENT, ["index"] = 5, ["name"] = L["NAME_AF_NERUBIAN"]},
  134.     [401] = {["type"] = TYPE_FRAGMENT, ["index"] = 7, ["name"] = L["NAME_AF_TOLVIR"]},
  135.     [676] = {["type"] = TYPE_FRAGMENT, ["index"] = 11, ["name"] = L["NAME_AF_PANDAREN"]},
  136.     [677] = {["type"] = TYPE_FRAGMENT, ["index"] = 12, ["name"] = L["NAME_AF_MOGU"]},
  137.     [754] = {["type"] = TYPE_FRAGMENT, ["index"] = 10, ["name"] = L["NAME_AF_MANTID"]}, -- MoP 5.2 Mantid Archaeology Fragment
  138.     [821] = {["type"] = TYPE_FRAGMENT, ["index"] = 13, ["name"] = L["NAME_AF_DRAENOR_CLANS"]}, -- WoD Draenor Clans Archaeology Fragment
  139.     [828] = {["type"] = TYPE_FRAGMENT, ["index"] = 14, ["name"] = L["NAME_AF_OGRE"]}, -- WoD Ogre Archaeology Fragment
  140.     [829] = {["type"] = TYPE_FRAGMENT, ["index"] = 15, ["name"] = L["NAME_AF_ARAKKOA"]}, -- WoD Arakkoa Archaeology Fragment
  141.   },
  142.   ["profession"] = {
  143.     [61]  = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_DALJCTOKEN"]},
  144.     [81]  = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_EPICUREANAWARD"]},
  145.     [361] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_ILLJCTOKEN"]},
  146.     [402] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_IRONPAWTOKEN"]},
  147.     [698] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_ZENJCTOKEN"]},                   -- MoP jewelcrafting
  148.     [910] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_SECRETDRAENORALCHEMY"]},         -- WoD alchemy
  149.     [999] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_SECRETDRAENORTAILORING"]},       -- WoD tailoring
  150.     [1008] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_SECRETDRAENORJEWELCRAFTING"]},  -- WoD jewelcrafting
  151.     [1017] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_SECRETDRAENORLEATHERWORKING"]}, -- WoD leatherworking
  152.     [1020] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_SECRETDRAENORBLACKSMITHING"]},  -- WoD blacksmithing
  153.   },
  154.   ["events"] = {
  155.     [515] = {["type"] = TYPE_CURRENCY, ["name"] = L["NAME_DARKMOONPRIZETICKET"]},
  156.   },
  157.   ["misc"] = {
  158.    
  159.   }
  160. }
  161.  
  162. local build = select(4, GetBuildInfo)
  163.  
  164. local tracking = {
  165.   ["gold"] = {["type"] = TYPE_MONEY, ["name"] = L["NAME_MONEY"], ["icon"] = "Interface\\Minimap\\Tracking\\Auctioneer"},
  166.  
  167.   [0]   = {["type"] = TYPE_FRAGMENT, ["index"] = 16, ["name"] = L["NAME_AF_OTHER"]},
  168. }
  169.  
  170. -- Add currencies back into the tracking table (this is easier than re-writing all occurences of tracking)
  171. for k,v in pairs(currencies["current"]["pve"]) do tracking[k] = v end
  172. for k,v in pairs(currencies["current"]["pvp"]) do tracking[k] = v end
  173. for k,v in pairs(currencies["legacy"]["pve"]) do tracking[k] = v end
  174. for k,v in pairs(currencies["legacy"]["pvp"]) do tracking[k] = v end
  175. for k,v in pairs(currencies["events"]) do tracking[k] = v end
  176. for k,v in pairs(currencies["profession"]) do tracking[k] = v end
  177. for k,v in pairs(currencies["archaeology"]) do tracking[k] = v end
  178. for k,v in pairs(currencies["misc"]) do tracking[k] = v end
  179.  
  180. -- Used to copy a table instead of just copying the reference to it.
  181. -- Does not copy metatable information
  182. function deepcopy(object)
  183.     local lookup_table = {}
  184.     local function _copy(object)
  185.         if type(object) ~= "table" then
  186.             return object
  187.         elseif lookup_table[object] then
  188.             return lookup_table[object]
  189.         end
  190.         local new_table = {}
  191.         lookup_table[object] = new_table
  192.         for index, value in pairs(object) do
  193.             new_table[_copy(index)] = _copy(value)
  194.         end
  195.         return new_table
  196.     end
  197.     return _copy(object)
  198. end
  199.  
  200. local function Notice( msg )
  201.   if ( msg ~= nil and DEFAULT_CHAT_FRAME ) then
  202.     DEFAULT_CHAT_FRAME:AddMessage( MODNAME.." notice: "..msg, 0.6, 1.0, 1.0 )
  203.   end
  204. end
  205.  
  206. -- Returns character name, colored by class
  207. function Currencyflow:ColorByClass( name, class )
  208.   local classcol = RAID_CLASS_COLORS[class] or {["r"] = 1, ["g"] = 1, ["b"] = 0}
  209.   return format("|cff%02x%02x%02x%s|r", classcol["r"]*255, classcol["g"]*255, classcol["b"]*255, name)
  210. end
  211.  
  212. function Currencyflow:GetToday()
  213.   local offset = time(date("*t")) - time(date("!*t")) -- Offset to UTC, in seconds
  214.   return floor((time()+offset) / 86400)
  215. end
  216.  
  217. function Currencyflow:updateTime()
  218.   local now = time()
  219.   self.session.time = self.session.time + now - self.savedTime
  220.  
  221.   self.db.factionrealm.chars[self.meidx].history = self.db.factionrealm.chars[self.meidx].history or {}
  222.   self.db.factionrealm.chars[self.meidx].history[self.today] = self.db.factionrealm.chars[self.meidx].history[self.today] or { time = 0, gold = { gained = 0, spent = 0 } }
  223.   self.db.factionrealm.chars[self.meidx].history[self.today].time = self.db.factionrealm.chars[self.meidx].history[self.today].time + now - self.savedTime
  224.   self.savedTime = now
  225. end
  226.  
  227. --[[
  228.   Displays the given amount of gold in the configured format.
  229.   if colorize is true, it will color the text red if negative, green if positive (or 0)
  230.   if it's false, it wil color the text white, and with a "-" in front if it's negative
  231. ]]
  232. function Currencyflow:FormatGold( amount, colorize )
  233.   local ICON_GOLD = "|TInterface\\MoneyFrame\\UI-GoldIcon:0|t"
  234.   local ICON_SILVER = "|TInterface\\MoneyFrame\\UI-SilverIcon:0|t"
  235.   local ICON_COPPER = "|TInterface\\MoneyFrame\\UI-CopperIcon:0|t"
  236.  
  237.   local COLOR_WHITE = "ffffff"
  238.   local COLOR_GREEN = "00ff00"
  239.   local COLOR_RED = "ff0000"
  240.   local COLOR_COPPER = "eda55f"
  241.   local COLOR_SILVER = "c7c7cf"
  242.   local COLOR_GOLD = "ffd700"
  243.  
  244.   -- Make sure amount is a number
  245.   -- NaN values are not equal to themselfs, see http://snippets.luacode.org/snippets/Test_for_NaN_75
  246.   if amount ~= amount or tostring(amount) == "-1.#IND" or tostring(amount) == "-nan(ind)" then amount = 0 end
  247.  
  248.   local gold = abs(amount / 10000)
  249.   local silver = abs(mod(amount / 100, 100))
  250.   local copper = abs(mod(amount, 100))
  251.  
  252.   -- Make sure the values are numbers too
  253.   if gold ~= gold then gold = 0 end
  254.   if silver ~= silver then silver = 0 end
  255.   if copper ~= copper then copper = 0 end
  256.  
  257.   -- Determine text color
  258.   local color = COLOR_WHITE
  259.   local sign = ""
  260.   if colorize and self.db.profile.cashFormat ~= 1 then
  261.     -- With format 1, the text color itself is in gold/silver/copper,
  262.     -- so colorize has no effect, and we always show "-" on negative
  263.     if amount < 0 then color = COLOR_RED else color = COLOR_GREEN end
  264.   elseif amount < 0 then
  265.     sign = "-"
  266.   end
  267.  
  268.   -- Determine unit display
  269.   if self.db.profile.cashFormat == 1 then
  270.     -- Abacus "Condensed"
  271.     if gold > 0 then
  272.       return sign..format("|cff%s%d|r |cff%s%02d|r |cff%s%02d|r", COLOR_GOLD, gold, COLOR_SILVER, silver, COLOR_COPPER, copper)
  273.     elseif silver > 0 then
  274.       return sign..format("|cff%s%d|r |cff%s%02d|r", COLOR_SILVER, silver, COLOR_COPPER, copper)
  275.     else
  276.       return sign..format("|cff%s%d|r", COLOR_COPPER, copper)
  277.     end
  278.   elseif self.db.profile.cashFormat == 2 then
  279.     -- Abacus "Short"
  280.     if gold > 0 then
  281.       return sign..format("|cff%s%.1f|r|cff%sg|r ", color, gold, COLOR_GOLD)
  282.     elseif silver > 0 then
  283.       return sign..format("|cff%s%.1f|r|cff%ss|r", color, silver, COLOR_SILVER)
  284.     else
  285.       return sign..format("|cff%s%d|r|cff%sc|r", color, copper, COLOR_COPPER)
  286.     end
  287.   elseif self.db.profile.cashFormat == 3 then
  288.     -- Abacus "Full"
  289.     if gold > 0 then
  290.       return sign..format("|cff%s%s|r|cff%sg|r |cff%s%02d|r|cff%ss|r |cff%s%02d|r|cff%sc|r", color, BreakUpLargeNumbers(math.floor(gold)), COLOR_GOLD, color, silver, COLOR_SILVER, color, copper, COLOR_COPPER)
  291.     elseif silver > 0 then
  292.       return sign..format("|cff%s%d|r|cff%ss|r |cff%s%02d|r|cff%sc|r", color, silver, COLOR_SILVER, color, copper, COLOR_COPPER)
  293.     else
  294.       return sign..format("|cff%s%d|r|cff%sc|r", color, copper, COLOR_COPPER)
  295.     end
  296.   elseif self.db.profile.cashFormat == 4 then
  297.     -- With coin icons
  298.     if gold > 0 then
  299.       return sign..format("|cff%s%s|r%s |cff%s%02d|r%s |cff%s%02d|r%s", color, BreakUpLargeNumbers(math.floor(gold)), ICON_GOLD, color, silver, ICON_SILVER, color, copper, ICON_COPPER)
  300.     elseif silver > 0 then
  301.       return sign..format("|cff%s%d|r%s |cff%s%02d|r%s", color, silver, ICON_SILVER, color, copper, ICON_COPPER)
  302.     else
  303.       return sign..format("|cff%s%d|r%s", color, copper, ICON_COPPER)
  304.     end
  305.   end
  306.   return "<error>"
  307. end
  308.  
  309. --[[
  310.   Formats (colors) the given amount of currency with either the given color, or
  311.   red/green if none given
  312. ]]
  313. function Currencyflow:FormatCurrency( amount, color )
  314.   if color == "" then
  315.     if amount < 0 then color = "ff0000" else color = "00ff00" end
  316.   end
  317.   return "|cff"..color..amount.."|r"
  318. end
  319.  
  320. --[[
  321.   Returns time, gained, spent values.
  322.   char: Character index, or 0 to sum all (non-ignored)
  323.   day: Day #, or 0 for session, or negative for range
  324.   currency: Currency id
  325. ]]
  326. function Currencyflow:db_GetHistory( char, day, currency )
  327.  
  328.   -- Basically the same thing, except no sums/ranges!
  329.   local getval = function( char, day, currency )
  330.     -- time is set to 1 to avoid division by zero later on
  331.     local time, gained, spent = 1, 0, 0
  332.     if day == 0 then
  333.       time = self.session.time or 0
  334.       if self.session[currency] then
  335.         gained = self.session[currency].gained or 0
  336.         spent = self.session[currency].spent or 0
  337.       end
  338.     elseif self.db.factionrealm.chars[char] and self.db.factionrealm.chars[char].history and self.db.factionrealm.chars[char].history[day] then
  339.       time = self.db.factionrealm.chars[char].history[day].time or 0
  340.       self.db.factionrealm.chars[char].history[day][currency] = self.db.factionrealm.chars[char].history[day][currency] or {}
  341.       if self.db.factionrealm.chars[char].history[day][currency] then
  342.         gained = self.db.factionrealm.chars[char].history[day][currency].gained or 0
  343.         spent = self.db.factionrealm.chars[char].history[day][currency].spent or 0
  344.       end
  345.     end
  346.     return time, gained, spent
  347.   end
  348.  
  349.   local i, time,gained,spent, t,g,s = 0, 0,0,0, 1,0,0
  350.  
  351.   if char > 0 then
  352.     if day >= 0  then
  353.       time, gained, spent = getval(char, day, currency)
  354.     else
  355.       -- day < 0, so we need a range
  356.       for i = self.today + day, self.today do
  357.         t,g,s = getval(char, i, currency)
  358.         time = time + t
  359.         gained = gained + g
  360.         spent = spent + s
  361.       end
  362.     end
  363.   elseif day >= 0 then
  364.     for k,v in pairs(self.db.factionrealm.chars) do
  365.       if not v.ignore then
  366.         t,g,s = getval(k, day, currency)
  367.         time = time + t
  368.         gained = gained + g
  369.         spent = spent + s
  370.       end
  371.     end
  372.   else
  373.     -- day < 0, so we need a range
  374.     for k,v in pairs(self.db.factionrealm.chars) do
  375.       if not v.ignore then
  376.         for i = self.today + day, self.today do
  377.           t,g,s = getval(k, i, currency)
  378.           time = time + t
  379.           gained = gained + g
  380.           spent = spent + s
  381.         end
  382.       end
  383.     end
  384.   end
  385.  
  386.   return time, gained, spent
  387. end
  388.  
  389. --[[
  390.   Returns current "inventory" of given char for given currency.
  391.   char: Character index, or 0 to sum all
  392.   currency: Currency id
  393. ]]
  394. function Currencyflow:db_GetTotal( char, currency )
  395.   local value = 0
  396.   if char == 0 then
  397.     for k,_ in pairs(self.db.factionrealm.chars) do
  398.       if self.db.factionrealm.chars[k] and not self.db.factionrealm.chars[k].ignore then
  399.         value = value + (self.db.factionrealm.chars[k][currency] or 0)
  400.       end
  401.     end
  402.   elseif self.db.factionrealm.chars[char] then
  403.     value = self.db.factionrealm.chars[char][currency] or 0
  404.   end
  405.   return value
  406. end
  407.  
  408. --[[
  409.   Update given currency to current amount. Updating session and todays
  410.   history, and creating structure as needed.
  411.   Pass false for Session only on login to sync database with the
  412.   real world
  413.   If ignore is set to true for this character, history is set to nil,
  414.   to reduce database size
  415. ]]
  416. function Currencyflow:db_UpdateCurrency( currencyId, updateSession )
  417.  
  418.   -- Bail if invalid id given
  419.   if tracking[currencyId] == nil then return end
  420.  
  421.   -- Update all character's maximum reached values, if weekly earnings are reset.
  422.   -- currencyId can be "gold"
  423.   if type(currencyId) == "number" then
  424.     lastWeekEarned = self.db.factionrealm.chars[self.meidx]["lastWeekEarned"..currencyId]
  425.     local currencyInfo = C_CurrencyInfo.GetCurrencyInfo(currencyId)
  426.  
  427.     if currencyInfo ~= nil then
  428.       amount = currencyInfo.quantity
  429.       earnedThisWeek = currencyInfo.quantityEarnedThisWeek
  430.       weeklyMax = currencyInfo.maxWeeklyQuantity
  431.       totalMax = currencyInfo.maxQuantity
  432.     end
  433.  
  434.     -- Only for currencies, that have a weekly maximum
  435.     if lastWeekEarned and weeklyMax > 0 and lastWeekEarned > earnedThisWeek then
  436.       for idx, charinfo in pairs(self.db.factionrealm.chars) do
  437.         charinfo["maxReached"..currencyId] = false
  438.       end
  439.     end
  440.   end
  441.  
  442.   -- If I'm being ignored, clear my history, and bail
  443.   if self.db.factionrealm.chars[self.meidx].ignore then
  444.     self.db.factionrealm.chars[self.meidx].history = nil
  445.     return
  446.   end
  447.  
  448.   self:updateTime()
  449.  
  450.   -- In case we roll over midnight during a session
  451.   if self.today < self.GetToday() then
  452.     self.today = self.GetToday()
  453.  
  454.     -- Remove last history entry
  455.     self.db.factionrealm.chars[self.meidx].history[self.today - HISTORY_DAYS] = nil
  456.  
  457.     -- Create blank entry for today
  458.     self.db.factionrealm.chars[self.meidx].history[self.today] = self.db.factionrealm.chars[self.meidx].history[self.today] or { time = 0, gold = { gained = 0, spent = 0 } }
  459.   end
  460.  
  461.   -- Remember what it was
  462.   local oldVal = self.db.factionrealm.chars[self.meidx][currencyId] or 0
  463.  
  464.   -- Get new value and check if maximum is reached
  465.   if tracking[currencyId].type == TYPE_MONEY then
  466.     amount = GetMoney()
  467.   elseif tracking[currencyId].type == TYPE_CURRENCY then
  468.     local currencyInfo = C_CurrencyInfo.GetCurrencyInfo(currencyId)
  469.     amount = currencyInfo.quantity
  470.     earnedThisWeek = currencyInfo.quantityEarnedThisWeek
  471.     weeklyMax = currencyInfo.maxWeeklyQuantity
  472.     totalMax = currencyInfo.maxQuantity
  473.     texture = currencyInfo.iconFileID
  474.     if not amount then amount = 0 end
  475.     if weeklyMax and weeklyMax > 0 then
  476.       self.db.factionrealm.chars[self.meidx]["maxReached" .. currencyId] = earnedThisWeek >= weeklyMax / 100  
  477.       -- we can safely save the new earnedThisWeek value, since we checked for a reset before
  478.       self.db.factionrealm.chars[self.meidx]["lastWeekEarned" .. currencyId] = earnedThisWeek
  479.     elseif totalMax and totalMax > 0 then
  480.       self.db.factionrealm.chars[self.meidx]["maxReached" .. currencyId] = amount >= totalMax / 100
  481.     end
  482.   elseif tracking[currencyId].type == TYPE_FRAGMENT then
  483.     local currencyInfo = C_CurrencyInfo.GetCurrencyInfo(currencyId)
  484.     if currencyInfo ~= nil then
  485.       amount = currencyInfo.quantity
  486.     end
  487.     if amount then self.db.factionrealm.chars[self.meidx]["maxReached" .. currencyId] = amount >= 200
  488.     else amount = 0 end
  489.   elseif tracking[currencyId].type == TYPE_ITEM then amount = GetItemCount(currencyId,true) or 0 end
  490.  
  491.   -- Bail if amount has not changed
  492.   if amount == oldVal then return end
  493.  
  494.   -- Set new value
  495.   self.db.factionrealm.chars[self.meidx][currencyId] = amount
  496.  
  497.   -- Make sure history structure exists
  498.   self.db.factionrealm.chars[self.meidx].history = self.db.factionrealm.chars[self.meidx].history or {}
  499.   self.db.factionrealm.chars[self.meidx].history[self.today] = self.db.factionrealm.chars[self.meidx].history[self.today] or {time = 0, gold = {gained = 0, spent = 0}}
  500.   self.db.factionrealm.chars[self.meidx].history[self.today][currencyId] = self.db.factionrealm.chars[self.meidx].history[self.today][currencyId] or {gained = 0, spent = 0}
  501.  
  502.   -- Make sure session structure exists
  503.   self.session[currencyId] = self.session[currencyId] or {gained = 0, spent = 0}
  504.  
  505.   -- If we seem to have gained/lost anything on login, it just "magically"
  506.   -- happened, and we don't track it in history
  507.   if updateSession then
  508.     if amount > oldVal then
  509.       self.db.factionrealm.chars[self.meidx].history[self.today][currencyId].gained = (self.db.factionrealm.chars[self.meidx].history[self.today][currencyId].gained or 0) + amount - oldVal
  510.       self.session[currencyId].gained = self.session[currencyId].gained + amount - oldVal
  511.     else
  512.       self.db.factionrealm.chars[self.meidx].history[self.today][currencyId].spent = (self.db.factionrealm.chars[self.meidx].history[self.today][currencyId].spent or 0) + oldVal - amount
  513.       self.session[currencyId].spent = self.session[currencyId].spent + oldVal - amount
  514.     end
  515.   end
  516. end
  517.  
  518. -- Add Other toons we know about and total to the tooltip, if so desired
  519. function Currencyflow:addCharactersAndTotal()
  520.  
  521.   -- If neither charactares or totals are configured to be shown, get out of here
  522.   if not self.db.profile.showOtherChars and not self.db.profile.showTotals then return end
  523.  
  524.   local colsPerItem = 1
  525.   if self.db.profile.showCashPerHour then colsPerItem = 2 end
  526.  
  527.   -- Sort the table according to settings
  528.   table.sort(self.db.factionrealm.chars, function(a,b)
  529.     if a == nil or b == nil then
  530.       return false
  531.     end
  532.  
  533.     -- Safety net for nil values.
  534.     a_value = nil == a[self.db.profile.sortChars] and 0 or a[self.db.profile.sortChars]
  535.     b_value = nil == b[self.db.profile.sortChars] and 0 or b[self.db.profile.sortChars]
  536.    
  537.     if self.db.profile.sortDesc then
  538.       if a[self.db.profile.sortChars] == b[self.db.profile.sortChars] then
  539.         return a.charname > b.charname
  540.       else
  541.         return a_value > b_value
  542.       end
  543.     elseif (a[self.db.profile.sortChars] == b[self.db.profile.sortChars]) then
  544.       return a.charname < b.charname
  545.     else
  546.       return a_value < b_value
  547.     end
  548.   end)
  549.  
  550.   -- We need to update self.meidx as it has most likely changed
  551.   self.meidx = -1
  552.   for k in pairs(self.db.factionrealm.chars) do
  553.     if self.db.factionrealm.chars[k].charname == UnitName("player") then
  554.       self.meidx = k
  555.       break
  556.     end
  557.   end
  558.  
  559.   -- Add other characters
  560.   if self.db.profile.showOtherChars then
  561.     tooltip:AddSeparator()
  562.     lineNum = tooltip:AddLine(" ")
  563.     tooltip:SetCell( lineNum, 1, format(fmt_yellow, L["CFGNAME_CHARACTERS"]), "LEFT", tooltip:GetColumnCount() )
  564.  
  565.     for k,v in  pairs(self.db.factionrealm.chars) do
  566.       if not v.ignore then
  567.         local newLineNum = tooltip:AddLine(" ")
  568.         tooltip:SetCell( newLineNum, 1, self:ColorByClass(v.charname, v.class) )
  569.         tooltip:SetCell( newLineNum, 2, self:FormatGold(self:db_GetTotal(k, "gold"), false), "RIGHT", colsPerItem )
  570.  
  571.         colNum = colsPerItem + 2
  572.  
  573.         for id,currency in pairs(tracking) do
  574.           if self.db.profile["showCurrency"..id] then
  575.             if self.db.profile.colorMaxReached and v["maxReached"..id] then
  576.               color = COLOR_MAXREACHED
  577.             elseif math.fmod(colNum,2) == 0 then
  578.               color = "aaaaff"
  579.             else
  580.               color = "ddddff"
  581.             end
  582.             tooltip:SetCell( newLineNum, colNum, self:FormatCurrency(self:db_GetTotal(k, id), color), "RIGHT" )
  583.             colNum = colNum + 1
  584.           end
  585.         end
  586.       end
  587.     end
  588.   end
  589.  
  590.   -- Add grand total
  591.   if self.db.profile.showTotals then
  592.     tooltip:AddSeparator()
  593.     local newLineNum = tooltip:AddLine(" ")
  594.     tooltip:SetCell( newLineNum, 1, format(fmt_yellow, L["CFGNAME_TOTAL"]) )
  595.     tooltip:SetCell( newLineNum, 2, self:FormatGold(self:db_GetTotal(0, "gold"), false), "RIGHT", colsPerItem )
  596.  
  597.     colNum = colsPerItem + 2
  598.  
  599.     for id,currency in pairs(tracking) do
  600.       if self.db.profile["showCurrency"..id] then
  601.         if math.fmod(colNum,2) == 0 then color = "aaaaff" else color = "ddddff" end
  602.         tooltip:SetCell( newLineNum, colNum, self:FormatCurrency(self:db_GetTotal(0, id), color), "RIGHT" )
  603.         colNum = colNum + 1
  604.       end
  605.     end
  606.   end
  607. end
  608.  
  609. function Currencyflow:drawTooltip()
  610.   tooltip:Hide()
  611.   tooltip:Clear()
  612.  
  613.   self:updateTime()
  614.  
  615.   -- Add our header
  616.   local lineNum = tooltip:AddHeader(" ")
  617.   tooltip:SetCell( lineNum, 1, format(fmt_white, FULLNAME), "CENTER", tooltip:GetColumnCount() )
  618.   tooltip:AddLine(" ")
  619.  
  620.   local colsPerItem = 1
  621.   if self.db.profile.showCashPerHour then colsPerItem = 2 end
  622.  
  623.   -- Add the header for the gold column(s)
  624.   lineNum = tooltip:AddLine(" ")
  625.   tooltip:SetCell( lineNum, 2, "|TInterface\\Icons\\INV_Misc_Coin_01:16|t", "CENTER" )
  626.   if self.db.profile.showCashPerHour then tooltip:SetCell( lineNum, 3, "|TInterface\\Icons\\INV_Misc_Coin_01:16|t/Hr", "CENTER" ) end
  627.  
  628.   -- Add a header for each of the currencies we're showing
  629.   local colNum = colsPerItem + 2
  630.   local icon
  631.  
  632.   for id,currency in pairs(tracking) do
  633.     if self.db.profile["showCurrency"..id] then
  634.       tooltip:SetCell( lineNum, colNum, "|T"..currency.icon..":16|t", "CENTER" )
  635.       tooltip:SetCellScript( lineNum, colNum, "OnEnter", function()
  636.         if not CurrencyHeaderTooltip then CurrencyHeaderTooltip = CreateFrame("GameTooltip", "CurrencyHeaderTooltip", UIParent, "GameTooltipTemplate") end
  637.         CurrencyHeaderTooltip:SetOwner(tooltip, "ANCHOR_CURSOR")
  638.         CurrencyHeaderTooltip:SetText(currency.name)
  639.         CurrencyHeaderTooltip:SetFrameLevel(999)
  640.         CurrencyHeaderTooltip:Show()
  641.       end )
  642.       tooltip:SetCellScript( lineNum, colNum, "OnLeave", function()
  643.         CurrencyHeaderTooltip:Hide()
  644.       end )
  645.       colNum = colNum + 1
  646.     end
  647.   end
  648.  
  649.   if self.db.profile.showThisSession  then self:addNewCurrencySection( "session", L["CFGNAME_THISSESSION"] ) end
  650.   if self.db.profile.showTodaySelf  then self:addNewCurrencySection( "todayself", L["CFGNAME_TODAYSELF"] ) end
  651.   if self.db.profile.showTodayTotal then self:addNewCurrencySection( "todayall", L["CFGNAME_TODAYTOTAL"] ) end
  652.   if self.db.profile.showYesterdaySelf  then self:addNewCurrencySection( "yesterdayself", L["CFGNAME_YESTERDAYSELF"] ) end
  653.   if self.db.profile.showYesterdayTotal then self:addNewCurrencySection( "yesterdayall", L["CFGNAME_YESTERDAYTOTAL"] ) end
  654.   if self.db.profile.showThisWeekSelf then self:addNewCurrencySection( "thisweekself", L["CFGNAME_WEEKSELF"] ) end
  655.   if self.db.profile.showThisWeekTotal  then self:addNewCurrencySection( "thisweekall", L["CFGNAME_WEEKTOTAL"] ) end
  656.   if self.db.profile.showThisMonthSelf  then self:addNewCurrencySection( "thismonthself", L["CFGNAME_MONTHSELF"] ) end
  657.   if self.db.profile.showThisMonthTotal then self:addNewCurrencySection( "thismonthall", L["CFGNAME_MONTHTOTAL"] ) end
  658.  
  659.   if not self.db.profile.showCashDetail then tooltip:AddLine(" ") end
  660.  
  661.   -- Add Other toons we know about
  662.   self:addCharactersAndTotal()
  663.  
  664.   -- And a hint to show options
  665.   tooltip:AddLine( " " )
  666.   lineNum = tooltip:AddLine( " " )
  667.   tooltip:SetCell( lineNum, 1, format(fmt_yellow, L["CFGNAME_TIPOPTIONS"]), "LEFT", tooltip:GetColumnCount() )
  668.   lineNum = tooltip:AddLine( " " )
  669.   tooltip:SetCell( lineNum, 1, format(fmt_yellow, L["CFGNAME_TIPRESETSESSION"]), "LEFT", tooltip:GetColumnCount() )
  670. end
  671.  
  672. function Currencyflow:addNewCurrencySection(type, title)
  673.   local char,day,currency, column, t,g,s, l1,l2,l3
  674.  
  675.   if type == "session" then char = self.meidx; day = 0
  676.   elseif type == "todayself" then char = self.meidx; day = self.today
  677.   elseif type == "todayall" then char = 0; day = self.today
  678.   elseif type == "yesterdayself" then char = self.meidx; day = self.today - 1
  679.   elseif type == "yesterdayall" then char = 0; day = self.today - 1
  680.   elseif type == "thisweekself" then char = self.meidx; day = -7
  681.   elseif type == "thisweekall" then char = 0; day = -7
  682.   elseif type == "thismonthself" then char = self.meidx; day = -30
  683.   elseif type == "thismonthall" then char = 0; day = -30
  684.   else return end
  685.  
  686.   -- Create the tooltip line(s)
  687.   if self.db.profile.showCashDetail then
  688.     lineNum = tooltip:AddLine(" ")
  689.     tooltip:SetCell( lineNum, 1, format(fmt_yellow, title), "LEFT", tooltip:GetColumnCount() )
  690.  
  691.     l1 = tooltip:AddLine(L["CFGNAME_GAINED"])
  692.     l2 = tooltip:AddLine(L["CFGNAME_SPENT"])
  693.     l3 = tooltip:AddLine(L["CFGNAME_PROFIT"])
  694.   else
  695.     l1 = tooltip:AddLine(title)
  696.   end
  697.  
  698.   -- Get values for gold  
  699.   column = 2
  700.   t,g,s = self:db_GetHistory(char, day, "gold")
  701.   self:setCurrencyColumn(l1, column, t,g,s, true)
  702.  
  703.   column = column + 1
  704.   if self.db.profile.showCashPerHour then column = column + 1 end
  705.  
  706.   -- Add each currency we're tracking (and showing)
  707.   for id,currency in pairs(tracking) do
  708.     if self.db.profile["showCurrency"..id] then
  709.       t,g,s = self:db_GetHistory( char, day, id )
  710.       self:setCurrencyColumn(l1, column, t,g,s, false)
  711.       column = column + 1
  712.     end
  713.   end
  714.  
  715.   if self.db.profile.showCashDetail then tooltip:AddLine(" ") end
  716. end
  717.  
  718. function Currencyflow:setCurrencyColumn( startRow, startCol, t,g,s, doPerHour )
  719.   local color
  720.   if self.db.profile.showCashDetail then
  721.     if startCol == 2 then
  722.       tooltip:SetCell( startRow, startCol, self:FormatGold(g, false), "RIGHT" )
  723.       tooltip:SetCell( startRow+1, startCol, self:FormatGold(s, false), "RIGHT" )
  724.       tooltip:SetCell( startRow+2, startCol, self:FormatGold(g-s, true), "RIGHT" )
  725.     else
  726.       if math.fmod(startCol,2) == 0 then color = "aaaaff" else color = "ddddff" end
  727.       tooltip:SetCell( startRow, startCol,self:FormatCurrency(g, color), "RIGHT" )
  728.       tooltip:SetCell( startRow+1, startCol, self:FormatCurrency(s, color), "RIGHT" )
  729.       tooltip:SetCell( startRow+2, startCol, self:FormatCurrency(g-s, ""), "RIGHT" )
  730.     end
  731.   elseif startCol == 2 then
  732.     tooltip:SetCell( startRow, startCol, self:FormatGold(g-s, true), "RIGHT" )
  733.   else
  734.     tooltip:SetCell( startRow, startCol, self:FormatCurrency(g-s, ""), "RIGHT" )
  735.   end
  736.  
  737.   if doPerHour and self.db.profile.showCashPerHour then
  738.     if self.db.profile.showCashDetail then
  739.       if startCol == 2 then
  740.         tooltip:SetCell( startRow, startCol+1, self:FormatGold( g/t*3600, false ), "RIGHT" )
  741.         tooltip:SetCell( startRow+1, startCol+1, self:FormatGold( s/t*3600, false ), "RIGHT" )
  742.         tooltip:SetCell( startRow+2, startCol+1, self:FormatGold( (g-s)/t*3600, true ), "RIGHT" )
  743.       else
  744.         if fmod(startCol,2) == 0 then color = "aaaaff" else color = "ddddff" end
  745.         tooltip:SetCell( startRow, startCol+1,self:FormatCurrency( g/t*3600, color ), "RIGHT" )
  746.         tooltip:SetCell( startRow+1, startCol+1, self:FormatCurrency( s/t*3600, color ), "RIGHT" )
  747.         tooltip:SetCell( startRow+2, startCol+1, self:FormatCurrency( (g-s)/t*3600, "" ), "RIGHT" )
  748.       end
  749.     elseif startCol == 2 then
  750.       tooltip:SetCell( startRow, startCol+1, self:FormatGold( (g-s)/t*3600, true ), "RIGHT" )
  751.     else
  752.       -- Not being used, but it's here for completeness
  753.       tooltip:SetCell( startRow, startCol+1, self:FormatCurrency( (g-s)/t*3600, "" ), "RIGHT" )
  754.     end
  755.   end
  756. end
  757.  
  758. local LDB = LibStub( "LibDataBroker-1.1" )
  759. local launcher = LDB:NewDataObject( MODNAME, {
  760.   type = "data source",
  761.   text = " ",
  762.   label = FULLNAME,
  763.   icon = "Interface\\Minimap\\Tracking\\Auctioneer",
  764.  
  765.   OnClick = function(clickedframe, button)
  766.     if button == "LeftButton" and IsShiftKeyDown() then
  767.       -- Reset current session
  768.       StaticPopupDialogs["RESET_SESSION"] = {
  769.         text = L["CFG_CONFIRMRESETSESSION"],
  770.         button1 = L["NAME_YES"],
  771.         button2 = L["NAME_NO"],
  772.         OnAccept = function()
  773.           Currencyflow.session = {time = 0, gold = {gained = 0, spent = 0}}
  774.         end,
  775.         timeout = 0,
  776.         whileDead = true,
  777.         hideOnEscape = true,
  778.       }
  779.       StaticPopup_Show ("RESET_SESSION")
  780.      
  781.     elseif button == "RightButton" then
  782.       Currencyflow:LoadCurrencies(); InterfaceOptionsFrame_OpenToCategory(FULLNAME)
  783.     end
  784.   end,
  785.  
  786.   OnEnter = function ( self )
  787.     -- We need to calculate how many columns we meed up front
  788.     local numcols = 2 -- title and gold
  789.     -- One for the cash per hour
  790.     if Currencyflow.db.profile.showCashPerHour then numcols = numcols + 1 end
  791.     -- And one for each currency we want shown
  792.     for id,currency in pairs(tracking) do
  793.       if Currencyflow.db.profile["showCurrency"..id] then numcols = numcols + 1 end
  794.     end
  795.  
  796.     tooltip = QT:Acquire( "CurrencyflowTT", numcols )
  797.     tooltip:SetScale( Currencyflow.db.profile.tipscale )
  798.  
  799.     Currencyflow:drawTooltip()
  800.  
  801.     tooltip:SetAutoHideDelay(0.1, self)
  802.     tooltip:EnableMouse()
  803.     tooltip:SmartAnchorTo(self)
  804.     tooltip:UpdateScrolling()
  805.     tooltip:Show()
  806.   end,
  807. } )
  808.  
  809. function Currencyflow:UpdateLabel()
  810.  
  811.   function getLabelSegment(segment)
  812.     segment = tonumber(segment)
  813.     if segment == 2 then
  814.       -- Current Gold
  815.       return self:FormatGold(GetMoney(), false)
  816.     elseif segment == 3 or segment == 4 then
  817.       -- Session gold total, gold/hr
  818.       t,g,s = self:db_GetHistory(self.meidx, 0, "gold")
  819.       if segment == 3 then return self:FormatGold(g-s, false) else return self:FormatGold((g-s)/t*3600, false).."/Hr" end
  820.     elseif segment == 5 or segment == 6 then
  821.       -- Today gold total, gold/hr
  822.       t,g,s = self:db_GetHistory(self.meidx, self.today, "gold")
  823.       if segment == 5 then return self:FormatGold(g-s, false) else return self:FormatGold((g-s)/t*3600, false).."/Hr" end
  824.     elseif segment == 7 or segment == 8 then
  825.       -- Week gold total, gold/hr
  826.       t,g,s = self:db_GetHistory(self.meidx, -7, "gold")
  827.       if segment == 7 then return self:FormatGold(g-s, false) else return self:FormatGold((g-s)/t*3600, false).."/Hr" end
  828.     elseif segment == 9 or segment == 10 then
  829.       -- Month gold total, gold/hr
  830.       t,g,s = self:db_GetHistory(self.meidx, -30, "gold")
  831.       if segment == 9 then return self:FormatGold(g-s, false) else return self:FormatGold((g-s)/t*3600, false).."/Hr" end
  832.     elseif tracking[segment] then
  833.       -- Other currencies
  834.       if tracking[segment].type == TYPE_CURRENCY or tracking[segment].type == TYPE_FRAGMENT then
  835.         if self.db.profile.colorMaxReached
  836.           and self.db.factionrealm.chars[self.meidx]["maxReached"..segment] then
  837.           color = COLOR_MAXREACHED
  838.         else
  839.           color = ""
  840.         end
  841.         local currencyInfo = C_CurrencyInfo.GetCurrencyInfo(segment)
  842.         if currencyInfo ~= nil then
  843.           amount = currencyInfo.quantity
  844.         else
  845.           amount = 0
  846.         end
  847.       elseif tracking[segment].type == TYPE_ITEM then amount = GetItemCount(segment,true) or 0 end
  848.       return self:FormatCurrency(amount, (color or "")).." |T"..tracking[segment].icon..":0|t"
  849.     else
  850.       -- invalid
  851.       return "???"
  852.     end
  853.   end
  854.  
  855.   local result
  856.   if self.db.profile.buttonFirst == "1" then result = MODNAME
  857.   else
  858.     result = getLabelSegment(self.db.profile.buttonFirst)
  859.     if self.db.profile.buttonSecond > "1" then result = result.." / "..getLabelSegment(self.db.profile.buttonSecond) end
  860.     if self.db.profile.buttonThird > "1" then result = result.." / "..getLabelSegment(self.db.profile.buttonThird) end
  861.     if self.db.profile.buttonFourth > "1" then result = result.." / "..getLabelSegment(self.db.profile.buttonFourth) end
  862.   end
  863.   launcher.text = result
  864. end
  865.  
  866. function Currencyflow:SetupOptions()
  867.  
  868.   -- Create configuration panel
  869.   ConfigReg:RegisterOptionsTable( FULLNAME, self:OptionsMain() )
  870.   ConfigReg:RegisterOptionsTable( FULLNAME.." - "..L["CFGPAGE_SECTIONS"], self:OptionsSections() )
  871.   ConfigReg:RegisterOptionsTable( FULLNAME.." - "..L["CFGPAGE_COLUMNS"], self:OptionsColumns() )
  872.   ConfigReg:RegisterOptionsTable( FULLNAME.." - "..L["CFGPAGE_CHARACTERS"], self:OptionsCharacters() )
  873.   ConfigReg:RegisterOptionsTable( FULLNAME.." - "..L["CFGPAGE_PROFILES"], LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db) )
  874.  
  875.   ConfigDlg:AddToBlizOptions( FULLNAME )
  876.   ConfigDlg:AddToBlizOptions( FULLNAME.." - "..L["CFGPAGE_SECTIONS"], L["CFGPAGE_SECTIONS"], FULLNAME )
  877.   ConfigDlg:AddToBlizOptions( FULLNAME.." - "..L["CFGPAGE_COLUMNS"], L["CFGPAGE_COLUMNS"], FULLNAME )
  878.   ConfigDlg:AddToBlizOptions( FULLNAME.." - "..L["CFGPAGE_CHARACTERS"], L["CFGPAGE_CHARACTERS"], FULLNAME )
  879.   ConfigDlg:AddToBlizOptions( FULLNAME.." - "..L["CFGPAGE_PROFILES"], L["CFGPAGE_PROFILES"], FULLNAME )
  880. end
  881.  
  882. function Currencyflow:OptionsMain()
  883.   local buttonOptions = {
  884.     ["001"] = L["CFGOPT_BTNNONE"],
  885.     ["002"] = L["CFGOPT_BTNMONEY"],
  886.     ["003"] = L["CFGOPT_BTNSESSIONTOTAL"],
  887.     ["004"] = L["CFGOPT_BTNSESSIONPERHOUR"],
  888.     ["005"] = L["CFGOPT_BTNTODAYTOTAL"],
  889.     ["006"] = L["CFGOPT_BTNTODAYPERHOUR"],
  890.     ["007"] = L["CFGOPT_BTNWEEKTOTAL"],
  891.     ["008"] = L["CFGOPT_BTNWEEKPERHOUR"],
  892.     ["009"] = L["CFGOPT_BTNMONTHTOTAL"],
  893.     ["010"] = L["CFGOPT_BTNMONTHPERHOUR"],
  894.   }
  895.   for id,currency in pairs(tracking) do buttonOptions[tostring(id)] = format(L["CFGOPT_BTNOTHER"], currency.name) end
  896.  
  897.   return {
  898.     type = "group",
  899.     desc = "General",
  900.     get = function(key) return self.db.profile[key.arg] end,
  901.     set = function(key, value) self.db.profile[key.arg] = value; Currencyflow:UpdateLabel() end,
  902.     args = {
  903.       header0 = {order = 0, name = L["CFGHDR_GENERAL"], type = "header"},
  904.       colorMaxReached = {
  905.         order = 1, name = L["CFG_COLORMAXREACHED"],
  906.         type = "toggle", arg = "colorMaxReached",
  907.         desc = L["CFGDESC_COLORMAXREACHED"],
  908.       },
  909.       header1 = {order = 5, name = L["CFGHDR_TOOLTIP"], type = "header"},
  910.       cashFormat = {
  911.         order = 10, name = L["CFGNAME_CASHFORMAT"],
  912.         type = "select", arg = "cashFormat",
  913.         values = { [1] = L["CFGOPT_CF_CONDENSED"], [2] = L["CFGOPT_CF_SHORT"], [3] = L["CFGOPT_CF_FULL"], [4] = L["CFGOPT_CF_COINS"] },
  914.         desc = L["CFGDESC_CASHFORMAT"],
  915.       },
  916.       tipscale = {
  917.         order = 20, name = L["CFGNAME_TTSCALE"],
  918.         type = "range", arg = "tipscale",
  919.         min = 0.5, max = 1.5, step = 0.05,
  920.         desc = L["CFGDESC_TTSCALE"],
  921.       },
  922.       showCashDetail = {
  923.         order = 30, name = L["CFGNAME_SHOWCASHDETAIL"],
  924.         type = "toggle", arg = "showCashDetail",
  925.         desc = L["CFGDESC_SHOWCASHDETAIL"],
  926.       },
  927.  
  928.       header2 = {order = 100, name = L["CFGHDR_BUTTON"], type = "header"},
  929.       buttonFirst = {
  930.         order = 110, name = L["CFGNAME_BUTTONFIRST"],
  931.         type = "select", arg = "buttonFirst",
  932.         values = buttonOptions,
  933.         desc = L["CFGDESC_BUTTONFIRST"],
  934.       },
  935.       buttonSecond = {
  936.         order = 120, name = L["CFGNAME_BUTTONSECOND"],
  937.         type = "select", arg = "buttonSecond",
  938.         values = buttonOptions,
  939.         desc = L["CFGDESC_BUTTONSECOND"],
  940.       },
  941.       buttonThird = {
  942.         order = 130, name = L["CFGNAME_BUTTONTHIRD"],
  943.         type = "select", arg = "buttonThird",
  944.         values = buttonOptions,
  945.         desc = L["CFGDESC_BUTTONTHIRD"],
  946.       },
  947.       buttonFourth = {
  948.         order = 140, name = L["CFGNAME_BUTTONFOURTH"],
  949.         type = "select", arg = "buttonFourth",
  950.         values = buttonOptions,
  951.         desc = L["CFGDESC_BUTTONFOURTH"],
  952.       },
  953.     }
  954.   }
  955. end
  956.  
  957. function Currencyflow:OptionsSections()
  958.   local order = 1
  959.   local options = {}
  960.   local addSectionCheckbox = function(id, name)
  961.     options[id] = {
  962.       name = name,
  963.       type = "toggle", order = order, arg = id,
  964.     }
  965.     order = order + 1
  966.   end
  967.  
  968.   addSectionCheckbox( "showThisSession", L["CFGNAME_THISSESSION"] )
  969.  
  970.   options["header1"] = {name = L["CFGHDR_HISTORY"], type = "header", order = order}
  971.   order = order + 1
  972.  
  973.   addSectionCheckbox( "showTodaySelf", L["CFGNAME_TODAYSELF"] )
  974.   addSectionCheckbox( "showTodayTotal", L["CFGNAME_TODAYTOTAL"] )
  975.   addSectionCheckbox( "showYesterdaySelf", L["CFGNAME_YESTERDAYSELF"] )
  976.   addSectionCheckbox( "showYesterdayTotal", L["CFGNAME_YESTERDAYTOTAL"] )
  977.   addSectionCheckbox( "showThisWeekSelf", L["CFGNAME_WEEKSELF"] )
  978.   addSectionCheckbox( "showThisWeekTotal", L["CFGNAME_WEEKTOTAL"] )
  979.   addSectionCheckbox( "showThisMonthSelf", L["CFGNAME_MONTHSELF"] )
  980.   addSectionCheckbox( "showThisMonthTotal", L["CFGNAME_MONTHTOTAL"] )
  981.  
  982.   options["header2"] = {name = L["CFGHDR_OTHERCHARS"], type = "header", order = 100}
  983.   options["showOtherChars"] = {
  984.     name = L["CFGNAME_OTHERCHARS"],
  985.     type = "toggle", order = 101, arg = "showOtherChars",
  986.     desc = L["CFGDESC_OTHERCHARS"],
  987.   }
  988.   options["sortChars"] = {
  989.     name = L["CFGNAME_SORTOTHERCHARS"],
  990.     type = "select", order = 102, arg = "sortChars",
  991.     desc = L["CFGDESC_SORTOTHERCHARS"],
  992.     values = function()
  993.       local val = {
  994.         ["charname"] = L["CFGOPT_SORTNAME"],
  995.         ["gold"] = L["NAME_MONEY"],
  996.       }
  997.       for id,currency in pairs(tracking) do
  998.         val[tostring(id)] = currency.name
  999.       end
  1000.       return val
  1001.     end,
  1002.     disabled = function() return not self.db.profile.showOtherChars end,
  1003.   }
  1004.  
  1005.   options["sortDesc"] = {
  1006.     name = L["CFGNAME_SORTDESC"],
  1007.     type = "toggle", order = 103, arg = "sortDesc",
  1008.     desc = L["CFGDESC_SORTDESC"],
  1009.     disabled = function() return not self.db.profile.showOtherChars end,
  1010.   }
  1011.  
  1012.   options["header3"] = {name = L["CFGHDR_TOTALS"], type = "header", order = 200}
  1013.  
  1014.   options["showTotals"] = {
  1015.     name = L["CFGNAME_SHOWTOTALS"],
  1016.     type = "toggle", order = 201, arg = "showTotals",
  1017.     desc = L["CFGDESC_SHOWTOTALS"],
  1018.   }
  1019.  
  1020.   return {
  1021.     type = "group",
  1022.     get = function(key) return self.db.profile[key.arg] end,
  1023.     set = function(key, value) self.db.profile[key.arg] = value; Currencyflow:UpdateLabel() end,
  1024.     args = options
  1025.   }
  1026. end
  1027.  
  1028. function Currencyflow:OptionsColumns()
  1029.   local order = 1
  1030.   local currencyColumns = {
  1031.     header1 = {name = L["CFGHDR_GENERAL"], type = "header", order = 100},
  1032.     showCashPerHour = {
  1033.       name = L["CFGNAME_SHOWCASHPERHOUR"],
  1034.       type = "toggle", order = 101, arg = "showCashPerHour",
  1035.       desc = L["CFGDESC_SHOWCASHPERHOUR"],
  1036.     },
  1037.   }
  1038.  
  1039.   local addColumn = function(id)
  1040.     -- Retrieve item info at time of usage, to minimize risk of
  1041.     -- item not being available
  1042.     currencyColumns["showCurrency"..id] = {
  1043.       name = function()
  1044.         return "|T"..tracking[id].icon..":16|t "..tracking[id].name
  1045.       end,
  1046.       type = "toggle", order = order, arg = "showCurrency"..id,
  1047.       desc = function() return format(L["CFGDESC_SHOWCOLUMNFOR"], tracking[id].name) end
  1048.     }
  1049.     order = order + 1
  1050.   end
  1051.  
  1052.  
  1053.   -- We have only one table with currencies, and we want to split them
  1054.   -- into sections (PvE, PvP, Fragments, etc.). So we do this the hacky way.
  1055.  
  1056.   -- Current Expansion PVE --
  1057.   currencyColumns["header2"] = {name = "Dragonflight PvE", type = "header", order = 200}
  1058.   order = 201
  1059.   for k,v in pairs(currencies["current"]["pve"]) do
  1060.     addColumn(k)
  1061.   end
  1062.  
  1063.   -- Current Expansion PVP
  1064.   currencyColumns["header3"] = {name = "Dragonflight PvP", type = "header", order = 300}
  1065.   order = 301
  1066.   for k,v in pairs(currencies["current"]["pvp"]) do
  1067.     addColumn(k)
  1068.   end
  1069.  
  1070.   -- Legacy --
  1071.   currencyColumns["header4"] = {name = "Legacy", type = "header", order = 400}
  1072.   order = 401
  1073.   for k,v in pairs(currencies["legacy"]["pve"]) do
  1074.     addColumn(k)
  1075.   end
  1076.   for k,v in pairs(currencies["legacy"]["pvp"]) do
  1077.     addColumn(k)
  1078.   end
  1079.  
  1080.   -- Archeology Fragment --
  1081.   currencyColumns["header5"] = {name = L["CFGHDR_ARCHFRAGMENTS"], type = "header", order = 600}
  1082.   order = 601
  1083.   for k,v in pairs(currencies["archaeology"]) do
  1084.     addColumn(k)
  1085.   end
  1086.  
  1087.   -- Profession --
  1088.   currencyColumns["header6"] = {name = "Profession", type = "header", order = 700}
  1089.   order = 701
  1090.   for k,v in pairs(currencies["profession"]) do
  1091.     addColumn(k)
  1092.   end
  1093.  
  1094.   return {
  1095.     type = "group",
  1096.     get = function(key) return self.db.profile[key.arg] end,
  1097.     set = function(key, value) self.db.profile[key.arg] = value; Currencyflow:UpdateLabel() end,
  1098.     args = currencyColumns,
  1099.   }
  1100. end
  1101.  
  1102. function Currencyflow:OptionsCharacters()
  1103.   return {
  1104.     type = "group",
  1105.     args = {
  1106.       header1 = { type = "description", name = L["CFGTXT_IGNOREDCHARS"], order = 10 },
  1107.       ignoreChars = {
  1108.         order = 11, type = "multiselect",
  1109.         name = L["CFGNAME_IGNORECHARS"],
  1110.         values = function()
  1111.           local val = {}
  1112.           for k,v in pairs(self.db.factionrealm.chars) do val[k] = v.charname end
  1113.           return val
  1114.         end,
  1115.         get = function(key,id) return self.db.factionrealm.chars[id].ignore or false end,
  1116.         set = function(key,id,value) self.db.factionrealm.chars[id].ignore = value end,
  1117.       },
  1118.  
  1119.       header2 = { type = "header", name = L["CFGHDR_DELETECHAR"], order = 20 },
  1120.       header3 = { type = "description", name = L["CFGTXT_DELETECHAR"], order = 21 },
  1121.       deleteChars = {
  1122.         order = 22, type = "select",
  1123.         name = L["CFGHDR_DELETECHAR"],
  1124.         desc = L["CFGDESC_DELETECHAR"],
  1125.         values = function()
  1126.           local val = {}
  1127.           for k,v in pairs(self.db.factionrealm.chars) do if k ~= self.meidx then val[k] = v.charname end end
  1128.           return val
  1129.         end,
  1130.         get = function(key) return charToDelete end,
  1131.         set = function(key, value) charToDelete = value end,
  1132.       },
  1133.       deleteConfirm = {
  1134.         order = 23, type = "execute",
  1135.         name = L["CFGNAME_DELETE"],
  1136.         func = function()
  1137.           if charToDelete ~= nil then self.db.factionrealm.chars[charToDelete] = nil end
  1138.           charToDelete = nil
  1139.         end,
  1140.         width = "half",
  1141.         confirm = function()
  1142.           return format(L["CFG_CONFIRMDELETE"], self.db.factionrealm.chars[charToDelete].charname)
  1143.         end,
  1144.         disabled = function() return charToDelete == nil end,
  1145.       }
  1146.     }
  1147.   }
  1148. end
  1149.  
  1150. -- This function tries to update the currencies list with client info
  1151. function Currencyflow:LoadCurrencies()
  1152.   for id,currency in pairs(tracking) do
  1153.     local name, icon
  1154.     if currency.type == TYPE_CURRENCY then
  1155.       local currencyInfo = C_CurrencyInfo.GetCurrencyInfo(id)
  1156.       if currencyInfo ~= nil then
  1157.         name = currencyInfo.name
  1158.         icon = currencyInfo.iconFileID
  1159.       end
  1160.     elseif currency.type == TYPE_ITEM then
  1161.       name, _, _, _, _, _, _, _, _, icon, _ = GetItemInfo(id)
  1162.     elseif currency.type == TYPE_FRAGMENT then
  1163.       local name, icon, _, _ = GetArchaeologyRaceInfo(currency.index)
  1164.       -- Another dumb marvel of blizz consistency. When info
  1165.       -- is not available, instead of returning nil or "",
  1166.       -- this one puts "UNKNOWN" in the name.... sigh...
  1167.       if icon == nil or icon == "" then
  1168.          name = nil
  1169.       end
  1170.     end
  1171.  
  1172.     if name ~= nil and name ~= "" then
  1173.        currency.name = name
  1174.     else
  1175.        currency.name = "|cff999999"..currency.name.."|r"
  1176.     end
  1177.  
  1178.     if icon ~= nil and icon ~= "" then
  1179.        currency.icon = icon
  1180.     else
  1181.        currency.icon = ICON_QM
  1182.     end
  1183.   end
  1184. end
  1185.  
  1186. function Currencyflow:OnEnable()
  1187.   Notice("Currencyflow enabled")
  1188.   self.savedTime = time()
  1189.   self.today = self.GetToday()
  1190.   self.session = {time = 0, gold = {gained = 0, spent = 0}}
  1191.  
  1192.   self:LoadCurrencies()
  1193.  
  1194.   -- Database, and initial layout
  1195.   self.db = LibStub("AceDB-3.0"):New("Currencyflow_DB", { profile = {
  1196.     cashFormat = 3,
  1197.     tipscale = 1.0,
  1198.     showCashDetail = true,
  1199.     buttonFirst = "2",
  1200.     buttonSecond = "1",
  1201.     buttonThird = "1",
  1202.     buttonFourth = "1",
  1203.  
  1204.     showThisSession = true,
  1205.     showTodaySelf = true,
  1206.     showTodayTotal = true,
  1207.     showYesterdaySelf = true,
  1208.     showYesterdayTotal = true,
  1209.     showThisWeekTotal = true,
  1210.     showThisMonthTotal = true,
  1211.     showOtherChars = true,
  1212.     sortChars = "charname",
  1213.     sortDesc = false,
  1214.     showTotals = true,
  1215.  
  1216.     showCashPerHour = true,
  1217.     showCurrency392 = false, -- Honor points
  1218.     showCurrency395 = false, -- Justice points
  1219.   }}, "Default")
  1220.  
  1221.   -- If there is a database, make sure it's up to date
  1222.   if self.db.factionrealm.chars then
  1223.     self:UpdateDatabase()
  1224.   else
  1225.     -- If original Broker_Cashflow (not this addon!) db version 9 exists, import it.
  1226.     cashflow = { db = LibStub("AceDB-3.0"):New("Cashflow_DB", { profile = {
  1227.         cashFormat = 3,
  1228.         tipscale = 1.0,
  1229.         showCashDetail = true,
  1230.         buttonFirst = "2",
  1231.         buttonSecond = "1",
  1232.         buttonThird = "1",
  1233.         buttonFourth = "1",
  1234.  
  1235.         showThisSession = true,
  1236.         showTodaySelf = true,
  1237.         showTodayTotal = true,
  1238.         showYesterdaySelf = true,
  1239.         showYesterdayTotal = true,
  1240.         showThisWeekTotal = true,
  1241.         showThisMonthTotal = true,
  1242.         showOtherChars = true,
  1243.         sortChars = "charname",
  1244.         sortDesc = false,
  1245.         showTotals = true,
  1246.  
  1247.         showCashPerHour = true,
  1248.         showCurrency392 = true, -- Honor points
  1249.         showCurrency395 = true, -- Justice points
  1250.       }}, "Default")}
  1251.  
  1252.     -- Again, this is another addon, it's the original.
  1253.     if cashflow.db.factionrealm.version and cashflow.db.factionrealm.version <= 9 then
  1254.       -- We can only copy the characters for the current faction/realm.
  1255.       Notice("Import database from Broker_Cashflow...")
  1256.       factionrealm_chars = deepcopy(cashflow.db.factionrealm.chars)
  1257.       self.db.factionrealm.version = cashflow.db.factionrealm.version
  1258.       self.db.factionrealm.chars = {}
  1259.       for _,v in pairs(factionrealm_chars) do
  1260.         if v then
  1261.           table.insert(self.db.factionrealm.chars, deepcopy(v))
  1262.         end
  1263.       end
  1264.       Notice("Import done.")
  1265.  
  1266.       self:UpdateDatabase()
  1267.     else
  1268.       -- Create a skelleton structure
  1269.       self.db.factionrealm.version = 9
  1270.       self.db.factionrealm.chars = {}
  1271.     end
  1272.   end
  1273.  
  1274.   -- Make sure I'm in the character list, and remember my position
  1275.   self.meidx = -1
  1276.  
  1277.   for k,v in pairs(self.db.factionrealm.chars) do
  1278.     if v.charname == UnitName("player") then self.meidx = k end
  1279.   end
  1280.   if self.meidx == -1 then
  1281.     local _,classname = UnitClass("player")
  1282.     table.insert(self.db.factionrealm.chars, {
  1283.       charname = UnitName("player"),
  1284.       class = classname,
  1285.       ignore = false,
  1286.       history = {[self.today] = {["time"] = 0}}
  1287.     })
  1288.     self.meidx = #self.db.factionrealm.chars
  1289.   end
  1290.  
  1291.   -- Remove old stuff
  1292.   self:RemoveOldData()
  1293.  
  1294.   -- Update current gold
  1295.   self:db_UpdateCurrency( "gold", false )
  1296.  
  1297.   -- Update other currencies
  1298.   for id,currency in pairs(tracking) do self:db_UpdateCurrency( id, false ) end
  1299.  
  1300.   -- Setup our configuration panel
  1301.   self:SetupOptions()
  1302.  
  1303.   -- Create some slashcommands
  1304.   _G.SlashCmdList["CASHFLOW"] = function() InterfaceOptionsFrame_OpenToCategory(FULLNAME) end
  1305.   _G["SLASH_CASHFLOW1"] = "/cashflow"
  1306.   _G["SLASH_CASHFLOW2"] = "/cf"
  1307.  
  1308.   -- self:RegisterEvent("CURRENCY_DISPLAY_UPDATE", "UpdateCurrencies")
  1309.   self:RegisterEvent("PLAYER_LEAVING_WORLD", "UnregisterEvents")
  1310.   self:RegisterEvent("PLAYER_ENTERING_WORLD", "RegisterEvents")
  1311.  
  1312.   self:UpdateLabel()
  1313. end
  1314.  
  1315. function Currencyflow:UnregisterEvents()
  1316.   self:UnregisterEvent("PLAYER_MONEY")
  1317.   self:UnregisterEvent("PLAYER_TRADE_MONEY")
  1318.   self:UnregisterEvent("TRADE_MONEY_CHANGED")
  1319.   self:UnregisterEvent("SEND_MAIL_MONEY_CHANGED")
  1320.   self:UnregisterEvent("SEND_MAIL_COD_CHANGED")
  1321.   self:UnregisterEvent("MAIL_CLOSED")
  1322.   self:UnregisterEvent("CURRENCY_DISPLAY_UPDATE")
  1323. end
  1324.  
  1325. function Currencyflow:RegisterEvents()
  1326.   self:RegisterEvent("PLAYER_MONEY", "UpdateGold")
  1327.   self:RegisterEvent("PLAYER_TRADE_MONEY", "UpdateGold")
  1328.   self:RegisterEvent("TRADE_MONEY_CHANGED", "UpdateGold")
  1329.   self:RegisterEvent("SEND_MAIL_MONEY_CHANGED", "UpdateGold")
  1330.   self:RegisterEvent("SEND_MAIL_COD_CHANGED", "UpdateGold")
  1331.   self:RegisterEvent("MAIL_CLOSED", "UpdateGold")
  1332.   self:RegisterEvent("CURRENCY_DISPLAY_UPDATE", "UpdateCurrencies")
  1333. end
  1334.  
  1335. -- This will update the database format to the current version
  1336. function Currencyflow:UpdateDatabase()
  1337.  
  1338.   -- If version is not set, we're "upgrading" to version 1
  1339.   if not self.db.factionrealm.version then self.db.factionrealm.version = 1 end
  1340.  
  1341.   -- Version 1 -> 2:
  1342.   --   Migrate characters table from factionrealm.chars[name] to
  1343.   --   factionrealm.chars[#].charname for easier sorting.
  1344.   --   Gotta love how "flexible" lua is!
  1345.   if self.db.factionrealm.version == 1 then
  1346.     Notice( "Updating database to version 2" )
  1347.     local a = {}
  1348.     for k,v in pairs(self.db.factionrealm.chars) do table.insert(a, k) end
  1349.     for _,k in pairs(a) do
  1350.       self.db.factionrealm.chars[k].charname = k
  1351.       table.insert(self.db.factionrealm.chars, self.db.factionrealm.chars[k])
  1352.       self.db.factionrealm.chars[k] = nil
  1353.     end
  1354.     self.db.factionrealm.version = 2
  1355.     Notice( "Update complete" )
  1356.   end
  1357.  
  1358.   -- Version 2 -> 3:
  1359.   --   Move history to character level
  1360.   if self.db.factionrealm.version == 2 then
  1361.     Notice( "Updating database to version 3" )
  1362.     for k,v in pairs(self.db.factionrealm.chars) do
  1363.       self.db.factionrealm.chars[k].history = {[self.today] = {["time"] = 0}}
  1364.     end
  1365.     self.db.factionrealm.history = nil
  1366.     self.db.factionrealm.version = 3
  1367.     Notice( "Update complete" )
  1368.   end
  1369.  
  1370.   -- Version 3 -> 4:
  1371.   --   Add "ignore" option to characters
  1372.   if self.db.factionrealm.version == 3 then
  1373.     Notice( "Updating database to version 4" )
  1374.     for k,v in pairs(self.db.factionrealm.chars) do
  1375.       self.db.factionrealm.chars[k].ignore = false;
  1376.     end
  1377.     self.db.factionrealm.version = 4
  1378.     Notice( "Update complete" )
  1379.   end
  1380.  
  1381.   -- Version 4 -> 5:
  1382.   --   Cataclysm!
  1383.   if self.db.factionrealm.version == 4 then
  1384.     Notice( "Updating database to version 5" )
  1385.     for k,v in pairs(self.db.factionrealm.chars) do
  1386.  
  1387.       -- Change ID of Champion's Seal (from item# 44990 to currency# 241)
  1388.       if self.db.factionrealm.chars[k][44990] then
  1389.         self.db.factionrealm.chars[k][241] = self.db.factionrealm.chars[k][44990];
  1390.         self.db.factionrealm.chars[k][44990] = nil;
  1391.       end
  1392.  
  1393.       -- Clean out the old stuff that doesn't exist anymore
  1394.       self.db.factionrealm.chars[k][29434] = nil; -- Badge of Justice
  1395.       self.db.factionrealm.chars[k][47241] = nil; -- Emblem of Triumph
  1396.       self.db.factionrealm.chars[k][49426] = nil; -- Emblem of Frost
  1397.       self.db.factionrealm.chars[k][29434] = nil; -- Badge of Justice
  1398.       self.db.factionrealm.chars[k][20560] = nil; -- Alterac Valley MoH
  1399.       self.db.factionrealm.chars[k][20559] = nil; -- Arathi Basin MoH
  1400.       self.db.factionrealm.chars[k][29024] = nil; -- Eye of the Storm MoH
  1401.       self.db.factionrealm.chars[k][47395] = nil; -- Isle of Conquest MoH
  1402.       self.db.factionrealm.chars[k][42425] = nil; -- Strand o/t Anctients MoH
  1403.       self.db.factionrealm.chars[k][20558] = nil; -- Warsong Gulch MoH
  1404.       self.db.factionrealm.chars[k][43589] = nil; -- Wintergrasp MoH
  1405.       self.db.factionrealm.chars[k][37836] = nil; -- Venture Coin
  1406.       self.db.factionrealm.chars[k][43307] = nil; -- Stone Keeper's Shard
  1407.       self.db.factionrealm.chars[k][43307] = nil; -- Old Arena Points
  1408.       self.db.factionrealm.chars[k][43308] = nil; -- Old Honor Points
  1409.  
  1410.       -- Reset honor, arena, and justice points, since old stuff has been converted
  1411.       -- No use trying to calculate it. I tried, was very inacurate
  1412.       self.db.factionrealm.chars[k][392] = nil;
  1413.       self.db.factionrealm.chars[k][395] = nil;
  1414.  
  1415.       -- Update preferences
  1416.       self.db.profile["showCurrency241"] = self.db.profile["showCurrency44990"];
  1417.       self.db.profile["showCurrency44990"] = nil;
  1418.       self.db.profile["showCurrency47241"] = nil;
  1419.       self.db.profile["showCurrency49426"] = nil;
  1420.       self.db.profile["showCurrency29434"] = nil;
  1421.       self.db.profile["showCurrency20560"] = nil;
  1422.       self.db.profile["showCurrency20559"] = nil;
  1423.       self.db.profile["showCurrency29024"] = nil;
  1424.       self.db.profile["showCurrency47395"] = nil;
  1425.       self.db.profile["showCurrency42425"] = nil;
  1426.       self.db.profile["showCurrency20558"] = nil;
  1427.       self.db.profile["showCurrency43589"] = nil;
  1428.       self.db.profile["showCurrency37836"] = nil;
  1429.       self.db.profile["showCurrency43307"] = nil;
  1430.       self.db.profile["showCurrency43307"] = nil;
  1431.       self.db.profile["showCurrency43308"] = nil;
  1432.     end
  1433.     self.db.factionrealm.version = 5
  1434.     Notice( "Update complete. Please cycle through all your characters to update current information." )
  1435.   end
  1436.  
  1437.   -- Version 5 -> 6:
  1438.   --   Dal JC token & cooking award item -> currency
  1439.   if self.db.factionrealm.version == 5 then
  1440.     Notice( "Updating database to version 6" )
  1441.     for k,v in pairs(self.db.factionrealm.chars) do
  1442.       -- Change ID of Jewelcrafters token (from item# 41596 to currency# 61)
  1443.       -- Change ID of Cooking award (from item# ... to currency# 81)
  1444.       if self.db.factionrealm.chars[k][41596] then
  1445.         self.db.factionrealm.chars[k][61] = self.db.factionrealm.chars[k][41596];
  1446.         self.db.factionrealm.chars[k][41596] = nil;
  1447.       end
  1448.       if self.db.factionrealm.chars[k][43016] then
  1449.         self.db.factionrealm.chars[k][81] = self.db.factionrealm.chars[k][43016];
  1450.         self.db.factionrealm.chars[k][43016] = nil;
  1451.       end
  1452.     end
  1453.     self.db.factionrealm.version = 6
  1454.   end
  1455.  
  1456.   -- Version 6 -> 7:
  1457.   --   Introduced buttonFirst and buttonSecond config options
  1458.   if self.db.factionrealm.version == 6 then
  1459.     Notice( "Updating database to version 7" )
  1460.     self.db.profile.buttonFirst = "2"
  1461.     self.db.profile.buttonSecond = "1"
  1462.     self.db.factionrealm.version = 7
  1463.   end
  1464.  
  1465.   -- Version 7 -> 8:
  1466.   --   Introduced buttonThird and buttonFourth config options
  1467.   if self.db.factionrealm.version == 7 then
  1468.     Notice( "Updating database to version 8" )
  1469.     self.db.profile.buttonThird = "1"
  1470.     self.db.profile.buttonFourth = "1"
  1471.     self.db.factionrealm.version = 8
  1472.   end
  1473.  
  1474.   -- Version 8 -> 9:
  1475.   --   History indexes changed (got rid of faulty offset calculation)
  1476.   if self.db.factionrealm.version == 8 then
  1477.     Notice( "Updating database to version 9" )
  1478.     for k,v in pairs(self.db.factionrealm.chars) do
  1479.       self.db.factionrealm.chars[k].history = {[self.today] = {["time"] = 0}}
  1480.     end
  1481.     self.db.factionrealm.version = 9
  1482.     Notice( "Update complete" )
  1483.   end
  1484.  
  1485.   -- Version 9 -> 10:
  1486.   --   Add boolean value indicating wether a currency's max is reached.
  1487.   if self.db.factionrealm.version == 9 then
  1488.     Notice( "Updating database to version 10" )
  1489.     for index, charinfo in pairs(self.db.factionrealm.chars) do
  1490.       for id, currency in pairs(tracking) do
  1491.         if charinfo[id] and currency.type == TYPE_CURRENCY then
  1492.           local currencyInfo = C_CurrencyInfo.GetCurrencyInfo(id)
  1493.           if currencyInfo ~= nil then
  1494.             weeklyMax = currencyInfo.maxWeeklyQuantity
  1495.             totalMax = currencyInfo.maxQuantity
  1496.           end
  1497.           -- Since we can't get other character's weekly earnings, set default to false
  1498.           -- Max values are 0 if unlimited
  1499.           if weeklyMax > 0 then
  1500.             charinfo["maxReached" .. id] = false
  1501.             charinfo["lastWeekEarned" .. id] = nil -- Needed to get hold of weekly resets
  1502.           elseif totalMax > 0 then charinfo["maxReached" .. id] = totalMax == charinfo[id]
  1503.           end
  1504.         elseif charinfo[id] and currency.type == TYPE_FRAGMENT then
  1505.           -- Fragments can be collected up to 200
  1506.           charinfo["maxReached" .. id] = charinfo[id] >= 200
  1507.         end
  1508.       end
  1509.     end
  1510.     self.db.factionrealm.version = 10
  1511.     Notice( "Update complete. For weekly maximums you need to log on each character." )
  1512.   end
  1513. end
  1514.  
  1515. function Currencyflow:RemoveOldData()
  1516.  
  1517.   local lastMonth = self.today - (HISTORY_DAYS - 1) -- Remove history over a month old
  1518.  
  1519.   for day in pairs(self.db.factionrealm.chars[self.meidx].history) do
  1520.     if day < lastMonth then self.db.factionrealm.chars[self.meidx].history[day] = nil end
  1521.   end
  1522.  
  1523.   self.db.factionrealm.chars[self.meidx].history[self.today] = self.db.factionrealm.chars[self.meidx].history[self.today] or {time = 0, gold = {gained = 0, spent = 0}}
  1524. end
  1525.  
  1526. function Currencyflow:UpdateGold()
  1527.   self:db_UpdateCurrency("gold", true)
  1528.   self:UpdateLabel()
  1529. end
  1530.  
  1531. function Currencyflow:UpdateCurrencies() -- Update all currencies
  1532.   for id,currency in pairs(tracking) do self:db_UpdateCurrency(id, true) end
  1533.   self:UpdateLabel()
  1534. end
  1535.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement