Quantcast

Feeling leery. Been too long since last commit.

Joseph Collins [02-05-13 - 09:14]
Feeling leery. Been too long since last commit.
Filename
Character.lua
ChillEffectAlts.lua
Currencies.lua
diff --git a/Character.lua b/Character.lua
index bbb80f6..74a71ef 100644
--- a/Character.lua
+++ b/Character.lua
@@ -111,6 +111,15 @@ function Character:ExpandCurrencyHeaders()
 	end
 end

+function Character:GetCurrencyCount(currency)
+	-- This is a little ugly. If we don't have a 'db' entry, the Character is a profile being passed in raw
+	if self.db then
+		return self.db.currencies[currency]
+	else
+		return self.currencies[currency]
+	end
+end
+
 --[[

 --]]
@@ -146,8 +155,8 @@ function Character:UpdateBank()
 	wipe(self.db.bank)

 	local link, name, link, rarity, count
-	for bag = NUM_BAG_SLOTS, NUM_BAG_SLOTS+NUM_BANKBAGSLOTS do
-		if bag == NUM_BAG_SLOTS then bag = 0 end -- a little hackish; the main bank inventory is slot 0 and bank bags start at NUM_BAG_SLOTS+1
+	for bag = NUM_BAG_SLOTS+1, NUM_BAG_SLOTS+NUM_BANKBAGSLOTS+1 do
+		if bag == NUM_BAG_SLOTS+NUM_BANKBAGSLOTS+1 then bag = -1 end -- a little hackish; the main bank inventory is slot -1 and bank bags start at NUM_BAG_SLOTS+1
 		for slot = 1, GetContainerNumSlots(bag) do
 			link = GetContainerItemLink(bag, slot)
 			if link then
diff --git a/ChillEffectAlts.lua b/ChillEffectAlts.lua
index d230c9a..4e654f9 100644
--- a/ChillEffectAlts.lua
+++ b/ChillEffectAlts.lua
@@ -12,8 +12,13 @@ function ChillEffectAlts:OnInitialize()
 			bags = {},
 			inventory = {},
 		},
+		global = {
+			shown = {}
+		}
 	}
 	self.db = LibStub("AceDB-3.0"):New("CEAltsDB", defaults)
+	self.db.realm[UnitName("player")] = true
+	self.db.factionrealm[UnitName("player")] = true

 	SLASH_ChillEffectAlts1 = "/alt"
 	SlashCmdList["ChillEffectAlts"] = function()
@@ -117,10 +122,13 @@ end

 local gui_built = false
 function ChillEffectAlts:OnEnable()
+	CurrenciesModule:SetDB(self.db)
+
 	if not gui_built then
 		CurrenciesModule:CreateCurrencyFrame()
 	end

+
 	Character = CharacterModule:new(self.db.char)

 	-- Track the open state of the bank. Can't check for IsShown, because addons
diff --git a/Currencies.lua b/Currencies.lua
index a605fc8..795231c 100644
--- a/Currencies.lua
+++ b/Currencies.lua
@@ -2,42 +2,228 @@ local addonName, addonTable = ...;

 local CECF_HEADER_HEIGHT = 84; -- Distance to the top of the inset
 local CECF_MAX_WIDTH = 530;
-local CECF_COLUMN_PADDING = 8;
+local CECF_TOTALS_ROW_HEIGHT = 20;
+local CECF_COLUMN_PADDING = 3;
 local CECF_COLUMN_MARGIN = 1;
-local CECF_FIRST_COLUMN_MIN_WIDTH = 140;
+local CECF_MAX_CHARACTERS_PER_REALM = 11
+local CECF_NUM_ROWS = 11
+local CECF_FIRST_COLUMN_MIN_WIDTH = 0;
 local CECF_LAST_COLUMN_MIN_WIDTH = 24;
-local NUM_MAX_CURRENCY_HEADERS = 10; -- Mostly a sanity check. We'll run out of space first.
+local MIN_COLUMN_CHAR_WIDTH = 5;
+local NUM_MAX_CURRENCY_HEADERS = 6; -- Mostly a sanity check. We'll run out of space first.
+local CharacterModule = addonTable.Character

--- id = {name, preferredDigits, texturePath}
--- IDs are used for ordering at initial load. Subsequent loads read {priority: ID} pairs from the db.
+--[[
+	Names are as returned by GetCurrencyListInfo for the relevant row. Localization: to-do
+	IDs are used for ordering. Could be a bitfield I suppose.
+	category*100 + expansion*10 + order*1
+
+	categories:
+		0	Always relevant
+		1	PvE (generic)
+		2	PvE (specific dungeon/patch)
+		3	PvP (generic)
+		4	PvP	(specific battleground)
+		5	Crafting
+		6	Miscellaneous
+	expansions:	In case of overlap, use the latter expansion
+		0	Always relevant
+		1	Classic
+		2	Burning Crusade
+		3	Wrath of the Lich King
+		4	Cataclysm
+		5	Mists of Pandaria
+
+--]]
 local CURRENCY_DATA = {
-	{"Gold", 							6,	[[Interface\MoneyFrame\UI-GoldIcon]]},
-	{"Justice Points", 					4,	[[Interface\Icons\pvecurrency-justice]]},
-	{"Valor Points", 					4,	[[Interface\Icons\pvecurrency-valor]]},
-	{"Elder Charms of Good Fortune", 	2,	[[Interface\Icons\inv_misc_coin_17]]},
-	{"Lesser Charms of Good Fortune",	4,	[[Interface\Icons\inv_misc_coin_18]]},
-	{"Honor Points",					4,	[[Interface\Icons\PVPCurrency-Honor-Horde]]},
-	{"Conquest Points",					5,	[[Interface\Icons\PVPCurrency-Conquest-Horde]]},
-	{"Ironpaw Tokens",					3,	[[Interface\Icons\inv_relics_idolofferocity]]},
-	{"Darkmoon Prize Tickets",			4,	[[Interface\Icons\Inv_misc_ticket_darkmoon_01]]},
-	{"Epicurean's Awards",				3,	[[Interface\Icons\INV_Misc_Ribbon_01]]},
-	{"Dalaran Jewelcrafter's Tokens",	3,	[[Interface\Icons\Inv_misc_gem_variety_01]]},
-	{"Illustrious Jewelcrafter's Tokens",3,	[[Interface\Icons\Inv_misc_token_argentdawn3]]},
-	{"Tol Barad Commendations",			4,	[[Interface\Icons\Achievement_zone_tolbarad]]},
-	{"Motes of Darkness",				2,	[[Interface\Icons\inv_elemental_primal_shadow]]},
-	{"Essences of Corrupted Deathwing",	2,	[[Interface\Icons\spell_shadow_sealofkings]]},
-	{"Champion's Seals",					4,	[[Interface\Icons\Ability_Paladin_ArtOfWar]]},
+	{"Money", 							6,	[[Interface\MoneyFrame\UI-GoldIcon]],				001},
+	{"Justice Points", 					4,	[[Interface\Icons\pvecurrency-justice]],			101},
+	{"Valor Points", 					4,	[[Interface\Icons\pvecurrency-valor]],				102},
+	{"Elder Charm of Good Fortune", 	2,	[[Interface\Icons\inv_misc_coin_17]],				251},
+	{"Lesser Charm of Good Fortune",	4,	[[Interface\Icons\inv_misc_coin_18]],				252},
+	{"Honor Points",					4,	[[Interface\Icons\PVPCurrency-Honor-Horde]],		301},
+	{"Conquest Points",					5,	[[Interface\Icons\PVPCurrency-Conquest-Horde]],		302},
+	{"Ironpaw Token",					3,	[[Interface\Icons\inv_relics_idolofferocity]],		551},
+	{"Darkmoon Prize Ticket",			4,	[[Interface\Icons\Inv_misc_ticket_darkmoon_01]],	601},
+	{"Epicurean's Award",				3,	[[Interface\Icons\INV_Misc_Ribbon_01]],				541},
+	{"Dalaran Jewelcrafter's Token",	3,	[[Interface\Icons\Inv_misc_gem_variety_01]],		531},
+	{"Illustrious Jewelcrafter's Token",3,	[[Interface\Icons\Inv_misc_token_argentdawn3]],		542},
+	{"Tol Barad Commendation",			4,	[[Interface\Icons\Achievement_zone_tolbarad]],		441},
+	{"Mote of Darkness",				2,	[[Interface\Icons\inv_elemental_primal_shadow]],	241},
+	{"Essence of Corrupted Deathwing",	2,	[[Interface\Icons\spell_shadow_sealofkings]],		242},
+	{"Champion's Seal",					4,	[[Interface\Icons\Ability_Paladin_ArtOfWar]],		231},
 }



 local Currencies = {}
+function Currencies:SetDB(db)
+	self.db = db
+end
+
+function Currencies:GetDB()
+	-- assert(self.db)
+	return self.db
+end
+-- Body rows get zebra striping and mouseover highlights.
+-- Non-body rows get icons in each column.
+local function CreateRow(name, isBodyRow)
+	local new = CreateFrame("Button", name, ChillEffectCurrencyFrame)
+
+	if isBodyRow then
+		--== Highlight is the parent for the mouseover
+		local highlight = CreateFrame("Frame", name.."Highlight", new)
+		highlight:SetPoint("TOPLEFT", 0, 1)
+		highlight:SetPoint("BOTTOMRIGHT", 0, -1)
+		new.highlight = highlight
+
+		--== Create zebra striping
+		new.stripe = new:CreateTexture()
+		new.stripe:SetTexture(1, 1, 1, 0.05)
+		new.stripe:SetPoint("TOPLEFT", 0, 0)--1)
+		new.stripe:SetPoint("BOTTOMRIGHT", 0, 0)--1)
+
+		--== Create mouseover highlight
+		local highlightTexture
+
+		highlightTexture = highlight:CreateTexture(highlight:GetName().."TopLeft", "ARTWORK")
+		highlightTexture:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-ReputationBar-Highlight]])
+		highlightTexture:SetBlendMode("ADD")
+		highlightTexture:SetSize(16, 15)
+		highlightTexture:SetPoint("TOPLEFT", -1, 3)
+		highlightTexture:SetTexCoord(0.06640625, 0, 0.4375, 0.65625)
+
+		highlightTexture = highlight:CreateTexture(highlight:GetName().."BottomLeft", "ARTWORK")
+		highlightTexture:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-ReputationBar-Highlight]])
+		highlightTexture:SetBlendMode("ADD")
+		highlightTexture:SetSize(16, 15)
+		highlightTexture:SetPoint("BOTTOMLEFT", -1, -3)
+		highlightTexture:SetTexCoord(0.06640625, 0, 0.65625, 0.4375)
+
+		highlightTexture = highlight:CreateTexture(highlight:GetName().."TopRight", "ARTWORK")
+		highlightTexture:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-ReputationBar-Highlight]])
+		highlightTexture:SetBlendMode("ADD")
+		highlightTexture:SetSize(16, 15)
+		highlightTexture:SetPoint("TOPRIGHT", 1, 3)
+		highlightTexture:SetTexCoord(0, 0.06640625, 0.4375, 0.65625)
+
+		highlightTexture = highlight:CreateTexture(highlight:GetName().."BottomRight", "ARTWORK")
+		highlightTexture:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-ReputationBar-Highlight]])
+		highlightTexture:SetBlendMode("ADD")
+		highlightTexture:SetSize(16, 15)
+		highlightTexture:SetPoint("BOTTOMRIGHT", 1, -3)
+		highlightTexture:SetTexCoord(0, 0.06640625, 0.65625, 0.4375)
+
+		highlightTexture = highlight:CreateTexture(highlight:GetName().."Top", "ARTWORK")
+		highlightTexture:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-ReputationBar-Highlight]])
+		highlightTexture:SetBlendMode("ADD")
+		highlightTexture:SetPoint("TOPLEFT", highlight:GetName().."TopLeft", "TOPRIGHT")
+		highlightTexture:SetPoint("BOTTOMRIGHT", highlight:GetName().."TopRight", "BOTTOMLEFT")
+		highlightTexture:SetTexCoord(0, 0.015, 0.4375, 0.65625)
+
+		highlightTexture = highlight:CreateTexture(highlight:GetName().."Bottom", "ARTWORK")
+		highlightTexture:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-ReputationBar-Highlight]])
+		highlightTexture:SetBlendMode("ADD")
+		highlightTexture:SetPoint("TOPLEFT", highlight:GetName().."BottomLeft", "TOPRIGHT")
+		highlightTexture:SetPoint("BOTTOMRIGHT", highlight:GetName().."BottomRight", "BOTTOMLEFT")
+		highlightTexture:SetTexCoord(0, 0.015, 0.65625, 0.4375)
+
+		highlightTexture = highlight:CreateTexture(highlight:GetName().."Left", "ARTWORK")
+		highlightTexture:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-ReputationBar-Highlight]])
+		highlightTexture:SetBlendMode("ADD")
+		highlightTexture:SetPoint("TOPLEFT", highlight:GetName().."TopLeft", "BOTTOMLEFT")
+		highlightTexture:SetPoint("BOTTOMRIGHT", highlight:GetName().."BottomLeft", "TOPRIGHT")
+		highlightTexture:SetTexCoord(0.06640625, 0, 0.65625, 0.6)
+
+		highlightTexture = highlight:CreateTexture(highlight:GetName().."Right", "ARTWORK")
+		highlightTexture:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-ReputationBar-Highlight]])
+		highlightTexture:SetBlendMode("ADD")
+		highlightTexture:SetPoint("TOPLEFT", highlight:GetName().."TopRight", "BOTTOMLEFT")
+		highlightTexture:SetPoint("BOTTOMRIGHT", highlight:GetName().."BottomRight", "TOPRIGHT")
+		highlightTexture:SetTexCoord(0, 0.06640625, 0.65625, 0.6)
+
+		highlight:Hide()
+
+		new:SetScript("OnEnter", function(self)
+			self.highlight:Show()
+		end)
+		new:SetScript("OnLeave", function(self)
+			self.highlight:Hide()
+		end)
+	end
+
+	--== Create columns
+	local column
+	new.columns = {}
+	for j = 1, NUM_MAX_CURRENCY_HEADERS+2 do
+		column = CreateFrame("Frame", name.."Column"..j, new)
+
+		column.text = column:CreateFontString()
+		column.text:SetFontObject("GameFontWhite")
+		column.text:SetPoint("LEFT", CECF_COLUMN_PADDING*2, 0) -- It needed some space. Weird, I know.
+		column.text:SetPoint("RIGHT", -CECF_COLUMN_PADDING, 0)
+
+		if j == 1 then
+			column:SetPoint("TOPLEFT", new, "TOPLEFT", 0, 0)
+			column:SetPoint("BOTTOMLEFT", new, "BOTTOMLEFT", 0, 0)
+			column.text:SetJustifyH("LEFT")
+		else
+			column:SetPoint("TOPLEFT", new.columns[j-1], "TOPRIGHT", CECF_COLUMN_MARGIN, 0)
+			column:SetPoint("BOTTOMLEFT", new.columns[j-1], "BOTTOMRIGHT", CECF_COLUMN_MARGIN, 0)
+			column.text:SetJustifyH("RIGHT")
+		end
+
+		-- if isBodyRow then
+			column.stripe = column:CreateTexture()
+			column.stripe:SetTexture(1, 1, 1, 0.07)
+			column.stripe:SetPoint("TOPLEFT", 0, 0)
+			column.stripe:SetPoint("BOTTOMRIGHT", 0, 0)
+
+			if j % 2 == 0 then
+				column.stripe:Show()
+			else
+				column.stripe:Hide()
+			end
+		-- end
+
+		if not isBodyRow then
+			if j > 1 then -- We'll never need the icon in the first column
+				column.icon = column:CreateTexture()
+				column.icon:SetPoint("CENTER")
+				column.icon:SetSize(CECF_TOTALS_ROW_HEIGHT, CECF_TOTALS_ROW_HEIGHT)
+			end
+		end
+
+		new.columns[j] = column
+	end
+
+	return new
+end
+
+-- Future self, you're probably going to forget this, but this gets called after the GUI updates, not before.
+-- You're welcome. I love you man. ~Your Past Self
+local function DropdownRow_OnClick(self, arg1, arg2, checked)
+	-- arg1 = currencyID, arg2 = nil
+
+	if checked then
+		self.db.global.shown[arg1] = true
+	else
+		self.db.global.shown[arg1] = nil
+	end
+
+	if #self.db.global.shown >= 6 then
+		print("You may only track 6 currencies at once")
+		return
+	end
+end
+
 function Currencies:CreateCurrencyFrame()
 	ChillEffectCurrencyFrame = CreateFrame("Frame", "ChillEffectCurrencyFrame", CharacterFrame, "PortraitFrameTemplate")
 	ChillEffectCurrencyFrame:SetAllPoints()
-	ChillEffectCurrencyFrame:Hide()
-	ChillEffectCurrencyFrame:SetHitRectInsets(0, 30, 0, 75) -- borrowed from the PaperDollFrame
-
+
+	-- Set the anchors for the inset during Redraw, because it will shift depending on the number of factions
+	ChillEffectCurrencyFrameInset = CreateFrame("Frame", "ChillEffectCurrencyFrameInset", ChillEffectCurrencyFrame, "InsetFrameTemplate")
+
 	ChillEffectCurrencyFrame:CreateTexture("ChillEffectCurrencyFramePortrait", "OVERLAY")
 	ChillEffectCurrencyFramePortrait:SetSize(60, 60)
 	ChillEffectCurrencyFramePortrait:SetPoint("TOPLEFT", -6, 7)
@@ -54,164 +240,113 @@ function Currencies:CreateCurrencyFrame()
 		end
 	end)

-	ChillEffectCurrencyFrameInset = CreateFrame("Frame", "ChillEffectCurrencyFrameInset", ChillEffectCurrencyFrame, "InsetFrameTemplate")
-	ChillEffectCurrencyFrameInset:SetPoint("TOPLEFT", 4, -CECF_HEADER_HEIGHT)
-	ChillEffectCurrencyFrameInset:SetPoint("BOTTOMRIGHT", -6, 4)
+	ChillEffectCurrencyFrameCloseButton:HookScript("OnClick", function()
+		CharacterFrameCloseButton:Click()
+	end)

+	ChillEffectCurrencyFrame:Hide()

+
 	--== Create, but don't initialize, the headers
-	ChillEffectCurrencyFrame.columns = {}
-	-- Set the character header
-	ChillEffectCurrencyFrameHeader1 = CreateFrame("Button", "ChillEffectCurrencyFrameHeader1", ChillEffectCurrencyFrame, "WhoFrameColumnHeaderTemplate")
-	ChillEffectCurrencyFrameHeader1:SetPoint("TOPLEFT", 6, -62)
-	ChillEffectCurrencyFrameHeader1:SetScript("OnClick", function()
-		PlaySound("igMainMenuOptionCheckBoxOn")
-	end)
-	ChillEffectCurrencyFrameHeader1:SetText("Character")
-	WhoFrameColumn_SetWidth(ChillEffectCurrencyFrameHeader1, CECF_FIRST_COLUMN_MIN_WIDTH)
-	ChillEffectCurrencyFrame.columns[1] = ChillEffectCurrencyFrameHeader1
-
-	-- OnClick scripts are set during redraw because the last button functions differently
-	local new, headerIcon
-	for i = 1, NUM_MAX_CURRENCY_HEADERS do
-		new = CreateFrame("Button", "ChillEffectCurrencyFrameHeader"..(i+1), ChillEffectCurrencyFrame, "WhoFrameColumnHeaderTemplate")
-		new:SetPoint("TOPLEFT", _G["ChillEffectCurrencyFrameHeader"..(i)], "TOPRIGHT", CECF_COLUMN_MARGIN, 0)
-		new:SetScript("OnMouseDown", function(self)
-			self.icon:SetPoint("TOP", 2, -6)
-		end)
-		new:SetScript("OnMouseUp", function(self)
-			self.icon:SetPoint("TOP", 0, -4)
-		end)
-		new.icon = new:CreateTexture(new:GetName().."Icon", "ARTWORK")
-		new.icon:SetSize(16, 16)
-		new.icon:SetPoint("TOP", 0, -4)
-		new:SetScript("OnEnter", function(self)
-			GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
-			GameTooltip:SetText(self.mouseover);
+	do
+		ChillEffectCurrencyFrame.columns = {}
+		-- Set the character header
+		ChillEffectCurrencyFrameHeader1 = CreateFrame("Button", "ChillEffectCurrencyFrameHeader1", ChillEffectCurrencyFrame, "WhoFrameColumnHeaderTemplate")
+		ChillEffectCurrencyFrameHeader1:SetPoint("TOPLEFT", 6, -62)
+		ChillEffectCurrencyFrameHeader1:SetScript("OnClick", function()
+			PlaySound("igMainMenuOptionCheckBoxOn")
 		end)
-		new:SetScript("OnLeave", GameTooltip_Hide)
+		ChillEffectCurrencyFrameHeader1:SetText("Character")
+		WhoFrameColumn_SetWidth(ChillEffectCurrencyFrameHeader1, CECF_FIRST_COLUMN_MIN_WIDTH)
+		ChillEffectCurrencyFrame.columns[1] = ChillEffectCurrencyFrameHeader1

-		ChillEffectCurrencyFrame.columns[i+1] = new
+		-- OnClick scripts are set during redraw because the last button functions differently
+		local new, headerIcon --, active
+		for i = 2, NUM_MAX_CURRENCY_HEADERS+2 do -- currencies + characters + expand button
+			new = CreateFrame("Button", "ChillEffectCurrencyFrameHeader"..(i), ChillEffectCurrencyFrame, "WhoFrameColumnHeaderTemplate")
+			new:SetPoint("TOPLEFT", _G["ChillEffectCurrencyFrameHeader"..(i-1)], "TOPRIGHT", CECF_COLUMN_MARGIN, 0)
+			new:SetScript("OnMouseDown", function(self)
+				self.icon:SetPoint("TOP", 2, -6)
+			end)
+			new:SetScript("OnMouseUp", function(self)
+				self.icon:SetPoint("TOP", 0, -4)
+			end)
+			new.icon = new:CreateTexture(new:GetName().."Icon", "ARTWORK")
+			new.icon:SetSize(16, 16)
+			new.icon:SetPoint("TOP", 0, -4)
+			new:SetScript("OnEnter", function(self)
+				GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
+				GameTooltip:SetText(self.mouseover);
+			end)
+			new:SetScript("OnLeave", GameTooltip_Hide)
+
+			-- new.active = new:CreateTexture(new:GetName().."ActiveLeft", "BORDER")
+			-- new.active:SetTexture([[Interface/PaperDollInfoFrame/UI-Character-Tab-RealHighlight]])
+			-- new.active:SetBlendMode("ADD")
+			-- new.active:SetRotation(PI)
+			-- new.active:SetPoint("TOPLEFT", -20, 12)
+			-- new.active:SetPoint("BOTTOMRIGHT", 20, -12)
+			-- new.active:Hide()
+
+			ChillEffectCurrencyFrame.columns[i] = new
+		end
 	end

-	self:RedrawCurrencyFrame()
-
 	--== Create the currency-selection dropdown
 	local dropdown = CreateFrame("Frame", "ChillEffectCurrencyFrameDropdown", ChillEffectCurrencyFrame, "UIDropDownMenuTemplate")
-	--dropDown:SetPoint(
-	UIDropDownMenu_SetWidth(dropdown, 120)
 	UIDropDownMenu_Initialize(dropdown, function(self)
 		local info = UIDropDownMenu_CreateInfo();
 		info.text = "Select Currencies"
 		info.disabled = true
+		info.isTitle = true
 		info.notCheckable = true
 		info.justifyH = "CENTER"
 		info.keepShownOnClick = true
 		UIDropDownMenu_AddButton(info, 1)

-		-- Start at two: You WILL see your gold!
-		for i=2,#CURRENCY_DATA do
+		for i=1,#CURRENCY_DATA do
 			info.text = CURRENCY_DATA[i][1]
-			info.arg1 = CURRENCY_DATA[i][2]
+			info.arg1 = CURRENCY_DATA[i][1]
 			info.icon = CURRENCY_DATA[i][3]
-			info.func = function(self, arg1, arg2, checked)
-
-			end
+			info.func = DropdownRow_OnClick
 			info.keepShownOnClick = true
 			info.disabled = false
+			info.isTitle = false
 			info.isNotRadio = true
 			info.notCheckable = false
 			info.justifyH = nil
+			info.checked = function()
+				if (Currencies:GetDB()).global.shown[CURRENCY_DATA[i][1]] then
+					return true
+				end
+			end
 			UIDropDownMenu_AddButton(info, 1)
+
 		end
 	end, "MENU")
-
 	ChillEffectCurrencyFrameDropdown = dropdown


 	--== Make the character rows
 	ChillEffectCurrencyFrame.rows = {}
-	local name
-	local CECF_NUM_ROWS = 5
-	local CECF_ROW_HEIGHT = (ChillEffectCurrencyFrame:GetHeight()-CECF_HEADER_HEIGHT-14)/CECF_NUM_ROWS
-	local scale = ChillEffectCurrencyFrame:GetEffectiveScale()
-	for i=1,CECF_NUM_ROWS do
-		name = "ChillEffectCurrencyFrameRow"..i
+	local CECF_ROW_HEIGHT = (ChillEffectCurrencyFrame:GetHeight()-CECF_HEADER_HEIGHT-44-8)/CECF_MAX_CHARACTERS_PER_REALM
+	for index = 1, CECF_NUM_ROWS do
+		ChillEffectCurrencyFrame.rows[index] = CreateRow("ChillEffectCurrencyFrameRow"..index, true)

-		new  = CreateFrame("Button", name, ChillEffectCurrencyFrame)
-		-- Attach it to the ChillEffectCurrencyFrame
-			-- new:SetPoint("TOPLEFT", ChillEffectCurrencyFrame, "TOPLEFT", 6, -72-((CECF_FULL_HEIGHT-10)*(i-1)/11))
-			-- new:SetPoint("BOTTOMRIGHT", ChillEffectCurrencyFrame, "TOPLEFT", CECF_MAX_WIDTH, -72-((CECF_FULL_HEIGHT-10)*(i)/11))
-		if i == 1 then
-			new:SetPoint("TOPLEFT", ChillEffectCurrencyFrame, "TOPLEFT", 6, -CECF_HEADER_HEIGHT-4)
-			new:SetPoint("BOTTOMRIGHT", ChillEffectCurrencyFrame, "TOPLEFT", CECF_MAX_WIDTH, -CECF_HEADER_HEIGHT-4-CECF_ROW_HEIGHT)
+		if index % 2 == 0 then
+			ChillEffectCurrencyFrame.rows[index].stripe:Show()
 		else
-			new:SetPoint("TOPLEFT", _G["ChillEffectCurrencyFrameRow"..(i-1)], "BOTTOMLEFT", 0, -1)
-			new:SetPoint("BOTTOMRIGHT", _G["ChillEffectCurrencyFrameRow"..(i-1)], "BOTTOMRIGHT", 0, -1-CECF_ROW_HEIGHT)
-		end
-
-		do -- Set up the highlight. Augh. Why no template?
-			glow = new:CreateTexture(name.."GlowTopLeft", "ARTWORK")
-			glow:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-ReputationBar-Highlight]])
-			glow:SetBlendMode("ADD")
-			glow:SetSize(16, 16)
-			glow:SetPoint("TOPLEFT", -1, 2)
-			glow:SetTexCoord(0.06640625, 0, 0.4375, 0.65625)
-
-			glow = new:CreateTexture(name.."GlowBottomLeft", "ARTWORK")
-			glow:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-ReputationBar-Highlight]])
-			glow:SetBlendMode("ADD")
-			glow:SetSize(16, 16)
-			glow:SetPoint("BOTTOMLEFT", -1, -2)
-			glow:SetTexCoord(0.06640625, 0, 0.65625, 0.4375)
-
-			glow = new:CreateTexture(name.."GlowTopRight", "ARTWORK")
-			glow:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-ReputationBar-Highlight]])
-			glow:SetBlendMode("ADD")
-			glow:SetSize(16, 16)
-			glow:SetPoint("TOPRIGHT", 1, 2)
-			glow:SetTexCoord(0, 0.06640625, 0.4375, 0.65625)
-
-			glow = new:CreateTexture(name.."GlowBottomRight", "ARTWORK")
-			glow:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-ReputationBar-Highlight]])
-			glow:SetBlendMode("ADD")
-			glow:SetSize(16, 16)
-			glow:SetPoint("BOTTOMRIGHT", 1, -2)
-			glow:SetTexCoord(0, 0.06640625, 0.65625, 0.4375)
-
-			glow = new:CreateTexture(name.."GlowTop", "ARTWORK")
-			glow:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-ReputationBar-Highlight]])
-			glow:SetBlendMode("ADD")
-			glow:SetPoint("TOPLEFT", name.."GlowTopLeft", "TOPRIGHT")
-			glow:SetPoint("BOTTOMRIGHT", name.."GlowTopRight", "BOTTOMLEFT")
-			glow:SetTexCoord(0, 0.015, 0.4375, 0.65625)
-
-			glow = new:CreateTexture(name.."GlowBottom", "ARTWORK")
-			glow:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-ReputationBar-Highlight]])
-			glow:SetBlendMode("ADD")
-			glow:SetPoint("TOPLEFT", name.."GlowBottomLeft", "TOPRIGHT")
-			glow:SetPoint("BOTTOMRIGHT", name.."GlowBottomRight", "BOTTOMLEFT")
-			glow:SetTexCoord(0, 0.015, 0.65625, 0.4375)
-
-			glow = new:CreateTexture(name.."GlowLeft", "ARTWORK")
-			glow:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-ReputationBar-Highlight]])
-			glow:SetBlendMode("ADD")
-			glow:SetPoint("TOPLEFT", name.."GlowTopLeft", "BOTTOMLEFT")
-			glow:SetPoint("BOTTOMRIGHT", name.."GlowBottomLeft", "TOPRIGHT")
-			glow:SetTexCoord(0.06640625, 0, 0.65625, 0.6)
-
-			glow = new:CreateTexture(name.."GlowRight", "ARTWORK")
-			glow:SetTexture([[Interface\PaperDollInfoFrame\UI-Character-ReputationBar-Highlight]])
-			glow:SetBlendMode("ADD")
-			--glow:SetSize(16, 16)
-			glow:SetPoint("TOPLEFT", name.."GlowTopRight", "BOTTOMLEFT")
-			glow:SetPoint("BOTTOMRIGHT", name.."GlowBottomRight", "TOPRIGHT")
-			glow:SetTexCoord(0, 0.06640625, 0.65625, 0.6)
+			ChillEffectCurrencyFrame.rows[index].stripe:Hide()
 		end
-
-		ChillEffectCurrencyFrame.rows[i] = new
 	end

+	--== Make the totals rows
+	ChillEffectCurrencyFrame.totals = {}
+	for index = 1,2 do
+		ChillEffectCurrencyFrame.totals[index] = CreateRow("ChillEffectCurrencyFrameTotals"..index, false)
+	end
+
+	--== CharacterFrame tab-shuffling magic
 	ChillEffectCurrencyFrame:SetID(5)
 	tinsert(CHARACTERFRAME_SUBFRAMES, "ChillEffectCurrencyFrame")
 	ChillEffectCurrencyFrame:SetScript("OnShow", function()
@@ -227,58 +362,272 @@ function Currencies:CreateCurrencyFrame()
 	self.frame = ChillEffectCurrencyFrame;
 end

-function Currencies:RedrawCurrencyFrame(currencyOrder)
+-- If this is the money column, display it in gold. If the text would overflow the expected column width, try to bignumber it.
+local function SetCurrencyColumnText(column, currencyName, currencyWidth, count)
+	if currencyName == MONEY then
+		if count >= 10000 then
+			column.text:SetText(floor(count/10000))
+		else
+			column.text:SetText(count/10000)
+		end
+	elseif log10(count) > currencyWidth then -- Honestly, what the hell? We'll try bignumbering it to fit, but this will probably never happen anyways.
+		column.text:SetText(floor(count/1000).."k")
+	else
+		column.text:SetText(count)
+	end
+end
+
+-- Sets the width of the header, body entries, and totals columns
+local function SetColumnWidth(columnIndex, columnWidth)
+	WhoFrameColumn_SetWidth(ChillEffectCurrencyFrame.columns[columnIndex], columnWidth)
+	for j=1, CECF_NUM_ROWS do
+		ChillEffectCurrencyFrame.rows[j].columns[columnIndex]:SetWidth(columnWidth)
+	end
+	for j=1, 2 do
+		ChillEffectCurrencyFrame.totals[j].columns[columnIndex]:SetWidth(columnWidth)
+	end
+end
+
+local sortType = "Name"
+local sortOrder = "ascending"
+local function SetSortingOrder(header)
+	if sortType == header.sortType then
+		if sortOrder == "ascending" then
+			sortOrder = "descending"
+		else
+			sortOrder = "ascending"
+		end
+	else
+		sortType = header.sortType
+		sortOrder = "descending"
+	end
+	-- print(format("Sorting by %s %s", sortType, sortOrder))
+	PlaySound("igMainMenuOptionCheckBoxOn")
+	Currencies:RedrawCurrencyFrame()
+end
+
+local function ShowSelectionDropdown(header)
+	ToggleDropDownMenu(1, nil, ChillEffectCurrencyFrameDropdown, header, 30, 26);
+	PlaySound("igMainMenuOptionCheckBoxOn")
+end
+
+function Currencies:RedrawCurrencyFrame()
 	local header
-	local horzSpaceAvailable = CECF_MAX_WIDTH - CECF_FIRST_COLUMN_MIN_WIDTH - 6; -- the 6 is the left-side offset for the first tab
-	-- print(horzSpaceAvailable .. "px available")
-	for i = 1, NUM_MAX_CURRENCY_HEADERS do
+	local currencyName, currencyWidth, currencyIcon
+	local hasHorde, hasAlliance, hasNeutral, numFactions
+	local realmName = GetRealmName()
+
+	--== Do we have multiple factions on this realm?
+	hasHorde = self.db.sv.factionrealm["Horde - ".. realmName] and true or false
+	hasAlliance = self.db.sv.factionrealm["Alliance - ".. realmName] and true or false
+	hasNeutral = self.db.sv.factionrealm["Neutral - ".. realmName] and true or false
+	numFactions = (hasHorde and 1 or 0) + (hasAlliance and 1 or 0) -- + (hasNeutral and 1 or 0)
+
+	--== Let's figure out the sorting. Pull everyone into a pair of {characterKey, sortTypeValue} tables, sort those, and use the resulting order
+	local character, count
+	local sortTable = {}
+	for k, v in pairs(self.db.sv.realm[realmName]) do
+		character = self.db.sv.char[k.." - ".. realmName]
+		if sortType == "Name" then
+			tinsert(sortTable, {k, character, k})
+		else
+			count = CharacterModule.GetCurrencyCount(character, sortType) or 0
+			tinsert(sortTable, {k, character, count})
+		end
+	end
+	sort(sortTable, function(a,b)
+		if sortOrder == "ascending" then
+			if a[3] < b[3] then
+				return true
+			elseif a[3] == b[3] and a[1] < b[1] then
+				return true
+			else
+				return false
+			end
+		else
+			if b[3] < a[3] then
+				return true
+			elseif a[3] == b[3] and a[1] < b[1] then
+				return true
+			else
+				return false
+			end
+		end
+	end)
+
+	--== Set the first column, the character names, using the savedVars for this realm
+	local row = 1
+	local widestName = 0
+	for k, v in pairs(sortTable) do
+		ChillEffectCurrencyFrame.rows[row].columns[1].text:SetText(v[1])
+		if ChillEffectCurrencyFrame.rows[row].columns[1].text:GetStringWidth() > widestName then
+			widestName = ChillEffectCurrencyFrame.rows[row].columns[1].text:GetStringWidth()
+		end
+		row = row + 1
+	end
+	for i = 2, 2 do
+		ChillEffectCurrencyFrame.totals[i].columns[1].text:SetText("Totals:")
+	end
+	ChillEffectCurrencyFrame.columns[1]:SetScript("OnClick", SetSortingOrder)
+	ChillEffectCurrencyFrame.columns[1].sortType = "Name"
+
+	--== That told us how many characters (rows) we need to show
+	for i=row, CECF_NUM_ROWS do
+		ChillEffectCurrencyFrame.rows[row]:Hide()
+	end
+	--== Also, how much space are the names taking? Subtract that, plus the left-side offset, and let's start our column-squeeing mojo
+	local horzSpaceAvailable = CECF_MAX_WIDTH - widestName - 6;
+
+	local customShown
+	if self.db.global.shown then
+		customShown = {}
+		for k, v in pairs(self.db.global.shown) do
+			local currencyIndex
+			for i, currencyData in ipairs(CURRENCY_DATA) do
+				if currencyData[1] == v then
+					currencyIndex = i
+				end
+			end
+			tinsert(customShown, currencyIndex)
+		end
+		sort(customShown)
+	end
+
+	--== Okay now figure out the columns
+	local numCurrencyColumns
+	if customShown then
+		numCurrencyColumns = #customShown + 1
+	else
+		numCurrencyColumns = NUM_MAX_CURRENCY_HEADERS + 1
+	end
+
+	for i = 1, numCurrencyColumns do
+
+		horzSpaceAvailable = horzSpaceAvailable - CECF_COLUMN_MARGIN;
+
+		if customShown then
+			currencyName, currencyWidth, currencyIcon = unpack(CURRENCY_DATA[customShown[i]])
+		else
+			currencyName, currencyWidth, currencyIcon = unpack(CURRENCY_DATA[i])
+		end

 		header = ChillEffectCurrencyFrame.columns[i+1]
 		header:Show()

-		horzSpaceAvailable = horzSpaceAvailable - CECF_COLUMN_MARGIN;
+		header.mouseover = currencyName
+		header.icon:SetTexture(currencyIcon)
+		header.sortType = currencyName

-		if currencyOrder then
-			print("uh oh. No currency order set")
-		else
-			header.mouseover = CURRENCY_DATA[i][1]
-			header.icon:SetTexture(CURRENCY_DATA[i][3])
-			header.icon:SetTexCoord(0, 1, 0, 1)
-
-			header:SetScript("OnClick", function(self)
-				-- Stuff about sorting currencies
-				PlaySound("igMainMenuOptionCheckBoxOn")
-			end)
+		header:SetScript("OnClick", SetSortingOrder)
+		-- SetColumnWidth calls header:SetWidth(). Not sure how I feel about that.
+		-- SetColumnWidth(i+1, 9*(currencyWidth+1) +2*CECF_COLUMN_PADDING) -- Why currencyWidth+1? Because the total has an approx max of one more digit (10 characters)

-			WhoFrameColumn_SetWidth(header, 10*CURRENCY_DATA[i][2] +2*CECF_COLUMN_PADDING)
-			horzSpaceAvailable = horzSpaceAvailable - header:GetWidth()
-			-- print(header:GetWidth() .. "px used, " .. horzSpaceAvailable .. " remaining")
+		-- Using min-width instead of dynamic due to the choice to implement a column cap.
+		if currencyWidth < MIN_COLUMN_CHAR_WIDTH then
+			SetColumnWidth(i+1, 9*(MIN_COLUMN_CHAR_WIDTH+1) +2*CECF_COLUMN_PADDING)
+		else
+			SetColumnWidth(i+1, 9*(currencyWidth+1) +2*CECF_COLUMN_PADDING)
 		end
-
-		-- Turn this last column into the [+] button and push the extra space into the Character tab
-		-- Hide any remaining buttons
-		if horzSpaceAvailable < 24 then
-			header.mouseover = "" --"Click to select currencies"
+		horzSpaceAvailable = horzSpaceAvailable - header:GetWidth()
+
+		--== Turn this last column into the [+] button and push the extra space into the Character tab, and hide any remaining buttons. Break the outer loop - we're done!
+		if horzSpaceAvailable < 24 or i > NUM_MAX_CURRENCY_HEADERS then
+			-- print("Breaking at column "..i)
+			header.mouseover = ""
 			header.icon:SetTexture([[Interface\Common\UI-ModelControlPanel]])
 			header.icon:SetTexCoord(0.578125, 0.828125, 0.1484375, 0.2734275)
 			horzSpaceAvailable = horzSpaceAvailable + header:GetWidth() - 24
-				-- print(header:GetWidth() .. "re-added, 24 taken, " .. horzSpaceAvailable .. " remaining")
-
-			header:SetScript("OnClick", function(self)
-				ToggleDropDownMenu(1, nil, ChillEffectCurrencyFrameDropdown, header, 30, 26);
-				PlaySound("igMainMenuOptionCheckBoxOn")
-			end)
-
-			WhoFrameColumn_SetWidth(header, CECF_LAST_COLUMN_MIN_WIDTH)
-			WhoFrameColumn_SetWidth(ChillEffectCurrencyFrameHeader1, CECF_FIRST_COLUMN_MIN_WIDTH + horzSpaceAvailable)
+			header:SetScript("OnClick", ShowSelectionDropdown)

+			-- Hide the headers
 			for j = i+2, NUM_MAX_CURRENCY_HEADERS+1 do
 				ChillEffectCurrencyFrame.columns[j]:Hide()
 			end
+
+			-- Hide the rows
+			for j=1, CECF_NUM_ROWS do
+				ChillEffectCurrencyFrame.rows[j].columns[i+1]:Hide()
+			end
+
+			-- Show the faction icons, hide the stripes
+			if numFactions == 1 then
+				if hasAlliance then
+					ChillEffectCurrencyFrame.totals[1].columns[i+1].icon:SetTexture([[Interface\PVPFrame\PVP-Currency-Alliance]])
+					ChillEffectCurrencyFrame.totals[1].columns[i+1].icon:Show()
+					ChillEffectCurrencyFrame.totals[1].columns[i+1].stripe:Hide()
+				else
+					ChillEffectCurrencyFrame.totals[1].columns[i+1].icon:SetTexture([[Interface\PVPFrame\PVP-Currency-Horde]])
+					ChillEffectCurrencyFrame.totals[1].columns[i+1].icon:Show()
+					ChillEffectCurrencyFrame.totals[1].columns[i+1].stripe:Hide()
+				end
+			elseif numFactions > 1 then
+				ChillEffectCurrencyFrame.totals[1].columns[i+1].icon:SetTexture([[Interface\PVPFrame\PVP-Currency-Alliance]])
+				ChillEffectCurrencyFrame.totals[1].columns[i+1].icon:Show()
+				ChillEffectCurrencyFrame.totals[1].columns[i+1].stripe:Hide()
+				ChillEffectCurrencyFrame.totals[2].columns[i+1].icon:SetTexture([[Interface\PVPFrame\PVP-Currency-Horde]])
+				ChillEffectCurrencyFrame.totals[2].columns[i+1].icon:Show()
+				ChillEffectCurrencyFrame.totals[2].columns[i+1].stripe:Hide()
+			end
+			-- Set this column to the right width and dump the extra space on the character name column
+			SetColumnWidth(i+1, CECF_LAST_COLUMN_MIN_WIDTH)
+			SetColumnWidth(1, widestName + horzSpaceAvailable)
+
+			-- Peace out y'all
 			break
 		end

+		--== If we get down to here, the column will have content, so set the texts. Including on the totals row(s)
+		local row = 1
+		local character, count
+		local totals = { ["Horde"] = {}, ["Alliance"] = {} }
+		totals["Horde"][currencyName] = 0
+		totals["Alliance"][currencyName] = 0
+		for k, v in pairs(sortTable) do
+			character = v[2]
+			count = CharacterModule.GetCurrencyCount(character, currencyName) or 0
+
+			SetCurrencyColumnText(ChillEffectCurrencyFrame.rows[row].columns[i+1], currencyName, currencyWidth, count)
+
+			if self.db.sv.factionrealm["Horde - ".. realmName][v[1]] then
+				totals["Horde"][currencyName] = totals["Horde"][currencyName] + count
+			elseif self.db.sv.factionrealm["Alliance - ".. realmName][v[1]] then
+				totals["Alliance"][currencyName] = totals["Alliance"][currencyName] + count
+			end
+			row = row + 1
+		end

+		if numFactions == 1 and hasAlliance then
+			SetCurrencyColumnText(ChillEffectCurrencyFrame.totals[1].columns[i+1], currencyName, currencyWidth, totals["Alliance"][currencyName])
+		elseif numFactions == 1 and hasHorde then
+			SetCurrencyColumnText(ChillEffectCurrencyFrame.totals[1].columns[i+1], currencyName, currencyWidth, totals["Horde"][currencyName])
+		elseif numFactions > 1 then
+			SetCurrencyColumnText(ChillEffectCurrencyFrame.totals[1].columns[i+1], currencyName, currencyWidth, totals["Alliance"][currencyName])
+			SetCurrencyColumnText(ChillEffectCurrencyFrame.totals[2].columns[i+1], currencyName, currencyWidth, totals["Horde"][currencyName])
+			-- ChillEffectCurrencyFrame.totals[2].columns[i+1].icon:Hide()
+		end
+		-- ChillEffectCurrencyFrame.totals[1].columns[i+1].icon:Hide()
+
+	end
+
+	ChillEffectCurrencyFrameInset:SetPoint("TOPLEFT", 4, -CECF_HEADER_HEIGHT)
+	ChillEffectCurrencyFrameInset:SetPoint("BOTTOMRIGHT", -6, 4+CECF_TOTALS_ROW_HEIGHT*numFactions)
+
+	local CECF_ROW_HEIGHT = (ChillEffectCurrencyFrame:GetHeight()-CECF_HEADER_HEIGHT-(4+CECF_TOTALS_ROW_HEIGHT*numFactions)-8)/(row-1) --Remember me? "row" is a local var from way up top - incremented after each character
+	for index = 1, CECF_NUM_ROWS do
+		if index == 1 then
+			ChillEffectCurrencyFrame.rows[index]:SetPoint("TOPLEFT", ChillEffectCurrencyFrame, "TOPLEFT", 6, -1-CECF_HEADER_HEIGHT-4)
+			ChillEffectCurrencyFrame.rows[index]:SetPoint("BOTTOMRIGHT", ChillEffectCurrencyFrame, "TOPLEFT", CECF_MAX_WIDTH, -1-CECF_HEADER_HEIGHT-4-CECF_ROW_HEIGHT)
+		elseif index <= CECF_MAX_CHARACTERS_PER_REALM then
+			ChillEffectCurrencyFrame.rows[index]:SetPoint("TOPLEFT", ChillEffectCurrencyFrame.rows[index-1], "BOTTOMLEFT", 0, 0)
+			ChillEffectCurrencyFrame.rows[index]:SetPoint("BOTTOMRIGHT", ChillEffectCurrencyFrame.rows[index-1], "BOTTOMRIGHT", 0, -CECF_ROW_HEIGHT)
+		end
+	end
+
+	ChillEffectCurrencyFrame.totals[1]:SetPoint("TOPLEFT", ChillEffectCurrencyFrameInset, "BOTTOMLEFT", 2, -2)
+	ChillEffectCurrencyFrame.totals[1]:SetPoint("BOTTOMRIGHT", ChillEffectCurrencyFrameInset, "BOTTOMLEFT", CECF_MAX_WIDTH, -2-CECF_TOTALS_ROW_HEIGHT)
+	if numFactions > 1 then
+		ChillEffectCurrencyFrame.totals[2]:SetPoint("TOPLEFT", ChillEffectCurrencyFrame.totals[1], "BOTTOMLEFT", 0, 0)
+		ChillEffectCurrencyFrame.totals[2]:SetPoint("BOTTOMRIGHT", ChillEffectCurrencyFrame.totals[1], "BOTTOMRIGHT", 0, -CECF_TOTALS_ROW_HEIGHT)
 	end
 end