vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 --[[
2 Informant
3 An addon for World of Warcraft that shows pertinent information about
4 an item in a tooltip when you hover over the item in the game.
5 3.8.0 (Kangaroo)
6 $Id: Informant.lua 912 2006-06-26 13:53:44Z mentalpower $
7  
8 License:
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13  
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18  
19 You should have received a copy of the GNU General Public License
20 along with this program(see GLP.txt); if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 --]]
23  
24 INFORMANT_VERSION = "3.8.0"
25 if (INFORMANT_VERSION == "<".."%version%>") then
26 INFORMANT_VERSION = "3.7.DEV"
27 end
28  
29 -- GLOBAL FUNCTION PROTOTYPES:
30  
31 local getItem--(itemID); itemID is the first value in a blizzard hyperlink id
32 -- this pattern would extract the id you need:
33 -- "item:(%d+):%d+:%d+:%d+"
34  
35  
36  
37 -- LOCAL FUNCTION PROTOTYPES:
38 local addLine -- addLine(text, color)
39 local clear -- clear()
40 local frameActive -- frameActive(isActive)
41 local frameLoaded -- frameLoaded()
42 local getCatName -- getCatName(catID)
43 local getFilter -- getFilter(filter)
44 local getFilterVal -- getFilterVal(type)
45 local getItem -- getItem(itemID)
46 local getRowCount -- getRowCount()
47 local nilSafeString -- nilSafeString(String)
48 local onEvent -- onEvent(event)
49 local onLoad -- onLoad()
50 local onVariablesLoaded -- onVariablesLoaded()
51 local onQuit -- onQuit()
52 local scrollUpdate -- scrollUpdate(offset)
53 local setDatabase -- setDatabase(database)
54 local setFilter -- setFilter(key, value)
55 local setFilterDefaults -- setFilterDefaults()
56 local setRequirements -- setRequirements(requirements)
57 local setSkills -- setSkills(skills)
58 local setVendors -- setVendors(vendors)
59 local showHideInfo -- showHideInfo()
60 local skillToName -- skillToName(userSkill)
61 local split -- split(str, at)
62 local tooltipHandler -- tooltipHandler(funcVars, retVal, frame, name, link, quality, count, price)
63 local getKeyBindProfile -- getKeyBindProfile()
64 local whitespace -- whitespace(length)
65  
66 -- LOCAL VARIABLES
67  
68 local self = {}
69 local lines = {}
70 local itemInfo = nil
71  
72 -- GLOBAL VARIABLES
73  
74 BINDING_HEADER_INFORMANT_HEADER = _INFM('BindingHeader')
75 BINDING_NAME_INFORMANT_POPUPDOWN = _INFM('BindingTitle')
76  
77 InformantConfig = {}
78  
79 -- LOCAL DEFINES
80  
81 CLASS_TO_CATEGORY_MAP = {
82 [2] = 1,
83 [4] = 2,
84 [1] = 3,
85 [0] = 4,
86 [7] = 5,
87 [6] = 6,
88 [11] = 7,
89 [9] = 8,
90 [5] = 9,
91 [15] = 10,
92 }
93  
94 local filterDefaults = {
95 ['all'] = 'on',
96 ['embed'] = 'off',
97 ['locale'] = 'default',
98 ['show-vendor'] = 'on',
99 ['show-vendor-buy'] = 'on',
100 ['show-vendor-sell'] = 'on',
101 ['show-usage'] = 'on',
102 ['show-stack'] = 'on',
103 ['show-merchant'] = 'on',
104 ['show-quest'] = 'on',
105 ['show-icon'] = 'on',
106 }
107  
108 -- FUNCTION DEFINITIONS
109  
110 function split(str, at)
111 local splut = {}
112  
113 if (type(str) ~= "string") then return nil end
114 if (not str) then str = "" end
115 if (not at)
116 then table.insert(splut, str)
117 else
118 for n, c in string.gfind(str, '([^%'..at..']*)(%'..at..'?)') do
119 table.insert(splut, n)
120 if (c == '') then break end
121 end
122 end
123 return splut
124 end
125  
126 function skillToName(userSkill)
127 local skillName = self.skills[tonumber(userSkill)]
128 local localized = "Unknown"
129 if (skillName) then
130 if (_INFM("Skill"..skillName)) then
131 localized = _INFM("Skill"..skillName)
132 else
133 localized = "Unknown:"..skillName
134 end
135 end
136 return localized, skillName
137 end
138  
139 function getItem(itemID)
140 local baseData = self.database[itemID]
141 if (not baseData) then
142 return getItemBasic(itemID)
143 end
144  
145 local _, _, _, iLevel, sType, _, iCount, _, sTexture = GetItemInfo(itemID)
146  
147 local baseSplit = split(baseData, ":")
148 local buy = tonumber(baseSplit[1])
149 local sell = tonumber(baseSplit[2])
150 local class = tonumber(baseSplit[3])
151 local quality = tonumber(baseSplit[4])
152 local stack = tonumber(iCount) or tonumber(baseSplit[5])
153 local additional = baseSplit[6]
154 local usedby = baseSplit[7]
155 local quantity = baseSplit[8]
156 local limited = baseSplit[9]
157 local merchantlist = baseSplit[10]
158 local cat = CLASS_TO_CATEGORY_MAP[class]
159  
160 local dataItem = {
161 ['buy'] = buy,
162 ['sell'] = sell,
163 ['class'] = class,
164 ['cat'] = cat,
165 ['quality'] = quality,
166 ['stack'] = stack,
167 ['additional'] = additional,
168 ['usedby'] = usedby,
169 ['quantity'] = quantity,
170 ['limited'] = limited,
171 ['texture'] = sTexture,
172 ['fullData'] = true,
173 }
174  
175 local addition = ""
176 if (additional ~= "") then
177 addition = " - ".._INFM("Addit"..additional)
178 end
179 local catName = getCatName(cat)
180 if (not catName) then
181 if (sType) then
182 dataItem.classText = sType..addition
183 else
184 dataItem.classText = "Unknown"..addition
185 end
186 else
187 dataItem.classText = catName..addition
188 end
189  
190 if (usedby ~= '') then
191 local usedList = split(usedby, ",")
192 local skillName, localized, localeString
193 local usage = ""
194 dataItem.usedList = {}
195 if (usedList) then
196 for pos, userSkill in pairs(usedList) do
197 localized = skillToName(userSkill)
198 if (usage == "") then
199 usage = localized
200 else
201 usage = usage .. ", " .. localized
202 end
203 table.insert(dataItem.usedList, localized)
204 end
205 end
206 dataItem.usageText = usage
207 end
208  
209 local reqSkill = 0
210 local reqLevel = 0
211 local skillName = ""
212  
213 local skillsRequired = self.requirements[itemID]
214 if (skillsRequired) then
215 local skillSplit = split(skillsRequired, ":")
216 reqSkill = skillSplit[1]
217 reqLevel = skillSplit[2]
218 skillName = skillToName(reqSkill)
219 end
220  
221 dataItem.isPlayerMade = (reqSkill ~= 0)
222 dataItem.reqSkill = reqSkill
223 dataItem.reqSkillName = skillName
224 dataItem.reqLevel = iLevel or reqLevel
225  
226 if (merchantlist ~= '') then
227 local merchList = split(merchantlist, ",")
228 local vendName
229 local vendList = {}
230 if (merchList) then
231 for pos, merchID in pairs(merchList) do
232 vendName = self.vendors[tonumber(merchID)]
233 if (vendName) then
234 table.insert(vendList, vendName)
235 end
236 end
237 end
238 dataItem.vendors = vendList
239 end
240  
241 dataItem.quests = {}
242 dataItem.questCount = 0
243 local questItemUse = InformantQuests.usage[itemID]
244 if (questItemUse) then
245 local questData = split(questItemUse, ",")
246 local questInfoSplit, questID, questCount
247 for pos, questInfo in pairs(questData) do
248 questInfoSplit = split(questInfo, ":")
249 questID = tonumber(questInfoSplit[1])
250 questCount = tonumber(questInfoSplit[2])
251 if (not dataItem.quests[questID]) then
252 questName = Babylonian.GetString(InformantQuests.names, questID)
253 dataItem.quests[questID] = {
254 ['count'] = questCount,
255 ['name'] = questName,
256 ['level'] = tonumber(InformantQuests.levels[questID])
257 }
258 dataItem.questCount = dataItem.questCount + 1
259 end
260 end
261 end
262  
263 return dataItem
264 end
265  
266 function getItemBasic(itemID)
267 if (not itemID) then return end
268 local sName, sLink, iQuality, iLevel, sType, sSubType, iCount, sEquipLoc, sTexture = GetItemInfo(tonumber(itemID))
269  
270 if (sName) then
271 local dataItem = {
272 ['classText'] = sType,
273 ['quality'] = iQuality,
274 ['stack'] = iCount,
275 ['texture'] = sTexture,
276 ['reqLevel'] = iLevel,
277 ['fullData'] = false,
278 }
279 return dataItem
280 end
281 end
282  
283 function setSkills(skills)
284 self.skills = skills
285 Informant.SetSkills = nil -- Set only once
286 end
287  
288 function setRequirements(requirements)
289 self.requirements = requirements
290 Informant.SetRequirements = nil -- Set only once
291 end
292  
293 function setVendors(vendors)
294 self.vendors = vendors
295 Informant.SetVendors = nil -- Set only once
296 end
297  
298 function setDatabase(database)
299 self.database = database
300 Informant.SetDatabase = nil -- Set only once
301 end
302  
303  
304 function setFilter(key, value)
305 if (not InformantConfig.filters) then
306 InformantConfig.filters = {};
307 setFilterDefaults()
308 end
309 if (type(value) == "boolean") then
310 if (value) then
311 InformantConfig.filters[key] = 'on';
312 else
313 InformantConfig.filters[key] = 'off';
314 end
315 else
316 InformantConfig.filters[key] = value;
317 end
318 end
319  
320 function getFilterVal(type)
321 if (not InformantConfig.filters) then
322 InformantConfig.filters = {}
323 setFilterDefaults()
324 end
325 return InformantConfig.filters[type]
326 end
327  
328 function getFilter(filter)
329 value = getFilterVal(filter)
330 if ((value == _INFM('CmdOn')) or (value == "on")) then return true
331 elseif ((value == _INFM('CmdOff')) or (value == "off")) then return false end
332 return true
333 end
334  
335 function getLocale()
336 local locale = Informant.GetFilterVal('locale');
337 if (locale ~= 'on') and (locale ~= 'off') and (locale ~= 'default') then
338 return locale;
339 end
340 return GetLocale();
341 end
342  
343 local categories
344 function getCatName(catID)
345 if (not categories) then categories = {GetAuctionItemClasses()} end
346 for cat, name in categories do
347 if (cat == catID) then return name end
348 end
349 end
350  
351 function tooltipHandler(funcVars, retVal, frame, name, link, quality, count, price)
352 -- nothing to do, if informant is disabled
353 if (not getFilter('all')) then
354 return;
355 end;
356  
357 if EnhTooltip.LinkType(link) ~= "item" then return end
358  
359 local quant = 0
360 local sell = 0
361 local buy = 0
362 local stacks = 1
363  
364 local itemID, randomProp, enchant, uniqID, lame = EnhTooltip.BreakLink(link)
365 if (itemID and itemID > 0) and (Informant) then
366 itemInfo = getItem(itemID)
367 end
368 if (not itemInfo) then return end
369  
370 itemInfo.itemName = name
371 itemInfo.itemLink = link
372 itemInfo.itemCount = count
373 itemInfo.itemQuality = quality
374  
375 stacks = itemInfo.stack
376 if (not stacks) then stacks = 1 end
377  
378 buy = tonumber(itemInfo.buy) or 0
379 sell = tonumber(itemInfo.sell) or 0
380 quant = tonumber(itemInfo.quantity) or 0
381  
382 if (quant == 0) and (sell > 0) then
383 local ratio = buy / sell
384 if ((ratio > 3) and (ratio < 6)) then
385 quant = 1
386 else
387 ratio = buy / (sell * 5)
388 if ((ratio > 3) and (ratio < 6)) then
389 quant = 5
390 end
391 end
392 end
393 if (quant == 0) then quant = 1 end
394  
395 buy = buy/quant
396  
397 itemInfo.itemBuy = buy
398 itemInfo.itemSell = sell
399 itemInfo.itemQuant = quant
400  
401 local embedded = getFilter('embed')
402  
403 if (getFilter('show-icon')) then
404 if (itemInfo.texture) then
405 EnhTooltip.SetIcon(itemInfo.texture)
406 end
407 end
408  
409 if (getFilter('show-vendor')) then
410 if ((buy > 0) or (sell > 0)) then
411 local bgsc = EnhTooltip.GetTextGSC(buy, true)
412 local sgsc = EnhTooltip.GetTextGSC(sell, true)
413  
414 if (count and (count > 1)) then
415 if (getFilter('show-vendor-buy')) then
416 EnhTooltip.AddLine(string.format(_INFM('FrmtInfoBuymult'), count, bgsc), buy*count, embedded, true)
417 EnhTooltip.LineColor(0.8, 0.5, 0.1)
418 end
419 if (getFilter('show-vendor-sell')) then
420 EnhTooltip.AddLine(string.format(_INFM('FrmtInfoSellmult'), count, sgsc), sell*count, embedded, true)
421 EnhTooltip.LineColor(0.8, 0.5, 0.1)
422 end
423 else
424 if (getFilter('show-vendor-buy')) then
425 EnhTooltip.AddLine(string.format(_INFM('FrmtInfoBuy')), buy, embedded, true)
426 EnhTooltip.LineColor(0.8, 0.5, 0.1)
427 end
428 if (getFilter('show-vendor-sell')) then
429 EnhTooltip.AddLine(string.format(_INFM('FrmtInfoSell')), sell, embedded, true)
430 EnhTooltip.LineColor(0.8, 0.5, 0.1)
431 end
432 end
433 end
434 end
435  
436 if (getFilter('show-stack')) then
437 if (stacks > 1) then
438 EnhTooltip.AddLine(string.format(_INFM('FrmtInfoStx'), stacks), nil, embedded)
439 end
440 end
441 if (getFilter('show-merchant')) then
442 if (itemInfo.vendors) then
443 local merchantCount = table.getn(itemInfo.vendors)
444 if (merchantCount > 0) then
445 EnhTooltip.AddLine(string.format(_INFM('FrmtInfoMerchants'), merchantCount), nil, embedded)
446 EnhTooltip.LineColor(0.5, 0.8, 0.5)
447 end
448 end
449 end
450 if (getFilter('show-usage')) then
451 local reagentInfo = ""
452 if (itemInfo.classText) then
453 reagentInfo = string.format(_INFM('FrmtInfoClass'), itemInfo.classText)
454 EnhTooltip.AddLine(reagentInfo, nil, embedded)
455 EnhTooltip.LineColor(0.6, 0.4, 0.8)
456 end
457 if (itemInfo.usedList and itemInfo.usageText) then
458 if (table.getn(itemInfo.usedList) > 2) then
459  
460 local currentUseLine = nilSafeString(itemInfo.usedList[1])..", "..nilSafeString(itemInfo.usedList[2])..","
461 reagentInfo = string.format(_INFM('FrmtInfoUse'), currentUseLine)
462 EnhTooltip.AddLine(reagentInfo, nil, embedded)
463 EnhTooltip.LineColor(0.6, 0.4, 0.8)
464  
465 for index = 3, table.getn(itemInfo.usedList), 2 do
466 if (itemInfo.usedList[index+1]) then
467 reagentInfo = whitespace(string.len(_INFM('FrmtInfoUse')) + 3)..nilSafeString(itemInfo.usedList[index])..", "..nilSafeString(itemInfo.usedList[index+1])..","
468 EnhTooltip.AddLine(reagentInfo, nil, embedded)
469 EnhTooltip.LineColor(0.6, 0.4, 0.8)
470 else
471 reagentInfo = whitespace(string.len(_INFM('FrmtInfoUse')) + 3)..nilSafeString(itemInfo.usedList[index])
472 EnhTooltip.AddLine(reagentInfo, nil, embedded)
473 EnhTooltip.LineColor(0.6, 0.4, 0.8)
474 end
475 end
476 else
477 reagentInfo = string.format(_INFM('FrmtInfoUse'), itemInfo.usageText)
478 EnhTooltip.AddLine(reagentInfo, nil, embedded)
479 EnhTooltip.LineColor(0.6, 0.4, 0.8)
480 end
481 end
482 end
483 if (getFilter('show-quest')) then
484 if (itemInfo.quests) then
485 local questCount = itemInfo.questCount
486 if (questCount > 0) then
487 EnhTooltip.AddLine(string.format(_INFM('FrmtInfoQuest'), questCount), nil, embedded)
488 EnhTooltip.LineColor(0.5, 0.5, 0.8)
489 end
490 end
491 end
492 end
493  
494 function nilSafeString(str)
495 if (not str) then str = "" end
496 return str;
497 end
498  
499 function whitespace(length)
500 local spaces = ""
501 while length ~= 0 do
502 spaces = spaces.." "
503 length = length - 1
504 end
505 return spaces
506 end
507  
508 function showHideInfo()
509 if (InformantFrame:IsVisible()) then
510 InformantFrame:Hide()
511 elseif (itemInfo) then
512 InformantFrameTitle:SetText(_INFM('FrameTitle'))
513  
514 -- Woohoo! We need to provide any information we can from the item currently in itemInfo
515 local quality = itemInfo.itemQuality or itemInfo.quality or 0
516  
517 local color = "ffffff"
518 if (quality == 4) then color = "a335ee"
519 elseif (quality == 3) then color = "0070dd"
520 elseif (quality == 2) then color = "1eff00"
521 elseif (quality == 0) then color = "9d9d9d"
522 end
523  
524 clear()
525 addLine(string.format(_INFM('InfoHeader'), color, itemInfo.itemName))
526  
527 local buy = itemInfo.itemBuy or itemInfo.buy or 0
528 local sell = itemInfo.itemSell or itemInfo.sell or 0
529 local quant = itemInfo.itemQuant or itemInfo.quantity or 0
530 local count = itemInfo.itemCount or 1
531  
532 if ((buy > 0) or (sell > 0)) then
533 local bgsc = EnhTooltip.GetTextGSC(buy, true)
534 local sgsc = EnhTooltip.GetTextGSC(sell, true)
535  
536 if (count and (count > 1)) then
537 local bqgsc = EnhTooltip.GetTextGSC(buy*count, true)
538 local sqgsc = EnhTooltip.GetTextGSC(sell*count, true)
539 addLine(string.format(_INFM('FrmtInfoBuymult'), count, bgsc)..": "..bqgsc, "ee8822")
540 addLine(string.format(_INFM('FrmtInfoSellmult'), count, sgsc)..": "..sqgsc, "ee8822")
541 else
542 addLine(string.format(_INFM('FrmtInfoBuy'))..": "..bgsc, "ee8822")
543 addLine(string.format(_INFM('FrmtInfoSell'))..": "..sgsc, "ee8822")
544 end
545 end
546  
547 if (itemInfo.stack > 1) then
548 addLine(string.format(_INFM('FrmtInfoStx'), itemInfo.stack))
549 end
550  
551 local reagentInfo = ""
552 if (itemInfo.classText) then
553 reagentInfo = string.format(_INFM('FrmtInfoClass'), itemInfo.classText)
554 addLine(reagentInfo, "aa66ee")
555 end
556 if (itemInfo.usageText) then
557 reagentInfo = string.format(_INFM('FrmtInfoUse'), itemInfo.usageText)
558 addLine(reagentInfo, "aa66ee")
559 end
560  
561 if (itemInfo.isPlayerMade) then
562 addLine(string.format(_INFM('InfoPlayerMade'), itemInfo.reqLevel, itemInfo.reqSkillName), "5060ff")
563 end
564  
565 if (itemInfo.quests) then
566 local questCount = itemInfo.questCount
567 if (questCount > 0) then
568 addLine("")
569 addLine(string.format(_INFM('FrmtInfoQuest'), questCount), nil, embed)
570 addLine(string.format(_INFM('InfoQuestHeader'), questCount), "70ee90")
571 for pos, quest in itemInfo.quests do
572 addLine(string.format(_INFM('InfoQuestName'), quest.count, quest.name, quest.level), "80ee80")
573 end
574 addLine(string.format((_INFM('InfoQuestSource')).." WoWGuru.com"));
575 end
576 end
577  
578 if (itemInfo.vendors) then
579 local vendorCount = table.getn(itemInfo.vendors)
580 if (vendorCount > 0) then
581 addLine("")
582 addLine(string.format(_INFM('InfoVendorHeader'), vendorCount), "ddff40")
583 for pos, merchant in itemInfo.vendors do
584 addLine(string.format(" ".._INFM('InfoVendorName'), merchant), "eeee40")
585 end
586 end
587 end
588 InformantFrame:Show()
589 else
590 clear()
591 addLine(_INFM('InfoNoItem'), "ff4010")
592 InformantFrame:Show()
593 end
594 end
595  
596 function onQuit()
597 if (not InformantConfig.position) then
598 InformantConfig.position = { }
599 end
600 InformantConfig.position.x, InformantConfig.position.y = InformantFrame:GetCenter()
601 end
602  
603 function onLoad()
604 this:RegisterEvent("ADDON_LOADED")
605  
606 if (not InformantConfig) then
607 InformantConfig = {}
608 setFilterDefaults()
609 end
610  
611 InformantFrameTitle:SetText(_INFM('FrameTitle'))
612 -- Informant.InitTrades();
613 end
614  
615 local function frameLoaded()
616 Stubby.RegisterEventHook("PLAYER_LEAVING_WORLD", "Informant", onQuit)
617 Stubby.RegisterFunctionHook("EnhTooltip.AddTooltip", 300, tooltipHandler)
618  
619 onLoad()
620  
621 -- Setup the default for stubby to always load (people can override this on a
622 -- per toon basis)
623 Stubby.SetConfig("Informant", "LoadType", "always", true)
624  
625 -- Register our temporary command hook with stubby
626 Stubby.RegisterBootCode("Informant", "CommandHandler", [[
627 local function cmdHandler(msg)
628 local i,j, cmd, param = string.find(string.lower(msg), "^([^ ]+) (.+)$")
629 if (not cmd) then cmd = string.lower(msg) end
630 if (not cmd) then cmd = "" end
631 if (not param) then param = "" end
632 if (cmd == "load") then
633 if (param == "") then
634 Stubby.Print("Manually loading Informant...")
635 LoadAddOn("Informant")
636 elseif (param == "always") then
637 Stubby.Print("Setting Informant to always load for this character")
638 Stubby.SetConfig("Informant", "LoadType", param)
639 LoadAddOn("Informant")
640 elseif (param == "never") then
641 Stubby.Print("Setting Informant to never load automatically for this character (you may still load manually)")
642 Stubby.SetConfig("Informant", "LoadType", param)
643 else
644 Stubby.Print("Your command was not understood")
645 end
646 else
647 Stubby.Print("Informant is currently not loaded.")
648 Stubby.Print(" You may load it now by typing |cffffffff/informant load|r")
649 Stubby.Print(" You may also set your loading preferences for this character by using the following commands:")
650 Stubby.Print(" |cffffffff/informant load always|r - Informant will always load for this character")
651 Stubby.Print(" |cffffffff/informant load never|r - Informant will never load automatically for this character (you may still load it manually)")
652 end
653 end
654 SLASH_INFORMANT1 = "/informant"
655 SLASH_INFORMANT2 = "/inform"
656 SLASH_INFORMANT3 = "/info"
657 SLASH_INFORMANT4 = "/inf"
658 SlashCmdList["INFORMANT"] = cmdHandler
659 ]]);
660 Stubby.RegisterBootCode("Informant", "Triggers", [[
661 local loadType = Stubby.GetConfig("Informant", "LoadType")
662 if (loadType == "always") then
663 LoadAddOn("Informant")
664 else
665 Stubby.Print("]].._INFM('MesgNotLoaded')..[[");
666 end
667 ]]);
668 end
669  
670 function onVariablesLoaded()
671 setFilterDefaults()
672  
673 InformantFrameTitle:SetText(_INFM('FrameTitle'))
674  
675 if (InformantConfig.position) then
676 InformantFrame:ClearAllPoints()
677 InformantFrame:SetPoint("CENTER", UIParent, "BOTTOMLEFT", InformantConfig.position.x, InformantConfig.position.y)
678 end
679  
680 if (not InformantConfig.welcomed) then
681 clear()
682 addLine(_INFM('Welcome'))
683 InformantConfig.welcomed = true
684 end
685  
686 -- Restore key bindings
687 -- This workaround is required for LoadOnDemand addons since their saved
688 -- bindings are deleted upon login.
689 local profile = getKeyBindProfile();
690 if (InformantConfig and InformantConfig.bindings) then
691 if (not InformantConfig.bindings[profile]) then profile = 'global'; end
692 if (InformantConfig.bindings[profile]) then
693 for _,key in ipairs(InformantConfig.bindings[profile]) do
694 SetBinding(key, 'INFORMANT_POPUPDOWN')
695 end
696 end
697 end
698 this:RegisterEvent("UPDATE_BINDINGS") -- Monitor changes to bindings
699  
700 Informant.InitCommands()
701 end
702  
703 function onEvent(event)
704 if (event == "ADDON_LOADED" and string.lower(arg1) == "informant") then
705 onVariablesLoaded()
706 this:UnregisterEvent("ADDON_LOADED")
707 elseif (event == "UPDATE_BINDINGS") then
708 -- Store key bindings for Informant
709 local key1, key2 = GetBindingKey('INFORMANT_POPUPDOWN');
710 local profile = getKeyBindProfile();
711  
712 if (not InformantConfig.bindings) then InformantConfig.bindings = {}; end
713 if (not InformantConfig.bindings[profile]) then InformantConfig.bindings[profile] = {}; end
714  
715 InformantConfig.bindings[profile][1] = key1;
716 InformantConfig.bindings[profile][2] = key2;
717 end
718 end
719  
720 function frameActive(isActive)
721 if (isActive) then
722 scrollUpdate(0)
723 end
724 end
725  
726 function getRowCount()
727 return table.getn(lines)
728 end
729  
730 function scrollUpdate(offset)
731 local numLines = getRowCount()
732 if (numLines > 25) then
733 if (not offset) then
734 offset = FauxScrollFrame_GetOffset(InformantFrameScrollBar)
735 else
736 if (offset > numLines - 25) then offset = numLines - 25 end
737 FauxScrollFrame_SetOffset(InformantFrameScrollBar, offset)
738 end
739 else
740 offset = 0
741 end
742 local line
743 for i=1, 25 do
744 line = lines[i+offset]
745 local f = getglobal("InformantFrameText"..i)
746 if (line) then
747 f:SetText(line)
748 f:Show()
749 else
750 f:Hide()
751 end
752 end
753 if (numLines > 25) then
754 FauxScrollFrame_Update(InformantFrameScrollBar, numLines, 25, numLines)
755 InformantFrameScrollBar:Show()
756 else
757 InformantFrameScrollBar:Hide()
758 end
759 end
760  
761 function testWrap(text)
762 InformantFrameTextTest:SetText(text)
763 if (InformantFrameTextTest:GetWidth() < InformantFrame:GetWidth() - 20) then
764 return text, ""
765 end
766  
767 local pos, test, best, rest
768 best = text
769 rest = nil
770 pos = string.find(text, " ")
771 while (pos) do
772 test = string.sub(text, 1, pos-1)
773 InformantFrameTextTest:SetText(test)
774 if (InformantFrameTextTest:GetWidth() < InformantFrame:GetWidth() - 20) or (not rest) then
775 best = test
776 rest = string.sub(test, pos+1)
777 else
778 break
779 end
780 pos = string.find(text, " ", pos+1)
781 end
782 return best, rest
783 end
784  
785 function addLine(text, color, level)
786 if (text == nil) then return end
787 if (not level) then level = 1 end
788 if (level > 100) then
789 return
790 end
791  
792 if (type(text) == "table") then
793 for pos, line in text do
794 addLine(line, color, level)
795 end
796 return
797 end
798  
799 if (not text) then
800 table.insert(lines, "nil")
801 else
802 local best, rest = testWrap(text)
803 if (color) then
804 table.insert(lines, string.format("|cff%s%s|r", color, best))
805 else
806 table.insert(lines, best)
807 end
808 if (rest) and (rest ~= "") then
809 addLine(rest, color, level+1)
810 end
811 end
812 scrollUpdate()
813 end
814  
815 function clear()
816 lines = {}
817 scrollUpdate()
818 end
819  
820 function setFilterDefaults()
821 if (not InformantConfig.filters) then InformantConfig.filters = {}; end
822 for k,v in pairs(filterDefaults) do
823 if (InformantConfig.filters[k] == nil) then
824 InformantConfig.filters[k] = v;
825 end
826 end
827 end
828  
829 -- Key binding helper functions
830  
831 function getKeyBindProfile()
832 if (IsAddOnLoaded("PerCharBinding")) then
833 return GetRealmName() .. ":" .. UnitName("player")
834 end
835 return 'global'
836 end
837  
838 -- GLOBAL OBJECT
839  
840 Informant = {
841 version = INFORMANT_VERSION,
842 GetItem = getItem,
843 GetRowCount = getRowCount,
844 AddLine = addLine,
845 Clear = clear,
846 ShowHideInfo = showHideInfo,
847  
848 -- These functions are only meant for internal use.
849 SetSkills = setSkills,
850 SetRequirements = setRequirements,
851 SetVendors = setVendors,
852 SetDatabase = setDatabase,
853 FrameActive = frameActive,
854 FrameLoaded = frameLoaded,
855 ScrollUpdate = scrollUpdate,
856 GetFilter = getFilter,
857 GetFilterVal = getFilterVal,
858 GetLocale = getLocale,
859 OnEvent = onEvent,
860 SetFilter = setFilter,
861 SetFilterDefaults = setFilterDefaults,
862 }
863