| Zerotorescue@17 | 1 local addon = select(2, ...); | 
| Zerotorescue@1 | 2 local mod = addon:NewModule("Summary", "AceEvent-3.0", "AceTimer-3.0"); | 
| Zerotorescue@0 | 3 | 
| Zerotorescue@0 | 4 local AceGUI = LibStub("AceGUI-3.0"); | 
| Zerotorescue@0 | 5 | 
| Zerotorescue@23 | 6 local unknownItemName = "Unknown (#%d)"; | 
| Zerotorescue@23 | 7 | 
| Zerotorescue@23 | 8 local itemsCache = {}; | 
| Zerotorescue@23 | 9 | 
| Zerotorescue@23 | 10 local CACHE_ITEMS_TOTAL, CACHE_ITEMS_CURRENT = 0, 0; | 
| Zerotorescue@23 | 11 local cacheStart; | 
| Zerotorescue@23 | 12 | 
| Zerotorescue@0 | 13 function mod:OnEnable() | 
| Zerotorescue@0 | 14 	self:RegisterWidgets(); | 
| Zerotorescue@0 | 15 | 
| Zerotorescue@1 | 16 	-- Register our own slash commands | 
| Zerotorescue@1 | 17 	addon:RegisterSlash(function() | 
| Zerotorescue@1 | 18 		mod:BuildMain(); | 
| Zerotorescue@1 | 19 		mod:Build(); | 
| Zerotorescue@36 | 20 	end, { "s", "sum", "summary" }, "|Hfunction:InventoriumCommandHandler:summary|h|cff00fff7/im summary|r|h (or /im s) - Show the summary window containing an overview of all items within the groups tracked at this current character."); | 
| Zerotorescue@23 | 21 	addon:RegisterSlash(function() | 
| Zerotorescue@23 | 22 		if mod.frame then | 
| Zerotorescue@23 | 23 			mod.frame:SetWidth(650); | 
| Zerotorescue@23 | 24 			mod.frame:SetHeight(600); | 
| Zerotorescue@23 | 25 | 
| Zerotorescue@23 | 26 			print("Resetting width and height of the summary frame."); | 
| Zerotorescue@23 | 27 		end | 
| Zerotorescue@36 | 28 	end, { "r", "reset" }, "|Hfunction:InventoriumCommandHandler:reset|h|cff00fff7/im reset|r|h (or /im r) - Reset the size of the summary frame."); | 
| Zerotorescue@0 | 29 end | 
| Zerotorescue@0 | 30 | 
| Zerotorescue@13 | 31 local function ShowTooltip(self) | 
| Zerotorescue@13 | 32 	-- If this function is called from a widget, self is the widget and self.frame the actual frame | 
| Zerotorescue@13 | 33 	local this = self.frame or self; | 
| Zerotorescue@13 | 34 | 
| Zerotorescue@13 | 35 	GameTooltip:SetOwner(this, "ANCHOR_NONE"); | 
| Zerotorescue@13 | 36 	GameTooltip:SetPoint("BOTTOM", this, "TOP"); | 
| Zerotorescue@13 | 37 	GameTooltip:SetText(this.tooltipTitle, 1, .82, 0, 1); | 
| Zerotorescue@13 | 38 | 
| Zerotorescue@13 | 39 	if type(this.tooltip) == "string" then | 
| Zerotorescue@13 | 40 		GameTooltip:AddLine(this.tooltip, 1, 1, 1, 1); | 
| Zerotorescue@13 | 41 	end | 
| Zerotorescue@13 | 42 | 
| Zerotorescue@13 | 43 	GameTooltip:Show(); | 
| Zerotorescue@13 | 44 end | 
| Zerotorescue@13 | 45 | 
| Zerotorescue@13 | 46 local function HideTooltip() | 
| Zerotorescue@13 | 47 	GameTooltip:Hide(); | 
| Zerotorescue@13 | 48 end | 
| Zerotorescue@13 | 49 | 
| Zerotorescue@0 | 50 function mod:RegisterWidgets() | 
| Zerotorescue@0 | 51 	-- Register InlineGroupWithButton-widget | 
| Zerotorescue@0 | 52 	-- This widget adds a button next to the header of an inline group | 
| Zerotorescue@0 | 53 	-- SetPoint doesn't seem usable within AceGUI. | 
| Zerotorescue@0 | 54 | 
| Zerotorescue@0 | 55 	local widgetType = "InlineGroupWithButton"; | 
| Zerotorescue@0 | 56 	local widgetVersion = 1; | 
| Zerotorescue@0 | 57 | 
| Zerotorescue@0 | 58 	local function Constructor() | 
| Zerotorescue@0 | 59 	    local widget = AceGUI:Create("InlineGroup"); | 
| Zerotorescue@0 | 60 	    widget.type = widgetType; | 
| Zerotorescue@0 | 61 | 
| Zerotorescue@0 | 62 	    widget.MakeButton = function(self, buttonSettings) | 
| Zerotorescue@0 | 63 			if type(buttonSettings) == "table" then | 
| Zerotorescue@14 | 64 				if not self.btnQueue then | 
| Zerotorescue@14 | 65 					-- Because widgets are re-used, we don't want to recreate this button | 
| Zerotorescue@14 | 66 					self.btnQueue = CreateFrame("Button", nil, self.frame, "UIPanelButtonTemplate"); | 
| Zerotorescue@14 | 67 					self.btnQueue:SetHeight(22); | 
| Zerotorescue@14 | 68 					self.btnQueue:SetWidth(120); | 
| Zerotorescue@14 | 69 				end | 
| Zerotorescue@14 | 70 				self.btnQueue:SetText(buttonSettings.name); | 
| Zerotorescue@14 | 71 				self.btnQueue:SetPoint("TOPRIGHT", self.frame, "TOPRIGHT", -10, 5); | 
| Zerotorescue@14 | 72 | 
| Zerotorescue@14 | 73 				-- Triggers | 
| Zerotorescue@14 | 74 				self.btnQueue:SetScript("OnClick", buttonSettings.exec); | 
| Zerotorescue@14 | 75 | 
| Zerotorescue@14 | 76 				-- Tooltip | 
| Zerotorescue@14 | 77 				self.btnQueue.tooltipTitle = buttonSettings.name; | 
| Zerotorescue@14 | 78 				self.btnQueue.tooltip = buttonSettings.desc or ""; | 
| Zerotorescue@14 | 79 				self.btnQueue:SetScript("OnEnter", ShowTooltip); | 
| Zerotorescue@14 | 80 				self.btnQueue:SetScript("OnLeave", HideTooltip); | 
| Zerotorescue@0 | 81 			else | 
| Zerotorescue@0 | 82 				error("settings must be a table - usage: MakeButton(table);"); | 
| Zerotorescue@0 | 83 			end | 
| Zerotorescue@14 | 84 	    end; | 
| Zerotorescue@0 | 85 | 
| Zerotorescue@0 | 86 	    return widget; | 
| Zerotorescue@0 | 87 	end | 
| Zerotorescue@0 | 88 | 
| Zerotorescue@0 | 89 	AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion); | 
| Zerotorescue@0 | 90 end | 
| Zerotorescue@0 | 91 | 
| Zerotorescue@0 | 92 function mod:BuildMain() | 
| Zerotorescue@11 | 93 	LibStub("AceConfigDialog-3.0"):Close("InventoriumOptions"); | 
| Zerotorescue@0 | 94 | 
| Zerotorescue@10 | 95 	self:CloseFrame(); | 
| Zerotorescue@10 | 96 | 
| Zerotorescue@1 | 97 	-- Main Window | 
| Zerotorescue@1 | 98 	mod.frame = AceGUI:Create("Frame"); | 
| Zerotorescue@23 | 99 	_G["InventoriumSummary"] = mod.frame; -- name the global frame so it can be put in the UISpecialFrames | 
| Zerotorescue@13 | 100 	mod.frame:SetTitle("Summary"); | 
| Zerotorescue@1 | 101 	mod.frame:SetLayout("Fill"); | 
| Zerotorescue@1 | 102 	mod.frame:SetCallback("OnClose", function(widget) | 
| Zerotorescue@7 | 103 		mod:CancelTimer(self.tmrUpdater, true); | 
| Zerotorescue@9 | 104 		mod:CloseFrame(); | 
| Zerotorescue@1 | 105 	end); | 
| Zerotorescue@13 | 106 	mod.frame:SetWidth(addon.db.global.defaults.summary.width); | 
| Zerotorescue@13 | 107 	mod.frame:SetHeight(addon.db.global.defaults.summary.height); | 
| Zerotorescue@13 | 108 	mod.frame.OnWidthSet = function(_, width) | 
| Zerotorescue@13 | 109 		addon.db.global.defaults.summary.width = width; | 
| Zerotorescue@13 | 110 	end; | 
| Zerotorescue@13 | 111 	mod.frame.OnHeightSet = function(_, height) | 
| Zerotorescue@13 | 112 		addon.db.global.defaults.summary.height = height; | 
| Zerotorescue@13 | 113 	end; | 
| Zerotorescue@0 | 114 | 
| Zerotorescue@23 | 115 	-- Close on escape | 
| Zerotorescue@23 | 116 	tinsert(UISpecialFrames, "InventoriumSummary"); | 
| Zerotorescue@23 | 117 | 
| Zerotorescue@1 | 118 	-- ScrollFrame child | 
| Zerotorescue@1 | 119 	mod.scrollFrame = AceGUI:Create("ScrollFrame"); | 
| Zerotorescue@1 | 120 	mod.scrollFrame:SetLayout("Flow"); | 
| Zerotorescue@0 | 121 | 
| Zerotorescue@1 | 122 	mod.frame:AddChild(mod.scrollFrame); | 
| Zerotorescue@1 | 123 | 
| Zerotorescue@1 | 124 	-- Reset items cache | 
| Zerotorescue@1 | 125 	table.wipe(itemsCache); | 
| Zerotorescue@0 | 126 end | 
| Zerotorescue@0 | 127 | 
| Zerotorescue@9 | 128 function mod:CloseFrame() | 
| Zerotorescue@9 | 129 	if mod.frame then | 
| Zerotorescue@9 | 130 		mod.frame:Release(); | 
| Zerotorescue@9 | 131 		mod.frame = nil; | 
| Zerotorescue@10 | 132 | 
| Zerotorescue@10 | 133 		-- Stop caching | 
| Zerotorescue@10 | 134 | 
| Zerotorescue@10 | 135 		-- Stop timer | 
| Zerotorescue@10 | 136 		self:CancelTimer(self.tmrUpdater, true); | 
| Zerotorescue@10 | 137 | 
| Zerotorescue@10 | 138 		-- Reset trackers | 
| Zerotorescue@10 | 139 		CACHE_ITEMS_TOTAL = 0; | 
| Zerotorescue@10 | 140 		CACHE_ITEMS_CURRENT = 0; | 
| Zerotorescue@9 | 141 	end | 
| Zerotorescue@9 | 142 end | 
| Zerotorescue@9 | 143 | 
| Zerotorescue@0 | 144 local sortMethod = "item"; | 
| Zerotorescue@0 | 145 local sortDirectory = "ASC"; | 
| Zerotorescue@0 | 146 local function ReSort(subject) | 
| Zerotorescue@0 | 147 	if sortMethod == subject then | 
| Zerotorescue@0 | 148 		sortDirectory = (sortDirectory == "ASC" and "DESC") or "ASC"; | 
| Zerotorescue@0 | 149 	else | 
| Zerotorescue@0 | 150 		sortDirectory = "ASC"; | 
| Zerotorescue@0 | 151 	end | 
| Zerotorescue@0 | 152 	sortMethod = subject; | 
| Zerotorescue@0 | 153 | 
| Zerotorescue@0 | 154 	mod:Build(); | 
| Zerotorescue@0 | 155 end | 
| Zerotorescue@10 | 156 | 
| Zerotorescue@10 | 157 -- From http://www.wowwiki.com/API_sort | 
| Zerotorescue@10 | 158 local function pairsByKeys (t, f) | 
| Zerotorescue@10 | 159 	local a = {} | 
| Zerotorescue@10 | 160 	for n in pairs(t) do table.insert(a, n) end | 
| Zerotorescue@10 | 161 		table.sort(a, f) | 
| Zerotorescue@10 | 162 	local i = 0      -- iterator variable | 
| Zerotorescue@10 | 163 	local iter = function ()   -- iterator function | 
| Zerotorescue@10 | 164 		i = i + 1 | 
| Zerotorescue@10 | 165 		if a[i] == nil then return nil | 
| Zerotorescue@10 | 166 		else return a[i], t[a[i]] | 
| Zerotorescue@10 | 167 		end | 
| Zerotorescue@10 | 168 	end | 
| Zerotorescue@10 | 169 	return iter | 
| Zerotorescue@10 | 170 end | 
| Zerotorescue@0 | 171 | 
| Zerotorescue@0 | 172 function mod:Build() | 
| Zerotorescue@10 | 173 	local buildStartTime, times = GetTime(), {}; | 
| Zerotorescue@0 | 174 | 
| Zerotorescue@1 | 175 	-- We are going to add hunderds of widgets to this container, but don't want it to also cause hunderds of reflows, thus pause reflowing and just do it once when everything is prepared | 
| Zerotorescue@1 | 176 	-- This appears to be required for each container we wish to pause, so also do this for the contents | 
| Zerotorescue@1 | 177 	mod.scrollFrame:PauseLayout(); | 
| Zerotorescue@1 | 178 | 
| Zerotorescue@10 | 179 	mod.scrollFrame:ReleaseChildren(); | 
| Zerotorescue@10 | 180 | 
| Zerotorescue@10 | 181 	-- Refresh button | 
| Zerotorescue@10 | 182 	local btnRefresh = AceGUI:Create("Button"); | 
| Zerotorescue@10 | 183 	btnRefresh:SetText("Refresh"); | 
| Zerotorescue@10 | 184 	btnRefresh:SetRelativeWidth(.2); | 
| Zerotorescue@10 | 185 	btnRefresh:SetCallback("OnClick", function() | 
| Zerotorescue@10 | 186 		-- Reset items cache | 
| Zerotorescue@10 | 187 		table.wipe(itemsCache); | 
| Zerotorescue@10 | 188 | 
| Zerotorescue@10 | 189 		-- Rebuild itemlist and start caching | 
| Zerotorescue@10 | 190 		mod:Build(); | 
| Zerotorescue@10 | 191 	end); | 
| Zerotorescue@13 | 192 	btnRefresh:SetCallback("OnEnter", ShowTooltip); | 
| Zerotorescue@13 | 193 	btnRefresh:SetCallback("OnLeave", HideTooltip); | 
| Zerotorescue@13 | 194 	btnRefresh.frame.tooltipTitle = "Refresh Cache"; | 
| Zerotorescue@13 | 195 	btnRefresh.frame.tooltip = "Refresh the list and recache the item counts and auction values."; | 
| Zerotorescue@10 | 196 | 
| Zerotorescue@10 | 197 	mod.scrollFrame:AddChild(btnRefresh); | 
| Zerotorescue@10 | 198 | 
| Zerotorescue@13 | 199 	local lblSpacer = AceGUI:Create("Label"); | 
| Zerotorescue@13 | 200 	lblSpacer:SetRelativeWidth(.03); | 
| Zerotorescue@13 | 201 | 
| Zerotorescue@13 | 202 	mod.scrollFrame:AddChild(lblSpacer); | 
| Zerotorescue@13 | 203 | 
| Zerotorescue@10 | 204 	-- Speed slider | 
| Zerotorescue@13 | 205 	local sdrSpeed = AceGUI:Create("Slider"); | 
| Zerotorescue@13 | 206 	sdrSpeed:SetLabel("Processing speed"); | 
| Zerotorescue@14 | 207 	sdrSpeed:SetSliderValues(0.01, 5, 0.05); | 
| Zerotorescue@13 | 208 	sdrSpeed:SetIsPercent(true); | 
| Zerotorescue@13 | 209 	sdrSpeed:SetRelativeWidth(.3); | 
| Zerotorescue@13 | 210 	sdrSpeed:SetCallback("OnMouseUp", function(self, event, value) | 
| Zerotorescue@13 | 211 		addon.db.global.defaults.summary.speed = ceil( value * 100 / 5 ); | 
| Zerotorescue@13 | 212 | 
| Zerotorescue@13 | 213 		CACHE_ITEMS_PER_UPDATE = addon.db.global.defaults.summary.speed; -- max = 20, min = 1 | 
| Zerotorescue@10 | 214 	end); | 
| Zerotorescue@13 | 215 	sdrSpeed:SetValue( addon.db.global.defaults.summary.speed * 5 / 100 ); | 
| Zerotorescue@13 | 216 	sdrSpeed:SetCallback("OnEnter", ShowTooltip); | 
| Zerotorescue@13 | 217 	sdrSpeed:SetCallback("OnLeave", HideTooltip); | 
| Zerotorescue@13 | 218 	sdrSpeed.frame.tooltipTitle = "Caching Processing Speed"; | 
| Zerotorescue@13 | 219 	sdrSpeed.frame.tooltip = "Change the speed at which item counts and auction values are being cached. Higher is faster but may drastically reduce your FPS while caching.\n\nAnything above 100% will probably become uncomfortable."; | 
| Zerotorescue@10 | 220 | 
| Zerotorescue@13 | 221 	mod.scrollFrame:AddChild(sdrSpeed); | 
| Zerotorescue@13 | 222 | 
| Zerotorescue@13 | 223 	local lblSpacer = AceGUI:Create("Label"); | 
| Zerotorescue@13 | 224 	lblSpacer:SetRelativeWidth(.23); | 
| Zerotorescue@13 | 225 | 
| Zerotorescue@13 | 226 	mod.scrollFrame:AddChild(lblSpacer); | 
| Zerotorescue@13 | 227 | 
| Zerotorescue@13 | 228 	-- Config button | 
| Zerotorescue@13 | 229 	--[[local btnConfig = AceGUI:Create("Button"); | 
| Zerotorescue@13 | 230 	btnConfig:SetText("Config"); | 
| Zerotorescue@13 | 231 	btnConfig:SetRelativeWidth(.2); | 
| Zerotorescue@13 | 232 	btnConfig:SetCallback("OnClick", function() | 
| Zerotorescue@13 | 233 		--TODO: Tidy up | 
| Zerotorescue@13 | 234 		SlashCmdList["INVENTORIUM"]("config"); | 
| Zerotorescue@13 | 235 	end); | 
| Zerotorescue@13 | 236 	btnConfig:SetCallback("OnEnter", ShowTooltip); | 
| Zerotorescue@13 | 237 	btnConfig:SetCallback("OnLeave", HideTooltip); | 
| Zerotorescue@13 | 238 	btnConfig.frame.tooltipTitle = "Config"; | 
| Zerotorescue@13 | 239 	btnConfig.frame.tooltip = "Click to open the config window. This will close the current window."; | 
| Zerotorescue@13 | 240 | 
| Zerotorescue@13 | 241 	mod.scrollFrame:AddChild(btnConfig);]] | 
| Zerotorescue@13 | 242 | 
| Zerotorescue@13 | 243 	local lblSpacer = AceGUI:Create("Label"); | 
| Zerotorescue@13 | 244 	lblSpacer:SetRelativeWidth(.03); | 
| Zerotorescue@13 | 245 | 
| Zerotorescue@13 | 246 	mod.scrollFrame:AddChild(lblSpacer); | 
| Zerotorescue@13 | 247 | 
| Zerotorescue@13 | 248 	-- Queue all button | 
| Zerotorescue@13 | 249 	local btnQueueAll = AceGUI:Create("Button"); | 
| Zerotorescue@13 | 250 	btnQueueAll:SetText("Queue All"); | 
| Zerotorescue@13 | 251 	btnQueueAll:SetRelativeWidth(.2); | 
| Zerotorescue@13 | 252 	btnQueueAll:SetCallback("OnClick", function() | 
| Zerotorescue@14 | 253 		self:SendMessage("IM_QUEUE_ALL"); | 
| Zerotorescue@13 | 254 	end); | 
| Zerotorescue@13 | 255 	btnQueueAll:SetCallback("OnEnter", ShowTooltip); | 
| Zerotorescue@13 | 256 	btnQueueAll:SetCallback("OnLeave", HideTooltip); | 
| Zerotorescue@13 | 257 	btnQueueAll.frame.tooltipTitle = "Queue all"; | 
| Zerotorescue@13 | 258 	btnQueueAll.frame.tooltip = "Queue everything that requires restocking within every single visible group."; | 
| Zerotorescue@13 | 259 | 
| Zerotorescue@13 | 260 	mod.scrollFrame:AddChild(btnQueueAll); | 
| Zerotorescue@10 | 261 | 
| Zerotorescue@10 | 262 	times.init = ceil( ( GetTime() - buildStartTime ) * 1000 ); | 
| Zerotorescue@10 | 263 	addon:Debug("Time spent legend: (init / sorting / preparing / building / all)."); | 
| Zerotorescue@10 | 264 | 
| Zerotorescue@1 | 265 	local playerName = UnitName("player"); | 
| Zerotorescue@1 | 266 | 
| Zerotorescue@1 | 267 	-- Go through all our stored groups | 
| Zerotorescue@10 | 268 	for groupName, values in pairsByKeys(addon.db.global.groups, function(a, b) return a:lower() < b:lower(); end) do | 
| Zerotorescue@10 | 269 		local groupStartTime, groupTimes = GetTime(), {}; | 
| Zerotorescue@10 | 270 | 
| Zerotorescue@1 | 271 		local trackAt = (values.trackAtCharacters or (values.trackAtCharacters == nil and addon.db.global.defaults.trackAtCharacters)); | 
| Zerotorescue@1 | 272 | 
| Zerotorescue@1 | 273 		-- Does this group have any items and do we want to track it at this char? | 
| Zerotorescue@1 | 274 		if values.items and trackAt[playerName] then | 
| Zerotorescue@10 | 275 | 
| Zerotorescue@10 | 276 | 
| Zerotorescue@0 | 277 			-- Get group settings | 
| Zerotorescue@9 | 278 			local minimumStock = (values.minimumStock or (values.minimumStock == nil and addon.db.global.defaults.minimumStock)); | 
| Zerotorescue@1 | 279 			local showWhenBelow = (values.summaryThresholdShow or (values.summaryThresholdShow == nil and addon.db.global.defaults.summaryThresholdShow)); | 
| Zerotorescue@1 | 280 			local priceThreshold = (values.priceThreshold or (values.priceThreshold == nil and addon.db.global.defaults.priceThreshold)); | 
| Zerotorescue@27 | 281 			local hideWhenBelowPriceThreshold = (values.summaryHidePriceThreshold or (values.summaryHidePriceThreshold == nil and addon.db.global.defaults.summaryHidePriceThreshold)); | 
| Zerotorescue@23 | 282 			local alwaysGetAuctionValue = (values.alwaysGetAuctionValue or (values.alwaysGetAuctionValue == nil and addon.db.global.defaults.alwaysGetAuctionValue)); | 
| Zerotorescue@10 | 283 | 
| Zerotorescue@0 | 284 			-- Make group container | 
| Zerotorescue@0 | 285 			local iGroup = AceGUI:Create("InlineGroupWithButton"); | 
| Zerotorescue@1 | 286 			iGroup:PauseLayout(); | 
| Zerotorescue@0 | 287 			iGroup:SetTitle(groupName); | 
| Zerotorescue@0 | 288 			iGroup:SetFullWidth(true); | 
| Zerotorescue@0 | 289 			iGroup:SetLayout("Flow"); | 
| Zerotorescue@0 | 290 			iGroup:MakeButton({ | 
| Zerotorescue@0 | 291 				name = "Queue", | 
| Zerotorescue@0 | 292 				desc = "Queue all items in this group.", | 
| Zerotorescue@0 | 293 				exec = function() | 
| Zerotorescue@14 | 294 					print("Queueing all items within " .. groupName .. " craftable by the currently open profession."); | 
| Zerotorescue@14 | 295 					self:SendMessage("IM_QUEUE_GROUP", groupName); | 
| Zerotorescue@0 | 296 				end, | 
| Zerotorescue@0 | 297 			}); | 
| Zerotorescue@0 | 298 | 
| Zerotorescue@10 | 299 | 
| Zerotorescue@10 | 300 | 
| Zerotorescue@0 | 301 			-- Headers | 
| Zerotorescue@1 | 302 | 
| Zerotorescue@0 | 303 			-- Itemlink | 
| Zerotorescue@0 | 304 			local lblItem = AceGUI:Create("InteractiveLabel"); | 
| Zerotorescue@0 | 305 			lblItem:SetText("|cfffed000Item|r"); | 
| Zerotorescue@0 | 306 			lblItem:SetFontObject(GameFontHighlight); | 
| Zerotorescue@10 | 307 			lblItem:SetRelativeWidth(.7); | 
| Zerotorescue@0 | 308 			lblItem:SetCallback("OnClick", function() ReSort("item"); end); | 
| Zerotorescue@13 | 309 			lblItem:SetCallback("OnEnter", ShowTooltip); | 
| Zerotorescue@13 | 310 			lblItem:SetCallback("OnLeave", HideTooltip); | 
| Zerotorescue@13 | 311 			lblItem.frame.tooltipTitle = "Item"; | 
| Zerotorescue@13 | 312 			lblItem.frame.tooltip = "Sort on the item quality, then name."; | 
| Zerotorescue@0 | 313 | 
| Zerotorescue@0 | 314 			iGroup:AddChild(lblItem); | 
| Zerotorescue@0 | 315 | 
| Zerotorescue@0 | 316 			-- Current quantity | 
| Zerotorescue@0 | 317 			local lblQuantity = AceGUI:Create("InteractiveLabel"); | 
| Zerotorescue@0 | 318 			lblQuantity:SetText("|cfffed000Cur.|r"); | 
| Zerotorescue@0 | 319 			lblQuantity:SetFontObject(GameFontHighlight); | 
| Zerotorescue@10 | 320 			lblQuantity:SetRelativeWidth(.099); | 
| Zerotorescue@0 | 321 			lblQuantity:SetCallback("OnClick", function() ReSort("current"); end); | 
| Zerotorescue@13 | 322 			lblQuantity:SetCallback("OnEnter", ShowTooltip); | 
| Zerotorescue@13 | 323 			lblQuantity:SetCallback("OnLeave", HideTooltip); | 
| Zerotorescue@13 | 324 			lblQuantity.frame.tooltipTitle = "Current stock"; | 
| Zerotorescue@13 | 325 			lblQuantity.frame.tooltip = "Sort on the amount of items currently in stock."; | 
| Zerotorescue@0 | 326 | 
| Zerotorescue@0 | 327 			iGroup:AddChild(lblQuantity); | 
| Zerotorescue@0 | 328 | 
| Zerotorescue@36 | 329 			-- Local quantity | 
| Zerotorescue@36 | 330 			--[[local lblLocal = AceGUI:Create("InteractiveLabel"); | 
| Zerotorescue@36 | 331 			lblLocal:SetText("|cfffed000Loc.|r"); | 
| Zerotorescue@36 | 332 			lblLocal:SetFontObject(GameFontHighlight); | 
| Zerotorescue@36 | 333 			lblLocal:SetRelativeWidth(.099); | 
| Zerotorescue@36 | 334 			lblLocal:SetCallback("OnClick", function() ReSort("current"); end); | 
| Zerotorescue@36 | 335 			lblLocal:SetCallback("OnEnter", ShowTooltip); | 
| Zerotorescue@36 | 336 			lblLocal:SetCallback("OnLeave", HideTooltip); | 
| Zerotorescue@36 | 337 			lblLocal.frame.tooltipTitle = "Local stock"; | 
| Zerotorescue@36 | 338 			lblLocal.frame.tooltip = "Sort on the amount of items currently in local stock."; | 
| Zerotorescue@36 | 339 | 
| Zerotorescue@36 | 340 			iGroup:AddChild(lblLocal);]] | 
| Zerotorescue@36 | 341 | 
| Zerotorescue@0 | 342 			-- Required stock | 
| Zerotorescue@9 | 343 			local lblMinimumStock = AceGUI:Create("InteractiveLabel"); | 
| Zerotorescue@13 | 344 			lblMinimumStock:SetText("|cfffed000Min.|r"); | 
| Zerotorescue@9 | 345 			lblMinimumStock:SetFontObject(GameFontHighlight); | 
| Zerotorescue@10 | 346 			lblMinimumStock:SetRelativeWidth(.099); | 
| Zerotorescue@9 | 347 			lblMinimumStock:SetCallback("OnClick", function() ReSort("percentage"); end); | 
| Zerotorescue@13 | 348 			lblMinimumStock:SetCallback("OnEnter", ShowTooltip); | 
| Zerotorescue@13 | 349 			lblMinimumStock:SetCallback("OnLeave", HideTooltip); | 
| Zerotorescue@13 | 350 			lblMinimumStock.frame.tooltipTitle = "Minimum stock"; | 
| Zerotorescue@13 | 351 			lblMinimumStock.frame.tooltip = "Sort on the minimum amount of items you wish to keep in stock."; | 
| Zerotorescue@0 | 352 | 
| Zerotorescue@9 | 353 			iGroup:AddChild(lblMinimumStock); | 
| Zerotorescue@0 | 354 | 
| Zerotorescue@1 | 355 			-- Lowest value | 
| Zerotorescue@1 | 356 			local lblValue = AceGUI:Create("InteractiveLabel"); | 
| Zerotorescue@1 | 357 			lblValue:SetText("|cfffed000Value|r"); | 
| Zerotorescue@1 | 358 			lblValue:SetFontObject(GameFontHighlight); | 
| Zerotorescue@10 | 359 			lblValue:SetRelativeWidth(.099); | 
| Zerotorescue@1 | 360 			lblValue:SetCallback("OnClick", function() ReSort("value"); end); | 
| Zerotorescue@13 | 361 			lblValue:SetCallback("OnEnter", ShowTooltip); | 
| Zerotorescue@13 | 362 			lblValue:SetCallback("OnLeave", HideTooltip); | 
| Zerotorescue@13 | 363 			lblValue.frame.tooltipTitle = "Value"; | 
| Zerotorescue@13 | 364 			lblValue.frame.tooltip = "Sort on the item auction value."; | 
| Zerotorescue@1 | 365 | 
| Zerotorescue@1 | 366 			iGroup:AddChild(lblValue); | 
| Zerotorescue@1 | 367 | 
| Zerotorescue@10 | 368 | 
| Zerotorescue@10 | 369 			-- Retrieve items list | 
| Zerotorescue@1 | 370 			if not itemsCache[groupName] then | 
| Zerotorescue@1 | 371 				itemsCache[groupName] = {}; | 
| Zerotorescue@0 | 372 | 
| Zerotorescue@1 | 373 				-- Sort item list | 
| Zerotorescue@12 | 374 				for itemId, _ in pairs(values.items) do | 
| Zerotorescue@1 | 375 					local itemName, itemLink, itemRarity = GetItemInfo(itemId); | 
| Zerotorescue@1 | 376 | 
| Zerotorescue@1 | 377 					table.insert(itemsCache[groupName], { | 
| Zerotorescue@1 | 378 						id = itemId, | 
| Zerotorescue@12 | 379 						name = itemName or unknownItemName:format(itemId), | 
| Zerotorescue@23 | 380 						link = itemLink, | 
| Zerotorescue@23 | 381 						value = ((priceThreshold == 0 and not alwaysGetAuctionValue) and -4) or -3,-- if (no price threshold is set for this item and you don't want to always get auction value), then don't look it up either --addon:GetAuctionValue(itemLink), | 
| Zerotorescue@12 | 382 						rarity = itemRarity or 1, | 
| Zerotorescue@23 | 383 						count = -3,--addon:GetItemCount(itemId, groupName), | 
| Zerotorescue@36 | 384 						--localCount = -3, | 
| Zerotorescue@1 | 385 						set = {}, | 
| Zerotorescue@1 | 386 					}); | 
| Zerotorescue@1 | 387 					CACHE_ITEMS_TOTAL = CACHE_ITEMS_TOTAL + 1; | 
| Zerotorescue@1 | 388 				end | 
| Zerotorescue@0 | 389 			end | 
| Zerotorescue@0 | 390 | 
| Zerotorescue@10 | 391 			groupTimes.init = ceil( ( GetTime() - groupStartTime ) * 1000 ); | 
| Zerotorescue@10 | 392 | 
| Zerotorescue@10 | 393 | 
| Zerotorescue@10 | 394 | 
| Zerotorescue@10 | 395 			-- Sort items | 
| Zerotorescue@1 | 396 			table.sort(itemsCache[groupName], function(a, b) | 
| Zerotorescue@1 | 397 				if sortMethod == "item" and a.rarity == b.rarity then | 
| Zerotorescue@1 | 398 					-- Do a name-compare for items of the same rarity | 
| Zerotorescue@1 | 399 					-- Otherwise epics first, then junk | 
| Zerotorescue@0 | 400 					if sortDirectory == "ASC" then | 
| Zerotorescue@1 | 401 						return a.name:upper() < b.name:upper(); | 
| Zerotorescue@0 | 402 					else | 
| Zerotorescue@1 | 403 						return a.name:upper() > b.name:upper(); | 
| Zerotorescue@1 | 404 					end | 
| Zerotorescue@1 | 405 				elseif sortMethod == "item"  then | 
| Zerotorescue@1 | 406 					if sortDirectory == "ASC" then | 
| Zerotorescue@1 | 407 						return a.rarity > b.rarity; -- the comparers were reversed because we want epics first | 
| Zerotorescue@1 | 408 					else | 
| Zerotorescue@1 | 409 						return a.rarity < b.rarity; -- the comparers were reversed because we want epics first | 
| Zerotorescue@0 | 410 					end | 
| Zerotorescue@0 | 411 				elseif sortMethod == "current" then | 
| Zerotorescue@0 | 412 					if sortDirectory == "ASC" then | 
| Zerotorescue@0 | 413 						return a.count < b.count; | 
| Zerotorescue@0 | 414 					else | 
| Zerotorescue@0 | 415 						return a.count > b.count; | 
| Zerotorescue@0 | 416 					end | 
| Zerotorescue@0 | 417 				elseif sortMethod == "percentage" then | 
| Zerotorescue@0 | 418 					if sortDirectory == "ASC" then | 
| Zerotorescue@10 | 419 						return ( a.count / minimumStock ) < ( b.count / minimumStock ); | 
| Zerotorescue@0 | 420 					else | 
| Zerotorescue@10 | 421 						return ( a.count / minimumStock ) > ( b.count / minimumStock ); | 
| Zerotorescue@0 | 422 					end | 
| Zerotorescue@1 | 423 				elseif sortMethod == "value" then | 
| Zerotorescue@1 | 424 					if sortDirectory == "ASC" then | 
| Zerotorescue@1 | 425 						return a.value < b.value; | 
| Zerotorescue@1 | 426 					else | 
| Zerotorescue@1 | 427 						return a.value > b.value; | 
| Zerotorescue@1 | 428 					end | 
| Zerotorescue@0 | 429 				end | 
| Zerotorescue@0 | 430 			end); | 
| Zerotorescue@0 | 431 | 
| Zerotorescue@10 | 432 			groupTimes.sorting = ceil( ( GetTime() - groupStartTime ) * 1000 ); | 
| Zerotorescue@10 | 433 | 
| Zerotorescue@10 | 434 | 
| Zerotorescue@10 | 435 | 
| Zerotorescue@10 | 436 | 
| Zerotorescue@10 | 437 			-- Show itemslist | 
| Zerotorescue@1 | 438 			for i, item in pairs(itemsCache[groupName]) do | 
| Zerotorescue@31 | 439 				-- Go through all items for this group | 
| Zerotorescue@31 | 440 | 
| Zerotorescue@31 | 441 				if ( item.count / minimumStock ) < showWhenBelow and (not hideWhenBelowPriceThreshold or priceThreshold == 0 or item.value < 0 or item.value >= priceThreshold) then | 
| Zerotorescue@31 | 442 																-- if the option "hide when below threshold" is disabled or no price threshold is set or the value is above the price threshold or the value could not be determined, proceed | 
| Zerotorescue@0 | 443 					local btnItemLink = AceGUI:Create("ItemLinkButton"); | 
| Zerotorescue@23 | 444 					btnItemLink:SetUserData("exec", function(_, itemId, _, buttonName) | 
| Zerotorescue@23 | 445 						local itemName, itemLink = GetItemInfo(itemId); | 
| Zerotorescue@23 | 446 | 
| Zerotorescue@23 | 447 						if buttonName == "LeftButton" and IsShiftKeyDown() and itemLink then | 
| Zerotorescue@23 | 448 							ChatEdit_InsertLink(itemLink); | 
| Zerotorescue@23 | 449 						elseif buttonName == "LeftButton" and IsAltKeyDown() and itemName and AuctionFrame and AuctionFrame:IsShown() and AuctionFrameBrowse then | 
| Zerotorescue@23 | 450 							-- Start search at page 0 | 
| Zerotorescue@23 | 451 							AuctionFrameBrowse.page = 0; | 
| Zerotorescue@23 | 452 | 
| Zerotorescue@23 | 453 							-- Set the search field (even though we could use "ChatEdit_InsertLink", this ensures the right field is updated) | 
| Zerotorescue@23 | 454 							BrowseName:SetText(itemName) | 
| Zerotorescue@23 | 455 | 
| Zerotorescue@23 | 456 							QueryAuctionItems(itemName, nil, nil, 0, 0, 0, 0, 0, 0); | 
| Zerotorescue@23 | 457 						end | 
| Zerotorescue@23 | 458 					end); | 
| Zerotorescue@10 | 459 					btnItemLink:SetRelativeWidth(.7); | 
| Zerotorescue@1 | 460 					btnItemLink:SetItemId(item.id); | 
| Zerotorescue@0 | 461 | 
| Zerotorescue@0 | 462 					iGroup:AddChild(btnItemLink); | 
| Zerotorescue@0 | 463 | 
| Zerotorescue@0 | 464 					-- Current quantity | 
| Zerotorescue@0 | 465 					local lblQuantity = AceGUI:Create("Label"); | 
| Zerotorescue@9 | 466 					lblQuantity:SetText(self:DisplayItemCount(item.count, minimumStock)); | 
| Zerotorescue@10 | 467 					lblQuantity:SetRelativeWidth(.099); | 
| Zerotorescue@0 | 468 | 
| Zerotorescue@0 | 469 					iGroup:AddChild(lblQuantity); | 
| Zerotorescue@0 | 470 | 
| Zerotorescue@36 | 471 					-- Local quantity | 
| Zerotorescue@36 | 472 					--[[local lblLocal = AceGUI:Create("Label"); | 
| Zerotorescue@36 | 473 					lblLocal:SetText(self:DisplayItemCount(item.count, minimumStock)); | 
| Zerotorescue@36 | 474 					lblLocal:SetRelativeWidth(.099); | 
| Zerotorescue@36 | 475 | 
| Zerotorescue@36 | 476 					iGroup:AddChild(lblLocal);]] | 
| Zerotorescue@36 | 477 | 
| Zerotorescue@0 | 478 					-- Required stock | 
| Zerotorescue@9 | 479 					local lblMinimumStock = AceGUI:Create("Label"); | 
| Zerotorescue@9 | 480 					lblMinimumStock:SetText(minimumStock); | 
| Zerotorescue@10 | 481 					lblMinimumStock:SetRelativeWidth(.099); | 
| Zerotorescue@0 | 482 | 
| Zerotorescue@9 | 483 					iGroup:AddChild(lblMinimumStock); | 
| Zerotorescue@1 | 484 | 
| Zerotorescue@1 | 485 					-- Value | 
| Zerotorescue@1 | 486 					local lblValue = AceGUI:Create("Label"); | 
| Zerotorescue@1 | 487 					lblValue:SetText(self:DisplayMoney(item.value, priceThreshold)); | 
| Zerotorescue@10 | 488 					lblValue:SetRelativeWidth(.099); | 
| Zerotorescue@1 | 489 | 
| Zerotorescue@1 | 490 					iGroup:AddChild(lblValue); | 
| Zerotorescue@1 | 491 | 
| Zerotorescue@1 | 492 					-- Remember references to the value and current fields so we can fill them later | 
| Zerotorescue@1 | 493 					if item.set then | 
| Zerotorescue@10 | 494 						-- -3 means the price is unknown, queue look up | 
| Zerotorescue@10 | 495 						if item.value == -3 then | 
| Zerotorescue@10 | 496 							item.set.value = lblValue; | 
| Zerotorescue@10 | 497 						end | 
| Zerotorescue@10 | 498 						if item.count == -3 then | 
| Zerotorescue@10 | 499 							item.set.current = lblQuantity; | 
| Zerotorescue@10 | 500 						end | 
| Zerotorescue@10 | 501 | 
| Zerotorescue@10 | 502 						-- Don't queue if we already know everything we want to know | 
| Zerotorescue@10 | 503 						if item.value ~= -3 and item.count ~= -3 then | 
| Zerotorescue@10 | 504 							item.set = nil; | 
| Zerotorescue@10 | 505 						end | 
| Zerotorescue@1 | 506 					end | 
| Zerotorescue@0 | 507 				end | 
| Zerotorescue@0 | 508 			end | 
| Zerotorescue@0 | 509 | 
| Zerotorescue@10 | 510 			groupTimes.preparing = ceil( ( GetTime() - groupStartTime ) * 1000 ); | 
| Zerotorescue@10 | 511 | 
| Zerotorescue@1 | 512 			iGroup:ResumeLayout(); | 
| Zerotorescue@1 | 513 			mod.scrollFrame:AddChild(iGroup); -- this can take up to .5 seconds, might need to look into again at a later time | 
| Zerotorescue@10 | 514 | 
| Zerotorescue@10 | 515 			groupTimes.building = ceil( ( GetTime() - groupStartTime ) * 1000 ); | 
| Zerotorescue@0 | 516 		end | 
| Zerotorescue@10 | 517 | 
| Zerotorescue@13 | 518 		if groupStartTime and groupTimes then | 
| Zerotorescue@13 | 519 			addon:Debug(("Building of %s took %d ms (%d / %d / %d / %d / %d)."):format(groupName, ceil( ( GetTime() - groupStartTime ) * 1000 ), groupTimes.init or 0, groupTimes.sorting or 0, groupTimes.preparing or 0, groupTimes.building or 0, ceil( ( GetTime() - buildStartTime ) * 1000 ))); | 
| Zerotorescue@13 | 520 		end | 
| Zerotorescue@0 | 521 	end | 
| Zerotorescue@1 | 522 | 
| Zerotorescue@1 | 523 	mod.scrollFrame:ResumeLayout(); | 
| Zerotorescue@1 | 524 	mod.scrollFrame:DoLayout(); | 
| Zerotorescue@1 | 525 | 
| Zerotorescue@10 | 526 	addon:Debug(("Done building summary after %d ms."):format(ceil( ( GetTime() - buildStartTime ) * 1000 ))); | 
| Zerotorescue@10 | 527 | 
| Zerotorescue@1 | 528 	if CACHE_ITEMS_TOTAL > 0 then | 
| Zerotorescue@1 | 529 		cacheStart = GetTime(); | 
| Zerotorescue@7 | 530 		self:CancelTimer(self.tmrUpdater, true); | 
| Zerotorescue@1 | 531 		self.tmrUpdater = self:ScheduleRepeatingTimer("UpdateNextItem", .01); -- Once every 100 frames (or once every x frames if you have less than 100 FPS, basically, once every frame) | 
| Zerotorescue@1 | 532 	end | 
| Zerotorescue@1 | 533 end | 
| Zerotorescue@1 | 534 | 
| Zerotorescue@1 | 535 function mod:UpdateNextItem() | 
| Zerotorescue@1 | 536 	local i = 0; | 
| Zerotorescue@1 | 537 | 
| Zerotorescue@1 | 538 	for groupName, items in pairs(itemsCache) do | 
| Zerotorescue@1 | 539 		local minimumStock = addon:GetOptionByKey(groupName, "minimumStock"); | 
| Zerotorescue@1 | 540 		local priceThreshold = addon:GetOptionByKey(groupName, "priceThreshold"); | 
| Zerotorescue@1 | 541 | 
| Zerotorescue@1 | 542 		for _, item in pairs(items) do | 
| Zerotorescue@1 | 543 			if item.set then | 
| Zerotorescue@10 | 544 				if item.count == -3 then | 
| Zerotorescue@10 | 545 					-- Only if item count was queued, update it | 
| Zerotorescue@23 | 546 					item.count = addon:GetItemCount(item.id, groupName); | 
| Zerotorescue@10 | 547 					if item.set.current and item.set.current.SetText then | 
| Zerotorescue@10 | 548 						item.set.current:SetText(self:DisplayItemCount(item.count, minimumStock)); | 
| Zerotorescue@10 | 549 					end | 
| Zerotorescue@1 | 550 				end | 
| Zerotorescue@1 | 551 | 
| Zerotorescue@10 | 552 				if item.value == -3 then | 
| Zerotorescue@10 | 553 					-- Only if item value was queued, update it | 
| Zerotorescue@23 | 554 | 
| Zerotorescue@23 | 555 					-- The itemlink might not have been loaded yet in which case we retry | 
| Zerotorescue@23 | 556 					item.link = item.link or select(2, GetItemInfo(item.id)); | 
| Zerotorescue@23 | 557 | 
| Zerotorescue@23 | 558 					if item.link then | 
| Zerotorescue@23 | 559 						item.value = addon:GetAuctionValue(item.link, groupName); | 
| Zerotorescue@23 | 560 						if item.set.value and item.set.value.SetText then | 
| Zerotorescue@23 | 561 							item.set.value:SetText(self:DisplayMoney(item.value, priceThreshold)); | 
| Zerotorescue@23 | 562 						end | 
| Zerotorescue@10 | 563 					end | 
| Zerotorescue@1 | 564 				end | 
| Zerotorescue@1 | 565 | 
| Zerotorescue@1 | 566 				item.set = nil; | 
| Zerotorescue@1 | 567 | 
| Zerotorescue@1 | 568 				i = i + 1; | 
| Zerotorescue@1 | 569 				CACHE_ITEMS_CURRENT = CACHE_ITEMS_CURRENT + 1; | 
| Zerotorescue@1 | 570 | 
| Zerotorescue@9 | 571 				if mod.frame then | 
| Zerotorescue@9 | 572 					mod.frame:SetStatusText(("Caching auction values and item-counts... %d%% has already been processed."):format(floor(CACHE_ITEMS_CURRENT / CACHE_ITEMS_TOTAL * 100))); | 
| Zerotorescue@9 | 573 				end | 
| Zerotorescue@1 | 574 | 
| Zerotorescue@13 | 575 				if i >= addon.db.global.defaults.summary.speed then | 
| Zerotorescue@1 | 576 					return; | 
| Zerotorescue@1 | 577 				end | 
| Zerotorescue@1 | 578 			end | 
| Zerotorescue@1 | 579 		end | 
| Zerotorescue@1 | 580 	end | 
| Zerotorescue@1 | 581 | 
| Zerotorescue@1 | 582 	-- Reset trackers | 
| Zerotorescue@1 | 583 	CACHE_ITEMS_TOTAL = 0; | 
| Zerotorescue@1 | 584 	CACHE_ITEMS_CURRENT = 0; | 
| Zerotorescue@1 | 585 | 
| Zerotorescue@1 | 586 	-- Stop timer | 
| Zerotorescue@1 | 587 	self:CancelTimer(self.tmrUpdater, true); | 
| Zerotorescue@10 | 588 | 
| Zerotorescue@10 | 589 	-- Rebuild list so hidden items due to too low prices get added | 
| Zerotorescue@10 | 590 	self:Build(); | 
| Zerotorescue@1 | 591 | 
| Zerotorescue@1 | 592 	-- Announce | 
| Zerotorescue@10 | 593 	mod.frame:SetStatusText("All required prices and itemcounts have been cached. This process took " .. ceil(GetTime() - cacheStart) .. " seconds."); | 
| Zerotorescue@1 | 594 | 
| Zerotorescue@1 | 595 	-- Forget time | 
| Zerotorescue@1 | 596 	cacheStart = nil; | 
| Zerotorescue@0 | 597 end | 
| Zerotorescue@0 | 598 | 
| Zerotorescue@0 | 599 function mod:ColorCode(num, required) | 
| Zerotorescue@0 | 600 	local percentage = ( num / required ); | 
| Zerotorescue@0 | 601 | 
| Zerotorescue@0 | 602 	if percentage >= addon.db.global.defaults.colors.green then | 
| Zerotorescue@0 | 603 		return ("|cff00ff00%d|r"):format(num); | 
| Zerotorescue@0 | 604 	elseif percentage >= addon.db.global.defaults.colors.yellow then | 
| Zerotorescue@0 | 605 		return ("|cffffff00%d|r"):format(num); | 
| Zerotorescue@0 | 606 	elseif percentage >= addon.db.global.defaults.colors.orange then | 
| Zerotorescue@0 | 607 		return ("|cffff9933%d|r"):format(num); | 
| Zerotorescue@0 | 608 	elseif percentage >= addon.db.global.defaults.colors.red then | 
| Zerotorescue@0 | 609 		return ("|cffff0000%d|r"):format(num); | 
| Zerotorescue@0 | 610 	end | 
| Zerotorescue@0 | 611 end | 
| Zerotorescue@0 | 612 | 
| Zerotorescue@1 | 613 function mod:DisplayMoney(value, priceThreshold) | 
| Zerotorescue@7 | 614 	if value == -1 then | 
| Zerotorescue@7 | 615 		return "|cff0000ffNone up|r"; | 
| Zerotorescue@7 | 616 	elseif value == -2 then | 
| Zerotorescue@7 | 617 		return "|cff0000ffNo AH mod|r"; | 
| Zerotorescue@9 | 618 	elseif value == -3 then | 
| Zerotorescue@9 | 619 		return "|cffffff00Unknown|r"; | 
| Zerotorescue@13 | 620 	elseif value == -4 then | 
| Zerotorescue@13 | 621 		return "|cff00ff00-|r"; | 
| Zerotorescue@23 | 622 	elseif value == -5 then | 
| Zerotorescue@23 | 623 		return "|cffff9933Error|r"; | 
| Zerotorescue@23 | 624 	elseif priceThreshold and value < priceThreshold then | 
| Zerotorescue@17 | 625 		return ("|cffaaaaaa%s|r"):format(addon:ReadableMoney(value or 0, true):gsub("|([a-fA-F0-9]+)([gsc]+)|r", "%2")); | 
| Zerotorescue@1 | 626 	else | 
| Zerotorescue@1 | 627 		return addon:ReadableMoney(value or 0, true); | 
| Zerotorescue@1 | 628 	end | 
| Zerotorescue@1 | 629 end | 
| Zerotorescue@1 | 630 | 
| Zerotorescue@9 | 631 function mod:DisplayItemCount(value, minimumStock) | 
| Zerotorescue@13 | 632 	if value == -1 then | 
| Zerotorescue@13 | 633 		return "|cffffff00Unknown|r"; | 
| Zerotorescue@13 | 634 	elseif value == -3 then | 
| Zerotorescue@9 | 635 		return "|cffffff00Unknown|r"; | 
| Zerotorescue@9 | 636 	else | 
| Zerotorescue@9 | 637 		return self:ColorCode(value, minimumStock); | 
| Zerotorescue@9 | 638 	end | 
| Zerotorescue@9 | 639 end | 
| Zerotorescue@9 | 640 | 
| Zerotorescue@0 | 641 function mod:NumberFormat(num) | 
| Zerotorescue@0 | 642 	local formatted = string.gsub(num, "(%d)(%d%d%d)$", "%1,%2", 1); | 
| Zerotorescue@0 | 643 | 
| Zerotorescue@0 | 644 	while true do | 
| Zerotorescue@0 | 645 		formatted, matches = string.gsub(formatted, "(%d)(%d%d%d),", "%1,%2,", 1); | 
| Zerotorescue@0 | 646 | 
| Zerotorescue@0 | 647 		if matches == 0 then | 
| Zerotorescue@0 | 648 			break; | 
| Zerotorescue@0 | 649 		end | 
| Zerotorescue@0 | 650 	end | 
| Zerotorescue@0 | 651 | 
| Zerotorescue@0 | 652 	return formatted; | 
| Zerotorescue@1 | 653 end |