Quantcast
-- to enable debug mode, run: /run BG_GlobalDB.debug = true
-- to disable debug mode (disabled by default) run: /run BG_GlobalDB.debug = false
_, BrokerGarbage = ...

-- Addon Basics
-- ---------------------------------------------------------
-- output functions
function BrokerGarbage:Print(text)
	DEFAULT_CHAT_FRAME:AddMessage("|cffee6622Broker_Garbage|r "..text)
end

-- prints debug messages only when debug mode is active
function BrokerGarbage:Debug(...)
  if BG_GlobalDB and BG_GlobalDB.debug then
	BrokerGarbage:Print("! "..string.join(", ", tostringall(...)))
  end
end

-- warn the player by displaying a warning message
function BrokerGarbage:Warning(text)
	if BG_GlobalDB.showWarnings and time() - lastReminder >= 5 then
		BrokerGarbage:Print("|cfff0000"..BrokerGarbage.locale.warningMessagePrefix.."!|r ", text)
		lastReminder = time()
	end
end

-- check if a given value can be found in a table
function BrokerGarbage:Find(table, value)
	for k, v in pairs(table) do
		if (v == value) then return true end
	end
	return false
end

-- joins any number of non-basic index tables together, one after the other. elements within the input-tables will get mixed, though
function BrokerGarbage:JoinTables(...)
	local result = {}
	local tab

	for i=1,select("#", ...) do
		tab = select(i, ...)
		if tab then
			for index, value in pairs(tab) do
				result[index] = value
			end
		end
	end

	return result
end

-- joins numerically indexed tables
function BrokerGarbage:JoinSimpleTables(...)
	local result = {}
	local tab, i, j

	for i=1,select("#", ...) do
		tab = select(i, ...)
		if tab then
			for _, value in pairs(tab) do
				tinsert(result, value)
			end
		end
	end

	return result
end

-- counts table entries. for numerically indexed tables, use #table
function BrokerGarbage:Count(table)
  local i = 0
  for _, _ in pairs(table) do i = i + 1 end
  return i
end

-- Saved Variables Management / API
-- ---------------------------------------------------------
function BrokerGarbage:CheckSettings()
	-- check for settings
	local first
	if not BG_GlobalDB then BG_GlobalDB = {}; first = true end
	for key, value in pairs(BrokerGarbage.defaultGlobalSettings) do
		if BG_GlobalDB[key] == nil then
			BG_GlobalDB[key] = value
		end
	end

	if not BG_LocalDB then
		BG_LocalDB = {}
		if not first then first = false end
	end
	for key, value in pairs(BrokerGarbage.defaultLocalSettings) do
		if BG_LocalDB[key] == nil then
			BG_LocalDB[key] = value
		end
	end

	if first ~= nil then
		BrokerGarbage:CreateDefaultLists(first)
	end

	-- update LDB string for older versions
	if BG_GlobalDB.LDBformat == "%1$sx%2$d (%3$s)" or string.find(BG_GlobalDB.LDBformat, "%%%d%$[sd]") then
		BG_GlobalDB.LDBformat = BrokerGarbage.defaultGlobalSettings.LDBformat
		BrokerGarbage:Print(BrokerGarbage.locale.resetLDB)
	end
end

-- inserts some basic list settings
function BrokerGarbage:CreateDefaultLists(global)
	if global then
		BG_GlobalDB.include[46069] = true											-- argentum lance
		BG_GlobalDB.include["Consumable.Water.Conjured"] = true
		BG_GlobalDB.include["Consumable.Food.Edible.Basic.Conjured"] = true
		BG_GlobalDB.forceVendorPrice["Consumable.Food.Edible.Basic"] = true
		BG_GlobalDB.forceVendorPrice["Consumable.Water.Basic"] = true
		BG_GlobalDB.forceVendorPrice["Tradeskill.Mat.BySource.Vendor"] = true
	end

	-- tradeskills
	local tradeSkills =  { GetProfessions() }
	for i = 1, 6 do	-- we get at most 6 professions (2x primary, cooking, fishing, first aid, archeology)
		local englishSkill, isGather = BrokerGarbage:UnLocalize(tradeSkills[i])
		BrokerGarbage:Print("Found "..(englishSkill or "nil"))
		if englishSkill then
			if isGather then
				BG_LocalDB.exclude["Tradeskill.Gather." .. englishSkill] = true
				if englishSkill ~= "Herbalism" then
					BG_LocalDB.exclude["Tradeskill.Tool." .. englishSkill] = true
				end
			else
				BG_LocalDB.exclude["Tradeskill.Mat.ByProfession." .. englishSkill] = true
				BG_LocalDB.exclude["Tradeskill.Tool." .. englishSkill] = true
			end
		end
	end

	-- class specific
	if BrokerGarbage.playerClass == "WARRIOR" or BrokerGarbage.playerClass == "ROGUE" or BrokerGarbage.playerClass == "DEATHKNIGHT" then
		BG_LocalDB.autoSellList["Consumable.Water"] = true

	elseif BrokerGarbage.playerClass == "SHAMAN" then
		if not BG_LocalDB.include[17058] then BG_LocalDB.include[17058] = 20 end	-- fish oil
		if not BG_LocalDB.include[17057] then BG_LocalDB.include[17057] = 20 end	-- scales
	end
	BG_LocalDB.exclude["Misc.Reagent.Class."..string.gsub(string.lower(BrokerGarbage.playerClass), "^.", string.upper)] = true

	BrokerGarbage:Print(BrokerGarbage.locale.listsUpdatedPleaseCheck)
	BrokerGarbage.itemsCache = {}
	BrokerGarbage:ScanInventory()
	if BrokerGarbage.ListOptionsUpdate then
		BrokerGarbage:ListOptionsUpdate()
	end
end

-- returns options for plugin use
function BrokerGarbage:GetOption(optionName, global)
	if global == nil then
		return BG_LocalDB[optionName], BG_GlobalDB[optionName]
	elseif global == false then
		return BG_LocalDB[optionName]
	else
		return BG_GlobalDB[optionName]
	end
end
function BrokerGarbage:SetOption(optionName, global, value)
	if not global then
		BG_LocalDB[optionName] = value
	else
		BG_GlobalDB[optionName] = value
	end
end
function BrokerGarbage:ToggleOption(optionName, global)
	if not global then
		BG_LocalDB[optionName] = not BG_LocalDB[optionName]
	else
		BG_GlobalDB[optionName] = not BG_GlobalDB[optionName]
	end
end
function BrokerGarbage:RegisterPlugin(name, init)
	if not name or not init then
		BGC:Print("Error! Cannot register a plugin without a name and initialize function.")
		return
	end

	table.insert(BrokerGarbage.tabs, {
		name = name,
		init = init
	})
	return #BrokerGarbage.tabs
end

-- Helpers
-- ---------------------------------------------------------
-- returns an item's itemID
function BrokerGarbage:GetItemID(itemLink)
	if not itemLink then return end
	local itemID = string.gsub(itemLink, ".-Hitem:([0-9]*):.*", "%1")
	return tonumber(itemID)
end

-- returns original English names for non-English locales
function BrokerGarbage:UnLocalize(skillName)
	BrokerGarbage:Print("Checking "..(skillName or "nil"))
	if not skillName then return nil, nil end
	skillName = GetProfessionInfo(skillName)
	BrokerGarbage:Print("Got name "..(skillName or "nil"))
	if string.find(GetLocale(), "en") then return skillName end

	-- crafting skills
	local searchString = ""
	for i = 2, 12 do
		searchString = select(i, GetAuctionItemSubClasses(9))
		if string.find(skillName, searchString) then
			return BrokerGarbage.tradeSkills[i], false
		end
	end

	-- gathering skills
	local skill
	if skillName == GetSpellInfo(8613) then
		skill = "Skinning"
	elseif skillName == GetSpellInfo(2575) then
		skill = "Mining"
	else
		-- herbalism sucks
		searchString = select(6, GetAuctionItemSubClasses(6))
		if string.find(skillName, searchString) then
			skill = "Herbalism"
		end
	end

	return skill, skill and true or nil
end

-- easier syntax for LDB display strings
function BrokerGarbage:FormatString(text)
	local item
	if not BrokerGarbage.cheapestItems or not BrokerGarbage.cheapestItems[1] then
		item = { itemID = 0, count = 0, value = 0 }
	else
		item = BrokerGarbage.cheapestItems[1]
	end

	-- [junkvalue]
	local junkValue = 0
	for i = 0, 4 do
		junkValue = junkValue + (BrokerGarbage.toSellValue[i] or 0)
	end
	text = string.gsub(text, "%[junkvalue%]", BrokerGarbage:FormatMoney(junkValue))

	-- [itemname][itemcount][itemvalue]
	text = string.gsub(text, "%[itemname%]", (select(2,GetItemInfo(item.itemID)) or ""))
	text = string.gsub(text, "%[itemcount%]", item.count)
	text = string.gsub(text, "%[itemvalue%]", BrokerGarbage:FormatMoney(item.value))

	-- [freeslots][totalslots]
	text = string.gsub(text, "%[freeslots%]", BrokerGarbage.totalFreeSlots + BrokerGarbage.freeSpecialSlots)
	text = string.gsub(text, "%[totalslots%]", BrokerGarbage.totalBagSpace + BrokerGarbage.specialSlots)

	-- [specialfree][specialslots][specialslots][basicslots]
	text = string.gsub(text, "%[specialfree%]", BrokerGarbage.freeSpecialSlots)
	text = string.gsub(text, "%[specialslots%]", BrokerGarbage.specialSlots)
	text = string.gsub(text, "%[basicfree%]", BrokerGarbage.totalFreeSlots)
	text = string.gsub(text, "%[basicslots%]", BrokerGarbage.totalBagSpace)

	-- [bagspacecolor][basicbagcolor][specialbagcolor][endcolor]
	text = string.gsub(text, "%[bagspacecolor%]",
		BrokerGarbage:Colorize(BrokerGarbage.totalFreeSlots + BrokerGarbage.freeSpecialSlots, BrokerGarbage.totalBagSpace + BrokerGarbage.specialSlots))
	text = string.gsub(text, "%[basicbagcolor%]",
			BrokerGarbage:Colorize(BrokerGarbage.totalFreeSlots, BrokerGarbage.totalBagSpace))
	text = string.gsub(text, "%[specialbagcolor%]",
			BrokerGarbage:Colorize(BrokerGarbage.freeSpecialSlots, BrokerGarbage.specialSlots))
	text = string.gsub(text, "%[endcolor%]", "|r")

	return text
end

-- returns a red-to-green color depending on the given percentage
function BrokerGarbage:Colorize(min, max)
	local color
	if not min then
		return ""
	elseif type(min) == "table" then
		color = { min.r*255, min.g*255, min.b*255}
	else
		local percentage = min/(max and max ~= 0 and max or 1)
		if percentage <= 0.5 then
			color =  {255, percentage*510, 0}
		else
			color =  {510 - percentage*510, 255, 0}
		end
	end

	color = string.format("|cff%02x%02x%02x", color[1], color[2], color[3])
	return color
end

function BrokerGarbage:ResetMoney(which, global)
	if not global then
		if which == "lost" then
			BG_LocalDB.moneyLostByDeleting = 0
		elseif which == "earned" then
			BG_LocalDB.moneyEarned = 0
		end
	else
		if which == "lost" then
			BG_GlobalDB.moneyLostByDeleting = 0
		elseif which == "earned" then
			BG_GlobalDB.moneyEarned = 0
		end
	end
end

-- resets statistics. global = true -> global, otherwise local
function BrokerGarbage:ResetAll(global)
	if global then
		BG_GlobalDB.moneyEarned = 0
		BG_GlobalDB.moneyLostByDeleting = 0
		BG_GlobalDB.itemsDropped = 0
		BG_GlobalDB.itemsSold = 0
	else
		BG_LocalDB.moneyEarned = 0
		BG_LocalDB.moneyLostByDeleting = 0
	end
end

function BrokerGarbage:LPTDropDown(self, level, functionHandler)
	local dataTable = BrokerGarbage.PTSets or {}
	if UIDROPDOWNMENU_MENU_VALUE and string.find(UIDROPDOWNMENU_MENU_VALUE, ".") then
		local parts = { strsplit(".", UIDROPDOWNMENU_MENU_VALUE) } or {}
		for k = 1, #parts do
			dataTable = dataTable[ parts[k] ] or {}
		end
	elseif UIDROPDOWNMENU_MENU_VALUE then
		dataTable = dataTable[ UIDROPDOWNMENU_MENU_VALUE ] or {}
	end

	-- display a heading
	if (level == 1) then
		local info = UIDropDownMenu_CreateInfo()
		info.isTitle = true
		info.notCheckable = true
		info.text = BrokerGarbage.locale.categoriesHeading
		UIDropDownMenu_AddButton(info, level)

		-- and some warning text, in case LPT is not available
		if not BrokerGarbage.PT then
			local info = UIDropDownMenu_CreateInfo()
			info.isTitle = true
			info.notCheckable = true
			info.text = BrokerGarbage.locale.LPTNotLoaded
			UIDropDownMenu_AddButton(info, level)
		end
	end

	for key, value in pairs(dataTable or {}) do
		local info = UIDropDownMenu_CreateInfo()
		local prefix = ""
		if UIDROPDOWNMENU_MENU_VALUE then
			prefix = UIDROPDOWNMENU_MENU_VALUE .. "."
		end

		info.text = key
		info.value = prefix .. key
		info.hasArrow = type(value) == "table" and true or false
		info.func = functionHandler

		UIDropDownMenu_AddButton(info, level);
	end
end

function BrokerGarbage:GetProfessionSkill(skill)
	if not skill or (type(skill) ~= "number" and type(skill) ~= "string") then return end
	if type(skill) == "number" then
		skill = GetSpellInfo(skill)
	end

	local rank, maxRank
	local professions = { GetProfessions() }
	for _, profession in ipairs(professions) do
		local pName, _, pRank, pMaxRank = GetProfessionInfo(profession)
		if pName and pName == skill then
			rank = pRank
			maxRank = pMaxRank
			break
		end
	end
	return rank, maxRank
end

local scanTooltip = CreateFrame('GameTooltip', 'BGItemScanTooltip', UIParent, 'GameTooltipTemplate')
-- misc: either "true" to check only for the current character, or a table {container, slot} for reference
function BrokerGarbage:CanDisenchant(itemLink, location)
	if not itemLink then return end

	local required, skillRank = 0	-- required disenchant skill
	if IsAddOnLoaded("Enchantrix") then
		required = Enchantrix.Util.DisenchantSkillRequiredForItem(itemLink)	-- might be more accurate/up to date in case I miss something
		skillRank = Enchantrix.Util.GetUserEnchantingSkill()	-- Enchantrix caches this. So let's use it!
	else
		local _, _, quality, level, _, _, _, stackSize, invType = GetItemInfo(itemLink)

		-- stackables are not DE-able, legendary/heirlooms are not DE-able
		if quality >= 2 and quality < 5 and stackSize == 1
			and string.find(invType, "INVTYPE") and not string.find(invType, "BAG") then

			skillRank = BrokerGarbage:GetProfessionSkill(BrokerGarbage.enchanting) or 0
			if skillRank > 0 then
				if level <=  20 then
					required = 1
				elseif level <=  60 then
					required = 5*5*math.ceil(level/5)-100
				elseif level <=  99 then
					required = 225
				elseif level <= 120 then
					required = 275
				else
					if quality == 2 then		-- green
						if level <= 150 then
							required = 325
						elseif level <= 200 then
							required = 350
						elseif level <= 305 then
							required = 425
						else
							required = 475
						end
					elseif quality == 3 then	-- blue
						if level <= 200 then
							required = 325
						elseif level <= 325 then
							required = 450
						else
							required = 500
						end
					elseif quality == 4 then	-- purple
						if level <= 199 then
							required = 300
						elseif level <= 277 then
							required = 375
						else
							required = 500
						end
					end
				end
			end
		end
	end

	if not skillRank or not required then
		-- this item is not disenchantable
		return false
	elseif skillRank >= required then
		-- this character can disenchant the item. Perfect!
		return true
	elseif BG_GlobalDB.hasEnchanter then
		if location and type(location) == "boolean" then
			-- misc = true => Only regard this character. Exit.
			return false
		elseif location and type(location) == "table" then
			-- misc = {bag, slot} => Can we mail this item?
			return not BrokerGarbage:IsItemSoulbound(itemLink, location.bag, location.slot)
		else
			return not BrokerGarbage:IsItemSoulbound(itemLink)
		end
	else
		return false
	end
end

-- returns true if the given item is soulbound
function BrokerGarbage:IsItemSoulbound(itemLink, bag, slot)
	scanTooltip:SetOwner(UIParent, 'ANCHOR_NONE')
	local searchString

	if not (bag and slot) then
		-- check if item is BOP
		scanTooltip:SetHyperlink(itemLink)
		searchString = ITEM_BIND_ON_PICKUP
	else
		-- check if item is soulbound
		scanTooltip:SetBagItem(bag, slot)
		searchString = ITEM_SOULBOUND
	end

	local numLines = scanTooltip:NumLines()
	for i = 1, numLines do
		local leftLine = getglobal("BGItemScanTooltip".."TextLeft"..i)
		local leftLineText = leftLine:GetText()

		if string.find(leftLineText, searchString) then
			return true
		end
	end
	return false
end

-- gets an item's classification and saves it to the item cache
function BrokerGarbage:UpdateCache(itemID)
	if not itemID then return nil end
	local class, temp, limit

	local hasData, itemLink, quality, itemLevel, _, _, subClass, stackSize, invType, _, value = GetItemInfo(itemID)
	local family = GetItemFamily(itemID)
	if not hasData then
		BrokerGarbage:Debug("UpdateCache("..(itemID or "<none>")..") failed - no GetItemInfo() data available!")
		return nil
	end

	-- check if item is excluded by itemID
	if BG_GlobalDB.exclude[itemID] or BG_LocalDB.exclude[itemID] then
		BrokerGarbage:Debug("Item "..itemID.." is excluded via its itemID.")
		class = BrokerGarbage.EXCLUDE
	end

	-- check if the item is classified by its itemID
	if not class or class ~= BrokerGarbage.EXCLUDE then
		if BG_GlobalDB.include[itemID] or BG_LocalDB.include[itemID] then

			if BG_LocalDB.include[itemID] and type(BG_LocalDB.include[itemID]) ~= "boolean" then
				-- limited item, local rule
				BrokerGarbage:Debug("Item "..itemID.." is locally limited via its itemID.")
				class = BrokerGarbage.LIMITED
				limit = BG_LocalDB.include[itemID]

			elseif BG_GlobalDB.include[itemID] and type(BG_GlobalDB.include[itemID]) ~= "boolean" then
				-- limited item, global rule
				BrokerGarbage:Debug("Item "..itemID.." is globally limited via its itemID.")
				class = BrokerGarbage.LIMITED
				limit = BG_GlobalDB.include[itemID]

			else
				BrokerGarbage:Debug("Item "..itemID.." is included via its itemID.")
				class = BrokerGarbage.INCLUDE
			end

		elseif BG_GlobalDB.forceVendorPrice[itemID] then
			BrokerGarbage:Debug("Item "..itemID.." has a forced vendor price via its itemID.")
			class = BrokerGarbage.VENDOR

		elseif BG_GlobalDB.autoSellList[itemID] or BG_LocalDB.autoSellList[itemID] then
			BrokerGarbage:Debug("Item "..itemID.." is to be auto-sold via its itemID.")
			class = BrokerGarbage.VENDORLIST

		elseif quality
			and not IsUsableSpell(BrokerGarbage.enchanting)	and BrokerGarbage:IsItemSoulbound(itemLink)
			and string.find(invType, "INVTYPE") and not string.find(invType, "BAG")
			and not BrokerGarbage.usableByClass[BrokerGarbage.playerClass][subClass]
			and not BrokerGarbage.usableByAll[invType] then

			BrokerGarbage:Debug("Item "..itemID.." should be sold as we can't ever wear it.")
			class = BrokerGarbage.UNUSABLE

		-- check if the item is classified by its category
		elseif BrokerGarbage.PT then
			-- check if item is excluded by its category
			for setName,_ in pairs(BrokerGarbage:JoinTables(BG_GlobalDB.exclude, BG_LocalDB.exclude)) do
				if type(setName) == "string" then
					_, temp = BrokerGarbage.PT:ItemInSet(itemID, setName)
				end
				if temp then
					BrokerGarbage:Debug("Item "..itemID.." is excluded via its category.")
					class = BrokerGarbage.EXCLUDE
					break
				end
			end

			-- Include List
			if not class then
				for setName,_ in pairs(BrokerGarbage:JoinTables(BG_LocalDB.include, BG_GlobalDB.include)) do
					if type(setName) == "string" then
						_, temp = BrokerGarbage.PT:ItemInSet(itemID, setName)
					end
					if temp then
						BrokerGarbage:Debug("Item "..itemID.." in included via its item category.")
						class = BrokerGarbage.INCLUDE
						break
					end
				end
			end

			-- Sell List
			if not class then
				for setName,_ in pairs(BrokerGarbage:JoinTables(BG_GlobalDB.autoSellList, BG_LocalDB.autoSellList)) do
					if type(setName) == "string" then
						_, temp = BrokerGarbage.PT:ItemInSet(itemID, setName)
					end
					if temp then
						BrokerGarbage:Debug("Item "..itemID.." is on the sell list via its item category.")
						class = BrokerGarbage.VENDORLIST
						break
					end
				end
			end

			-- Force Vendor Price List
			if not class then
				for setName,_ in pairs(BG_GlobalDB.forceVendorPrice) do
					if type(setName) == "string" then
						_, temp = BrokerGarbage.PT:ItemInSet(itemID, setName)
					end
					if temp then
						BrokerGarbage:Debug("Item "..itemID.." has a forced vendor price via its item category.")
						class = BrokerGarbage.VENDOR
						break
					end
				end
			end
		end
	end

	local tvalue, tclass = BrokerGarbage:GetSingleItemValue(itemID)
	if not class then class = tclass end
	if not (class == BrokerGarbage.VENDOR or class == BrokerGarbage.VENDORLIST or
		(class == BrokerGarbage.INCLUDE and BG_GlobalDB.autoSellIncludeItems)) then
		value = tvalue
	end

	-- save to items cache
	if not class or not quality then
		BrokerGarbage:Debug("Error! Caching item "..itemID.." failed!")
		return
	end
	if not BrokerGarbage.itemsCache[itemID] then
		BrokerGarbage.itemsCache[itemID] = {
			classification = class,
			quality = quality,
			family = family,
			itemType = itemType,
			level = itemLevel,
			value = value or 0,
			limit = limit,
			stackSize = stackSize,
			isClam = BrokerGarbage:Find(BrokerGarbage.clams, itemID),
		}
	else
		BrokerGarbage.itemsCache[itemID].classification = class
		BrokerGarbage.itemsCache[itemID].quality = quality
		BrokerGarbage.itemsCache[itemID].family = family
		BrokerGarbage.itemsCache[itemID].itemType = itemType
		BrokerGarbage.itemsCache[itemID].value = value or 0
		BrokerGarbage.itemsCache[itemID].limit = limit
		BrokerGarbage.itemsCache[itemID].level = itemLevel
		BrokerGarbage.itemsCache[itemID].stackSize = stackSize
		BrokerGarbage.itemsCache[itemID].isClam = BrokerGarbage:Find(BrokerGarbage.clams, itemID)
	end
end

-- fetch an item from the item cache, or insert if it doesn't exist yet
function BrokerGarbage:GetCached(itemID)
	if not itemID then return end
	if not BrokerGarbage.itemsCache[itemID] then
		BrokerGarbage:UpdateCache(itemID)
	end
	return BrokerGarbage.itemsCache[itemID]
end

-- returns total bag slots and free bag slots of your whole inventory
function BrokerGarbage:GetBagSlots()
	local numSlots, freeSlots = 0, 0
	local specialSlots, specialFree = 0, 0
	local bagSlots, emptySlots, bagType

	for i = 0, 4 do
		bagSlots = GetContainerNumSlots(i) or 0
		emptySlots, bagType = GetContainerNumFreeSlots(i)

		if bagType and bagType == 0 then
			numSlots = numSlots + bagSlots
			freeSlots = freeSlots + emptySlots
		else
			specialSlots = specialSlots + bagSlots
			specialFree = specialFree + emptySlots
		end
	end
	return numSlots, freeSlots, specialSlots, specialFree
end

-- formats money int values, depending on settings
function BrokerGarbage:FormatMoney(amount, displayMode)
	if not amount then return "" end
	displayMode = displayMode or BG_GlobalDB.showMoney

	local signum
	if amount < 0 then
		signum = "-"
		amount = -amount
	else
		signum = ""
	end

	local gold   = floor(amount / (100 * 100))
	local silver = math.fmod(floor(amount / 100), 100)
	local copper = math.fmod(floor(amount), 100)

	if displayMode == 0 then
		return format(signum.."%i.%i.%i", gold, silver,copper)

	elseif displayMode == 1 then
		return format(signum.."|cffffd700%i|r.|cffc7c7cf%.2i|r.|cffeda55f%.2i|r", gold, silver, copper)

	-- copied from Ara Broker Money
	elseif displayMode == 2 then
		if amount>9999 then
			return format(signum.."|cffeeeeee%i|r|cffffd700g|r |cffeeeeee%.2i|r|cffc7c7cfs|r |cffeeeeee%.2i|r|cffeda55fc|r", floor(amount*.0001), floor(amount*.01)%100, amount%100 )

		elseif amount > 99 then
			return format(signum.."|cffeeeeee%i|r|cffc7c7cfs|r |cffeeeeee%.2i|r|cffeda55fc|r", floor(amount*.01), amount%100 )

		else
			return format(signum.."|cffeeeeee%i|r|cffeda55fc|r", amount)
		end

	-- copied from Haggler
	elseif displayMode == 3 then
		gold         = gold   > 0 and gold  .."|TInterface\\MoneyFrame\\UI-GoldIcon:0|t" or ""
		silver       = silver > 0 and silver.."|TInterface\\MoneyFrame\\UI-SilverIcon:0|t" or ""
		copper       = copper > 0 and copper.."|TInterface\\MoneyFrame\\UI-CopperIcon:0|t" or ""
		-- add spaces if needed
		copper       = (silver ~= "" and copper ~= "") and " "..copper or copper
		silver       = (gold   ~= "" and silver ~= "") and " "..silver or silver

		return signum..gold..silver..copper

	elseif displayMode == 4 then
		gold         = gold   > 0 and "|cffeeeeee"..gold  .."|r|cffffd700g|r" or ""
		silver       = silver > 0 and "|cffeeeeee"..silver.."|r|cffc7c7cfs|r" or ""
		copper       = copper > 0 and "|cffeeeeee"..copper.."|r|cffeda55fc|r" or ""
		-- add spaces if needed
		copper       = (silver ~= "" and copper ~= "") and " "..copper or copper
		silver       = (gold   ~= "" and silver ~= "") and " "..silver or silver

		return signum..gold..silver..copper
	end
end