| Zerotorescue@11 | 1 -- You can access this addon's object through: LibStub("AceAddon-3.0"):GetAddon("Inventorium") | 
| Zerotorescue@17 | 2 local addon = select(2, ...); | 
| Zerotorescue@17 | 3 addon = LibStub("AceAddon-3.0"):NewAddon(addon, "Inventorium", "AceEvent-3.0"); | 
| Zerotorescue@1 | 4 | 
| Zerotorescue@122 | 5 local _G = _G; | 
| Zerotorescue@122 | 6 local sformat, ssplit, slower, strim, smatch = _G.string.format, _G.string.split, _G.string.lower, _G.string.trim, _G.string.match; | 
| Zerotorescue@128 | 7 local floor, print, pairs, tonumber = _G.floor, _G.print, _G.pairs, _G.tonumber; | 
| Zerotorescue@122 | 8 | 
| Zerotorescue@61 | 9 --@debug@ | 
| Zerotorescue@61 | 10 local addonRevision = 1; | 
| Zerotorescue@61 | 11 --@end-debug@ | 
| Zerotorescue@61 | 12 --[===[@non-debug@ | 
| Zerotorescue@61 | 13 local addonRevision = @project-revision@; | 
| Zerotorescue@61 | 14 --@end-non-debug@]===] | 
| Zerotorescue@61 | 15 | 
| Zerotorescue@62 | 16 --  All modules must be able to retrieve our supported addons database, thus keep it a part of the addon object rather than local | 
| Zerotorescue@13 | 17 addon.supportedAddons = {}; | 
| Zerotorescue@13 | 18 addon.supportedAddons.auctionPricing = {}; | 
| Zerotorescue@13 | 19 addon.supportedAddons.itemCount = {}; | 
| Zerotorescue@13 | 20 addon.supportedAddons.crafting = {}; | 
| Zerotorescue@0 | 21 | 
| Zerotorescue@120 | 22 addon.Locations = { | 
| Zerotorescue@120 | 23 	["Bag"] = "Bag", | 
| Zerotorescue@120 | 24 	["Bank"] = "Bank", | 
| Zerotorescue@120 | 25 	["Guild"] = "Guild", | 
| Zerotorescue@120 | 26 	["Mailbox"] = "Mailbox", | 
| Zerotorescue@120 | 27 	["Merchant"] = "Merchant", | 
| Zerotorescue@120 | 28 }; | 
| Zerotorescue@120 | 29 | 
| Zerotorescue@0 | 30 function addon:OnInitialize() | 
| Zerotorescue@0 | 31 	-- SAVED VARIABLES | 
| Zerotorescue@0 | 32 | 
| Zerotorescue@0 | 33 	local defaults = { | 
| Zerotorescue@0 | 34 		global = { | 
| Zerotorescue@61 | 35 			version = nil, | 
| Zerotorescue@61 | 36 		}, | 
| Zerotorescue@61 | 37 		profile = { | 
| Zerotorescue@0 | 38 			defaults = { | 
| Zerotorescue@13 | 39 				auctionPricingAddon = "Auctioneer", | 
| Zerotorescue@13 | 40 				itemCountAddon = "Altoholic", | 
| Zerotorescue@13 | 41 				craftingAddon = "AdvancedTradeSkillWindow", | 
| Zerotorescue@61 | 42 				minLocalStock = 20, | 
| Zerotorescue@57 | 43 				alertBelowLocalMinimum = true, | 
| Zerotorescue@82 | 44 				autoRefill = true, | 
| Zerotorescue@101 | 45 				autoRefillSkipConfirm = false, | 
| Zerotorescue@61 | 46 				minGlobalStock = 60, | 
| Zerotorescue@61 | 47 				alertBelowGlobalMinimum = true, | 
| Zerotorescue@0 | 48 				summaryThresholdShow = 10, | 
| Zerotorescue@0 | 49 				restockTarget = 60, | 
| Zerotorescue@0 | 50 				minCraftingQueue = 0.05, | 
| Zerotorescue@0 | 51 				bonusQueue = 0.1, | 
| Zerotorescue@0 | 52 				priceThreshold = 0, | 
| Zerotorescue@13 | 53 				summaryHidePriceThreshold = false, | 
| Zerotorescue@106 | 54 				hideHelp = false, | 
| Zerotorescue@40 | 55 				trackAtCharacters = { | 
| Zerotorescue@40 | 56 				}, | 
| Zerotorescue@31 | 57 				localItemData = { | 
| Zerotorescue@31 | 58 					["Bag"] = true, | 
| Zerotorescue@31 | 59 					["Auction House"] = true, | 
| Zerotorescue@31 | 60 				}, | 
| Zerotorescue@13 | 61 				summary = { | 
| Zerotorescue@13 | 62 					speed = 5, | 
| Zerotorescue@74 | 63 					width = 700, | 
| Zerotorescue@13 | 64 					height = 600, | 
| Zerotorescue@13 | 65 				}, | 
| Zerotorescue@0 | 66 				colors = { | 
| Zerotorescue@17 | 67 					red = 0, | 
| Zerotorescue@17 | 68 					orange = 0.3, | 
| Zerotorescue@17 | 69 					yellow = 0.6, | 
| Zerotorescue@17 | 70 					green = 0.95, | 
| Zerotorescue@0 | 71 				}, | 
| Zerotorescue@0 | 72 			}, | 
| Zerotorescue@61 | 73 			groups = { | 
| Zerotorescue@61 | 74 			}, | 
| Zerotorescue@0 | 75 		}, | 
| Zerotorescue@0 | 76 		factionrealm = { | 
| Zerotorescue@40 | 77 			characters = { | 
| Zerotorescue@40 | 78 			}, | 
| Zerotorescue@0 | 79 		}, | 
| Zerotorescue@0 | 80 	}; | 
| Zerotorescue@0 | 81 | 
| Zerotorescue@0 | 82 	-- Register our saved variables database | 
| Zerotorescue@11 | 83 	self.db = LibStub("AceDB-3.0"):New("InventoriumDB", defaults, true); | 
| Zerotorescue@61 | 84 | 
| Zerotorescue@62 | 85 	-- SLASH COMMANDS | 
| Zerotorescue@62 | 86 | 
| Zerotorescue@62 | 87 	-- Disable the AddonLoader slash commands | 
| Zerotorescue@62 | 88 	SLASH_INVENTORIUM1 = nil; | 
| Zerotorescue@62 | 89 	SLASH_IM1 = nil; | 
| Zerotorescue@62 | 90 | 
| Zerotorescue@62 | 91 	-- Register our own slash commands | 
| Zerotorescue@62 | 92 	SLASH_INVENTORIUM1 = "/inventorium"; | 
| Zerotorescue@62 | 93 	SLASH_INVENTORIUM2 = "/im"; | 
| Zerotorescue@62 | 94 	SlashCmdList["INVENTORIUM"] = function(msg) | 
| Zerotorescue@62 | 95 		addon:CommandHandler(msg); | 
| Zerotorescue@62 | 96 	end; | 
| Zerotorescue@62 | 97 | 
| Zerotorescue@62 | 98 	-- Debug command handling | 
| Zerotorescue@62 | 99 	self:RegisterSlash(function(this) | 
| Zerotorescue@62 | 100 		this.debugChannel = false; | 
| Zerotorescue@62 | 101 		for i = 1, NUM_CHAT_WINDOWS do | 
| Zerotorescue@62 | 102 			local name = GetChatWindowInfo(i); | 
| Zerotorescue@62 | 103 | 
| Zerotorescue@128 | 104 			if string.upper(name) == "DEBUG" then | 
| Zerotorescue@128 | 105 				addon:Print("A debug channel already exists, removing the old one... (" .. i .. ")"); | 
| Zerotorescue@128 | 106 				FCF_Close(_G["ChatFrame" .. i]); | 
| Zerotorescue@62 | 107 			end | 
| Zerotorescue@62 | 108 		end | 
| Zerotorescue@62 | 109 | 
| Zerotorescue@62 | 110 		if not this.debugChannel then | 
| Zerotorescue@62 | 111 			-- Create a new debug channel | 
| Zerotorescue@62 | 112 			local chatFrame = FCF_OpenNewWindow('Debug'); | 
| Zerotorescue@62 | 113 			ChatFrame_RemoveAllMessageGroups(chatFrame); | 
| Zerotorescue@62 | 114 			this.debugChannel = chatFrame; | 
| Zerotorescue@62 | 115 | 
| Zerotorescue@98 | 116 			addon:Print("New debug channel created."); | 
| Zerotorescue@62 | 117 		end | 
| Zerotorescue@62 | 118 	end, { "d", "debug" }); | 
| Zerotorescue@62 | 119 | 
| Zerotorescue@62 | 120 	-- Remember this character is on this account | 
| Zerotorescue@62 | 121 	local playerName = UnitName("player"); | 
| Zerotorescue@62 | 122 	if not self.db.factionrealm.characters[playerName] then | 
| Zerotorescue@62 | 123 		self.db.factionrealm.characters[playerName] = true; | 
| Zerotorescue@62 | 124 | 
| Zerotorescue@62 | 125 		-- Default to tracking on all chars, untracking is a convenience, not tracking by default would probably get multiple issue reports. | 
| Zerotorescue@62 | 126 		self.db.profile.defaults.trackAtCharacters[playerName] = true; | 
| Zerotorescue@62 | 127 	end | 
| Zerotorescue@66 | 128 | 
| Zerotorescue@66 | 129 	self:UpdateDatabase(); | 
| Zerotorescue@62 | 130 end | 
| Zerotorescue@62 | 131 | 
| Zerotorescue@65 | 132 | 
| Zerotorescue@65 | 133 | 
| Zerotorescue@65 | 134 | 
| Zerotorescue@65 | 135 | 
| Zerotorescue@65 | 136 -- Database patching after new revisions | 
| Zerotorescue@65 | 137 | 
| Zerotorescue@62 | 138 function addon:UpdateDatabase() | 
| Zerotorescue@61 | 139 	if not self.db.global.version or self.db.global.version < addonRevision then | 
| Zerotorescue@61 | 140 		-- Is our database outdated? Then patch it. | 
| Zerotorescue@61 | 141 | 
| Zerotorescue@61 | 142 		if not self.db.global.version then | 
| Zerotorescue@61 | 143 			-- Old version was before version was saved, many changes were done in that revision | 
| Zerotorescue@61 | 144 | 
| Zerotorescue@98 | 145 			addon:Print("Updating Inventorium database from version " .. (self.db.global.version or "Unknown") .. " to version " .. addonRevision .. "..."); | 
| Zerotorescue@61 | 146 | 
| Zerotorescue@61 | 147 			if self.db.global and self.db.global.defaults then | 
| Zerotorescue@98 | 148 				addon:Print("Moving all global data into your current profile..."); | 
| Zerotorescue@61 | 149 | 
| Zerotorescue@61 | 150 				-- All data mustn't be global but profile-based | 
| Zerotorescue@61 | 151 				self.db.profile.defaults = CopyTable(self.db.global.defaults); | 
| Zerotorescue@61 | 152 				self.db.profile.groups = CopyTable(self.db.global.groups); | 
| Zerotorescue@61 | 153 | 
| Zerotorescue@61 | 154 				self.db.global.defaults = nil; | 
| Zerotorescue@61 | 155 				self.db.global.groups = nil; | 
| Zerotorescue@61 | 156 | 
| Zerotorescue@62 | 157 				self.CommandHandler = function() | 
| Zerotorescue@62 | 158 					message("You must /reload once to finalize the Inventorium database updates. This will only be required once during the BETA."); | 
| Zerotorescue@61 | 159 				end; | 
| Zerotorescue@62 | 160 				self:CommandHandler(); | 
| Zerotorescue@61 | 161 			end | 
| Zerotorescue@61 | 162 | 
| Zerotorescue@61 | 163 			if self.db.profile.defaults.minimumStock then | 
| Zerotorescue@98 | 164 				addon:Print("Copying the minimum stock value into the minimum global stock..."); | 
| Zerotorescue@61 | 165 | 
| Zerotorescue@61 | 166 				-- We added another stock option and renamed the old to be more obvious about what it means | 
| Zerotorescue@61 | 167 				self.db.profile.defaults.minGlobalStock = self.db.profile.defaults.minimumStock; | 
| Zerotorescue@61 | 168 				self.db.profile.defaults.minimumStock = nil; | 
| Zerotorescue@61 | 169 			end | 
| Zerotorescue@61 | 170 | 
| Zerotorescue@61 | 171 			if self.db.profile.defaults.minimumLocalStock then | 
| Zerotorescue@98 | 172 				addon:Print("Renaming the minimum local stock property..."); | 
| Zerotorescue@61 | 173 | 
| Zerotorescue@61 | 174 				-- We added another stock option and then renamed it | 
| Zerotorescue@61 | 175 				self.db.profile.defaults.minLocalStock = self.db.profile.defaults.minimumLocalStock; | 
| Zerotorescue@61 | 176 				self.db.profile.defaults.minimumLocalStock = nil; | 
| Zerotorescue@61 | 177 			end | 
| Zerotorescue@61 | 178 | 
| Zerotorescue@61 | 179 			if self.db.profile.defaults.alertBelowMinimum then | 
| Zerotorescue@98 | 180 				addon:Print("Copying the alert below minimum value into the alert below global minimum value..."); | 
| Zerotorescue@61 | 181 | 
| Zerotorescue@61 | 182 				-- We added another stock option and then renamed it | 
| Zerotorescue@61 | 183 				self.db.profile.defaults.alertBelowGlobalMinimum = self.db.profile.defaults.alertBelowMinimum; | 
| Zerotorescue@61 | 184 				self.db.profile.defaults.alertBelowMinimum = nil; | 
| Zerotorescue@61 | 185 			end | 
| Zerotorescue@61 | 186 | 
| Zerotorescue@61 | 187 			-- Go through all groups to see if there's one with the above two renamed variables | 
| Zerotorescue@61 | 188 			for groupName, values in pairs(self.db.profile.groups) do | 
| Zerotorescue@61 | 189 				if values.minimumStock then | 
| Zerotorescue@61 | 190 					values.minGlobalStock = values.minimumStock; | 
| Zerotorescue@61 | 191 					values.minimumStock = nil; | 
| Zerotorescue@61 | 192 				end | 
| Zerotorescue@61 | 193 			end | 
| Zerotorescue@61 | 194 		end | 
| Zerotorescue@61 | 195 | 
| Zerotorescue@61 | 196 		-- Remember the version of our database | 
| Zerotorescue@61 | 197 		self.db.global.version = addonRevision; | 
| Zerotorescue@61 | 198 	end | 
| Zerotorescue@46 | 199 end | 
| Zerotorescue@46 | 200 | 
| Zerotorescue@62 | 201 function addon:GetOptionByKey(groupName, optionName, noDefault) | 
| Zerotorescue@62 | 202 	if groupName and addon.db.profile.groups[groupName] and addon.db.profile.groups[groupName][optionName] ~= nil then | 
| Zerotorescue@62 | 203 		-- If this option exists within the settings of this group | 
| Zerotorescue@62 | 204 | 
| Zerotorescue@62 | 205 		return addon.db.profile.groups[groupName][optionName]; | 
| Zerotorescue@62 | 206 	elseif groupName and addon.db.profile.groups[groupName] and addon.db.profile.groups[groupName].virtualGroup ~= "" and not noDefault then | 
| Zerotorescue@62 | 207 		-- If a virtual group was selected | 
| Zerotorescue@62 | 208 | 
| Zerotorescue@62 | 209 		return self:GetOptionByKey(addon.db.profile.groups[groupName].virtualGroup, optionName, noDefault); | 
| Zerotorescue@62 | 210 	elseif addon.db.profile.defaults[optionName] and not noDefault then | 
| Zerotorescue@62 | 211 		return addon.db.profile.defaults[optionName]; | 
| Zerotorescue@62 | 212 	else | 
| Zerotorescue@62 | 213 		return nil; | 
| Zerotorescue@0 | 214 	end | 
| Zerotorescue@0 | 215 end | 
| Zerotorescue@0 | 216 | 
| Zerotorescue@35 | 217 function addon:GetItemCountAddon(group) | 
| Zerotorescue@35 | 218 	local selectedExternalAddon = self:GetOptionByKey(group, "itemCountAddon"); | 
| Zerotorescue@35 | 219 | 
| Zerotorescue@35 | 220 	if self.supportedAddons.itemCount[selectedExternalAddon] and self.supportedAddons.itemCount[selectedExternalAddon].IsEnabled() then | 
| Zerotorescue@35 | 221 		-- Try to use the default item count addon | 
| Zerotorescue@35 | 222 | 
| Zerotorescue@35 | 223 		return self.supportedAddons.itemCount[selectedExternalAddon], selectedExternalAddon; | 
| Zerotorescue@35 | 224 	else | 
| Zerotorescue@35 | 225 		-- Default not available, get the first one then | 
| Zerotorescue@35 | 226 | 
| Zerotorescue@35 | 227 		for name, value in pairs(self.supportedAddons.itemCount) do | 
| Zerotorescue@35 | 228 			if value.IsEnabled() then | 
| Zerotorescue@35 | 229 				return value, name; | 
| Zerotorescue@35 | 230 			end | 
| Zerotorescue@35 | 231 		end | 
| Zerotorescue@35 | 232 	end | 
| Zerotorescue@35 | 233 | 
| Zerotorescue@35 | 234 	return; | 
| Zerotorescue@35 | 235 end | 
| Zerotorescue@35 | 236 | 
| Zerotorescue@23 | 237 function addon:GetItemCount(itemId, group) | 
| Zerotorescue@13 | 238 	itemId = tonumber(itemId); | 
| Zerotorescue@13 | 239 | 
| Zerotorescue@13 | 240 	if not itemId then return; end | 
| Zerotorescue@13 | 241 | 
| Zerotorescue@35 | 242 	local itemCountAddon = self:GetItemCountAddon(group); | 
| Zerotorescue@23 | 243 | 
| Zerotorescue@35 | 244 	return (itemCountAddon and itemCountAddon.GetTotalCount(itemId)) or -1; | 
| Zerotorescue@0 | 245 end | 
| Zerotorescue@0 | 246 | 
| Zerotorescue@50 | 247 function addon:GetLocalItemCount(itemId, group) | 
| Zerotorescue@50 | 248 	itemId = tonumber(itemId); | 
| Zerotorescue@50 | 249 | 
| Zerotorescue@50 | 250 	if not itemId then return; end | 
| Zerotorescue@50 | 251 | 
| Zerotorescue@50 | 252 	local itemCountAddon = self:GetItemCountAddon(group); | 
| Zerotorescue@50 | 253 | 
| Zerotorescue@50 | 254 	local currentItemCount; | 
| Zerotorescue@50 | 255 | 
| Zerotorescue@50 | 256 	if itemCountAddon and itemCountAddon.GetCharacterCount then | 
| Zerotorescue@50 | 257 		local bag, bank, auctionHouse, mail = itemCountAddon.GetCharacterCount(itemId); | 
| Zerotorescue@50 | 258 | 
| Zerotorescue@50 | 259 		local selectedLocalItemCountSources = self:GetOptionByKey(group, "localItemData"); | 
| Zerotorescue@50 | 260 | 
| Zerotorescue@50 | 261 		currentItemCount = 0; | 
| Zerotorescue@50 | 262 		if selectedLocalItemCountSources["Bag"] then | 
| Zerotorescue@50 | 263 			currentItemCount = currentItemCount + bag; | 
| Zerotorescue@50 | 264 		end | 
| Zerotorescue@50 | 265 		if selectedLocalItemCountSources["Bank"] then | 
| Zerotorescue@50 | 266 			currentItemCount = currentItemCount + bank; | 
| Zerotorescue@50 | 267 		end | 
| Zerotorescue@50 | 268 		if selectedLocalItemCountSources["Auction House"] then | 
| Zerotorescue@50 | 269 			currentItemCount = currentItemCount + auctionHouse; | 
| Zerotorescue@50 | 270 		end | 
| Zerotorescue@50 | 271 		if selectedLocalItemCountSources["Mailbox"] then | 
| Zerotorescue@50 | 272 			currentItemCount = currentItemCount + mail; | 
| Zerotorescue@50 | 273 		end | 
| Zerotorescue@50 | 274 	end | 
| Zerotorescue@50 | 275 | 
| Zerotorescue@50 | 276 	return currentItemCount or -1; | 
| Zerotorescue@50 | 277 end | 
| Zerotorescue@50 | 278 | 
| Zerotorescue@23 | 279 function addon:GetAuctionValue(itemLink, group) | 
| Zerotorescue@23 | 280 	if not itemLink then return -5; end | 
| Zerotorescue@13 | 281 | 
| Zerotorescue@23 | 282 	local selectedExternalAddon = self:GetOptionByKey(group, "auctionPricingAddon"); | 
| Zerotorescue@23 | 283 | 
| Zerotorescue@23 | 284 	if self.supportedAddons.auctionPricing[selectedExternalAddon] and self.supportedAddons.auctionPricing[selectedExternalAddon].IsEnabled() then | 
| Zerotorescue@13 | 285 		-- Try to use the default auction pricing addon | 
| Zerotorescue@1 | 286 | 
| Zerotorescue@23 | 287 		return self.supportedAddons.auctionPricing[selectedExternalAddon].GetValue(itemLink); | 
| Zerotorescue@13 | 288 	else | 
| Zerotorescue@13 | 289 		-- Default not available, get the first one then | 
| Zerotorescue@1 | 290 | 
| Zerotorescue@13 | 291 		for name, value in pairs(self.supportedAddons.auctionPricing) do | 
| Zerotorescue@13 | 292 			if value.IsEnabled() then | 
| Zerotorescue@13 | 293 				return value.GetValue(itemLink); | 
| Zerotorescue@13 | 294 			end | 
| Zerotorescue@1 | 295 		end | 
| Zerotorescue@1 | 296 	end | 
| Zerotorescue@7 | 297 | 
| Zerotorescue@7 | 298 	return -2; | 
| Zerotorescue@1 | 299 end | 
| Zerotorescue@1 | 300 | 
| Zerotorescue@65 | 301 | 
| Zerotorescue@65 | 302 | 
| Zerotorescue@65 | 303 | 
| Zerotorescue@65 | 304 | 
| Zerotorescue@62 | 305 -- Slash commands | 
| Zerotorescue@62 | 306 | 
| Zerotorescue@62 | 307 local slashArgs = {}; | 
| Zerotorescue@62 | 308 local slashError = "Wrong argument, the following arguments are available:"; | 
| Zerotorescue@62 | 309 | 
| Zerotorescue@62 | 310 function addon:CommandHandler(message) | 
| Zerotorescue@122 | 311 	local cmd, arg = ssplit(" ", (message or ""), 2); | 
| Zerotorescue@122 | 312 	cmd = slower(cmd); | 
| Zerotorescue@62 | 313 | 
| Zerotorescue@62 | 314 	if slashArgs[cmd] then | 
| Zerotorescue@62 | 315 		-- Pass a reference to the addon (to be used as "self") and the provided arg | 
| Zerotorescue@62 | 316 		slashArgs[cmd](addon, arg); | 
| Zerotorescue@62 | 317 	else | 
| Zerotorescue@98 | 318 		addon:Print(slashError); | 
| Zerotorescue@62 | 319 	end | 
| Zerotorescue@62 | 320 end | 
| Zerotorescue@62 | 321 | 
| Zerotorescue@62 | 322 function addon:RegisterSlash(func, args, description) | 
| Zerotorescue@62 | 323 	for _, arg in pairs(args) do | 
| Zerotorescue@62 | 324 		slashArgs[arg] = func; | 
| Zerotorescue@62 | 325 	end | 
| Zerotorescue@62 | 326 | 
| Zerotorescue@62 | 327 	if description then | 
| Zerotorescue@62 | 328 		slashError = slashError .. "\n" .. description; | 
| Zerotorescue@62 | 329 	end | 
| Zerotorescue@62 | 330 end | 
| Zerotorescue@62 | 331 | 
| Zerotorescue@65 | 332 | 
| Zerotorescue@65 | 333 | 
| Zerotorescue@65 | 334 | 
| Zerotorescue@65 | 335 | 
| Zerotorescue@106 | 336 function addon:ColorCode(num, required) | 
| Zerotorescue@106 | 337 	local percentage = ( num / required ); | 
| Zerotorescue@106 | 338 | 
| Zerotorescue@106 | 339 	if percentage >= addon.db.profile.defaults.colors.green then | 
| Zerotorescue@106 | 340 		return sformat("|cff00ff00%d|r", num); | 
| Zerotorescue@106 | 341 	elseif percentage >= addon.db.profile.defaults.colors.yellow then | 
| Zerotorescue@106 | 342 		return sformat("|cffffff00%d|r", num); | 
| Zerotorescue@106 | 343 	elseif percentage >= addon.db.profile.defaults.colors.orange then | 
| Zerotorescue@106 | 344 		return sformat("|cffff9933%d|r", num); | 
| Zerotorescue@106 | 345 	elseif percentage >= addon.db.profile.defaults.colors.red then | 
| Zerotorescue@106 | 346 		return sformat("|cffff0000%d|r", num); | 
| Zerotorescue@106 | 347 	else | 
| Zerotorescue@106 | 348 		return num; | 
| Zerotorescue@106 | 349 	end | 
| Zerotorescue@106 | 350 end | 
| Zerotorescue@106 | 351 | 
| Zerotorescue@106 | 352 function addon:DisplayItemCount(value, minimumStock) | 
| Zerotorescue@106 | 353 	if value == -1 then | 
| Zerotorescue@106 | 354 		return "|cffffff00Unknown|r"; | 
| Zerotorescue@106 | 355 	elseif value == -3 then | 
| Zerotorescue@106 | 356 		return "|cffffff00Unknown|r"; | 
| Zerotorescue@106 | 357 	else | 
| Zerotorescue@106 | 358 		return sformat("%s / %d", self:ColorCode(value, minimumStock), minimumStock); | 
| Zerotorescue@106 | 359 	end | 
| Zerotorescue@106 | 360 end | 
| Zerotorescue@106 | 361 | 
| Zerotorescue@62 | 362 -- Readable money | 
| Zerotorescue@62 | 363 | 
| Zerotorescue@62 | 364 local goldText = "%s%d|cffffd700g|r "; | 
| Zerotorescue@62 | 365 local silverText = "%s%d|cffc7c7cfs|r "; | 
| Zerotorescue@62 | 366 local copperText = "%s%d|cffeda55fc|r"; | 
| Zerotorescue@62 | 367 | 
| Zerotorescue@62 | 368 function addon:ReadableMoney(copper, clean) | 
| Zerotorescue@62 | 369 	local text = ""; | 
| Zerotorescue@62 | 370 | 
| Zerotorescue@128 | 371 	local gold = floor( copper / COPPER_PER_GOLD ); | 
| Zerotorescue@62 | 372 	if gold > 0 then | 
| Zerotorescue@106 | 373 		text = sformat(goldText, text, gold); | 
| Zerotorescue@62 | 374 	end | 
| Zerotorescue@62 | 375 | 
| Zerotorescue@62 | 376 	if not clean or (not gold or gold < 10) then | 
| Zerotorescue@128 | 377 		local silver = floor( ( copper % COPPER_PER_GOLD ) / COPPER_PER_SILVER ); | 
| Zerotorescue@62 | 378 		if silver > 0 then | 
| Zerotorescue@106 | 379 			text = sformat(silverText, text, silver); | 
| Zerotorescue@62 | 380 		end | 
| Zerotorescue@62 | 381 | 
| Zerotorescue@62 | 382 		if not clean or (not gold or gold < 1) then | 
| Zerotorescue@128 | 383 			local copper = floor( copper % COPPER_PER_SILVER ); | 
| Zerotorescue@62 | 384 			if copper > 0 or text == "" then | 
| Zerotorescue@106 | 385 				text = sformat(copperText, text, copper); | 
| Zerotorescue@62 | 386 			end | 
| Zerotorescue@62 | 387 		end | 
| Zerotorescue@62 | 388 	end | 
| Zerotorescue@62 | 389 | 
| Zerotorescue@62 | 390 | 
| Zerotorescue@122 | 391 	return strim(text); | 
| Zerotorescue@62 | 392 end | 
| Zerotorescue@62 | 393 | 
| Zerotorescue@62 | 394 function addon:ReadableMoneyToCopper(value) | 
| Zerotorescue@62 | 395 	-- If a player enters a value it will be filled without color codes | 
| Zerotorescue@62 | 396 	-- If it is retrieved from the database, it will be colored coded | 
| Zerotorescue@62 | 397 	-- Thus we look for both | 
| Zerotorescue@122 | 398 	local gold = tonumber(smatch(value, "(%d+)|c[a-fA-F0-9]+g|r") or smatch(value, "(%d+)g")); | 
| Zerotorescue@122 | 399 	local silver = tonumber(smatch(value, "(%d+)|c[a-fA-F0-9]+s|r") or smatch(value, "(%d+)s")); | 
| Zerotorescue@122 | 400 	local copper = tonumber(smatch(value, "(%d+)|c[a-fA-F0-9]+c|r") or smatch(value, "(%d+)c")); | 
| Zerotorescue@62 | 401 | 
| Zerotorescue@62 | 402 	return ( (gold or 0) * COPPER_PER_GOLD ) + ( (silver or 0) * COPPER_PER_SILVER ) + (copper or 0); | 
| Zerotorescue@62 | 403 end | 
| Zerotorescue@62 | 404 | 
| Zerotorescue@62 | 405 function addon:ValidateReadableMoney(info, value) | 
| Zerotorescue@62 | 406 	-- If a player enters a value it will be filled without color codes | 
| Zerotorescue@62 | 407 	-- If it is retrieved from the database, it will be colored coded | 
| Zerotorescue@62 | 408 	-- Thus we look for both | 
| Zerotorescue@122 | 409 	local gold = tonumber(smatch(value, "(%d+)|c[a-fA-F0-9]+g|r") or smatch(value, "(%d+)g")); | 
| Zerotorescue@122 | 410 	local silver = tonumber(smatch(value, "(%d+)|c[a-fA-F0-9]+s|r") or smatch(value, "(%d+)s")); | 
| Zerotorescue@122 | 411 	local copper = tonumber(smatch(value, "(%d+)|c[a-fA-F0-9]+c|r") or smatch(value, "(%d+)c")); | 
| Zerotorescue@62 | 412 | 
| Zerotorescue@62 | 413 	if not gold and not silver and not copper then | 
| Zerotorescue@62 | 414 		return "The provided amount of money is invalid. Please provide the amount of money as #g#s#c, e.g. 591617g24s43c."; | 
| Zerotorescue@62 | 415 	else | 
| Zerotorescue@62 | 416 		return true; | 
| Zerotorescue@62 | 417 	end | 
| Zerotorescue@62 | 418 end | 
| Zerotorescue@62 | 419 | 
| Zerotorescue@0 | 420 | 
| Zerotorescue@0 | 421 | 
| Zerotorescue@65 | 422 | 
| Zerotorescue@65 | 423 | 
| Zerotorescue@13 | 424 -- Public | 
| Zerotorescue@13 | 425 | 
| Zerotorescue@36 | 426 function IMRegisterPricingAddon(name, get, enabled, onSelect) | 
| Zerotorescue@13 | 427 	addon.supportedAddons.auctionPricing[name] = { | 
| Zerotorescue@13 | 428 		GetValue = get, | 
| Zerotorescue@13 | 429 		IsEnabled = enabled, | 
| Zerotorescue@36 | 430 		OnSelect = onSelect, | 
| Zerotorescue@13 | 431 	}; | 
| Zerotorescue@13 | 432 end | 
| Zerotorescue@13 | 433 | 
| Zerotorescue@50 | 434 function IMRegisterItemCountAddon(name, getTotal, getCharacter, enabled, onSelect) | 
| Zerotorescue@13 | 435 	addon.supportedAddons.itemCount[name] = { | 
| Zerotorescue@17 | 436 		GetTotalCount = getTotal, | 
| Zerotorescue@17 | 437 		GetCharacterCount = getCharacter, | 
| Zerotorescue@13 | 438 		IsEnabled = enabled, | 
| Zerotorescue@50 | 439 		OnSelect = onSelect, | 
| Zerotorescue@13 | 440 	}; | 
| Zerotorescue@13 | 441 end | 
| Zerotorescue@13 | 442 | 
| Zerotorescue@50 | 443 function IMRegisterCraftingAddon(name, queue, enabled, onSelect) | 
| Zerotorescue@13 | 444 	addon.supportedAddons.crafting[name] = { | 
| Zerotorescue@13 | 445 		Queue = queue, | 
| Zerotorescue@13 | 446 		IsEnabled = enabled, | 
| Zerotorescue@50 | 447 		OnSelect = onSelect, | 
| Zerotorescue@13 | 448 	}; | 
| Zerotorescue@13 | 449 end | 
| Zerotorescue@13 | 450 | 
| Zerotorescue@62 | 451 -- We need a global command handler for our chat-links | 
| Zerotorescue@62 | 452 function InventoriumCommandHandler(msg) | 
| Zerotorescue@62 | 453 	addon:CommandHandler(msg); | 
| Zerotorescue@62 | 454 end | 
| Zerotorescue@62 | 455 | 
| Zerotorescue@13 | 456 | 
| Zerotorescue@13 | 457 | 
| Zerotorescue@65 | 458 | 
| Zerotorescue@65 | 459 | 
| Zerotorescue@76 | 460 -- General | 
| Zerotorescue@76 | 461 | 
| Zerotorescue@76 | 462 addon.Colors = { | 
| Zerotorescue@76 | 463 	Red = { 1, 0, 0 }, | 
| Zerotorescue@98 | 464 	Orange = { 1, .46, .1 }, | 
| Zerotorescue@76 | 465 	Green = { 0, 1, 0 }, | 
| Zerotorescue@98 | 466 	Blue = { 0, 0, 1 }, | 
| Zerotorescue@98 | 467 	Yellow = { 1, 1, 0 }, | 
| Zerotorescue@98 | 468 	Cyan = { 0, 1, 1 }, | 
| Zerotorescue@76 | 469 }; -- easy to extend if more colors are needed | 
| Zerotorescue@76 | 470 function addon:Print(text, color) | 
| Zerotorescue@76 | 471 	local red, green, blue; | 
| Zerotorescue@76 | 472 | 
| Zerotorescue@76 | 473 	if color then | 
| Zerotorescue@76 | 474 		red, green, blue = color[1], color[2], color[3]; | 
| Zerotorescue@76 | 475 	end | 
| Zerotorescue@76 | 476 | 
| Zerotorescue@76 | 477 	DEFAULT_CHAT_FRAME:AddMessage(text or "", red, green, blue, nil, 5); | 
| Zerotorescue@76 | 478 end | 
| Zerotorescue@76 | 479 | 
| Zerotorescue@95 | 480 function addon:GetItemId(itemLink) | 
| Zerotorescue@84 | 481 	itemLink = itemLink and itemLink:match("|Hitem:([-0-9]+):"); -- if itemLink is nil, it won't execute the second part | 
| Zerotorescue@84 | 482 	itemLink = itemLink and tonumber(itemLink); | 
| Zerotorescue@84 | 483 | 
| Zerotorescue@84 | 484 	return itemLink; | 
| Zerotorescue@84 | 485 end | 
| Zerotorescue@84 | 486 | 
| Zerotorescue@13 | 487 -- Debug | 
| Zerotorescue@0 | 488 | 
| Zerotorescue@89 | 489 function addon:Debug(t, ...) | 
| Zerotorescue@0 | 490 	if not self.debugChannel and self.debugChannel ~= false then | 
| Zerotorescue@0 | 491 		-- We want to check just once, so if you add a debug channel later just do a /reload (registering an event for this is wasted resources) | 
| Zerotorescue@0 | 492 		self.debugChannel = false; | 
| Zerotorescue@0 | 493 | 
| Zerotorescue@0 | 494 		for i = 1, NUM_CHAT_WINDOWS do | 
| Zerotorescue@0 | 495 			local name = GetChatWindowInfo(i); | 
| Zerotorescue@0 | 496 | 
| Zerotorescue@0 | 497 			if name:upper() == "DEBUG" then | 
| Zerotorescue@0 | 498 				self.debugChannel = _G["ChatFrame" .. i]; | 
| Zerotorescue@0 | 499 			end | 
| Zerotorescue@0 | 500 		end | 
| Zerotorescue@0 | 501 	end | 
| Zerotorescue@0 | 502 | 
| Zerotorescue@0 | 503 	if self.debugChannel then | 
| Zerotorescue@110 | 504 		self.debugChannel:AddMessage("|cffffff00Inventorium|r:" .. sformat(t, ...)); | 
| Zerotorescue@0 | 505 	end | 
| Zerotorescue@0 | 506 end |