------------------------------------------------------
-- AdSpace.lua
------------------------------------------------------

FAS_SPECIAL_VENDOR_COLOR = {r=1.0, g=0.5, b=0.25};
FAS_INDENT = "  ";

FAS_AllClasses = { "PALADIN", "SHAMAN", "MAGE", "PRIEST", "WARLOCK", "WARRIOR", "HUNTER", "ROGUE", "DRUID", "ANY" };

-- Configuration
FAS_Config = { };

FAS_OptionsText = {
	["Recipes"] = FAS_OPTION_RECIPES,
	["ShowCost"] = FAS_OPTION_RECIPE_COST,
	["Librams"] = FAS_OPTION_LIBRAM,
	["Darkmoon"] = FAS_OPTION_DARKMOON,
	["AD"] = FAS_OPTION_AD,
	["ZG"] = FAS_OPTION_ZG.." "..GFWUtils.Gray(FAS_OPTION_ZG_FACTION),
	["AQ20"] = FAS_OPTION_AQ20.." "..GFWUtils.Gray(FAS_OPTION_AQ20_FACTION),
	["AQ40"] = FAS_OPTION_AQ40.." "..GFWUtils.Gray(FAS_OPTION_AQ40_FACTION),
	["PostToRaid"] = FAS_OPTION_POST_RAID,
};

local function FAS_Tooltip_Hook(frame, name, link, source)
	--DevTools_Dump({frame=frame:GetName(), name=name, link=link, source=source})
	if (link) then
		local _, _, itemID  = string.find(link, "item:(%d+)");
		itemID = tonumber(itemID);
		local itemInfo = FAS_ItemInfo[itemID];

		if (not FAS_Config.NoRecipes and itemInfo) then
			if (source == "MERCHANT") then
				return false; -- kinda silly to show merchants who sell this when we're seeing this at a merchant
			end
			local myFaction = UnitFactionGroup("player");
			local vendors = GFWTable.Merge(FAS_VendorInfo[myFaction][itemID], FAS_VendorInfo["Neutral"][itemID]);
			local note = itemInfo.note;
			
			local color;
			local intro;
			if (note) then
				color = FAS_SPECIAL_VENDOR_COLOR;
			else
				color = GFW_FONT_COLOR;
			end
			if (not FAS_Config.NoShowCost) then
				intro = string.format(SOLD_FOR_PRICE_BY, GFWUtils.TextGSC(itemInfo.b));
			else
				intro = SOLD_BY;
			end
					
			if (table.getn(vendors) > 1) then
				frame:AddLine(intro..":", color.r, color.g, color.b);
				for i, aVendor in pairs(vendors) do
					local vendorLoc = FAS_VendorLocations[aVendor];
					if (vendorLoc) then
						local vendorName = FAS_Localized[aVendor] or aVendor;
						local vendorLocation = FAS_Localized[vendorLoc] or vendorLoc;
						frame:AddLine(FAS_INDENT..string.format(VENDOR_LOCATION_FORMAT, vendorName, vendorLocation), color.r, color.g, color.b);
					else
						local version = GetAddOnMetadata("GFW_AdSpace", "Version");
						GFWUtils.PrintOnce(GFWUtils.Red("AdSpace "..version.." error: ").."Can't find location for "..aVendor..". Please report to gazmik@fizzwidget.com.", 60);
						return false;
					end
				end
			elseif (table.getn(vendors) == 1) then
				local vendorLoc = FAS_VendorLocations[vendors[1]];
				if (vendorLoc) then
					local vendorName = FAS_Localized[vendors[1]] or vendors[1];
					local vendorLocation = FAS_Localized[vendorLoc] or vendorLoc;
					frame:AddLine(intro.." "..string.format(VENDOR_LOCATION_FORMAT, vendorName, vendorLocation), color.r, color.g, color.b);
				else
					local version = GetAddOnMetadata("GFW_AdSpace", "Version");
					GFWUtils.PrintOnce(GFWUtils.Red("AdSpace "..version.." error: ").."Can't find location for "..vendorName..". Please report to gazmik@fizzwidget.com.", 60);
					return false;
				end
			else
				local found = false;
				for _, faction in pairs({"Alliance", "Horde", "Neutral"}) do
					if (FAS_VendorInfo[faction][itemID]) then
						found = true;
					end
				end
				if not (found) then
					local version = GetAddOnMetadata("GFW_AdSpace", "Version");
					GFWUtils.PrintOnce(GFWUtils.Red("AdSpace "..version.." error: ")..link.."("..itemID..") is listed but has no vendors. Please report to gazmik@fizzwidget.com.", 60);
					return false;
				end
			end
			if (note ~= "") then
				frame:AddLine(note, color.r, color.g, color.b);
			end
			return true;
		end
		
		local libramInfo = FAS_LibramInfo[itemID];
		if (not FAS_Config.NoLibrams and libramInfo) then
			local color = FAS_SPECIAL_VENDOR_COLOR;
			local returnToName = FAS_Localized[libramInfo.name] or libramInfo.name;
			local returnToLocation = FAS_Localized[FAS_VendorLocations[libramInfo.name]] or FAS_VendorLocations[libramInfo.name];
			local bonus = FAS_Localized[libramInfo.bonus] or libramInfo.bonus;
			frame:AddLine(RETURN_TO.." "..string.format(VENDOR_LOCATION_FORMAT, returnToName, returnToLocation), color.r, color.g, color.b);
			frame:AddLine(string.format(ARCANUM_FORMAT, bonus), color.r, color.g, color.b);
			return true;
		end

		local darkmoonInfo = FAS_DarkmoonInfo[itemID];
		if (not FAS_Config.NoDarkmoon and darkmoonInfo) then
			local color = FAS_SPECIAL_VENDOR_COLOR;
			frame:AddLine(darkmoonInfo, color.r, color.g, color.b);
			return true;
		end

		local tokenInfo = FAS_TokenInfo[itemID];
		if ((not FAS_Config.NoZG or not FAS_Config.NoAQ20 or not FAS_Config.NoAQ40) and  tokenInfo) then
			local color = FAS_SPECIAL_VENDOR_COLOR;
			local addedLines;
			for _, faction in pairs(FAS_TokenFactions) do
				local _, _, factionAbbrev = string.find(faction, "(.-)_FACTION");
				if (FAS_Config[factionAbbrev]) then
					local reportLines = {};
					for _, class in pairs(FAS_AllClasses) do
						if (not (class == "SHAMAN" and UnitFactionGroup("player") == "Alliance") and 
						    not (class == "PALADIN" and UnitFactionGroup("player") == "Horde")) then
							for _, rewardID in pairs(tokenInfo) do
								local reward = FAS_TokenRewards[rewardID];
								if (reward and reward.class == class and reward.faction == faction) then
									local repNeeded;
									if (reward.rep) then
										repNeeded = getglobal("FACTION_STANDING_LABEL"..reward.rep);
									end
									local reportLine = "";
									reportLine = reportLine .. reward.type;
									if (repNeeded) then
										reportLine = reportLine .. " ("..repNeeded..")";
									end
									reportLine = reportLine .. ", ";
									if (reportLines[class]) then
										reportLines[class] = reportLines[class] .. reportLine;
									else
										reportLines[class] = reportLine;
									end
								end
							end
							if (reportLines[class]) then
								reportLines[class] = string.gsub(reportLines[class], ", $", "");
							end
						end
					end
					if (GFWTable.Count(reportLines) > 0) then
						frame:AddLine(string.format(FAS_FACTION_REWARDS, getglobal(faction)), color.r, color.g, color.b);
						addedLines = true;
						for class, reportLine in pairs(reportLines) do
							frame:AddLine("  "..getglobal(class)..": "..reportLine, color.r, color.g, color.b);
						end
					end
				end
			end
			if (addedLines) then
				return true;
			end
		end

		for key, tokenSetList in pairs(FAS_FactionTokenSets) do
			if (FAS_Config[key]) then
				for _, coinSet in pairs(tokenSetList) do
					local found;
					local otherCoins = {};
					for _, coinID in pairs(coinSet) do
						if (itemID == coinID) then
							found = true;
						else
							local itemText = FAS_TokenNames[coinID];
							itemText = FAS_Localized[itemText] or itemText;
							table.insert(otherCoins, itemText);
						end
					end
					if (found) then
						local color = FAS_SPECIAL_VENDOR_COLOR;
						frame:AddLine(FAS_TURNIN.." "..getglobal(key.."_FACTION"), color.r, color.g, color.b);
						if (table.getn(otherCoins) > 0) then
							frame:AddDoubleLine(" ", FAS_WITH.." "..table.concat(otherCoins, ", "), color.r, color.g, color.b, color.r, color.g, color.b);
						end
						return true;
					end
				end
			end
		end
	end
	
end

function FAS_OnLoad()

	-- Register Slash Commands
	SLASH_FAS1 = "/adspace";
	SLASH_FAS2 = "/ads";
	SlashCmdList["FAS"] = function(msg)
		FAS_ChatCommandHandler(msg);
	end
	
	-- Register for Events
	--this:RegisterEvent("ADDON_LOADED");

	GFWTooltip_AddCallback("GFW_AdSpace", FAS_Tooltip_Hook);

	table.insert(UISpecialFrames,"FAS_OptionsFrame");	

	local version = GetAddOnMetadata("GFW_AdSpace", "Version");
	GFWUtils.Print("Fizzwidget AdSpace "..version.." initialized!");
end

function FAS_OnEvent(event, arg1)

	if ( event == "ADDON_LOADED" ) then
		this:UnregisterEvent("ADDON_LOADED");
	end
end

function FAS_ChatCommandHandler(msg)

	if ( msg == "" ) then
		if FAS_OptionsFrame:IsVisible() then
			HideUIPanel(FAS_OptionsFrame);
		else
			ShowUIPanel(FAS_OptionsFrame);
		end
		return;
	end

	-- Print Help
	if ( msg == "help" ) or ( msg == "" ) then
		local version = GetAddOnMetadata("GFW_AdSpace", "Version");
		GFWUtils.Print("Fizzwidget AdSpace "..version..":");
		GFWUtils.Print("/adspace (or /ads)");
		GFWUtils.Print("- "..GFWUtils.Hilite("help").." - Print this helplist.");
		GFWUtils.Print("- "..GFWUtils.Hilite("[item link]").." - Show info for an item in the chat window.");
		GFWUtils.Print("- "..GFWUtils.Hilite("status").." - Check current settings.");
		GFWUtils.Print("- "..GFWUtils.Hilite("recipes on").." | "..GFWUtils.Hilite("off").." - Show info for vendor-supplied recipes in tooltips.");
		GFWUtils.Print("- "..GFWUtils.Hilite("showcost on").." | "..GFWUtils.Hilite("off").." - Also show vendor prices for recipes.");
		GFWUtils.Print("- "..GFWUtils.Hilite("librams on").." | "..GFWUtils.Hilite("off").." - Show info for librams in tooltips.");
		GFWUtils.Print("- "..GFWUtils.Hilite("darkmoon on").." | "..GFWUtils.Hilite("off").." - Show info for Darkmoon Faire grey item turn-ins in tooltips.");
		GFWUtils.Print("- "..GFWUtils.Hilite("zg on").." | "..GFWUtils.Hilite("off").." - Show info for for special raid loot from Zul'Gurub (Zandalar Tribe rewards) in tooltips.");
		GFWUtils.Print("- "..GFWUtils.Hilite("aq20 on").." | "..GFWUtils.Hilite("off").." - Show info for for special raid loot from Ruins of Ahn'Qiraj (Cenarion Circle rewards) in tooltips.");
		GFWUtils.Print("- "..GFWUtils.Hilite("aq40 on").." | "..GFWUtils.Hilite("off").." - Show info for for special raid loot from Ahn'Qiraj (Brood of Nozdormu rewards) in tooltips.");
		GFWUtils.Print("- "..GFWUtils.Hilite("post on").." | "..GFWUtils.Hilite("off").." - Post to raid/party chat when getting raid loot info via "..GFWUtils.Hilite("/ads [item link]")..".");
		return;
	end
	
	if (msg == "version") then
		local version = GetAddOnMetadata("GFW_AdSpace", "Version");
		GFWUtils.Print("Fizzwidget AdSpace "..version);
		return;
	end
	
	if ( msg == "status" ) then
		local gotSomething;
		if (not FAS_Config.NoRecipes) then
			GFWUtils.Print("Showing info for "..GFWUtils.Hilite("vendor-supplied recipes").." in tooltips.");
			gotSomething = 1;
			if (not FAS_Config.NoShowCost) then
				GFWUtils.Print("Also showing vendor price for recipes.");
			end
		end
		if (not FAS_Config.NoLibrams) then
			GFWUtils.Print("Showing info for "..GFWUtils.Hilite("Librams").." in tooltips.");
			gotSomething = 1;
		end
		if (not FAS_Config.NoDarkmoon) then
			GFWUtils.Print("Showing info for "..GFWUtils.Hilite("Darkmoon Faire grey item turn-ins").." in tooltips.");
			gotSomething = 1;
		end
		if (not FAS_Config.NoZG) then
			GFWUtils.Print("Showing info for special raid loot from "..GFWUtils.Hilite("Zul'Gurub (Zandalar Tribe rewards)").." in tooltips.");
			gotSomething = 1;
		end
		if (not FAS_Config.NoAQ20) then
			GFWUtils.Print("Showing info for special raid loot from "..GFWUtils.Hilite("Ruins of Ahn'Qiraj (AQ20 Cenarion Circle rewards)").." in tooltips.");
			gotSomething = 1;
		end
		if (not FAS_Config.NoAQ40) then
			GFWUtils.Print("Showing info for special raid loot from "..GFWUtils.Hilite("Ahn'Qiraj (AQ40 Brood of Nozdormu rewards)").." in tooltips.");
			gotSomething = 1;
		end
		if ((not FAS_Config.NoZG or not FAS_Config.NoAQ20 or not FAS_Config.NoAQ40) and not FAS_Config.NoPostToRaid) then
			GFWUtils.Print("Will post to raid/party chat when showing info for raid loot via "..GFWUtils.Hilite("/ads [link]")..".");
		end
		if (not gotSomething) then
			GFWUtils.Print("Not adding any info to tooltips.");
		end
		return;
	end
	
	if (msg == "test") then
		local itemInfoCount = 0;
		for itemID in pairs(FAS_ItemInfo) do
			local found = false;
			for _, faction in pairs({"Alliance", "Horde", "Neutral"}) do
				if (FAS_VendorInfo[faction][itemID]) then
					found = true;
				end
			end
			if not (found) then
				GFWUtils.Print("Item ID "..itemID.." not found in FAS_VendorInfo.");
			end
			itemInfoCount = itemInfoCount + 1;
		end
		GFWUtils.Print(itemInfoCount.." entries in FAS_ItemInfo.");
		for _, faction in pairs({"Alliance", "Horde", "Neutral"}) do
			local vendorInfoCount = 0;
			for itemID in pairs(FAS_VendorInfo[faction]) do
				if (FAS_ItemInfo[itemID] == nil) then
					GFWUtils.Print("Item ID "..itemID.." not found in FAS_ItemInfo.");
				end
				vendorInfoCount = vendorInfoCount + 1;
			end
			GFWUtils.Print(vendorInfoCount.." entries in FAS_VendorInfo["..faction.."].");
		end
		return;
	end

	local _, _, cmd, args = string.find(msg, "^([%l%d']+) *(.*)");
	if (cmd) then cmd = string.lower(cmd); end
	
	if (cmd == "recipes" or cmd == "recipe") then
		if (args == "on") then
			FAS_Config.NoRecipes = nil;
		elseif (args == "off") then
			FAS_Config.NoRecipes = true;
		else
			FAS_Config.NoRecipes = not FAS_Config.NoRecipes;
		end
		if (not FAS_Config.NoRecipes) then
			GFWUtils.Print("Showing info for "..GFWUtils.Hilite("vendor-supplied recipes").." in tooltips.");
		else
			GFWUtils.Print(GFWUtils.Red("Not").."showing info for "..GFWUtils.Hilite("vendor-supplied recipes").." in tooltips.");
		end
		return;
	end
	if (cmd == "showcost" or cmd == "cost") then
		if (args == "on") then
			FAS_Config.NoShowCost = nil;
		elseif (args == "off") then
			FAS_Config.NoShowCost = true;
		else
			FAS_Config.NoShowCost = not FAS_Config.NoShowCost;
		end
		if (not FAS_Config.NoShowCost) then
			GFWUtils.Print("Also showing vendor price for recipes.");
		else
			GFWUtils.Print(GFWUtils.Red("Not").."showing vendor price for recipes.");
		end
		return;
	end
	if (cmd == "librams" or cmd == "libram") then
		if (args == "on") then
			FAS_Config.NoLibrams = nil;
		elseif (args == "off") then
			FAS_Config.NoLibrams = true;
		else
			FAS_Config.NoLibrams = not FAS_Config.NoLibrams;
		end
		if (not FAS_Config.NoLibrams) then
			GFWUtils.Print("Showing info for "..GFWUtils.Hilite("Librams").." in tooltips.");
		else
			GFWUtils.Print(GFWUtils.Red("Not").."showing info for "..GFWUtils.Hilite("Librams").." in tooltips.");
		end
		return;
	end
	if (cmd == "darkmoon") then
		if (args == "on") then
			FAS_Config.NoDarkmoon = nil;
		elseif (args == "off") then
			FAS_Config.NoDarkmoon = true;
		else
			FAS_Config.NoDarkmoon = not FAS_Config.NoDarkmoon;
		end
		if (not FAS_Config.NoDarkmoon) then
			GFWUtils.Print("Showing info for "..GFWUtils.Hilite("Darkmoon Faire grey item turn-ins").." in tooltips.");
		else
			GFWUtils.Print(GFWUtils.Red("Not").."showing info for "..GFWUtils.Hilite("Darkmoon Faire grey item turn-ins").." in tooltips.");
		end
		return;
	end
	if (cmd == "zg" or cmd == "zul'gurub" or cmd == "zulgurub" or cmd == "zandalar") then
		if (args == "on") then
			FAS_Config.NoZG = nil;
		elseif (args == "off") then
			FAS_Config.NoZG = true;
		else
			FAS_Config.NoZG = not FAS_Config.NoZG;
		end
		if (not FAS_Config.NoZG) then
			GFWUtils.Print("Showing info for special raid loot from"..GFWUtils.Hilite("Zul'Gurub (Zandalar Tribe rewards)").." in tooltips.");
		else
			GFWUtils.Print(GFWUtils.Red("Not").."showing info for special raid loot from"..GFWUtils.Hilite("Zul'Gurub (Zandalar Tribe rewards)").." in tooltips.");
		end
		return;
	end
	if (cmd == "aq20" or cmd == "cenarion") then
		if (args == "on") then
			FAS_Config.NoAQ20 = nil;
		elseif (args == "off") then
			FAS_Config.NoAQ20 = true;
		else
			FAS_Config.NoAQ20 = not FAS_Config.NoAQ20;
		end
		if (not FAS_Config.NoAQ20) then
			GFWUtils.Print("Showing info for "..GFWUtils.Hilite("Ruins of Ahn'Qiraj (AQ20)").." special raid loot in tooltips.");
		else
			GFWUtils.Print(GFWUtils.Red("Not").."showing info for "..GFWUtils.Hilite("Ruins of Ahn'Qiraj (AQ20)").." special raid loot in tooltips.");
		end
		return;
	end
	if (cmd == "aq40" or cmd == "brood" or cmd == "nozdormu") then
		if (args == "on") then
			FAS_Config.NoAQ40 = nil;
		elseif (args == "off") then
			FAS_Config.NoAQ40 = true;
		else
			FAS_Config.NoAQ40 = not FAS_Config.NoAQ40;
		end
		if (not FAS_Config.NoAQ40) then
			GFWUtils.Print("Showing info for "..GFWUtils.Hilite("Ahn'Qiraj (AQ40)").." special raid loot in tooltips.");
		else
			GFWUtils.Print(GFWUtils.Red("Not").."showing info for "..GFWUtils.Hilite("Ahn'Qiraj (AQ40)").." special raid loot in tooltips.");
		end
		return;
	end
	if (cmd == "post" or cmd == "raid" or cmd == "party") then
		if (args == "on") then
			FAS_Config.NoPostToRaid = nil;
		elseif (args == "off") then
			FAS_Config.NoPostToRaid = true;
		else
			FAS_Config.NoPostToRaid = not FAS_Config.NoPostToRaid;
		end
		if (not FAS_Config.NoPostToRaid) then
			GFWUtils.Print("Will post to raid/party chat when getting info for raid loot via "..GFWUtils.Hilite("/ads [link]")".");
		else
			GFWUtils.Print("Will only print to chat window when getting info for raid loot via "..GFWUtils.Hilite("/ads [link]")".");
		end
		return;
	end
	
	if (args == nil or args == "") then
		args = msg;
	end
	local postedText;
	for itemLink in string.gmatch(args, "|c%x+|Hitem:[-%d:]+|h%[.-%]|h|r") do
		postedText = nil;
		local _, _, itemID  = string.find(itemLink, "item:(%d+)");
		if (itemID == nil or itemID == "") then
			GFWUtils.Print("Usage: "..GFWUtils.Hilite("/ads info <item link>"));
			return;
		end
		itemID = tonumber(itemID);
		
		local itemInfo = FAS_ItemInfo[itemID];
		if (itemInfo) then
			local myFaction = UnitFactionGroup("player");
			local vendors = GFWTable.Merge(FAS_VendorInfo[myFaction][itemID], FAS_VendorInfo["Neutral"][itemID]);
			local note = itemInfo.note;
			local intro = itemLink..": "..string.format(SOLD_FOR_PRICE_BY, GFWUtils.TextGSC(itemInfo.b));

			if (vendors == nil or vendors == {}) then
				local version = GetAddOnMetadata("GFW_AdSpace", "Version");
				GFWUtils.Print(GFWUtils.Red("AdSpace "..version.." error: ")..itemLink.."("..itemID..") is listed but has no vendors. Please report to gazmik@fizzwidget.com.");
				return;
			end
			GFWUtils.Print(intro);
			for i, aVendor in pairs(vendors) do
				local vendorName = FAS_Localized[aVendor] or aVendor;
				local vendorLocation = FAS_Localized[FAS_VendorLocations[aVendor]] or FAS_VendorLocations[aVendor];
				GFWUtils.Print(string.format(VENDOR_LOCATION_FORMAT, vendorName, vendorLocation));
			end
			if (note and note ~= "") then
				GFWUtils.Print(GFWUtils.Hilite(note));
			end
			postedText = 1;
		end
		
		local libramInfo = FAS_LibramInfo[itemID];
		if (libramInfo) then
			local returnToName = FAS_Localized[libramInfo.name] or libramInfo.name;
			local returnToLocation = FAS_Localized[FAS_VendorLocations[libramInfo.name]] or FAS_VendorLocations[libramInfo.name];
			local bonus = FAS_Localized[libramInfo.bonus] or libramInfo.bonus;
			GFWUtils.Print(itemLink..": "..RETURN_TO.." "..string.format(VENDOR_LOCATION_FORMAT, returnToName, returnToLocation));
			GFWUtils.Print(bonus);
			postedText = 1;
		end
		
		local darkmoonInfo = FAS_DarkmoonInfo[itemID];
		if (darkmoonInfo) then
			GFWUtils.Print(itemLink..": "..darkmoonInfo);
			postedText = 1;
		end

		local tokenInfo = FAS_TokenInfo[itemID];
		if (tokenInfo) then
			for _, faction in pairs(FAS_TokenFactions) do
				local reportLines = {};
				for _, class in pairs(FAS_AllClasses) do
					for _, rewardID in pairs(tokenInfo) do
						local reward = FAS_TokenRewards[rewardID];
						if (reward and reward.class == class and reward.faction == faction) then
							local link = GFWUtils.ItemLink(rewardID);
							local repNeeded;
							if (reward.rep) then
								repNeeded = getglobal("FACTION_STANDING_LABEL"..reward.rep);
							end
							local reportLine = "";
							if (link) then
								reportLine = reportLine .. link .. " - ";
							end
							reportLine = reportLine .. reward.type;
							if (repNeeded) then
								reportLine = reportLine .. " ("..repNeeded..")";
							end
							reportLine = reportLine .. ", ";
							if (reportLines[class]) then
								reportLines[class] = reportLines[class] .. reportLine;
							else
								reportLines[class] = reportLine;
							end
						end
					end
					if (reportLines[class]) then
						reportLines[class] = string.gsub(reportLines[class], ", $", "");
					end
				end
				if (GFWTable.Count(reportLines) > 0) then
					local _, _, factionAbbrev = string.find(faction, "(.-)_FACTION");
					postedText = 1;
					if (FAS_Config[factionAbbrev]) then
						FAS_Post(itemLink..": "..string.format(FAS_FACTION_REWARDS, getglobal(faction)));
						for class, reportLine in pairs(reportLines) do
							FAS_Post("   "..getglobal(class)..": "..reportLine);
						end
					else
						FAS_Post(itemLink..": "..string.format(FAS_FACTION_REWARDS_COUNT, GFWTable.Count(reportLines), getglobal(faction)));
					end
				end
			end
		end

		local rewardInfo = FAS_TokenRewards[itemID];
		if (rewardInfo) then
			local link = GFWUtils.ItemLink(itemID);
			FAS_Post(link..": "..string.format(ITEM_REQ_REPUTATION, getglobal(rewardInfo.faction), getglobal("FACTION_STANDING_LABEL"..rewardInfo.rep)));
			local reportLines = {};
			for tokenID, rewards in pairs(FAS_TokenInfo) do
				if (GFWTable.KeyOf(rewards, itemID)) then
					local itemText = GFWUtils.ItemLink(tokenID);
					local itemQuality = FAS_TokenQuality[tokenID];
					if (itemText == nil) then
						itemText = FAS_TokenNames[tokenID];
						itemText = FAS_Localized[itemText] or itemText;
						local _, _, _, color = GetItemQualityColor(math.floor(itemQuality));
						itemText = color..itemText..FONT_COLOR_CODE_CLOSE;
					end
					if (rewardInfo == ENSCRIBE) then
						-- ZG enchants take 1 each of any reagent
						itemText = "1 x "..itemText;
					else
						-- other token quests take 1 epic only, or 5 of one green + 5 another green + 2 blue + 1 "special"
						if (itemQuality == 2) then
							itemText = "5 x "..itemText;
						elseif (itemQuality == 3) then
							itemText = "2 x "..itemText;					
						else
							itemText = "1 x "..itemText;
						end
					end
					table.insert(reportLines, itemText);
				end
			end
			table.sort(reportLines);
			for _, line in pairs(reportLines) do
				FAS_Post(line);
			end	
			postedText = 1;
		end
		
		if (not postedText) then
			GFWUtils.Print("Nothing known about "..itemLink..".");
		end
	end
	if (postedText) then
		return;
	end
	-- if we made it down here, there were args we didn't understand... time to remind the user what to do.
	FAS_ChatCommandHandler("help");

end

function FAS_StripColor(text)
	if (string.find(text, "|c%x+|Hitem:[-%d:]+|h%[.-%]|h|r")) then
		return text;
	else
		return string.gsub(text, "|c"..string.rep("%x", 8).."(.-)|r", "%1");
	end
end

function FAS_Post(msg)
	if (not FAS_Config.NoPostToRaid and GetNumRaidMembers() > 0) then
		msg = FAS_StripColor(msg);
		SendChatMessage(msg, "RAID");	
	elseif (not FAS_Config.NoPostToRaid and GetNumPartyMembers() > 0) then
		msg = FAS_StripColor(msg);
		SendChatMessage(msg, "PARTY");	
	else
		GFWUtils.Print(msg);
	end
end

function FAS_CheckMerchant(itemID)
	for merchantIndex = 1, GetMerchantNumItems() do
		local link = GetMerchantItemLink(merchantIndex);
		local _, _, merchantItemID  = string.find(link, "item:(%d+)");
		if (tonumber(merchantItemID) == itemID) then
			return true;
		end
	end
	return false;
end

function FAS_OptionsShow()

	local version = GetAddOnMetadata("GFW_AdSpace", "Version");
	FAS_VersionText:SetText("v. "..version);

	for option, description in pairs(FAS_OptionsText) do
		local button = getglobal("FAS_OptionsButton_"..option);
		local text = getglobal("FAS_OptionsButton_"..option.."Text");
		
		if (button and text) then
			button:SetChecked(FAS_Config["No"..option]);
			text:SetText(description);
		end
	end
	
end

function FAS_OptionsClick()
	local button = this:GetName();
	local option = string.gsub(button, "FAS_OptionsButton_", "");
	FAS_Config["No"..option] = this:GetChecked();
end

-- private, for building localization tables
function FAS_Translate(langCode)

	tempTranslations = {};
	
	local localizedVendorInfo = getglobal("FAS_VendorInfo_"..langCode);
	local localizedVendorLocations = getglobal("FAS_VendorLocations_"..langCode);
	for faction, factionVendorList in pairs(FAS_VendorInfo) do
		for itemID, vendorList in pairs(factionVendorList) do
			local localizedVendors = localizedVendorInfo[faction][itemID];
			if (localizedVendors and type(localizedVendors) == "table") then
				for index, name in pairs(vendorList) do
					local localizedName = localizedVendors[index];
					
					if (localizedName == nil) then break; end
					
					if (localizedName ~= name) then
						if (tempTranslations[name] == nil) then
							tempTranslations[name] = {};
						end
						table.insert(tempTranslations[name], localizedName);
					end
					
					local location = FAS_VendorLocations[name];
					local localizedLocation = localizedVendorLocations[localizedName];
					if (localizedLocation and localizedLocation ~= location) then
						if (tempTranslations[location] == nil) then
							tempTranslations[location] = {};
						end
						table.insert(tempTranslations[location], localizedLocation);
					end
				end
			end
		end
	end
	
	local localizedLibramInfo = getglobal("FAS_LibramInfo_"..langCode);
	for itemID, libramInfo in pairs(FAS_LibramInfo) do
		local localizedInfo = localizedLibramInfo[itemID];
		if (localizedInfo and type(localizedInfo) == "table") then
					
			if (localizedInfo.name ~= libramInfo.name) then
				if (tempTranslations[libramInfo.name] == nil) then
					tempTranslations[libramInfo.name] = {};
				end
				table.insert(tempTranslations[libramInfo.name], localizedInfo.name);
			end
			if (localizedInfo.bonus ~= libramInfo.bonus) then
				if (tempTranslations[libramInfo.bonus] == nil) then
					tempTranslations[libramInfo.bonus] = {};
				end
				table.insert(tempTranslations[libramInfo.bonus], localizedInfo.bonus);
			end
			
			local location = FAS_VendorLocations[libramInfo.name];
			local localizedLocation = localizedVendorLocations[localizedInfo.name];
			if (localizedLocation and localizedLocation ~= location) then
				if (tempTranslations[location] == nil) then
					tempTranslations[location] = {};
				end
				table.insert(tempTranslations[location], localizedLocation);
			end
		end
	end
	
	FAS_Config[langCode] = {};
	for baseString, translations in pairs(tempTranslations) do
		if (table.getn(translations) == 1) then
			FAS_Config[langCode][baseString] = translations[1];
		else
			local mergedTranslations = {}
			for _, translation in pairs(translations) do
				if (GFWTable.KeyOf(mergedTranslations, translation) == nil) then
					table.insert(mergedTranslations, translation);
				end
			end
			if (table.getn(mergedTranslations) == 1) then
				FAS_Config[langCode][baseString] = mergedTranslations[1];
			else
				FAS_Config[langCode][baseString] = mergedTranslations;
			end
		end
	end

end

