| Nenue@6 | 1 --- Turok - Import.lua | 
| Nenue@6 | 2 -- @file-author@ | 
| Nenue@6 | 3 -- @project-revision@ @project-hash@ | 
| Nenue@6 | 4 -- @file-revision@ @file-hash@ | 
| Nenue@6 | 5 -- Created: 1/4/2016 11:07 AM | 
| Nenue@6 | 6 -- Dialog interfaces and framework debugging tools; see the Google Doc | 
| Nenue@6 | 7 | 
| Nenue@6 | 8 local tconcat, unpack, pairs, ipairs, tostring, string = table.concat, unpack, pairs, ipairs, tostring, string | 
| Nenue@6 | 9 local BOOKTYPE_SPELL, GetSpellBookItemName, GetSpellBookItemInfo = BOOKTYPE_SPELL, GetSpellBookItemName, GetSpellBookItemInfo | 
| Nenue@6 | 10 local GetSpellTabInfo, GetNumSpellTabs, GetSpellInfo, GetFlyoutInfo, GetSpellDescription = GetSpellTabInfo, GetNumSpellTabs, GetSpellInfo, GetFlyoutInfo, GetSpellDescription | 
| Nenue@6 | 11 local GetFlyoutSlotInfo, GetSpellBaseCooldown, FindSpellBookSlotBySpellID, IsTalentSpell = GetFlyoutSlotInfo, GetSpellBaseCooldown, FindSpellBookSlotBySpellID, IsTalentSpell | 
| Nenue@6 | 12 local GetNumClasses, GetClassInfo, GetNumSpecializationsForClassID, GetSpecializationInfoForClassID | 
| Nenue@6 | 13 = GetNumClasses, GetClassInfo, GetNumSpecializationsForClassID, GetSpecializationInfoForClassID | 
| Nenue@6 | 14 local _G, setmetatable, type, T = _G, setmetatable, type, Turok | 
| Nenue@6 | 15 local mod = Turok.modules.TimerControl | 
| Nenue@6 | 16 mod.EditDialog = TkTimerConfig | 
| Nenue@6 | 17 mod.SelectDialog = {} | 
| Nenue@6 | 18 | 
| Nenue@6 | 19 local print = function(...) | 
| Nenue@6 | 20   if Devian and DevianDB.workspace ~= 1 then | 
| Nenue@6 | 21     print('Dialog', ...) | 
| Nenue@6 | 22   end | 
| Nenue@6 | 23 end | 
| Nenue@6 | 24 print('Peep!', ...) | 
| Nenue@6 | 25 local strpad = function(str, num) | 
| Nenue@6 | 26   return tostring(str) .. string.rep(' ', num - #tostring(str)) | 
| Nenue@6 | 27 end | 
| Nenue@6 | 28 | 
| Nenue@6 | 29 --- Handles mouse click on spellbook row frame | 
| Nenue@6 | 30 mod.SpellBook_Click = function(self, btn) | 
| Nenue@6 | 31   print('mouse', btn, self.spellID) | 
| Nenue@6 | 32   mod.Dialog_Select(mod.EditDialog, self.spellID) | 
| Nenue@6 | 33 end | 
| Nenue@6 | 34 | 
| Nenue@6 | 35 --- Creates the spell book import frame | 
| Nenue@6 | 36 -- | 
| Nenue@6 | 37 local cmd | 
| Nenue@6 | 38 function mod.Import_Open() | 
| Nenue@6 | 39   local self = mod | 
| Nenue@6 | 40   print('Spirit', 'SpecSpells') | 
| Nenue@6 | 41   local book_list = {} | 
| Nenue@6 | 42   local tab = {} | 
| Nenue@6 | 43   local list_info = {} | 
| Nenue@6 | 44   local book_max = 0 | 
| Nenue@6 | 45   for k = 1, GetNumSpellTabs() do | 
| Nenue@6 | 46     local name, texture, offset, numSpells = GetSpellTabInfo(k) | 
| Nenue@6 | 47     tab[offset] = {k, name, texture, numSpells} | 
| Nenue@6 | 48     print('Spirit', name, offset, numSpells) | 
| Nenue@6 | 49     book_max = offset + numSpells | 
| Nenue@6 | 50   end | 
| Nenue@6 | 51   local tabID, tabName, tabTexture | 
| Nenue@6 | 52   local flyout, spellflyout = {}, {} | 
| Nenue@6 | 53   for i = 1, book_max do | 
| Nenue@6 | 54     if tab[i] then | 
| Nenue@6 | 55       tabID, tabName, tabTexture = unpack(tab[i]) | 
| Nenue@6 | 56     end | 
| Nenue@6 | 57 | 
| Nenue@6 | 58     if book_list[i] == nil then | 
| Nenue@6 | 59       local skillType, spellID = GetSpellBookItemInfo(i, BOOKTYPE_SPELL) | 
| Nenue@6 | 60       local spellNameUpper, spellSubText = GetSpellBookItemName(i, BOOKTYPE_SPELL) | 
| Nenue@6 | 61       local spellName, spellRank, spellTexture, castTime, minRange, maxRange = GetSpellInfo(spellID) | 
| Nenue@6 | 62       _G.print('Spirit', i, spellID, spellName) | 
| Nenue@6 | 63       _G.print('Spirit', '  ', skillType, spellSubText) | 
| Nenue@6 | 64 | 
| Nenue@6 | 65       local spellDesc | 
| Nenue@6 | 66       if skillType == 'FLYOUT' then | 
| Nenue@6 | 67         local numSlots | 
| Nenue@6 | 68         spellName, spellDesc, numSlots = GetFlyoutInfo(spellID) | 
| Nenue@6 | 69         print('flyout #'..spellID..':', spellName) | 
| Nenue@6 | 70         flyout[spellID] = {} | 
| Nenue@6 | 71         for i=1, numSlots do | 
| Nenue@6 | 72           local fspellID, _, isKnown, fSpellName, fSpellValue = GetFlyoutSlotInfo(spellID, i) | 
| Nenue@6 | 73           print('  spell #', fspellID, fSpellName, isKnown) | 
| Nenue@6 | 74           if isKnown then | 
| Nenue@6 | 75           flyout[spellID][i] = fspellID | 
| Nenue@6 | 76           spellflyout[fspellID] = spellID | 
| Nenue@6 | 77           end | 
| Nenue@6 | 78         end | 
| Nenue@6 | 79 | 
| Nenue@6 | 80       else | 
| Nenue@6 | 81         spellDesc = GetSpellDescription(spellID) | 
| Nenue@6 | 82       end | 
| Nenue@6 | 83 | 
| Nenue@6 | 84       book_list[i] = { | 
| Nenue@6 | 85         skillType = skillType, | 
| Nenue@6 | 86         spellIndex = i, | 
| Nenue@6 | 87         spellID = spellID, | 
| Nenue@6 | 88         spellName = spellName, | 
| Nenue@6 | 89         spellDesc = spellDesc, | 
| Nenue@6 | 90         spellNameUpper = spellNameUpper, | 
| Nenue@6 | 91         spellSubText = spellSubText, | 
| Nenue@6 | 92         spellTexture = spellTexture, | 
| Nenue@6 | 93         spellCooldown = GetSpellBaseCooldown(spellID), | 
| Nenue@6 | 94         castTime = castTime, | 
| Nenue@6 | 95         minRange = minRange, | 
| Nenue@6 | 96         maxRange = maxRange, | 
| Nenue@6 | 97         tabID = tabID, | 
| Nenue@6 | 98         tabName = tabName, | 
| Nenue@6 | 99         tabTexture = tabTexture | 
| Nenue@6 | 100       } | 
| Nenue@6 | 101 | 
| Nenue@6 | 102 | 
| Nenue@6 | 103 | 
| Nenue@6 | 104       end | 
| Nenue@6 | 105   end | 
| Nenue@6 | 106 | 
| Nenue@6 | 107   local selector = CreateFrame('Frame', 'TkSpellSelector', UIParent, 'TurokListFrame') | 
| Nenue@6 | 108   self.frames.selector = selector | 
| Nenue@6 | 109   selector.name:SetText("Spells") | 
| Nenue@6 | 110   selector:SetPoint('TOP') | 
| Nenue@6 | 111   selector.page = 1 | 
| Nenue@6 | 112 | 
| Nenue@6 | 113   selector.GetRow = function(row, info, id, item_num) | 
| Nenue@6 | 114     print('  ', row:GetName(), info, id, item_num) | 
| Nenue@6 | 115     if not row.opts then | 
| Nenue@6 | 116       row.opts = { | 
| Nenue@6 | 117         CreateFrame('CheckButton', 'TkCheck_'..item_num, row, 'TurokCheckButtonInline'), | 
| Nenue@6 | 118         row:CreateFontString('TextItem_'..item_num, 'OVERLAY', 'TurokFontDetail'), | 
| Nenue@6 | 119         row:CreateTexture(nil, 'OVERLAY'), | 
| Nenue@6 | 120         row:CreateTexture(nil, 'OVERLAY'), | 
| Nenue@6 | 121         row:CreateFontString('TextItem_'..item_num..'ID', 'OVERLAY', 'TurokFontDetail'), | 
| Nenue@6 | 122       } | 
| Nenue@6 | 123     end | 
| Nenue@6 | 124     local page = book_list[id] | 
| Nenue@6 | 125     if page.skillType == 'FLYOUT' then | 
| Nenue@6 | 126       row.background:SetTexture(1,.2,.3,.4) | 
| Nenue@6 | 127 | 
| Nenue@6 | 128     elseif rawget(mod.frames.spellID, page.spellID) then | 
| Nenue@6 | 129       print('has timer frame under spell #', page.spellID, mod.frames.spellID[page.spellID]) | 
| Nenue@6 | 130        row.background:SetTexture(1,1,0,1) | 
| Nenue@6 | 131       local timer = mod.frames.spellID[page.spellID] | 
| Nenue@6 | 132       row:SetScript('OnMouseDown', function(self) self.clicked = true end) | 
| Nenue@6 | 133       row:SetScript('OnMouseUp', function(self) if self.clicked then self.clicked = nil mod.Dialog_Select(mod.Editor, timer.timerName) end end) | 
| Nenue@6 | 134     elseif page.spellCooldown and page.spellCooldown > 0 then | 
| Nenue@6 | 135         row.background:SetTexture(.3,.6,1,1) | 
| Nenue@6 | 136     else | 
| Nenue@6 | 137         row.background:SetTexture(0,0,0,0.3) | 
| Nenue@6 | 138     end | 
| Nenue@6 | 139 | 
| Nenue@6 | 140     row:SetScript('OnMouseDown', mod.SpellBook_Click) | 
| Nenue@6 | 141 | 
| Nenue@6 | 142     row.desc = page.spellDesc | 
| Nenue@6 | 143     row.spellID = page.spellID | 
| Nenue@6 | 144     row.opts[1].desc = page.skillType | 
| Nenue@6 | 145     row.opts[1]:SetSize(20,20) | 
| Nenue@6 | 146     row.opts[1].description:SetText(nil) | 
| Nenue@6 | 147     row.opts[1]:SetChecked(page.checked) | 
| Nenue@6 | 148     row.opts[2]:SetText(page.spellName) | 
| Nenue@6 | 149     row.opts[2]:SetWidth(200) | 
| Nenue@6 | 150     row.opts[2]:SetJustifyH('LEFT') | 
| Nenue@6 | 151     row.opts[3]:SetSize(20,20) | 
| Nenue@6 | 152     row.opts[3]:SetTexture(page.spellTexture) | 
| Nenue@6 | 153     row.opts[3]:SetPoint('CENTER') | 
| Nenue@6 | 154     row.opts[4]:SetSize(20,20) | 
| Nenue@6 | 155     row.opts[4]:SetTexture(page.tabTexture) | 
| Nenue@6 | 156     row.opts[4]:SetPoint('CENTER') | 
| Nenue@6 | 157     row.opts[5]:SetWidth(60) | 
| Nenue@6 | 158     row.opts[5]:SetJustifyH('LEFT') | 
| Nenue@6 | 159     row.opts[5]:SetText(page.spellID) | 
| Nenue@6 | 160   end | 
| Nenue@6 | 161 | 
| Nenue@6 | 162   selector.Click = function(button, list) | 
| Nenue@6 | 163     local b = button:GetName():match("_(%a+)$") | 
| Nenue@6 | 164     if b == 'Prev' then | 
| Nenue@6 | 165       --print(b, list.offset, list.num_rows) | 
| Nenue@6 | 166       if list.page > 1 then | 
| Nenue@6 | 167         list.page = list.page - 1 | 
| Nenue@6 | 168         TkList_SetView(list, list.num_rows * (list.page-1) + 1) | 
| Nenue@6 | 169       end | 
| Nenue@6 | 170       list.pagenum:SetText(list.page) | 
| Nenue@6 | 171     elseif b == 'Next' then | 
| Nenue@6 | 172       --print(' ',list.page, list.num_rows, list.max_row) | 
| Nenue@6 | 173       if (list.page) * list.num_rows < list.max_row then | 
| Nenue@6 | 174         list.page = list.page + 1 | 
| Nenue@6 | 175         TkList_SetView(list, list.offset + list.num_rows) | 
| Nenue@6 | 176       end | 
| Nenue@6 | 177       list.pagenum:SetText(list.page) | 
| Nenue@6 | 178 | 
| Nenue@6 | 179     elseif b == 'Add' then | 
| Nenue@6 | 180       mod.CommitBook(book_list, tab, list_info) | 
| Nenue@6 | 181     end | 
| Nenue@6 | 182     --print(list.page, list.offset, list.num_rows) | 
| Nenue@6 | 183   end | 
| Nenue@6 | 184 | 
| Nenue@6 | 185   selector.Wheel = function(self, delta) | 
| Nenue@6 | 186     local offset = self.offset - delta | 
| Nenue@6 | 187     if offset > 0 and offset <= (self.max_row - self.num_rows) then | 
| Nenue@6 | 188       TkList_SetView(self, offset) | 
| Nenue@6 | 189     end | 
| Nenue@6 | 190   end | 
| Nenue@6 | 191 | 
| Nenue@6 | 192   selector.Check = function(checkbutton, row, list) | 
| Nenue@6 | 193     local index = checkbutton:GetParent().actual_row | 
| Nenue@6 | 194     book_list[index].checked = (not book_list[index].checked) and true or false | 
| Nenue@6 | 195     checkbutton:SetChecked(book_list[index].checked) | 
| Nenue@6 | 196 | 
| Nenue@6 | 197     if book_list[index].skillType == 'FLYOUT' then | 
| Nenue@6 | 198       for slot, spellID in pairs(flyout[book_list[index].spellID]) do | 
| Nenue@6 | 199 | 
| Nenue@6 | 200         local spIndex = FindSpellBookSlotBySpellID(spellID) | 
| Nenue@6 | 201         print('  also toggling', slot, spellID, ' book slot', spIndex, book_list[spIndex].spellName) | 
| Nenue@6 | 202         book_list[spIndex].checked = book_list[index].checked | 
| Nenue@6 | 203       end | 
| Nenue@6 | 204       TkList_SetView(list, list.offset) | 
| Nenue@6 | 205     end | 
| Nenue@6 | 206   end | 
| Nenue@6 | 207   TkList_Init(selector, book_list, 1, 12) | 
| Nenue@6 | 208   selector:Show() | 
| Nenue@6 | 209   mod.SelectDialog = selector | 
| Nenue@6 | 210 end | 
| Nenue@6 | 211 --@end-debug@ | 
| Nenue@6 | 212 | 
| Nenue@6 | 213 | 
| Nenue@6 | 214 function mod.CommitBook(bookInfo, tabInfo, uiInfo) | 
| Nenue@6 | 215   print('committing') | 
| Nenue@6 | 216   print('  book data: ', #bookInfo, 'entries') | 
| Nenue@6 | 217   print('  tab data: ', #tabInfo, 'entries') | 
| Nenue@6 | 218 | 
| Nenue@6 | 219   for index, e in ipairs(bookInfo) do | 
| Nenue@6 | 220     if e.checked then | 
| Nenue@6 | 221       local spellPretext = '' | 
| Nenue@6 | 222       if IsTalentSpell(index) then | 
| Nenue@6 | 223         spellPretext = 'Talent' | 
| Nenue@6 | 224       end | 
| Nenue@6 | 225         print('   ', strpad(spellPretext .. e.spellName, 20)) | 
| Nenue@6 | 226         print('   ', strpad(e.spellSubText, 10), strpad(e.spellCooldown,5), strpad(e.skillType,6)) | 
| Nenue@6 | 227 | 
| Nenue@6 | 228     end | 
| Nenue@6 | 229   end | 
| Nenue@6 | 230 end | 
| Nenue@6 | 231 | 
| Nenue@6 | 232 | 
| Nenue@6 | 233 | 
| Nenue@6 | 234 | 
| Nenue@6 | 235 --- /tki command | 
| Nenue@6 | 236 -- Constructs an index that associates global spec ID's with a list of the timers that would display under it. | 
| Nenue@6 | 237 -- List entries are stored as [name] = true to prevent duplication of values in SavedVariables. | 
| Nenue@6 | 238 | 
| Nenue@6 | 239 function mod:CreateIndex() | 
| Nenue@6 | 240 | 
| Nenue@6 | 241   --@debug@ Revert config to defaults | 
| Nenue@6 | 242   _G.TurokData = T.defaults | 
| Nenue@6 | 243   --@end-debug@ | 
| Nenue@6 | 244 | 
| Nenue@6 | 245   mod.db.timerindex = {} | 
| Nenue@6 | 246   setmetatable(mod.db.timerindex, {__mode = "v"}) -- ensure that dead leafs fall off | 
| Nenue@6 | 247   local index = mod.index | 
| Nenue@6 | 248   local timers = mod.timersByName | 
| Nenue@6 | 249 | 
| Nenue@6 | 250   -- build class info hash and create subtables | 
| Nenue@6 | 251   local classID = {} | 
| Nenue@6 | 252   local className = {} | 
| Nenue@6 | 253   local specIDPage = {} | 
| Nenue@6 | 254   local specPageID = {} | 
| Nenue@6 | 255   local classSpecs = {} | 
| Nenue@6 | 256   print('|cFF0088FFCreateIndex|r') | 
| Nenue@6 | 257 | 
| Nenue@6 | 258   --- use the internal class/specialization list | 
| Nenue@6 | 259   for i = 1, GetNumClasses() do | 
| Nenue@6 | 260     local _, tag, id = GetClassInfo(i) | 
| Nenue@6 | 261     classID[tag] = id | 
| Nenue@6 | 262     className[id] = tag | 
| Nenue@6 | 263     index[id] = {} | 
| Nenue@6 | 264     specPageID[tag] = {} | 
| Nenue@6 | 265     index[tag] = index[id] | 
| Nenue@6 | 266 | 
| Nenue@6 | 267     classSpecs[tag] = GetNumSpecializationsForClassID(id) | 
| Nenue@6 | 268     for j = 1, classSpecs[tag] do | 
| Nenue@6 | 269       local specID, specName = GetSpecializationInfoForClassID(id, j) | 
| Nenue@6 | 270       print('|cFFFF0088map:|r', tag, j, specID, specName) | 
| Nenue@6 | 271       specIDPage[specID] = j | 
| Nenue@6 | 272       specPageID[tag][j] = specID | 
| Nenue@6 | 273       index[specID] = {} | 
| Nenue@6 | 274       index[id][j] = {} | 
| Nenue@6 | 275     end | 
| Nenue@6 | 276   end | 
| Nenue@6 | 277   index.global = {} | 
| Nenue@6 | 278 | 
| Nenue@6 | 279   for name,timer in pairs(timers) do | 
| Nenue@6 | 280     -- class is set | 
| Nenue@6 | 281     if type(timer) == 'table' then | 
| Nenue@6 | 282       print(name) | 
| Nenue@6 | 283       if timer.playerClass then | 
| Nenue@6 | 284 | 
| Nenue@6 | 285         index[timer.playerClass][name] = true | 
| Nenue@6 | 286 | 
| Nenue@6 | 287         -- spec restricted | 
| Nenue@6 | 288         if timer.specPage then | 
| Nenue@6 | 289           if type(timer.specPage) ~= 'table' then | 
| Nenue@6 | 290             -- fix it up | 
| Nenue@6 | 291             timer.specPage = {timer.specPage } | 
| Nenue@6 | 292           end | 
| Nenue@6 | 293 | 
| Nenue@6 | 294           print('  |cFFFFFF00class:|r', timer.playerClass .. ', |cFF99FF00spec:|r '.. tconcat(timer.specPage,', ')) | 
| Nenue@6 | 295           for _, specPage in ipairs(timer.specPage) do | 
| Nenue@6 | 296             index[timer.playerClass][specPage][name] = true | 
| Nenue@6 | 297             index[specPageID[timer.playerClass][specPage]][name] = true | 
| Nenue@6 | 298           end | 
| Nenue@6 | 299 | 
| Nenue@6 | 300           -- no spec restriction, copy it out | 
| Nenue@6 | 301         elseif not timer.specID then | 
| Nenue@6 | 302           print('  |cFFFFFF00class:|r', timer.playerClass .. ', |cFF99FF00spec:|r ALL') | 
| Nenue@6 | 303           for i = 1, classSpecs[timer.playerClass] do | 
| Nenue@6 | 304             local specID = specPageID[timer.playerClass][i] | 
| Nenue@6 | 305 | 
| Nenue@6 | 306             index[timer.playerClass][i][name] = true             -- store for local ID | 
| Nenue@6 | 307             index[specID][name] = true -- store for global ID | 
| Nenue@6 | 308           end | 
| Nenue@6 | 309         end | 
| Nenue@6 | 310       end | 
| Nenue@6 | 311 | 
| Nenue@6 | 312       if timer.specID then | 
| Nenue@6 | 313         index[timer.specID][name] = true | 
| Nenue@6 | 314       end | 
| Nenue@6 | 315 | 
| Nenue@6 | 316       if not (timer.playerClass or timer.specID or timer.specPage) then | 
| Nenue@6 | 317         for tag, id in pairs(classID) do | 
| Nenue@6 | 318           index[tag][name] = true | 
| Nenue@6 | 319           for specPage, specID in pairs(specPageID[tag]) do | 
| Nenue@6 | 320             index[tag][specPage][name] = true | 
| Nenue@6 | 321             index[specID][name] = true | 
| Nenue@6 | 322           end | 
| Nenue@6 | 323         end | 
| Nenue@6 | 324         print('  |cFFFFFF00class:|r ALL, |cFF99FF00spec:|r ALL') | 
| Nenue@6 | 325       end | 
| Nenue@6 | 326     end | 
| Nenue@6 | 327   end | 
| Nenue@6 | 328 | 
| Nenue@6 | 329   _G.TurokData.timerindex = index | 
| Nenue@6 | 330   T:Print('Hive data updated. /rl to commit.') | 
| Nenue@6 | 331 end |