changeset 34:9856ebc63fa4

- half solution to Update being fired multiple times during load - change securefunc handlers to dispense a reason code; catch that reason code in the enclosure passed to hooksecurefunc, and decide whether to update or not from there.
author Nenue
date Sun, 17 Apr 2016 00:21:45 -0400
parents 64f2a9bbea79
children 69d03f8e293e
files Core.xml ObjectiveTracker/Achievements.lua ObjectiveTracker/AutoQuestPopups.lua ObjectiveTracker/BonusObjectives.lua ObjectiveTracker/Events.lua ObjectiveTracker/Frame.lua ObjectiveTracker/ObjectiveTracker.lua ObjectiveTracker/ObjectiveTracker.xml ObjectiveTracker/Quests.lua ObjectiveTracker/Schema.lua ObjectiveTracker/SecureButton.xml ObjectiveTracker/Widgets.lua ObjectiveTracker/Widgets.xml
diffstat 13 files changed, 555 insertions(+), 371 deletions(-) [+]
line wrap: on
line diff
--- a/Core.xml	Fri Apr 15 17:01:06 2016 -0400
+++ b/Core.xml	Sun Apr 17 00:21:45 2016 -0400
@@ -30,6 +30,9 @@
   <Font name="VeneerNumberFont" virtual="true" font="Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf" outline="NORMAL" height="13" >
     <Color r="1" g="1" b="1" a="1" />
   </Font>
+  <Font name="VeneerNumberFontSmall" virtual="true" font="Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Regular.ttf" outline="NORMAL" height="11" >
+    <Color r="1" g="1" b="1" a="1" />
+  </Font>
   <Font name="VeneerTitleFont" virtual="true" font="Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf" outline="NORMAL" height="15" >
     <Color r="1" g="1" b="1" a="1" />
   </Font>
--- a/ObjectiveTracker/Achievements.lua	Fri Apr 15 17:01:06 2016 -0400
+++ b/ObjectiveTracker/Achievements.lua	Sun Apr 17 00:21:45 2016 -0400
@@ -21,46 +21,63 @@
   Cheevs.trackedCheevs = {GetTrackedAchievements()}
   return GetNumTrackedAchievements()
 end
-Cheevs.GetInfo = function(self, index)
-  local cheevID = Cheevs.trackedCheevs[index]
+Cheevs.GetInfo = function(self, watchIndex)
+  --- step 1: confirm primary data and begin an entry if needed
+  local cheevID = Cheevs.trackedCheevs[watchIndex]
   local id, name, points, completed, month, day, year, description, flags, icon, rewardText, isGuildAch, wasEarnedByMe, earnedBy = GetAchievementInfo(cheevID)
+  if not id then return false end
 
-  self.Info[cheevID] = {}
+  if not self.Info[cheevID] then self.Info[cheevID] = {} end
   local c = self.Info[cheevID]
+  local numObjectives = GetAchievementNumCriteria(cheevID)
+
+  local tagInfo = {}
+  local objectives = c.objectives or {}
+  for i = 1, numObjectives do
+    local description, type, completed, quantity, requiredQuantity, characterName, flags, assetID, quantityString, criteriaID = GetAchievementCriteriaInfo(cheevID, i)
+    local line = objectives[i] or {}
+    line.objectiveIndex = i
+    line.cheevID = cheevID
+    line.text = description
+    line.type = type
+    line.finished = completed
+    line.value = quantity
+    line.maxValue = requiredQuantity
+    line.characterName = characterName
+    line.flags = flags
+    line.assetID = assetID
+    line.quantityString = quantityString
+    line.criteriaID = criteriaID
+    objectives[i] = line
+  end
+
+
+  local rewards = {}
+  print('Cheevs.|cFF0088FFGetInfo|r('..watchIndex..')', 'obj:', GetAchievementNumCriteria(cheevID), name, description)
+
+  c.rewardInfo = rewards
+  c.numObjectives = numObjectives
+  c.objectives = objectives
   c.type = 'Cheevs'
-  c.watchIndex = index
+  c.title = name
+  c.points = points
+  c.completed = completed
+  c.month = month
+  c.day = day
+  c.year = year
+  c.description = description
+  c.flags = flags
+  c.icon = icon
+  c.rewardText = rewardText
+  c.isGuildAch = isGuildAch
+  c.wasEarnedByMe = wasEarnedByMe
+  c.earnedBy = earnedBy
+
+  c.tagInfo = tagInfo
+  c.watchIndex = watchIndex
   c.id = cheevID
   c.cheevID = cheevID
-  c.title = name
-  c.points, c.completed, c.month, c.day, c.year, c.description, c.flags, c.icon, c.rewardText, c.isGuildAch, c.wasEarnedByMe, c.earnedBy =
-  points, completed, month, day, year, description, flags, icon, rewardText, isGuildAch, wasEarnedByMe, earnedBy
-  c.numObjectives = GetAchievementNumCriteria(cheevID)
-
-  local tagInfo = {}
-
-
-  c.objectives = {}
-  for i = 1, c.numObjectives do
-    local description, type, completed, quantity, requiredQuantity, characterName, flags, assetID, quantityString, criteriaID = GetAchievementCriteriaInfo(cheevID, i)
-    c.objectives[i] = {
-      objectiveIndex = i,
-      cheevID = cheevID,
-      text = description,
-      type = type,
-      finished = completed,
-      value = quantity,
-      maxValue = requiredQuantity,
-      characterName = characterName,
-      flags = flags,
-      assetID = assetID,
-      quantityString = quantityString,
-      criteriaID = criteriaID,
-    }
-  end
-  print('Cheevs.|cFF0088FFGetInfo|r('..index..')', 'obj:', GetAchievementNumCriteria(cheevID), name, description)
-
-  c.tagInfo = tagInfo
-  self.WatchInfo[index] = c
+  self.WatchInfo[watchIndex] = c
   return self.Info[cheevID]
 end
 
--- a/ObjectiveTracker/AutoQuestPopups.lua	Fri Apr 15 17:01:06 2016 -0400
+++ b/ObjectiveTracker/AutoQuestPopups.lua	Sun Apr 17 00:21:45 2016 -0400
@@ -13,7 +13,7 @@
 --- Data retrieval
 function AutoQuest:GetNumWatched ()
   print(self.name, self)
-  Quest:GetNumWatched()
+  --Quest:GetNumWatched()
   self.numWatched = GetNumAutoQuestPopUps()
 
   return self.numWatched
@@ -32,7 +32,7 @@
   popup.title = title
   popup.description = type
   popup.popupType = type
-  popup.questLogIndex = questLogIndex
+  popup.logIndex = questLogIndex
   popup.popupIndex = popupIndex
 
   self.Info[questID] = popup
@@ -52,9 +52,9 @@
 AutoQuest.Select = function(handler, block)
 
   if block.info.popupType == 'OFFER'  then
-    ShowQuestOffer(block.info.questLogIndex)
+    ShowQuestOffer(block.info.logIndex)
   else
-    ShowQuestComplete(block.info.questLogIndex)
+    ShowQuestComplete(block.info.logIndex)
   end
   RemoveAutoQuestPopUp(block.info.questID)
 end
--- a/ObjectiveTracker/BonusObjectives.lua	Fri Apr 15 17:01:06 2016 -0400
+++ b/ObjectiveTracker/BonusObjectives.lua	Sun Apr 17 00:21:45 2016 -0400
@@ -95,7 +95,7 @@
   local existingTasks = {}
   self.WatchInfo = {}
   print('|cFFFFFF00Bonus.GetNumWatched()|r', #tasks)
-  print('  TasksTable pull:')
+  print(' |cFF00FFFFInternalGetTaskInfo|r:')
   for i, questID in ipairs(tasks) do
     local isInArea, isOnMap, numObjectives = InternalGetTaskInfo(questID)
     local existingTask = self.QuestBlock[questID]
@@ -131,12 +131,11 @@
         t.objectives[objectiveIndex] = t.objectives[objectiveIndex] or  {}
         local  o = t.objectives[objectiveIndex]
 
-        o.objectiveIndex = objectiveIndex
+        o.index = objectiveIndex
         o.text = text
-        o.objectiveType = objectiveType
+        o.type = objectiveType
         o.finished = finished
         o.displayAsObjective = displayAsObjective
-        print('     |cFF00FF88*', objectiveIndex, text)
       end
 
       T.SetRewards(t, questID)
@@ -147,7 +146,7 @@
           taskTitle = GetMapNameByID(GetCurrentMapAreaID())
         end
       end
-
+      t.numObjectives = numObjectives
       t.isInArea = isInArea
       t.isOnMap = isOnMap
       t.existingTask = existingTask
@@ -188,13 +187,30 @@
     end
   end
 
-  print('|cFFFF8800'..block.name..':OnTurnIn call', questID, xp, money)
-  local savedTasks = B.Conf.TasksLog
+  print('|cFFFF8800'..block:GetName()..':OnTurnIn call', questID, xp, money)
+  local savedTasks = B.Conf.TasksLog or {}
 
   info.completedTime = GetTime()
   info.animate = true
-  T.SetAnimate(handler.watchReasonModule)
-  savedTasks[questID] = info
+  T.SetAnimate(self.updateReasonModule)
+  savedTasks[questID] = {
+    id = questID,
+    title = info.title,
+    finished = true,
+    numObjectives = info.numObjectives,
+    objectives = info.objectives,
+    rewardInfo = info.rewardInfo,
+  }
+  B.Conf.TasksLog = savedTasks
+
+  print(' ## CONF TASKLOG ##')
+  for i, t in pairs(savedTasks[questID]) do
+    print('    |cFFFFFF00'.. tostring(i)..'|r', t)
+
+  end
+  for o, j in ipairs(savedTasks[questID].objectives) do
+    print('     |cFF00FFFF#'.. o ..'|r', j.type, j.finished)
+  end
 
   print('adding', info.title, 'to cache')
 end
@@ -209,6 +225,7 @@
 --- Update hooks
 Bonus.UpdateObjectives = function(handler, block)
   Default.UpdateObjectives(handler, block)
+  return 'default'
 end
 
 Bonus.UpdateLine = function(handler, block, line, data)
@@ -216,22 +233,30 @@
   local print = lprint
   local text, attachment = '', nil
   line.displayColor = 'FFFFFF'
-  print('  ', data.objectiveIndex,'|cFFFF0088-|r', data.objectiveType, data.text)
-  if data.objectiveType == 'progressbar' then
+  if data.type == 'progressbar' then
     print('    |cFFFF44DDpercent='..tostring(GetQuestProgressBarPercent(info.questID)))
     local percent = 100
-    attachment = T.SetWidget(line, data, 'ProgressBar', info.questID..'-'..data.objectiveIndex)
+    attachment = T.SetWidget(line, data, 'ProgressBar', info.questID..'-'..data.index)
     if not data.finished then
       percent = GetQuestProgressBarPercent(info.questID)
     end
+    data.value = percent
+    data.maxValue = 100
+
+    print(attachment:GetNumPoints())
+    for i = 1, attachment:GetNumPoints() do
+      print('  ',attachment:GetPoint(i))
+    end
+
+
     attachment.value = percent
     attachment.maxValue = 100
     attachment:SetPoint('TOP', line, 'TOP', 0, 0)
-    attachment.status:SetFormattedText(PERCENTAGE_STRING, (percent / 100))
+    attachment.status:SetFormattedText(PERCENTAGE_STRING, percent)
+    print(attachment.status:GetText())
     print('    |cFFFF0022** text:|r', data.text, '|cFFFF0022value:|r', data.value, '|cFFFF0022max:|r', data.maxValue)
-  else
-    text = data.text
   end
+  text = data.text
   return text, attachment
 end
 
--- a/ObjectiveTracker/Events.lua	Fri Apr 15 17:01:06 2016 -0400
+++ b/ObjectiveTracker/Events.lua	Sun Apr 17 00:21:45 2016 -0400
@@ -7,66 +7,71 @@
 local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame')
 local print = B.print('Objectives')
 
+local _G = _G
+local OBJECTIVE_TRACKER_UPDATE_MODULE_ACHIEVEMENT = OBJECTIVE_TRACKER_UPDATE_MODULE_ACHIEVEMENT
+local OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST_ADDED = OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST_ADDED
+local OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST = OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST
+local OBJECTIVE_TRACKER_UPDATE_MODULE_AUTO_QUEST_POPUP = OBJECTIVE_TRACKER_UPDATE_MODULE_AUTO_QUEST_POPUP
+local GetQuestID, GetQuestLogIndexByID, AddQuestWatch, SetSuperTrackedQuestID = GetQuestID, GetQuestLogIndexByID, AddQuestWatch, SetSuperTrackedQuestID
+local QuestPOIUpdateIcons = QuestPOIUpdateIcons
 -------------------------------------------------------------------
---- SecureHooked blizzard functions
+--- Deal with blizzard API calls that affect the tracker/log contents
+--- mainly just hiding blocks until they can be picked up by the next update event
 -------------------------------------------------------------------
 T.AddQuestWatch = function(questID)
-    T:Update(0x00000003)
+  if not B.Conf.VeneerObjectiveWrapper.enabled then return end
+  return OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST
 end
 
 local Quest = T.Quest
 T.RemoveQuestWatch = function(questIndex, ...)
   print('|cFFFF8800RemoveQuestWatch', questIndex, ...)
-
-  local info = T.Quest.LogInfo[questIndex]
-
-  -- remove quest refs
-  local block = Quest.QuestBlock[info.questID]
-  Quest.QuestBlock[info.questID] = nil
-  Quest.LogBlock[questIndex] = nil
-
-  -- remove if they still match
-  if Quest.WatchInfo[info.watchIndex] == info then
-    print('cleaning dead WatchInfo entry')
-    Quest.WatchInfo[info.watchIndex] = nil
+  local block = T.Quest.LogBlock[questIndex]
+  if block then
+    block:Hide()
   end
-  if Quest.itemButtons[info.questID] then
-    -- hide for now, it will get cleaned up shortly
-    Quest.itemButtons[info.questID]:Hide()
-  end
-
-  T:Update(OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST)
+  return OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST
 end
 
 T.AddTrackedAchievement = function(cheevID)
   T.CleanWidgets()
-  T:Update(OBJECTIVE_TRACKER_UPDATE_MODULE_ACHIEVEMENT)
+  return OBJECTIVE_TRACKER_UPDATE_MODULE_ACHIEVEMENT
 end
 
 
 T.RemoveTrackedAchievement = function(cheevID)
-  print('|cFFFF8800UntrackAchievement', cheevID)
   T.CleanWidgets()
-  T:Update(OBJECTIVE_TRACKER_UPDATE_MODULE_ACHIEVEMENT)
+  return OBJECTIVE_TRACKER_UPDATE_MODULE_ACHIEVEMENT
 end
 
 T.AcceptQuest = function()
-  T:Update(OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST_ADDED)
 end
 
 T.AbandonQuest = function()
   QuestPOIUpdateIcons()
-  T:Update(OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST)
+  return OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST
 end
-T.TurnInQuest = function()
+T.CompleteQuest = function()
+  local questID = GetQuestID()
+  if T.Quest.Info[questID] then
+    local q = T.Quest.Info[questID]
+    if q.logIndex then
+      local block = T.Quest.LogBlock[q.logIndex]
+      if block and block.id == questID then
+        block:Hide()
+      end
+    end
+  end
+
   QuestPOIUpdateIcons()
-  T:Update(OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST)
+  return OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST
 end
 T.AddAutoQuestPopUp = function(...)
-   T:Update(OBJECTIVE_TRACKER_UPDATE_MODULE_AUTO_QUEST_POPUP)
+  return OBJECTIVE_TRACKER_UPDATE_MODULE_AUTO_QUEST_POPUP
 end
-T.RemoveAutoQuestPopUp = function(...)
-  T:Update(OBJECTIVE_TRACKER_UPDATE_MODULE_AUTO_QUEST_POPUP)
+T.RemoveAutoQuestPopUp = function(questID)
+  return OBJECTIVE_TRACKER_UPDATE_MODULE_AUTO_QUEST_POPUP
+
 end
 
 
--- a/ObjectiveTracker/Frame.lua	Fri Apr 15 17:01:06 2016 -0400
+++ b/ObjectiveTracker/Frame.lua	Sun Apr 17 00:21:45 2016 -0400
@@ -6,7 +6,7 @@
 local B = select(2,...).frame
 local Module = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame')
 local _G, ipairs, max, min, unpack, floor, pairs, tostring, type, band = _G, ipairs, max, min, unpack, floor, pairs, tostring, type, bit.band
-local IsResting, UnitXP, UnitXPMax, GetXPExhaustion = IsResting, UnitXP, UnitXPMax, GetXPExhaustion
+local IsResting, UnitXP, UnitXPMax, GetXPExhaustion, tinsert, tremove = IsResting, UnitXP, UnitXPMax, GetXPExhaustion, table.insert, table.remove
 local UnitLevel, IsQuestWatched, UIParent = UnitLevel, IsQuestWatched, UIParent
 local GetAutoQuestPopUp, GetQuestLogCompletionText = GetAutoQuestPopUp, GetQuestLogCompletionText
 local PERCENTAGE_STRING, GetQuestProgressBarPercent = PERCENTAGE_STRING, GetQuestProgressBarPercent
@@ -14,76 +14,91 @@
 local InCombatLockdown, format, lshift, CreateFrame = InCombatLockdown, format, bit.lshift, CreateFrame
 local IsModifiedClick, ChatEdit_GetActiveWindow = IsModifiedClick, ChatEdit_GetActiveWindow
 local print = B.print('Tracker')
+local oprint = B.print('Objectives')
+local bprint = B.print('Block')
+local tprint = B.print('Tracker')
+local lprint = B.print('Line')
 local unitLevel = 1
 local OBJECTIVE_TRACKER_UPDATE_REASON = OBJECTIVE_TRACKER_UPDATE_REASON
 local debug = false
 
---- Upvalues
+--- FRAMES
 local Wrapper = _G.VeneerObjectiveWrapper
 local Scroller = Wrapper.scrollArea
 local Scroll = _G.VeneerObjectiveScroll
 local orderedHandlers = Module.orderedHandlers
 local orderedNames = Module.orderedNames
 
---- Temp values set during updates
+--- FRAME TEMP VARIABLES
 local wrapperWidth, wrapperHeight
 local scrollWidth, scrollHeight
-local previousBlock
-local currentBlock
---- todo: source these from config
+
+--- SCHEMA VARIABLES
+local schemaName, lastSchema = {
+  tracker = '',
+  block = '',
+  line = ''
+}, {}
+local trackerSchema, blockSchema, lineSchema
+
 local itemButtonSize, itemButtonSpacing =  36, 1
+local wrapperMaxWidth, wrapperMaxHeight = 270, 490 -- these are the hard bounds, actual *Height variables are changed
+local wrapperHeadFont, wrapperHeadSize, wrapperHeadOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 16, 'NONE'
+local wrapperPosition = {'RIGHT', UIParent, 'RIGHT', -84, 0 }
+local rewardSize = 24
 
 local headerHeight, headerColor, headerSpacing = 16, {1,.75,0,1}, 2
 local headerbg = {'VERTICAL', 1, 1, 0.5, 0.5, 1, 1, 0.5, 0}
 local headerFont, headerSize, headerOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 14, 'OUTLINE'
 
 local titlebg = {'HORIZONTAL', 1, 0, .7, 0, 1, 0, .7, .2}
-local titlebg_daily = {'HORIZONTAL', 0, .7, 1, 0, 0, 1, .7, .2 }
-local titlebg_account = {'HORIZONTAL', 0, .45, 1, 0, 0,  .45, 1, .2}
 local titleFont, titleSize, titleOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 16, 'OUTLINE'
+local titleColor = {0,.7,1,1}
 
 local textbg =  {'HORIZONTAL', 0, 0, 0, 0.4, 0, 0, 0, 0 }
-local textbg_daily = {'HORIZONTAL', 0, .7, 1, .1, 0, 1, .7, .075 }
-local textbg_account = {'HORIZONTAL', 0, .45, 1, 0.4, 0,  .41, 1, .085 }
 local textFont, textSize, textOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Regular.ttf]], 16, 'OUTLINE'
-
+local textColor = {1,1,1,1}
 
 local selectionbg = {'HORIZONTAL', 1, 1, 1, 0, 1, 1, 1, 0.225}
 local titleSpacing, textSpacing, blockSpacing = 3, 3, 1
 local titleIndent, textIndent,selectionIndent = 2, 5, 50
+--- END SCHEMA
+--- schema swapper
+Module.UpdateSchema = function(layer, newSchema)
+  if not (Module.Conf.Schema[layer] and Module.Conf.Schema[layer][newSchema]) then
+    return
+  elseif schemaName[layer] == newSchema then
+    return
+  end
+  lastSchema[layer] = schemaName[layer]
+  schemaName[layer] = newSchema
+  local c = Module.Conf.Schema[layer][newSchema]
 
-local lineColors = {
-  normal = {
-    text = {.5,.75,1},
-  },
-  completed = {
-    text = {0, 1, 0}
-  },
-  failed = {
-    text = {1,0,0 }
-  },
-  autocomplete = {
-    text = {0,1,0 }
-  },
-  object = {
-    text = {0,1,1}
-  },
-  monster = {
-    text = {1,1,0}
-  },
-  item = {
-    text = {1,.25,.5}
-  }
-}
-
-local wrapperMaxWidth, wrapperMaxHeight = 270, 490 -- these are the hard bounds, actual *Height variables are changed
-local wrapperHeadFont, wrapperHeadSize, wrapperHeadOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 16, 'NONE'
-local wrapperPosition = {'RIGHT', UIParent, 'RIGHT', -84, 0 }
-local rewardSize = 24
-local oprint = B.print('Objectives')
-local bprint = B.print('Block')
-local tprint = B.print('Tracker')
-local lprint = B.print('Line')
+  if layer == 'tracker' then
+    headerHeight, headerSpacing = c.headerHeight, c.headerSpacing
+    headerColor = c.headerColor
+    headerbg = c.headerbg
+    headerFont, headerSize, headerOutline = c.headerFont, c.headerSize, c.headerOutline
+    trackerSchema = newSchema
+  elseif layer == 'block' then
+    titlebg = c.titlebg
+    titleFont, titleSize, titleOutline = c.titleFont, c.titleSize, c.titleOutline
+    selectionbg = c.selectionbg
+    titleSpacing, textSpacing, blockSpacing = c.titleSpacing, c.textSpacing, c.blockSpacing
+    titleIndent, textIndent,selectionIndent = 2, 5, 50
+    titleColor = c.titleColor
+    rewardSize = 24
+    blockSchema = newSchema
+    textFont, textSize, textOutline = c.textFont, c.textSize, c.textOutline
+    textbg =  c.textbg
+    textIndent = c.textIndent
+    rewardSize = c.rewardSize
+  elseif layer == 'line' then
+    textColor = c.textColor
+    lineSchema = newSchema
+  end
+  print('|cFFFF0088UpdateSchema:|r', layer, lastSchema[layer], '->', newSchema)
+end
 
 Default.AddBlock = function(self, block, blockIndex)
   local blockIndex = blockIndex or (self.currentBlock + 1)
@@ -91,6 +106,47 @@
   local tracker = self.frame
   local info = block.info
 
+  if blockSchema ~= block.schema then
+    print('new schema detected, applicating...')
+    block.schema = blockSchema
+    block:SetWidth(Module.Conf.Wrapper.Width)
+    block.title:SetSpacing(titleSpacing)
+    block.title:SetPoint('TOP', block, 'TOP', 0, -titleSpacing)
+    block.title:SetPoint('LEFT', block, 'LEFT', titleIndent, 0)
+    block.titlebg:SetTexture(1,1,1,1)
+    block.titlebg:SetGradientAlpha(unpack(titlebg))
+    block.titlebg:SetPoint('TOP', block, 'TOP', 0, 0)
+    block.titlebg:SetPoint('BOTTOM', block.title, 'BOTTOM', 0, -titleSpacing)
+    block.status:SetSpacing(textSpacing)
+    block.status:SetPoint('TOP', block.titlebg, 'BOTTOM', 0, -textSpacing)
+    block.status:SetPoint('LEFT', block.titlebg, 'LEFT', textIndent, 0)
+    block.statusbg:SetPoint('TOP', block.titlebg, 'BOTTOM', 0, 0)
+    block.statusbg:SetPoint('BOTTOM', block, 'BOTTOM', 0, 0)
+    block.statusbg:SetTexture(1,1,1,1)
+    block.statusbg:SetGradientAlpha(unpack(textbg))
+    block.SelectionOverlay:SetGradientAlpha(unpack(selectionbg))
+    block.SelectionOverlay:SetPoint('TOPLEFT', selectionIndent, 0)
+    block.SelectionOverlay:SetPoint('BOTTOMRIGHT')
+
+    local anchor, target, point, x, y = 'TOPRIGHT', block, 'TOPRIGHT', -2, -2
+    for i, tile in ipairs(block.rewardTile)  do
+      print(rewardSize)
+      tile:SetSize(rewardSize, rewardSize)
+      tile:ClearAllPoints()
+      tile:SetPoint(anchor, target, point, x, y)
+      block.rewardLabel[i]:SetPoint('TOP', tile, 'TOP', 0, 0)
+      anchor, target, point, x, y = 'TOPRIGHT', tile, 'TOPLEFT', -2, 0
+    end
+  end
+
+  if block.debug then
+    local func = (B.Conf.GuidesMode == true) and 'Show' or 'Hide'
+    for _, region in ipairs(block.debug) do
+      region[func]()
+    end
+  end
+
+  -- positioned by offset since they tend to swap contents
   block.index = blockIndex
   block:SetPoint('TOPLEFT', self.frame, 'TOPLEFT', 0, block.offset)
   block:SetPoint('RIGHT', tracker,'RIGHT', 0, 0)
@@ -98,7 +154,6 @@
   self.currentAnchor = block
   print('    |cFFFFFF00'..tracker.height..'|r', '|cFF00FF00'..block:GetName()..'|r', block.height, tracker.height)
   tracker.height = tracker.height + block.height
-  self.numBlocks = max(self.numBlocks, blockIndex)
   self.actualBlocks = self.actualBlocks + 1
 end
 
@@ -125,42 +180,46 @@
 Default.AddLine = function(handler, block, text, attachment, template)
   local print = lprint
   local lineIndex = block.currentLine + 1
-  local line = handler:GetLine(block)
+  local line = handler:GetLine(block, lineIndex)
   line.index = lineIndex
-  line:ClearAllPoints()
-  line:SetPoint('LEFT', block, 'LEFT', 0, 0)
-  line:SetPoint('TOP', block.endPoint, 'BOTTOM', 0, 0)
-  line:SetPoint('RIGHT', block, 'RIGHT', 0, 0)
+  if line.schema ~= template then
+    print('  |cFF00FF00change schema', template)
+    Module.UpdateSchema('line', template)
+    line.status:SetSpacing(textSpacing)
+    line.status:SetPoint('LEFT', line, 'LEFT', textIndent, 0)
+    line.status:SetPoint('RIGHT', line, 'RIGHT', -textIndent, 0)
+    line.status:SetTextColor(unpack(textColor))
+    line.schema = template
+  else
+    print('  |cFFFFFF00keep schema', template)
+  end
+  line:SetPoint('TOP', block.endPoint, 'BOTTOM', 0, -textSpacing)
   line:Show()
 
-  print('     |cFF0088FFAddLine >>|r', block, '::',  block.endPoint:GetName(),'"'.. text .. '"', attachment, template)
+
+  print(' |cFF0088FFAddLine >>|r', block, '::',  block.endPoint:GetName(),'"'.. text .. '"', attachment, template)
+
+
+  -- fill in the text, then derive pixel-rounded height
   line.status:SetText(text)
-  line.height = floor(line.status:GetStringHeight()+.5) + textSpacing
-  line:SetHeight(line.height)
-
-  local r, g, b, a = 1, 1, 1, 1
-  if lineColors[template] then
-    r, g, b = unpack(lineColors[template].text)
-  end
-  line.status:SetTextColor(r, g, b, a)
+  line.height = floor(line.status:GetStringHeight()+.5)
 
   -- For progressbar and timer lines, status text may be used as the title heading
   if attachment then
-    local widgetOffset = 0
-    line.height = attachment:GetHeight() + textSpacing
-    if text and #text >= 1 then
-      widgetOffset = line.status:GetHeight() + textSpacing
-      line.height = line.height + floor(line.status:GetStringHeight()+.5) + textSpacing
-      print('     |cFFFF0088doing things with captioned widget')
-    else
-      print('     |cFFFF0088doing things with a widget')
+    print('  |cFFFF0088doing things with a widget', attachment:GetSize())
+    line.height = attachment:GetHeight()
+    if text then
+      line.height = max(line.height, line.status:GetStringHeight())
     end
-    attachment:SetPoint('TOP', line, 'TOP', 0, -widgetOffset)
+    if attachment.status:GetText() then
+      line.height = max(line.height, attachment.status:GetStringHeight())
+    end
     attachment:Show()
   end
 
-  block.attachmentHeight = block.attachmentHeight + line.height
-  print('     |cFF0088FFsetting line #'..lineIndex..' for|r', block.info.title, "\n            |cFF0088FFsize:|r", line.height,
+  line:SetHeight(line.height)
+  block.attachmentHeight = block.attachmentHeight + line.height + textSpacing
+  print('  |cFF0088FFsetting line #'..lineIndex..' for|r', block.info.title, "\n     |cFF0088FFsize:|r", line.height,
     "|cFF0088FFpoint:|r", line:GetPoint(1), "|cFF0088FFwidget:|r", (line.widget and 'Y' or 'N'))
   block.currentLine = lineIndex
   block.endPoint = line.statusbg -- edge used for the next block
@@ -175,13 +234,10 @@
   local lines = block.lines
   if not lineIndex then
     lineIndex = block.currentLine + 1
-    print('        fetching the "next" line:', lineIndex)
-  else
-    print('        fetching explicit offset:', lineIndex)
+    print('        |cFFFFFF00generating a frame')
   end
 
   block.numLines = max(block.numLines, lineIndex)
-  print('        |cFF00FFFFposition|r', block.currentLine, '|cFF00FFFFof|r|cFFFFFF00' , block.numLines)
 
   if not lines[lineIndex] then
     print('     |cFF00FF88created line #'..lineIndex..' from for '..handler.name..' block #'..blockIndex)
@@ -189,14 +245,8 @@
     local line = lines[lineIndex]
     line.index = lineIndex
     line.height = 0
-    line.status:SetSpacing(textSpacing)
-    line.status:SetPoint('LEFT', line, 'LEFT', textIndent, 0)
     B.SetConfigLayers(line)
 
-    if lines[lineIndex+1] then
-      lines[lineIndex+1]:ClearAllPoints()
-    end
-
     if debug then
       for _, region in ipairs(lines[lineIndex].debug) do
         region:Show()
@@ -210,59 +260,25 @@
 
 
 --- Creates or retrieves a complete block frame object
-Default.GetBlock = function(handler, blockIndex)
+--- todo: make it use data index to avoid re-coloring every block
+Default.GetBlock = function(handler, logIndex)
   local print = bprint
-  local block = handler.usedBlocks[blockIndex]
+  print('|cFFFFFF00getting a block for logID', logIndex ..',', #handler.usedBlocks,'used', #handler.freeBlocks, 'free')
+  local block = handler.LogBlock[logIndex]
 
-  if not handler.usedBlocks[blockIndex] then
+  if not block then
     if #handler.freeBlocks >= 1 then
-      block = handler.freeBlocks[#handler.freeBlocks]
-      handler.freeBlocks[#handler.freeBlocks] = nil
+      block = tremove(handler.freeBlocks)
+      print('  assigning from free heap|cFF00FFFF', block:GetName())
     else
+
+      local blockIndex = handler.numBlocks + 1
       block = CreateFrame('Frame', 'Veneer'..tostring(handler)..'Block'..blockIndex, handler.frame, 'VeneerTrackerBlock')
-
-      local c = Module.Conf.Wrapper
-      block.index = blockIndex
       block.lines = {}
       block.numLines = 0
       block.currentLine = 0
-      block:SetWidth(c.Width)
-
-      block.title:SetSpacing(c.TitleSpacing)
-      block.title:SetPoint('TOP', block, 'TOP', 0, -titleSpacing)
-      block.title:SetPoint('LEFT', block, 'LEFT', titleIndent, 0)
-
-      block.titlebg:SetTexture(1,1,1,1)
-      block.titlebg:SetGradientAlpha(unpack(titlebg))
-      block.titlebg:SetPoint('TOP', block, 'TOP', 0, 0)
-      block.titlebg:SetPoint('BOTTOM', block.title, 'BOTTOM', 0, -titleSpacing)
-
-      block.status:SetSpacing(c.TextSpacing)
-      block.status:SetPoint('TOP', block.titlebg, 'BOTTOM', 0, -textSpacing)
-      block.status:SetPoint('LEFT', block.titlebg, 'LEFT', textIndent, 0)
-
-      block.statusbg:SetPoint('TOP', block.titlebg, 'BOTTOM', 0, 0)
-      block.statusbg:SetPoint('BOTTOM', block, 'BOTTOM', 0, 0)
-      block.statusbg:SetTexture(1,1,1,1)
-      block.statusbg:SetGradientAlpha(unpack(textbg))
-
-      block.SelectionOverlay:SetGradientAlpha(unpack(Module.colors.default.selectionbg))
-      block.SelectionOverlay:SetPoint('TOPLEFT', selectionIndent, 0)
-      block.SelectionOverlay:SetPoint('BOTTOMRIGHT')
-
-      --block.icon:SetSize(rewardSize, rewardSize)
-      --block.icon:SetPoint()
-      local anchor, target, point, x, y = 'TOPRIGHT', block, 'TOPRIGHT', -2, -2
-      for i, tile in ipairs(block.rewardTile)  do
-        print(rewardSize)
-        tile:SetSize(rewardSize, rewardSize)
-        tile:ClearAllPoints()
-        tile:SetPoint(anchor, target, point, x, y)
-        block.rewardLabel[i]:SetPoint('TOP', tile, 'TOP', 0, -2)
-        anchor, target, point, x, y = 'TOPRIGHT', tile, 'TOPLEFT', -2, 0
-      end
-
-
+      block.attachmentHeight = 0
+      B.SetConfigLayers(block)
       --- methods for event handlers
 
       block.Select = handler.Select
@@ -271,33 +287,32 @@
       block.Link = handler.Link
       block.clickZone:SetScript('OnMouseUp', function(self, ...) handler.OnMouseUp(block, ...) end)
       block.clickZone:SetScript('OnMouseDown', function(self, ...) handler.OnMouseDown(block, ...) end)
-      block.attachmentHeight = 0
       block:ClearAllPoints()
+      block.index = blockIndex
+      handler.numBlocks = max(handler.numBlocks, blockIndex)
 
-      B.SetConfigLayers(block)
-
-      if debug then
-        for _, region in ipairs(block.debug) do
-          region:Show()
-        end
-      end
+      print('  |cFFFFFF00creating new|r', block:GetName())
     end
-    handler.usedBlocks[blockIndex] = block
+    handler.LogBlock[logIndex] = block
+    tinsert(handler.usedBlocks, block)
+  else
+    print('  |cFFFFFF00use existing block|r', block:GetName())
   end
-  return handler.usedBlocks[blockIndex]
+  return block
 end
 
 local currentPosition, anchorFrame, anchorPoint
 --- Positioning and stuff
 local tick = 0
-local maxReason = 0
+local firstUpdate = true
 function Module:Update (reason, ...)
+  if not B.Conf.VeneerObjectiveWrapper.enabled then
+    return
+  end
+
   tick = tick + 1
-  -- is this the first time updating?
-  if maxReason == 0 then
-    reason = OBJECTIVE_TRACKER_UPDATE_ALL
-  elseif not reason then
-    reason = OBJECTIVE_TRACKER_UPDATE_REASON
+  if firstUpdate or not reason then
+    reason = _G.OBJECTIVE_TRACKER_UPDATE_ALL
   end
 
   local print = tprint
@@ -305,7 +320,7 @@
   local hasStuff
   local insertingStuff
 
-  print(format('%d |cFFFF%04X Update()', tick, lshift(reason, 4)), reason, ...)
+  print(format('|cFFBB0066Update:|r |cFFFF%04X%d|r  ', tick, lshift(reason, 4)), reason, ...)
   currentPosition = 0
   anchorPoint = 'TOP'
   anchorFrame = Scroll
@@ -314,20 +329,21 @@
   for id, handler in pairs(Module.orderedHandlers) do
     local frame = handler.frame
 
-    print(format('|cFF00FFFF%s and(%04X vs %04x+%04x) = %04X|r', handler.name, reason, handler.updateReasonModule, handler.updateReasonEvents, band(reason, handler.updateReasonModule + handler.updateReasonEvents)))
+
     if band(reason, handler.updateReasonModule + handler.updateReasonEvents) > 0 then
       handler:UpdateTracker(reason, ...)
-      print(' |cFF00FF00'..id..'|r', handler.displayName, 'count:', handler.numWatched)
       insertingStuff = true
     else
       print(' |cFFFF0088'..id..'|r', 'no reason to update')
     end
 
     if handler.numWatched >= 1 then
+
+      print(format('|cFF88FFBB%s and(%04X, %04x+%04x) = %04X|r', handler.name, reason, handler.updateReasonModule, handler.updateReasonEvents, band(reason, handler.updateReasonModule + handler.updateReasonEvents)))
       hasStuff = true
       currentPosition = currentPosition + 1
       frame.destinationOffset = -wrapperHeight
-      if frame.previousOffset ~= wrapperHeight and frame:IsVisible() then
+      if (not firstUpdate) and frame.previousOffset ~= wrapperHeight and frame:IsVisible() then
         print(frame.SlideIn.translation)
         local postFrame, postPoint = anchorFrame, anchorPoint
         local delta = frame.destinationOffset - frame.previousOffset
@@ -340,8 +356,9 @@
           b.SlideIn.translation:SetOffset(0, delta)
           b.SlideIn:Play()
         end
+        local start = GetTime()
         frame.SlideIn:SetScript('OnFinished', function()
-          print('  |cFF00BBFFsliding finished:', delta, 'pixels covered')
+          print('  |cFF00BBFFsliding finished:', delta, 'pixels covered; duration:', GetTime()-start)
           frame:SetParent(Scroll)
           frame:SetPoint('TOP', Scroll, 'TOP', 0, frame.destinationOffset)
           frame.previousOffset = frame.destinationOffset
@@ -356,7 +373,8 @@
 
         end)
       else
-        print('  |cFF00BBFFpinning to', anchorFrame:GetName(), anchorPoint)
+        print('  |cFF00BBFFpinning to', anchorFrame:GetName(), anchorPoint, '|rcurrent frame height:', frame.height)
+        print('  |cFFFF0088total height:', wrapperHeight)
         frame:SetParent(Scroll)
         frame:SetPoint('TOP', Scroll, 'TOP', 0, frame.destinationOffset)
       end
@@ -365,10 +383,10 @@
       anchorFrame = handler.frame
       anchorPoint = 'BOTTOM'
 
-      print('current frame height:', frame.height)
       wrapperHeight = wrapperHeight + frame.height
-      print('|cFFFF0088total height:', wrapperHeight)
     else
+
+      print('  |cFFFF4400GetNumWatched:|r',handler.name, '0')
       frame:SetPoint('TOP', Scroll, 'TOP', 0, 0)
       frame.destinationOffset = 0
       frame.previousOffset = 0
@@ -406,6 +424,9 @@
   end
   Quest.GetClosest()
   --Module.UpdateActionButtons(reason)
+  if firstUpdate then
+    firstUpdate = nil
+  end
 end
 
 --- Content generator base
@@ -422,6 +443,11 @@
 
   handler.updateReason = reason
   handler.numWatched = handler:GetNumWatched()
+  if handler.numWatched >= 1 then
+
+    print('  |cFF00FF88GetNumWatched:|r',handler.name, handler.numWatched, 'of', handler.numAll)
+  end
+
   handler.currentBlock = 0
   handler.currentAnchor = tracker.titlebg
   local blockPosition = -headerHeight
@@ -437,15 +463,22 @@
     end
   end
 
-  for i = handler.currentBlock+1, handler.numBlocks do
-    local used = handler.usedBlocks
+
+  local numBlocks = handler.numBlocks
+  local used = handler.usedBlocks
+  if numBlocks < #used then
+    print('  |cFF0088FFcull the dead: showing|r', numBlocks, '|cFF0088FF out of|r', #used)
     local free = handler.freeBlocks
-    print('clean up dead quest block')
-    if used[i] then
-      used[i]:Hide()
-      used[i]:ClearAllPoints()
-      free[#free+1]= used[blockIndex]
-      used[i] = nil
+    local remaining = #used
+    for i = #used, 1, -1 do
+      print('    -', 'i='.. i, 'watchIndex='..used[i].info.watchIndex)
+      if used[i].info.watchIndex > numBlocks then
+        print('    clean up dead quest block')
+        local released = tremove(used, i)
+        released:Hide()
+        released:ClearAllPoints()
+        tinsert(free, used[blockIndex])
+      end
     end
   end
 
@@ -470,6 +503,7 @@
   return tracker.numWatched, tracker.numAll
 end
 
+
 --- Updates the selected block frame to display the given info batch
 -- If `previousBlock` is set, it will attempt to anchor to that
 -- @param blockNum the ordered block to be updated, not a watchIndex value
@@ -477,7 +511,6 @@
 -- REMEMBER: t.info and questData[questID] are the same table
 Default.UpdateBlock = function (handler, blockIndex, id, added)
   local print = bprint
-  print('  Updating |cFF00FF00'..handler.displayName..'|r|cFF00FFFF'..blockIndex..'|r')
   if not blockIndex then
     return
   end
@@ -485,25 +518,26 @@
   if not info then
     return
   end
+  print('  Updating |cFF00FF00'..handler.displayName..'|r|cFF00FFFF'..blockIndex..'|r|cFF0099FF', info.id ,'|r')
   local frame = handler.frame
-  local block = handler:GetBlock(blockIndex)
+  local block = handler:GetBlock(info.id)
 
-  block.questID = info.questID
-  if id == info.questID then
-      --block.questFadeIn:Play()
+  if added then
+    -- do something if the block is being assigned a new thing
   end
 
   block.handler = handler
   block.info = info
-  block.mainStyle = info.mainStyle or 'Normal'
-  block.subStyle = info.subStyle
 
   info.blockIndex = blockIndex
   if info.questID then handler.QuestBlock[info.questID] = block end
-  if info.questLogIndex then handler.LogBlock[info.questLogIndex] = block end
+  if info.logIndex then handler.LogBlock[info.logIndex] = block end
   if info.watchIndex then handler.WatchBlock[info.watchIndex] = block end
   handler.BlockInfo[blockIndex] = info
-  handler:UpdateObjectives(block)
+  local newSchema = handler:UpdateObjectives(block)
+  if newSchema and newSchema ~= blockSchema then
+    Module.UpdateSchema('block', newSchema)
+  end
 
   block.title:SetText(info.title)
   local titleHeight = floor(block.title:GetHeight()+.5)
@@ -516,15 +550,12 @@
 
   print('    |cFF0088FFanchor to', handler.currentAnchor:GetName())
   print('    |cFF00FF00attachment:|r', attachmentHeight, '|cFF00FF00title:|r', titlebgHeight, '('.. titleHeight..')')
-  --block.titlebg:SetHeight(block.title:GetHeight() + Module.Conf.Wrapper.TitleSpacing)
+  if attachmentHeight > 0 then
+    attachmentHeight = attachmentHeight + textSpacing
+  end
+
   block.height = titlebgHeight + attachmentHeight
 
-  if statusHeight > 1 then
-    block.height = block.height + statusbgHeight
-    print('           status:', statusbgHeight, '('.. statusHeight..')')
-  else
-    print('      |cFFFF0088             skipped')
-  end
   block:SetHeight(block.height)
 
   print('           |cFFFFFF00height|r:', block.height)
@@ -578,6 +609,11 @@
     tagPoint, tagAnchor, tagRelative = handler:AddTag(block, 'typeTag', tagPoint, tagAnchor, tagRelative)
     tagPoint, tagAnchor, tagRelative = handler:AddTag(block, 'completionTag', tagPoint, tagAnchor, tagRelative)
   end
+
+  if info.statusKey and (Devian and Devian.InWorkspace()) then
+    block.debugText:SetText(info.statusKey)
+    block.debugText:Show()
+  end
   return block
 end
 
@@ -586,7 +622,7 @@
 
 --- Does the main iterations for populating block content.
 -- Hooked by corresponding handler functions where additional details need to be sorted.
-Default.UpdateObjectives = function(handler, block)
+Default.UpdateObjectives = function(handler, block, block_schema)
   local print = lprint
   local info = block.info
   print('|cFF00FF00default.objectives', block:GetName())
@@ -618,28 +654,28 @@
         displayObjectiveHeader = true
         line.height = 0
         text, attachment, template = handler:UpdateLine(block, line, data)
-        print('     |cFF88FF00#', i, data.type, text)
+        print('   |cFF88FF00#', i, data.type, text, attachment)
         handler:AddLine(block, text, attachment, template)
 
       end
     end
   end
 
-  if info.statusKey and (Devian and Devian.InWorkspace()) then
-    handler:AddLine(block, info.statusKey, nil)
-  end
 
-  for i = block.currentLine + 1, block.numLines do
-    print(i, block.numLines)
-    print('      - hide |cFFFF0088'..i..'|r', block.lines[i])
-    block.lines[i]:ClearAllPoints()
-    block.lines[i]:Hide()
+  if block.currentLine < block.numLines then
+    print('   - cull', block.currentLine, block.numLines)
+    for i = block.currentLine + 1, block.numLines do
+      print('   - hide |cFFFF0088'..i..'|r', block.lines[i])
+      block.lines[i]:ClearAllPoints()
+      block.lines[i]:Hide()
+    end
   end
 
   if block.currentLine > 0 then
     block.attachmentHeight = block.attachmentHeight + textSpacing
-    print('     |cFF00FF00attachment:', block.attachmentHeight)
+    print('   |cFF00FF00attachment:', block.attachmentHeight)
   end
+  return block_schema
 end
 
 
@@ -681,7 +717,7 @@
     local block = Module.Quest.QuestBlock[questID]
     if block then
         -- Dispatch the probe
-      if IsQuestWatched(info.questLogIndex) then
+      if IsQuestWatched(info.logIndex) then
         itemButton.previousItem = previousItem
         print('  |cFFFFFF00probing', block:GetName())
         block:SetScript('OnUpdate', function()
@@ -767,6 +803,7 @@
 
 end
 
+
 Default.Select = function(handler, block)
   Module:Update(handler.watchReasonModule)
 end
--- a/ObjectiveTracker/ObjectiveTracker.lua	Fri Apr 15 17:01:06 2016 -0400
+++ b/ObjectiveTracker/ObjectiveTracker.lua	Sun Apr 17 00:21:45 2016 -0400
@@ -67,33 +67,6 @@
 T.strings.CLICK_TO_COMPLETE = 'Click to complete'
 T.colors ={
   enable = true,
-  default = {
-    titlebg = {'HORIZONTAL', 1, 0, .7, .25,    1, 0, .7, .125},
-    textbg = {'HORIZONTAL', 0, 0, 0, 0.4,      0, 0, 0, 0 },
-    selectionbg = {'HORIZONTAL', 1, 1, 1, 0, 1, 1, 1, 0.225},
-  },
-  daily = {
-    titlebg = {'HORIZONTAL', 0, .7, 1, .25,  0, 1, .7, .125},
-    textbg = {'HORIZONTAL', 0, .7, 1, .1,    0, 1, .7, .075 },
-  },
-  weekly = {
-    titlebg = {'HORIZONTAL', 0, .35, .7, .25,   0, .35, .7, .125},
-    textbg = {'HORIZONTAL', 0, .35, .7, .1,     0, .35, .7, .075 },
-  },
-  account = {
-    titlebg = {'HORIZONTAL', .1, .1, .1, .25, .1, .1, .1, .125},
-    textbg = {'HORIZONTAL', .1, .1, .1, 0.4, .1, .1, .1, .085 },
-  },
-  -- alliance
-  faction_1 = {
-    titlebg = {'HORIZONTAL', .2, .4, 1, 0.4, .2, .4, 1, .085 },
-    textbg = {'HORIZONTAL', .2, .4, 1, 0.4, .2, .4, 1, .085 },
-  },
-  -- horde
-  faction_2 = {
-    titlebg = {'HORIZONTAL', .6, 0, 0.4, 0.4,  .6, 0, 0.4, .085 },
-    textbg = {'HORIZONTAL', .6, 0, 0.4, 0.4,   .6, 0, 0.4, .085 },
-  }
 }
 
 T.watchMoneyReasons = 0
@@ -101,6 +74,7 @@
 --- Baseline defaults table; values defined in the files that they pertain to
 T.defaults = {}
 
+
 --- Tracker display order
 T.orderedNames = {'Bonus', 'AutoQuest', 'Quest', 'Cheevs'}
 
@@ -146,15 +120,17 @@
   numWatched = 0,   --- number of entries being handled
   numBlocks = 0,    --- number of blocks created
   actualBlocks = 0, --- number of blocks in use
+  Info = {},        --- stored watch list information, keyed by whatever unique ID is involved for that tracker
+  Watched = {},     --- stores whether the given unique ID is tracked
 
-  freeBlocks = {},  --- block heap
-  usedBlocks = {},
+  freeBlocks = {},  --- blocks hidden due to list shrinkage
+  usedBlocks = {},  --- block in use
+  BlockInfo = {},   --- by block creation offset, used by framescript
 
-  Info = {},        -- find data by ID
-  BlockInfo = {},   -- find data by block ID
-  Watched = {},     -- find watchIndex by data ID
-  WatchInfo = {},   -- find data by watch index
-  WatchBlock = {},  -- find block by watch index
+  --- Indexes
+  LogBlock = {},    --- by API log offset, used by GetBlock if possible
+  WatchBlock = {},  --- block by internal offset, used in GetBlock scope
+  WatchInfo = {},   --- info by internal offset, used in Update scope
 }
 
 T.AutoQuest = {
@@ -163,7 +139,6 @@
   updateReasonModule = OBJECTIVE_TRACKER_UPDATE_MODULE_QUEST,
   updateReasonEvents = OBJECTIVE_TRACKER_UPDATE_QUEST + OBJECTIVE_TRACKER_UPDATE_QUEST_ADDED,
   LogInfo = {},
-  LogBlock = {},
   QuestBlock = {},
 }
 T.Quest = {
@@ -174,7 +149,6 @@
   itemButtons = {},
   freeButtons = {},
   LogInfo = {},
-  LogBlock = {},
   QuestBlock = {},
 }
 T.Cheevs = {
@@ -273,10 +247,6 @@
   if ( IsQuestTask(questID) ) then
     return OBJECTIVE_TRACKER_UPDATE_TASK_ADDED, questID
   else
-    if ( _G.AUTO_QUEST_WATCH == "1" ) then
-      AddQuestWatch(questLogIndex);
-      SetSuperTrackedQuestID(questID);
-    end
     return OBJECTIVE_TRACKER_UPDATE_QUEST_ADDED, questID, added
   end
 end
@@ -374,6 +344,7 @@
 
 --- Done once per ui load
 local BlizzHooks = {
+  ['AcceptQuest'] = 'AcceptQuest',
   ['AddQuestWatch'] = 'AddQuestWatch',
   ['RemoveQuestWatch'] = 'RemoveQuestWatch',
   ['AbandonQuest'] = 'AbandonQuest',
@@ -413,6 +384,7 @@
 
 local iprint = B.print('Info')
 T.SetRewards = function(t, questID)
+  local previousSelection = GetQuestLogSelection()
 
   SelectQuestLogEntry(GetQuestLogIndexByID(questID))
   local numQuestChoices = GetNumQuestLogChoices();
@@ -420,6 +392,10 @@
   local xp = GetQuestLogRewardXP();
   local playerTitle = GetQuestLogRewardTitle();
   ProcessQuestLogRewardFactions();
+  if previousSelection then
+    SelectQuestLogEntry(previousSelection)
+  end
+
   local rewards = {}
   local texture, name, isTradeskillSpell, isSpellLearned, hideSpellLearnText, isBoostSpell, garrFollowerID = GetQuestLogRewardSpell(questID)
   if name  then
@@ -474,6 +450,15 @@
 
 local Play = function(file) if Devian and Devian.InWorkspace() then PlaySoundFile(file) end end
 
+T.OnHookedFunc = function(name, ...)
+  print('|cFFFF8800securehook:|r', name, '|cFF00FFFFargs:|r', ...)
+  local updateReason = T[name](...)
+  if updateReason then
+    print('|cFF00FFFFupdate reason:|r', updateReason)
+    T:Update(updateReason)
+  end
+end
+
 function T:OnEvent (event, ...)
   local isHandled
   print('OnEvent(|cFF00FF00'.. event ..'|r):', ...)
@@ -522,7 +507,7 @@
     T.isHooked = true
     for blizzFunc, veneerFunc in pairs(BlizzHooks) do
       if T[veneerFunc] then
-        hooksecurefunc(blizzFunc, T[veneerFunc])
+        hooksecurefunc(blizzFunc, function(...) return T.OnHookedFunc(blizzFunc, ...) end)
       else
         hooksecurefunc(blizzFunc, function(...)
           print('|cFFFF0088securehook('..tostring(blizzFunc)..')|r args:', ...)
@@ -551,9 +536,7 @@
 function T:OnEnable()
 
   print(B.Conf.VeneerObjectiveWrapper.enabled)
-  if not B.Conf.VeneerObjectiveWrapper.enabled then
-    return
-  end
+
 
   for event, action in pairs(Event) do
     print('|cFFFF0088listen to', event, 'for action|r', tostring(action))
--- a/ObjectiveTracker/ObjectiveTracker.xml	Fri Apr 15 17:01:06 2016 -0400
+++ b/ObjectiveTracker/ObjectiveTracker.xml	Sun Apr 17 00:21:45 2016 -0400
@@ -306,6 +306,20 @@
           </Gradient>
         </Texture>
       </Layer>
+      <Layer level="BORDER">
+
+        <Texture parentKey="SelectionOverlay" alphaMode="ADD" hidden="true">
+          <Anchors>
+            <Anchor point="TOPLEFT" />
+            <Anchor point="BOTTOMRIGHT" />
+          </Anchors>
+          <Color r="1" g="1" b="1" a="1" />
+          <Gradient orientation="HORIZONTAL">
+            <MaxColor r="1" g="0" b="0" a="0.7" />
+            <MinColor r="1" g="0" b="0" a="0.7" />
+          </Gradient>
+        </Texture>
+      </Layer>
       <Layer level="ARTWORK">
           <Texture parentKey="StarBurst" hidden="false" alpha="0" alphaMode="ADD" atlas="OBJFX_StarBurst" useAtlasSize="true">
             <Anchors>
@@ -329,10 +343,6 @@
             </Anchors>
           </Texture>
 
-        <Texture alpha="0.75" parentArray="rewardTile" hidden="true" />
-        <Texture alpha="0.66" parentArray="rewardTile" hidden="true" />
-        <Texture alpha="0.57" parentArray="rewardTile" hidden="true" />
-
         <Texture parentKey="typeTag" file="Interface\QuestFrame\QuestTypeIcons" alphaMode="ADD" hidden="true">
           <Size x="18" y="18"/>
           <Anchors>
@@ -360,17 +370,10 @@
         </Texture>
 
 
-        <Texture parentKey="SelectionOverlay" alphaMode="ADD" hidden="true">
-          <Anchors>
-            <Anchor point="TOPLEFT" />
-            <Anchor point="BOTTOMRIGHT" />
-          </Anchors>
-          <Color r="1" g="1" b="1" a="1" />
-          <Gradient orientation="HORIZONTAL">
-            <MaxColor r="1" g="0" b="0" a="0.7" />
-            <MinColor r="1" g="0" b="0" a="0.7" />
-          </Gradient>
-        </Texture>
+
+        <Texture alpha="1" parentArray="rewardTile" hidden="true" />
+        <Texture alpha="1" parentArray="rewardTile" hidden="true" />
+        <Texture alpha="1" parentArray="rewardTile" hidden="true" />
       </Layer>
       <Layer level="OVERLAY">
         <FontString name="$parentTitle" parentKey="title" inherits="VeneerTitleFont" justifyH="LEFT" justifyV="TOP">
@@ -387,14 +390,14 @@
             <Anchor point="RIGHT" relativeKey="$parent" />
           </Anchors>
         </FontString>
+        <FontString parentArray="rewardLabel" inherits="VeneerNumberFontSmall" />
+        <FontString parentArray="rewardLabel" inherits="VeneerNumberFontSmall" />
+        <FontString parentArray="rewardLabel" inherits="VeneerNumberFontSmall" />
         <FontString name="$parentDebugText" parentKey="debugText" inherits="VeneerCriteriaFontNormal" justifyH="RIGHT" justifyV="TOP">
           <Anchors>
-            <Anchor point="TOPRIGHT" relativePoint="TOPRIGHT" />
+            <Anchor point="BOTTOMRIGHT" />
           </Anchors>
         </FontString>
-        <FontString parentArray="rewardLabel" inherits="VeneerNumberFont" />
-        <FontString parentArray="rewardLabel" inherits="VeneerNumberFont" />
-        <FontString parentArray="rewardLabel" inherits="VeneerNumberFont" />
 
 
         <Texture alphaMode="BLEND" parentArray="config" hidden="true">
@@ -490,6 +493,8 @@
 
   <Frame name="VeneerTrackerObjective" virtual="true" hidden="true">
     <Anchors>
+      <Anchor point="TOP" />
+      <Anchor point="LEFT" />
       <Anchor point="RIGHT" />
     </Anchors>
     <Layers>
@@ -560,6 +565,7 @@
   <Include file="Widgets.xml" />
 
   <Script file="ObjectiveTracker.lua" />
+  <Script file="Schema.lua" />
   <Script file="Quests.lua" />
   <Script file="Achievements.lua" />
   <Script file="AutoQuestPopups.lua" />
--- a/ObjectiveTracker/Quests.lua	Fri Apr 15 17:01:06 2016 -0400
+++ b/ObjectiveTracker/Quests.lua	Sun Apr 17 00:21:45 2016 -0400
@@ -33,45 +33,42 @@
   print('|cFF00FFFFUpdateObjectives()')
   local info = block.info
 
-  local titlebg, textbg = colors.default.titlebg, colors.default.textbg
   print((info.isAccount and 'isAccount' or ''), (info.isFaction and 'isFaction' or ''), (info.isDaily and 'isDaily' or ''), (info.isWeekly and 'isWeekly' or ''), info.tagID, info.tagName)
 
+  local block_schema = 'default'
   if info.isAccount then
     if info.isFaction then
       print('     faction', info.tagID)
-      titlebg, textbg = colors['faction_'..info.tagID].titlebg, colors.default.textbg
+      block_schema = 'faction_'..info.tagID
     else
       print('     account', info.isAccount, info.isFaction)
-      titlebg, textbg = colors.account.titlebg, colors.account.textbg
+      block_schema = 'account'
     end
   elseif info.isDaily then
     print('     daily', info.frequency)
-    titlebg, textbg = colors.daily.titlebg, colors.daily.textbg
+    block_schema = 'daily'
   elseif info.isWeekly then
     print('     weekly', info.frequency)
-    titlebg, textbg = colors.weekly.titlebg, colors.weekly.textbg
+    block_schema = 'weekly'
   end
-
-  block.titlebg:SetGradientAlpha(unpack(titlebg))
-  block.statusbg:SetGradientAlpha(unpack(textbg))
-
   local completionText
   if info.isComplete then
     if info.isAutoComplete then
-      local questID, popupType = GetAutoQuestPopUp(info.questLogIndex)
+      local questID, popupType = GetAutoQuestPopUp(info.logIndex)
       if popupType == 'COMPLETE' then
         print('    :: auto-complete quest :: set the message')
         info.completionText = T.strings.CLICK_TO_COMPLETE
       end
     else
       if not completionText or info.completionText then
-        info.completionText = GetQuestLogCompletionText(info.questLogIndex)
+        info.completionText = GetQuestLogCompletionText(info.logIndex)
       end
     end
     print('    :: complete quest :: show instruction: "'.. tostring(info.completionText) .. '"')
   end
 
-  Default.UpdateObjectives(handler, block)
+  Default.UpdateObjectives(handler, block, block_schema)
+  return block_schema
 end
 
 Quest.UpdateLine = function(handler, block, line, data)
@@ -87,7 +84,6 @@
 Quest.LogInfo = {}
 
 function Quest:GetNumWatched ()
-  print(self.name, self)
   superTrackQuestID = GetSuperTrackedQuestID()
   playerMoney = GetMoney();
   inScenario = C_Scenario.IsInScenario();
@@ -102,8 +98,6 @@
 -- Manifest of line data to be displayed in relation to the tracked object
 Quest.GetInfo = function (self, watchIndex)
   local print = iprint
-  print('')
-  print('|cFF00DDFFindex: |r'.. tostring(watchIndex))
 
   local questID, title, questLogIndex, numObjectives, requiredMoney, isComplete, startEvent, isAutoComplete,
     failureTime, timeElapsed, questType, isTask, isStory, isOnMap, hasLocalPOI = GetQuestWatchInfo(watchIndex)
@@ -111,21 +105,18 @@
     return
   end
 
+  tprint('    |cFFFFBB00GetInfo:|r', watchIndex, '|cFFFF2299'..title..'|r')
   local _, level, suggestedGroup, isHeader, isCollapsed, isComplete, frequency, _, startEvent, displayQuestID, isOnMap, hasLocalPOI, isTask, isStory = GetQuestLogTitle(questLogIndex)
 
   Quest.Info[questID] = Quest.Info[questID] or {}
 
 
   local q = Quest.Info[questID]
-  q.watchIndex = watchIndex
   q.type = 'Quest'
-  q.id = questID
-  q.questID = questID
   q.title = title
   q.level = level
   q.displayQuestID = displayQuestID
   q.suggestedGroup = suggestedGroup
-  q.questLogIndex = questLogIndex
 
   -- re-use Blizzard logic for consistency
   local showQuest = true
@@ -349,11 +340,15 @@
 
   T.SetRewards(q, questID)
 
+  q.questID = questID
+  q.logIndex = questLogIndex
+  q.watchIndex = watchIndex
+  q.id = questID
   self.WatchInfo[watchIndex] = q
   self.LogInfo[questLogIndex] = q
 
   if Devian and Devian.InWorkspace() then
-    print('|cFF00DDFFstatus:|r', temp_status, '|cFF00FF00questLogIndex|r:', title)
+    print('|cFF00DDFFstatus:|r', temp_status, '|cFF00FF00questLogIndex|r:', questLogIndex, title)
     local temp  ={}
     local data_txt = '|cFFFF4400values:|r'
     for k,v in pairs(q) do
@@ -380,7 +375,7 @@
   local objectives = {}
   for i = 1, numObjectives do
     local text, type, finished = GetQuestLogLeaderBoard(i, questLogIndex)
-    print(format('   #%d %s %s %s', i, tostring(type), tostring(text), tostring(finished)))
+    print(format('      |cFFFF4400GetObjectives:|r #%d %s %s %s', i, tostring(type), tostring(text), tostring(finished)))
     objectives[i] = {
       index = i,
       type = type,
@@ -417,7 +412,7 @@
 
 Quest.Select = function (handler, block)
   if block.info.isAutoComplete and block.info.isComplete then
-    ShowQuestComplete(block.info.questLogIndex)
+    ShowQuestComplete(block.info.logIndex)
   else
     SetSuperTrackedQuestID(block.info.questID)
   end
@@ -425,7 +420,7 @@
 
 Quest.Link = function(handler, block)
 
-  local questLink = GetQuestLink(block.info.questLogIndex);
+  local questLink = GetQuestLink(block.info.logIndex);
   if ( questLink ) then
     ChatEdit_InsertLink(questLink);
   end
@@ -438,6 +433,6 @@
 
 Quest.Remove = function(handler, block)
 
-  print('removing', block.info.questLogIndex, 'from watcher')
-  RemoveQuestWatch(block.info.questLogIndex)
+  print('removing', block.info.logIndex, 'from watcher')
+  RemoveQuestWatch(block.info.logIndex)
 end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ObjectiveTracker/Schema.lua	Sun Apr 17 00:21:45 2016 -0400
@@ -0,0 +1,112 @@
+--- ${PACKAGE_NAME}
+-- @file-author@
+-- @project-revision@ @project-hash@
+-- @file-revision@ @file-hash@
+-- Created: 4/15/2016 11:36 PM
+
+local B = select(2,...).frame
+local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame')
+local setmetatable, type, rawset = setmetatable, type, rawset
+local print = B.print('Schema')
+T.defaults.Schema = setmetatable({}, {
+  __newindex = function(schemas,layerName, layerTable)
+    -- tracker/block/line
+    if type(layerTable) == 'table' then
+      rawset(schemas, layerName, setmetatable(layerTable, {
+        __index = function(layerTable, schemaName)
+
+        end,
+        __newindex = function(layerTable, schemaName, schemaTable)
+          -- schema table
+          if type(schemaTable) == 'table' then
+            rawset(layerTable, schemaName, setmetatable(schemaTable, {
+              __index = function(schemaTable, key)
+                print('substituting a default value for |cFF00FFFF', layerName..'|r.|cFF0088FF'..schemaName..'|r.'..key)
+                return layerTable.default[key]
+              end
+            }))
+          end
+        end,
+      }))
+    end
+  end
+})
+
+T.defaults.Schema = {
+  tracker = {
+    default = {
+      headerbg = {'VERTICAL', 1, 1, 0.5, 0.5, 1, 1, 0.5, 0},
+      headerFont = {[[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 14, 'OUTLINE'},
+      blockSpacing = 1,
+    }
+  },
+  block = {
+    default = {
+      titlebg = {'HORIZONTAL', 1, 0, .7, .25,    1, 0, .7, .125},
+      textbg = {'HORIZONTAL', 0, 0, 0, 0.4,      0, 0, 0, 0 },
+      selectionbg = {'HORIZONTAL', 1, 1, 1, 0, 1, 1, 1, 0.225},
+      titleFont = {[[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 16, 'OUTLINE'},
+      textFont = {[[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Regular.ttf]], 16, 'OUTLINE'},
+      titleIndent = 4,
+      titleSpacing = 3,
+      textIndent = 3,
+      textSpacing = 3,
+      rewardSize = 24,
+    },
+    daily = {
+      titlebg = {'HORIZONTAL', 0, .7, 1, .25,  0, 1, .7, .125},
+      textbg = {'HORIZONTAL', 0, .7, 1, .1,    0, 1, .7, .075 },
+    },
+    weekly = {
+      titlebg = {'HORIZONTAL', 0, .35, .7, .25,   0, .35, .7, .125},
+      textbg = {'HORIZONTAL', 0, .35, .7, .1,     0, .35, .7, .075 },
+    },
+    account = {
+      titlebg = {'HORIZONTAL', .1, .1, .1, .25, .1, .1, .1, .125},
+      textbg = {'HORIZONTAL', .1, .1, .1, 0.4, .1, .1, .1, .085 },
+    },
+    -- alliance
+    faction_1 = {
+      titlebg = {'HORIZONTAL', .2, .4, 1, 0.4, .2, .4, 1, .085 },
+      textbg = {'HORIZONTAL', .2, .4, 1, 0.4, .2, .4, 1, .085 },
+    },
+    -- horde
+    faction_2 = {
+      titlebg = {'HORIZONTAL', .6, 0, 0.4, 0.4,  .6, 0, 0.4, .085 },
+      textbg = {'HORIZONTAL', .6, 0, 0.4, 0.4,   .6, 0, 0.4, .085 },
+    }
+  },
+  line = {
+    default  = {
+      textColor = {.5,.75,1},
+      textSpacing = 3,
+      textIndent = 3,
+    },
+    completed = {
+      textColor = {0, 1, 0}
+    },
+    failed = {
+      textColor = {1,0,0 }
+    },
+    autocomplete = {
+      textColor = {0,1,0 }
+    },
+    objectColor = {
+      textColor = {0,1,1}
+    },
+    monster = {
+      textColor = {1,1,0}
+    },
+    item = {
+      textColor = {1,.25,.5}
+    }
+  },
+  widget = {
+    progressbar = {
+
+    },
+    timer = {
+
+    }
+  },
+}
\ No newline at end of file
--- a/ObjectiveTracker/SecureButton.xml	Fri Apr 15 17:01:06 2016 -0400
+++ b/ObjectiveTracker/SecureButton.xml	Sun Apr 17 00:21:45 2016 -0400
@@ -49,7 +49,7 @@
       </OnHide>
       <OnEnter>
         GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
-        GameTooltip:SetQuestLogSpecialItem(self.questLogIndex);
+        GameTooltip:SetQuestLogSpecialItem(self.logIndex);
       </OnEnter>
       <OnLeave>
         GameTooltip:Hide();
--- a/ObjectiveTracker/Widgets.lua	Fri Apr 15 17:01:06 2016 -0400
+++ b/ObjectiveTracker/Widgets.lua	Sun Apr 17 00:21:45 2016 -0400
@@ -102,6 +102,10 @@
 local OnClick = {}
 OnClick.CloseButton = function(self)
   T:SetEnabled()
+  if T.Conf.enabled then
+    T:Update()
+  end
+
   UpdatePanelButton(self, T.Conf.enabled)
 end
 
@@ -177,7 +181,7 @@
   itemButton:SetAttribute("item", itemInfo.link)
 
   itemButton.questID = info.questID
-  itemButton.questLogIndex = info.questLogIndex
+  itemButton.logIndex = info.logIndex
   itemButton.charges = itemInfo.charges
   itemButton.rangeTimer = -1
   itemButton.block = block
@@ -214,14 +218,14 @@
   if (rangeTimer) then
     rangeTimer = rangeTimer - elapsed
     if (rangeTimer <= 0) then
-      local link, item, charges, showItemWhenComplete = GetQuestLogSpecialItemInfo(self.questLogIndex)
+      local link, item, charges, showItemWhenComplete = GetQuestLogSpecialItemInfo(self.logIndex)
       if ((not charges) or (charges ~= self.charges)) then
         T:Update()
         return
       end
 
       local count = self.HotKey
-      local valid = IsQuestLogSpecialItemInRange(self.questLogIndex)
+      local valid = IsQuestLogSpecialItemInRange(self.logIndex)
       if (valid == 0) then
         count:Show()
         count:SetVertexColor(1.0, 0.1, 0.1)
@@ -239,7 +243,7 @@
 end
 
 function Veneer_QuestObjectiveItem_UpdateCooldown (itemButton)
-  local start, duration, enable = GetQuestLogSpecialItemCooldown(itemButton.questLogIndex)
+  local start, duration, enable = GetQuestLogSpecialItemCooldown(itemButton.logIndex)
   if (start) then
     CooldownFrame_SetTimer(itemButton.Cooldown, start, duration, enable)
     if (duration > 0 and enable == 0) then
@@ -320,6 +324,7 @@
 
     frame:SetWidth(wrapperWidth - textIndent * 2)
     frame:SetScript('OnEvent', T.UpdateWidget[frame.widgetType])
+    frame:RegisterEvent('QUEST_LOG_UPDATE')
     frame:RegisterEvent('TRACKED_ACHIEVEMENT_UPDATE')
     frame:RegisterEvent('TRACKED_ACHIEVEMENT_LIST_CHANGED')
     frame:RegisterEvent('CRITERIA_UPDATE')
@@ -387,19 +392,18 @@
 
 }
 
-local progressHeight = 16
+local progressHeight = 8
 local progressBorder = 1
-local progressIndent = 3
 local progressFont = _G.VeneerCriteriaFontNormal
 
-
+local lprint = B.print('Line')
 T.InitializeWidget.ProgressBar = function(self)
+  local print = lprint
   local c = T.Conf.Wrapper
   self.height = progressHeight + c.TextSpacing
   self.width = c.Width - c.TextSpacing
-  self.indent = progressIndent
-  self.value = 1
-  self.maxValue = 1
+  self.value = self.value or 1
+  self.maxValue = self.maxValue or 1
 
   self:SetHeight(progressHeight)
   self.bg:SetHeight(progressHeight)
@@ -407,6 +411,7 @@
   self.fg:ClearAllPoints()
   self.fg:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', progressBorder, progressBorder)
   self.fg:SetHeight(progressHeight - progressBorder *  2)
+
   self.status:SetFontObject(progressFont)
   self.status:SetText(self.objective.quantityString)
 end
@@ -418,10 +423,6 @@
     print(k, v)
   end
 
-  if self.line.format then
-    self.status:SetFormattedText(self.line.format, quantity, requiredQuantity)
-  end
-
   local progress = (quantity / requiredQuantity)
   if progress >= 1 then
     self.fg:Show()
--- a/ObjectiveTracker/Widgets.xml	Fri Apr 15 17:01:06 2016 -0400
+++ b/ObjectiveTracker/Widgets.xml	Sun Apr 17 00:21:45 2016 -0400
@@ -43,7 +43,7 @@
       <Layer level="OVERLAY">
         <FontString name="$parentStatus" parentKey="status" inherits="VeneerCriteriaFont">
           <Anchors>
-            <Anchor point="CENTER" />
+            <Anchor point="TOPLEFT" />
           </Anchors>
         </FontString>
       </Layer>