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