Quantcast

Lots of Updates

Xruptor [08-26-16 - 22:32]
Lots of Updates
-Using a new Database for Professions and Currency.  Removing old CRAFT and TOKENS db.
-Added Slash commands using Ace3
-Implemented a new way for Currencies to be saved.  The old format was just too cumbersome, especially consider the other database formats BagSync uses.
-Modified FilterDB so I can use other databases with it.  Hurray!
-Completely redid how Profession recipes are saved.  BagSync used to have a feature that allowed users to link their professions from other characters.  Blizzard pretty much broke that ability and you could only see links that were provided to you from another player.  That's because blizzard made tradeskills temporary on the server.  You couldn't just save it and then use it again in the future.  It was limited to I think to the session.  Once you logged off it became invalid.  SOOOO instead I'm saving the RecipeID of every recipe the user knows in table and using that instead.  Works pretty good! :)
-Redid the Professions window to the new Ace3 format.
-Fixed a few issues with the new config window.
Filename
BagSync.lua
BagSync.toc
locale/deDE.lua
locale/enUS.lua
locale/esES.lua
locale/frFR.lua
locale/koKR.lua
locale/ptBR.lua
locale/ruRU.lua
locale/zhCN.lua
locale/zhTW.lua
modules/blacklist.lua
modules/config.lua
modules/currency.lua
modules/minimap.lua
modules/professions.lua
modules/search.lua
modules/test.lua
modules/tokens.lua
diff --git a/BagSync.lua b/BagSync.lua
index 9183c9f..2a345bc 100644
--- a/BagSync.lua
+++ b/BagSync.lua
@@ -154,14 +154,14 @@ function BSYC:StartupDB()
 	BagSyncGUILD_DB[self.currentRealm] = BagSyncGUILD_DB[self.currentRealm] or {}
 	self.db.guild = BagSyncGUILD_DB

-	BagSyncTOKEN_DB = BagSyncTOKEN_DB or {}
-	BagSyncTOKEN_DB[self.currentRealm] = BagSyncTOKEN_DB[self.currentRealm] or {}
-	self.db.token = BagSyncTOKEN_DB
+	BagSyncCURRENCY_DB = BagSyncCURRENCY_DB or {}
+	BagSyncCURRENCY_DB[self.currentRealm] = BagSyncCURRENCY_DB[self.currentRealm] or {}
+	self.db.currency = BagSyncCURRENCY_DB

-	BagSyncCRAFT_DB = BagSyncCRAFT_DB or {}
-	BagSyncCRAFT_DB[self.currentRealm] = BagSyncCRAFT_DB[self.currentRealm] or {}
-	BagSyncCRAFT_DB[self.currentRealm][self.currentPlayer] = BagSyncCRAFT_DB[self.currentRealm][self.currentPlayer] or {}
-	self.db.profession = BagSyncCRAFT_DB
+	BagSyncPROFESSION_DB = BagSyncPROFESSION_DB or {}
+	BagSyncPROFESSION_DB[self.currentRealm] = BagSyncPROFESSION_DB[self.currentRealm] or {}
+	BagSyncPROFESSION_DB[self.currentRealm][self.currentPlayer] = BagSyncPROFESSION_DB[self.currentRealm][self.currentPlayer] or {}
+	self.db.profession = BagSyncPROFESSION_DB

 	BagSyncBLACKLIST_DB = BagSyncBLACKLIST_DB or {}
 	BagSyncBLACKLIST_DB[self.currentRealm] = BagSyncBLACKLIST_DB[self.currentRealm] or {}
@@ -176,7 +176,7 @@ end
 function BSYC:FixDB(onlyChkGuild)
 	--Removes obsolete character information
 	--Removes obsolete guild information
-	--Removes obsolete characters from tokens db
+	--Removes obsolete characters from currency db
 	--Removes obsolete profession information
 	--removes obsolete blacklist information
 	--Will only check guild related information if the paramater is passed as true
@@ -223,54 +223,46 @@ function BSYC:FixDB(onlyChkGuild)
 		end
 	end

-	--token data and profession data, only do if were not doing a guild check
+	--currency data and profession data, only do if were not doing a guild check
 	--also display fixdb message only if were not doing a guild check
 	if not onlyChkGuild then

-		--fix tokens
-		for realm, rd in pairs(BagSyncTOKEN_DB) do
+		--fix currency
+		for realm, rd in pairs(BagSyncCURRENCY_DB) do
 			if string.find(realm, " ") then
 				--get rid of old realm names with whitespaces, we aren't going to use it anymore
-				BagSyncTOKEN_DB[realm] = nil
+				BagSyncCURRENCY_DB[realm] = nil
 			else
 				--realm
 				if not storeUsers[realm] then
 					--if it's not a realm that ANY users are on then delete it
-					BagSyncTOKEN_DB[realm] = nil
+					BagSyncCURRENCY_DB[realm] = nil
 				else
-					--delete old db information for tokens if it exists
-					if BagSyncTOKEN_DB[realm] and BagSyncTOKEN_DB[realm][1] then BagSyncTOKEN_DB[realm][1] = nil end
-					if BagSyncTOKEN_DB[realm] and BagSyncTOKEN_DB[realm][2] then BagSyncTOKEN_DB[realm][2] = nil end
-
 					for k, v in pairs(rd) do
-						for x, y in pairs(v) do
-							if x ~= "icon" and x ~= "header" then
-								if not storeUsers[realm][x] then
-									--if the user doesn't exist then delete data
-									BagSyncTOKEN_DB[realm][k][x] = nil
-								end
-							end
+						if not storeUsers[realm][k] then
+							--if the user doesn't exist then delete data
+							BagSyncCURRENCY_DB[realm][k] = nil
 						end
 					end
 				end
 			end
 		end
-
+
 		--fix professions
-		for realm, rd in pairs(BagSyncCRAFT_DB) do
+		for realm, rd in pairs(BagSyncPROFESSION_DB) do
 			if string.find(realm, " ") then
 				--get rid of old realm names with whitespaces, we aren't going to use it anymore
-				BagSyncCRAFT_DB[realm] = nil
+				BagSyncPROFESSION_DB[realm] = nil
 			else
 				--realm
 				if not storeUsers[realm] then
 					--if it's not a realm that ANY users are on then delete it
-					BagSyncCRAFT_DB[realm] = nil
+					BagSyncPROFESSION_DB[realm] = nil
 				else
 					for k, v in pairs(rd) do
 						if not storeUsers[realm][k] then
 							--if the user doesn't exist then delete data
-							BagSyncCRAFT_DB[realm][k] = nil
+							BagSyncPROFESSION_DB[realm][k] = nil
 						end
 					end
 				end
@@ -290,7 +282,10 @@ function BSYC:FixDB(onlyChkGuild)
 				end
 			end
 		end
-
+
+		if BagSyncCRAFT_DB then BagSyncCRAFT_DB = nil end --remove old crafting DB
+		if BagSyncTOKEN_DB then BagSyncTOKEN_DB = nil end --remove old tokens db
+
 		self:Print("|cFFFF9900"..L.FixDBComplete.."|r")
 	end
 end
@@ -338,20 +333,26 @@ function BSYC:CleanAuctionsDB()

 end

-function BSYC:FilterDB()
+function BSYC:FilterDB(dbSelect)

 	local xIndex = {}
+	local dbObj = self.db.global
+
+	if dbSelect and dbSelect == 1 then
+		--use BagSyncPROFESSION_DB
+		dbObj = self.db.profession
+	end

 	--add more realm names if necessary based on BNet or Cross Realms
 	if self.options.enableBNetAccountItems then
-		for k, v in pairs(BagSyncDB) do
+		for k, v in pairs(dbObj) do
 			for q, r in pairs(v) do
 				--we do this incase there are multiple characters with same name
 				xIndex[q.."^"..k] = r
 			end
 		end
 	elseif self.options.enableCrossRealmsItems then
-		for k, v in pairs(BagSyncDB) do
+		for k, v in pairs(dbObj) do
 			if k == self.currentRealm or self.crossRealmNames[k] then
 				for q, r in pairs(v) do
 					----we do this incase there are multiple characters with same name
@@ -360,7 +361,7 @@ function BSYC:FilterDB()
 			end
 		end
 	else
-		xIndex = BagSyncDB[self.currentRealm]
+		xIndex = dbObj[self.currentRealm]
 	end

 	return xIndex
@@ -738,15 +739,15 @@ function BSYC:ShowMoneyTooltip()
 end

 ------------------------
---      Tokens        --
+--      Currency      --
 ------------------------

-function BSYC:ScanTokens()
-	--LETS AVOID TOKEN SPAM AS MUCH AS POSSIBLE
-	if self.doTokenUpdate and self.doTokenUpdate > 0 then return end
+function BSYC:ScanCurrency()
+	--LETS AVOID CURRENCY SPAM AS MUCH AS POSSIBLE
+	if self.doCurrencyUpdate and self.doCurrencyUpdate > 0 then return end
 	if IsInBG() or IsInArena() or InCombatLockdown() or UnitAffectingCombat("player") then
 		--avoid (Honor point spam), avoid (arena point spam), if it's world PVP...well then it sucks to be you
-		self.doTokenUpdate = 1
+		self.doCurrencyUpdate = 1
 		BSYC:RegisterEvent("PLAYER_REGEN_ENABLED")
 		return
 	end
@@ -768,14 +769,12 @@ function BSYC:ScanTokens()
 				lastHeader = name
 			end
 			if (not isHeader) then
-				self.db.token[self.currentRealm][name] = self.db.token[self.currentRealm][name] or {}
-				self.db.token[self.currentRealm][name].icon = icon
-				self.db.token[self.currentRealm][name].header = lastHeader
-				self.db.token[self.currentRealm][name][self.currentPlayer] = count
+				self.db.currency[self.currentRealm][self.currentPlayer] = self.db.currency[self.currentRealm][self.currentPlayer] or {}
+				self.db.currency[self.currentRealm][self.currentPlayer][name] = format("%s,%s,%s", count, lastHeader, icon)
 			end
 		end
 	end
-	--we don't want to overwrite tokens, because some characters may have currency that the others dont have
+	--we don't want to overwrite currency, because some characters may have currency that the others dont have
 end

 ------------------------
@@ -838,19 +837,19 @@ function BSYC:GetClassColor(sName, sClass)
 	return tooltipColor(self.options.colors.first, sName)
 end

-function BSYC:AddTokenTooltip(frame, currencyName)
+function BSYC:AddCurrencyTooltip(frame, currencyName)
 	if not BagSyncOpt.enableTooltips then return end
-	if currencyName and self.db.token[self.currentRealm][currencyName] then
+--[[ 	if currencyName and self.db.currency[self.currentRealm][currencyName] then
 		if self.options.enableTooltipSeperator then
 			frame:AddLine(" ")
 		end
-		for charName, count in pairsByKeys(self.db.token[self.currentRealm][currencyName]) do
+		for charName, count in pairsByKeys(self.db.currency[self.currentRealm][currencyName]) do
 			if charName ~= "icon" and charName ~= "header" and count > 0 then
 				frame:AddDoubleLine(charName, count)
 			end
 		end
 		frame:Show()
-	end
+	end ]]
 end

 function BSYC:AddItemToTooltip(frame, link) --workaround
@@ -1017,10 +1016,6 @@ function BSYC:AddItemToTooltip(frame, link) --workaround
 	frame:Show()
 end

---simplified tooltip function, similar to the past HookTooltip that was used before Jan 06, 2011 (commit:a89046f844e24585ab8db60d10f2f168498b9af4)
---Honestly we aren't going to care about throttleing or anything like that anymore.  The lastdisplay array token should take care of that
---Special thanks to Tuller for tooltip hook function
-
 function BSYC:HookTooltip(tooltip)

 	tooltip.isModified = false
@@ -1134,42 +1129,95 @@ function BSYC:HookTooltip(tooltip)
 		if self.isModified then return end
 		self.isModified = true
 		local currencyName = GetCurrencyListInfo(index)
-		BSYC:AddTokenTooltip(self, currencyName)
+		BSYC:AddCurrencyTooltip(self, currencyName)
 	end)
 	hooksecurefunc(tooltip, "SetCurrencyByID", function(self, id)
 		if self.isModified then return end
 		self.isModified = true
 		local currencyName = GetCurrencyInfo(id)
-		BSYC:AddTokenTooltip(self, currencyName)
+		BSYC:AddCurrencyTooltip(self, currencyName)
 	end)
 	hooksecurefunc(tooltip, "SetBackpackToken", function(self, index)
 		if self.isModified then return end
 		self.isModified = true
 		local currencyName = GetBackpackCurrencyInfo(index)
-		BSYC:AddTokenTooltip(self, currencyName)
+		BSYC:AddCurrencyTooltip(self, currencyName)
 	end)
 	-- hooksecurefunc(tooltip, 'SetTradeSkillReagentInfo', function(self, index)
 		-- if self.isModified then return end
 		-- self.isModified = true
 		-- local currencyName = GetTradeSkillReagentInfo(index,1)
-		-- BSYC:AddTokenTooltip(self, currencyName)
+		-- BSYC:AddCurrencyTooltip(self, currencyName)
 	-- end)

 end

 ------------------------------
+--    SLASH COMMAND         --
+------------------------------
+
+function BSYC:ChatCommand(input)
+
+	local parts = { (" "):split(input) }
+	local cmd, args = strlower(parts[1] or ""), table.concat(parts, " ", 2)
+
+	if string.len(cmd) > 0 then
+
+		if cmd == L.SlashSearch then
+			self:GetModule("Search"):StartSearch()
+			return true
+		elseif cmd == L.SlashGold then
+			self:ShowMoneyTooltip()
+			return true
+		elseif cmd == L.SlashCurrency then
+			if BagSync_TokensFrame:IsVisible() then
+				BagSync_TokensFrame:Hide()
+			else
+				BagSync_TokensFrame:Show()
+			end
+			return true
+		elseif cmd == L.SlashProfiles then
+			self:GetModule("Profiles").frame:Show()
+			return true
+		elseif cmd == L.SlashProfessions then
+			self:GetModule("Professions").frame:Show()
+			return true
+		elseif cmd == L.SlashBlacklist then
+			self:GetModule("Blacklist").frame:Show()
+			return true
+		elseif cmd == L.SlashFixDB then
+			self:FixDB()
+			return true
+		elseif cmd == L.SlashConfig then
+			LibStub("AceConfigDialog-3.0"):Open("BagSync")
+			return true
+		else
+			--do an item search, use the full command to search
+			self:GetModule("Search"):StartSearch(input)
+			return true
+		end
+
+	end
+
+	self:Print(L.HelpSearchItemName)
+	self:Print(L.HelpSearchWindow)
+	self:Print(L.HelpGoldTooltip)
+	self:Print(L.HelpCurrencyWindow)
+	self:Print(L.HelpProfilesWindow)
+	self:Print(L.HelpProfessionsWindow)
+	self:Print(L.HelpBlacklistWindow)
+	self:Print(L.HelpFixDB)
+	self:Print(L.HelpConfigWindow )
+
+end
+
+------------------------------
 --    LOGIN HANDLER         --
 ------------------------------

 function BSYC:OnEnable()
-	--NOTE: Using OnEnable() instead of OnInitialize() because not all the SavedVarables are loaded and UnitFullName() will return nil for realm
-
-	BINDING_HEADER_BAGSYNC = "BagSync"
-	BINDING_NAME_BAGSYNCTOGGLESEARCH = L.ToggleSearch
-	BINDING_NAME_BAGSYNCTOGGLETOKENS = L.ToggleTokens
-	BINDING_NAME_BAGSYNCTOGGLEPROFILES = L.ToggleProfiles
-	BINDING_NAME_BAGSYNCTOGGLECRAFTS = L.ToggleProfessions
-	BINDING_NAME_BAGSYNCTOGGLEBLACKLIST = L.ToggleBlacklist
+	--NOTE: Using OnEnable() instead of OnInitialize() because not all the SavedVarables fully loaded
+	--also one of the major issues is that UnitFullName() will return nil for the short named realm

 	local ver = GetAddOnMetadata("BagSync","Version") or 0

@@ -1179,6 +1227,9 @@ function BSYC:OnEnable()
 	self.playerClass = select(2, UnitClass("player"))
 	self.playerFaction = UnitFactionGroup("player")

+	--strip realm of whitespace and special characters, alternative to UnitFullName, since UnitFullName does not work on OnInitialize()
+	--BSYC:Debug(gsub(GetRealmName(),"[%s%-]",""))
+
 	local autoCompleteRealms = GetAutoCompleteRealms() or { self.currentRealm }

 	self.crossRealmNames = {}
@@ -1227,8 +1278,8 @@ function BSYC:OnEnable()
 	self:SaveEquipment()

 	--force token scan
-	hooksecurefunc("BackpackTokenFrame_Update", function(self) BSYC:ScanTokens() end)
-	self:ScanTokens()
+	hooksecurefunc("BackpackTokenFrame_Update", function(self) BSYC:ScanCurrency() end)
+	self:ScanCurrency()

 	--clean up old auctions
 	self:CleanAuctionsDB()
@@ -1258,7 +1309,7 @@ function BSYC:OnEnable()

 	--currency
 	self:RegisterEvent("CURRENCY_DISPLAY_UPDATE")
-
+
 	--void storage
 	self:RegisterEvent("VOID_STORAGE_OPEN")
 	self:RegisterEvent("VOID_STORAGE_CLOSE")
@@ -1268,69 +1319,16 @@ function BSYC:OnEnable()

 	--this will be used for getting the tradeskill link
 	self:RegisterEvent("TRADE_SKILL_SHOW")
+	self:RegisterEvent("TRADE_SKILL_DATA_SOURCE_CHANGED")

 	--hook the tooltips
 	self:HookTooltip(GameTooltip)
 	self:HookTooltip(ItemRefTooltip)

-	SLASH_BAGSYNC1 = "/bagsync"
-	SLASH_BAGSYNC2 = "/bgs"
-	SlashCmdList["BAGSYNC"] = function(msg)
-
-		local a,b,c=strfind(msg, "(%S+)"); --contiguous string of non-space characters
-
-		if a then
-			if c and c:lower() == L.SlashSearch then
-				self:GetModule("Search"):StartSearch()
-				return true
-			elseif c and c:lower() == L.SlashGold then
-				self:ShowMoneyTooltip()
-				return true
-			elseif c and c:lower() == L.SlashTokens then
-				if BagSync_TokensFrame:IsVisible() then
-					BagSync_TokensFrame:Hide()
-				else
-					BagSync_TokensFrame:Show()
-				end
-				return true
-			elseif c and c:lower() == L.SlashProfiles then
-				self:GetModule("Profiles").frame:Show()
-				return true
-			elseif c and c:lower() == L.SlashProfessions then
-				if BagSync_CraftsFrame:IsVisible() then
-					BagSync_CraftsFrame:Hide()
-				else
-					BagSync_CraftsFrame:Show()
-				end
-				return true
-			elseif c and c:lower() == L.SlashBlacklist then
-				self:GetModule("Blacklist").frame:Show()
-				return true
-			elseif c and c:lower() == L.SlashFixDB then
-				self:FixDB()
-				return true
-			elseif c and c:lower() == L.SlashConfig then
-				LibStub("AceConfigDialog-3.0"):Open("BagSync")
-				return true
-			elseif c and c:lower() ~= "" then
-				--do an item search
-				self:GetModule("Search"):StartSearch(msg)
-				return true
-			end
-		end
-
-		self:Print(L.HelpSearchItemName)
-		self:Print(L.HelpSearchWindow)
-		self:Print(L.HelpGoldTooltip)
-		self:Print(L.HelpTokensWindow)
-		self:Print(L.HelpProfilesWindow)
-		self:Print(L.HelpProfessionsWindow)
-		self:Print(L.HelpBlacklistWindow)
-		self:Print(L.HelpFixDB)
-		self:Print(L.HelpConfigWindow )
+	--register the slash command
+	self:RegisterChatCommand("bgs", "ChatCommand")
+	self:RegisterChatCommand("bagsync", "ChatCommand")

-	end
-
 	self:Print("[v|cFFDF2B2B"..ver.."|r] /bgs, /bagsync")
 end

@@ -1340,16 +1338,16 @@ end

 function BSYC:CURRENCY_DISPLAY_UPDATE()
 	if IsInBG() or IsInArena() or InCombatLockdown() or UnitAffectingCombat("player") then return end
-	self.doTokenUpdate = 0
-	self:ScanTokens()
+	self.doCurrencyUpdate = 0
+	self:ScanCurrency()
 end

 function BSYC:PLAYER_REGEN_ENABLED()
 	if IsInBG() or IsInArena() or InCombatLockdown() or UnitAffectingCombat("player") then return end
 	self:UnregisterEvent("PLAYER_REGEN_ENABLED")
 	--were out of an arena or battleground scan the points
-	self.doTokenUpdate = 0
-	self:ScanTokens()
+	self.doCurrencyUpdate = 0
+	self:ScanCurrency()
 end

 function BSYC:GUILD_ROSTER_UPDATE()
@@ -1535,35 +1533,31 @@ end
 function BSYC:doRegularTradeSkill(numIndex, dbPlayer, dbIdx)
 	local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(numIndex)
 	if name and skillLevel then
-		dbPlayer[dbIdx] = format("%s,%s", name, skillLevel)
+		--don't overwrite recipe list
+		if dbPlayer[dbIdx] then
+			local name, level, list = strsplit(",", dbPlayer[dbIdx])
+			if list then
+				--only record list again if we even have a list to work with
+				dbPlayer[dbIdx] = format("%s,%s,%s", name, skillLevel, list)
+			else
+				dbPlayer[dbIdx] = format("%s,%s", name, skillLevel)
+			end
+		else
+			dbPlayer[dbIdx] = format("%s,%s", name, skillLevel)
+		end
 	end
 end

 function BSYC:TRADE_SKILL_SHOW()
 	--IsTradeSkillLinked() returns true only if trade window was opened from chat link (meaning another player)
-	if (not C_TradeSkillUI.IsTradeSkillLinked()) then
+	if (not _G.C_TradeSkillUI.IsTradeSkillLinked()) then

-		local tradename = C_TradeSkillUI.GetTradeSkillLine()
 		local prof1, prof2, archaeology, fishing, cooking, firstAid = GetProfessions()

-		local iconProf1 = prof1 and select(2, GetProfessionInfo(prof1))
-		local iconProf2 = prof2 and select(2, GetProfessionInfo(prof2))
-
-		--list of tradeskills with NO skill link but can be used as primaries (ex. a person with two gathering skills)
-		local noLinkTS = {
-			["Interface\\Icons\\Trade_Herbalism"] = true, --this is Herbalism
-			["Interface\\Icons\\INV_Misc_Pelt_Wolf_01"] = true, --this is Skinning
-			["Interface\\Icons\\INV_Pick_02"] = true, --this is Mining
-		}
-
 		local dbPlayer = self.db.profession[self.currentRealm][self.currentPlayer]

 		--prof1
-		if prof1 and (GetProfessionInfo(prof1) == tradename) and C_TradeSkillUI.GetTradeSkillListLink() then
-			local skill = select(3, GetProfessionInfo(prof1))
-			dbPlayer[1] = { tradename, C_TradeSkillUI.GetTradeSkillListLink(), skill }
-		elseif prof1 and iconProf1 and noLinkTS[iconProf1] then
-			--only store if it's herbalism, skinning, or mining
+		if prof1 then
 			self:doRegularTradeSkill(prof1, dbPlayer, 1)
 		elseif not prof1 and dbPlayer[1] then
 			--they removed a profession
@@ -1571,11 +1565,7 @@ function BSYC:TRADE_SKILL_SHOW()
 		end

 		--prof2
-		if prof2 and (GetProfessionInfo(prof2) == tradename) and C_TradeSkillUI.GetTradeSkillListLink() then
-			local skill = select(3, GetProfessionInfo(prof2))
-			dbPlayer[2] = { tradename, C_TradeSkillUI.GetTradeSkillListLink(), skill }
-		elseif prof2 and iconProf2 and noLinkTS[iconProf2] then
-			--only store if it's herbalism, skinning, or mining
+		if prof2 then
 			self:doRegularTradeSkill(prof2, dbPlayer, 2)
 		elseif not prof2 and dbPlayer[2] then
 			--they removed a profession
@@ -1599,22 +1589,92 @@ function BSYC:TRADE_SKILL_SHOW()
 		end

 		--cooking
-		if cooking and (GetProfessionInfo(cooking) == tradename) and C_TradeSkillUI.GetTradeSkillListLink() then
-			local skill = select(3, GetProfessionInfo(cooking))
-			dbPlayer[5] = { tradename, C_TradeSkillUI.GetTradeSkillListLink(), skill }
+		if cooking then
+			self:doRegularTradeSkill(cooking, dbPlayer, 5)
 		elseif not cooking and dbPlayer[5] then
 			--they removed a profession
 			dbPlayer[5] = nil
 		end

 		--firstAid
-		if firstAid and (GetProfessionInfo(firstAid) == tradename) and C_TradeSkillUI.GetTradeSkillListLink() then
-			local skill = select(3, GetProfessionInfo(firstAid))
-			dbPlayer[6] = { tradename, C_TradeSkillUI.GetTradeSkillListLink(), skill }
+		if firstAid then
+			self:doRegularTradeSkill(firstAid, dbPlayer, 6)
 		elseif not firstAid and dbPlayer[6] then
 			--they removed a profession
 			dbPlayer[6] = nil
 		end
+	end
+
+	--grab the player recipes but only scan once, TRADE_SKILL_LIST_UPDATE is triggered multiple times for some reason
+	self:RegisterEvent("TRADE_SKILL_LIST_UPDATE")
+end
+
+--this function pretty much only grabs the recipelist for the CURRENT opened profession, not all the profession info which TRADE_SKILL_SHOW does.
+--this is because you can't open up herbalism, mining, etc...
+function BSYC:TRADE_SKILL_LIST_UPDATE()
+
+	if (not _G.C_TradeSkillUI.IsTradeSkillLinked()) then
+
+		local getIndex = 0
+		local getProfIndex = 0
+		local prof1, prof2, archaeology, fishing, cooking, firstAid = GetProfessions()
+		local tradeid, tradename = _G.C_TradeSkillUI.GetTradeSkillLine()
+
+		if not tradename then return end --don't do anything if no tradeskill name
+
+		local dbPlayer = self.db.profession[self.currentRealm][self.currentPlayer]
+
+		--prof1
+		if prof1 and GetProfessionInfo(prof1) == tradename then
+			getIndex = 1
+			getProfIndex = prof1
+		elseif prof2 and GetProfessionInfo(prof2) == tradename then
+			getIndex = 2
+			getProfIndex = prof2
+		elseif archaeology and GetProfessionInfo(archaeology) == tradename then
+			getIndex = 3
+			getProfIndex = archaeology
+		elseif fishing and GetProfessionInfo(fishing) == tradename then
+			getIndex = 4
+			getProfIndex = fishing
+		elseif cooking and GetProfessionInfo(cooking) == tradename then
+			getIndex = 5
+			getProfIndex = cooking
+		elseif firstAid and GetProfessionInfo(firstAid) == tradename then
+			getIndex = 6
+			getProfIndex = firstAid
+		end
+
+		--don't do anything if we have nothing to work with
+		if getIndex < 1 then return end
+
+		local name, icon, skillLevel = GetProfessionInfo(getProfIndex)
+
+		local recipeString = ""
+		local recipeIDs = _G.C_TradeSkillUI.GetAllRecipeIDs()
+		local recipeInfo = {}
+
+		for idx = 1, #recipeIDs do
+			recipeInfo = _G.C_TradeSkillUI.GetRecipeInfo(recipeIDs[idx])
+
+			if recipeInfo and recipeInfo.learned and recipeInfo.craftable then
+				recipeString = recipeString.."|"..recipeInfo.recipeID
+			end
+		end
+
+		--only record if we have something to work with
+		if name and skillLevel and string.len(recipeString) > 0 then
+			recipeString = strsub(recipeString, string.len("|") + 1) --remove the delimiter in front of recipeID list
+			dbPlayer[getIndex] = format("%s,%s,%s", name, skillLevel, recipeString)
+		end

 	end
+
+	--unregister for next time the tradeskill window is opened
+	self:UnregisterEvent("TRADE_SKILL_LIST_UPDATE")
 end
+
+--if they have the tradeskill window opened and then click on another professions it keeps the window opened and thus TRADE_SKILL_LIST_UPDATE never gets fired
+function BSYC:TRADE_SKILL_DATA_SOURCE_CHANGED()
+	self:RegisterEvent("TRADE_SKILL_LIST_UPDATE")
+end
\ No newline at end of file
diff --git a/BagSync.toc b/BagSync.toc
index c96ed40..72da643 100644
--- a/BagSync.toc
+++ b/BagSync.toc
@@ -2,9 +2,9 @@
 ## Title: BagSync
 ## Notes: BagSync tracks your characters items and displays it within tooltips.
 ## Author: Xruptor
-## Version: 9.2
+## Version: 10.0
 ## OptionalDeps: tekDebug
-## SavedVariables: BagSyncDB, BagSyncOpt, BagSyncGUILD_DB, BagSyncTOKEN_DB, BagSyncCRAFT_DB, BagSyncBLACKLIST_DB, BagSync_REALMKEY
+## SavedVariables: BagSyncDB, BagSyncOpt, BagSyncGUILD_DB, BagSyncCURRENCY_DB, BagSyncPROFESSION_DB, BagSyncBLACKLIST_DB, BagSync_REALMKEY

 libs\LibStub\LibStub.lua
 libs\CallbackHandler-1.0\CallbackHandler-1.0.xml
@@ -34,7 +34,7 @@ BagSync.lua

 modules\minimap.lua
 modules\search.lua
-modules\tokens.lua
+modules\currency.lua
 modules\professions.lua
 modules\blacklist.lua
 modules\profiles.lua
diff --git a/locale/deDE.lua b/locale/deDE.lua
index f46e3c9..0990297 100644
--- a/locale/deDE.lua
+++ b/locale/deDE.lua
@@ -2,6 +2,8 @@
 local L = LibStub("AceLocale-3.0"):NewLocale("BagSync", "deDE")
 if not L then return end

+--PLEASE LOOK AT enUS.lua for a complete localization list
+
 --special thanks to GrimPala from wowinterface.com

 L.TooltipBag = "Taschen: %d"
@@ -14,7 +16,6 @@ L.TooltipReagent = "Materiallager: %d"
 L.TooltipAuction = "AH: %d"
 L.Search = "Suche"
 L.TooltipTotal = "Gesamt:"
-L.Tokens = "Abzeichen"
 L.Profiles = "Profile"
 L.Professions = "Berufe"
 L.Blacklist = "Blacklist"
@@ -26,7 +27,6 @@ L.DeleteWarning = "Wähle ein Profil zum löschen aus.\nINFO: Dies ist nicht umk
 L.Delete = "Löschen"
 L.Confirm = "Bestätigen"
 L.ToggleSearch = "Öffne/Schließe Suche"
-L.ToggleTokens = "Öffne/Schließe Abzeichen"
 L.ToggleProfiles = "Öffne/Schließe Profile"
 L.FixDBComplete = "Die Funktion FixDB wurde ausgeführt! Die Datenbank wurde optimiert!"
 L.ON = "An"
@@ -40,7 +40,6 @@ L.RemoveItemID = "Entferne ItemID"
 L.HelpSearchItemName = "/bgs [itemname] - Nach einem Item suchen"
 L.HelpSearchWindow = "/bgs search - Öffnet das Suchfenster"
 L.HelpGoldTooltip = "/bgs gold - Zeigt einen Tooltip mit dem Gold eines jeden Charakters."
-L.HelpTokensWindow = "/bgs tokens - Öffnet das Abzeichenfenster."
 L.HelpProfilesWindow = "/bgs profiles - Öffnet das Profilfenster."
 L.HelpFixDB = "/bgs fixdb - Führt eine Reparatur der Datenbank (FixDB) aus."
 L.HelpConfigWindow = "/bgs config - Öffnet die Einstellungen für BagSync"
diff --git a/locale/enUS.lua b/locale/enUS.lua
index 7fa7639..86c16bc 100644
--- a/locale/enUS.lua
+++ b/locale/enUS.lua
@@ -14,9 +14,9 @@ L.TooltipTotal = "Total:"
 L.TooltipDelimiter = ", "
 L.Search = "Search"
 L.Refresh = "Refresh"
-L.Tokens = "Tokens"
 L.Profiles = "Profiles"
 L.Professions = "Professions"
+L.Currency = "Currency"
 L.Blacklist = "Blacklist"
 L.Gold = "Gold"
 L.Close = "Close"
@@ -26,7 +26,7 @@ L.DeleteWarning = "Select a profile to delete.\nNOTE: This is irreversible!"
 L.Delete = "Delete"
 L.Confirm = "Confirm"
 L.ToggleSearch = "Toggle Search"
-L.ToggleTokens = "Toggle Tokens"
+L.ToggleCurrency = "Toggle Currency"
 L.ToggleProfiles = "Toggle Profiles"
 L.ToggleProfessions = "Toggle Professions"
 L.ToggleBlacklist = "Toggle Blacklist"
@@ -35,12 +35,11 @@ L.ON = "ON"
 L.OFF = "OFF"
 L.LeftClickSearch = "Left Click = Search Window"
 L.RightClickBagSyncMenu = "Right Click = BagSync Menu"
-L.LeftClickViewTradeSkill = "Left Click = Link to view tradeskill."
-L.RightClickInsertTradeskill = "Right Click = Insert tradeskill link."
+L.ProfessionLeftClick = "Left Click = Open Profession Recipe List"
 L.ClickViewProfession = "Click to view profession: "
 L.ClickHere = "Click Here"
 L.ErrorUserNotFound = "BagSync: Error user not found!"
-L.EnterItemID = "Please enter an itemid. (Use Wowhead.com)"
+L.EnterItemID = "Please enter an ItemID. (Use http://Wowhead.com/)"
 L.AddItemID = "Add ItemID"
 L.RemoveItemID = "Remove ItemID"
 L.ItemIDNotFound = "[%d] ItemID not found.  Try again!"
@@ -48,12 +47,13 @@ L.ItemIDNotValid = "[%d] ItemID not valid ItemID or the server didn't respond.
 L.ItemIDRemoved = "[%d] ItemID Removed"
 L.ItemIDAdded = "[%d] ItemID Added"
 L.ItemIDExist = "[%d] ItemID already in database."
+L.ProfessionsFailedRequest = "[%d] Server Request Failed."
 -- ----THESE ARE FOR SLASH COMMANDS
 L.SlashItemName = "[itemname]"
 L.SlashSearch = "search"
 L.SlashGold = "gold"
 L.SlashConfig = "config"
-L.SlashTokens = "tokens"
+L.SlashCurrency = "currency"
 L.SlashFixDB = "fixdb"
 L.SlashProfiles = "profiles"
 L.SlashProfessions = "professions"
@@ -62,7 +62,7 @@ L.SlashBlacklist = "blacklist"
 L.HelpSearchItemName = "/bgs [itemname] - Does a quick search for an item"
 L.HelpSearchWindow = "/bgs search - Opens the search window"
 L.HelpGoldTooltip = "/bgs gold - Displays a tooltip with the amount of gold on each character."
-L.HelpTokensWindow = "/bgs tokens - Opens the tokens/currency window."
+L.HelpCurrencyWindow = "/bgs currency - Opens the currency window."
 L.HelpProfilesWindow = "/bgs profiles - Opens the profiles window."
 L.HelpFixDB = "/bgs fixdb - Runs the database fix (FixDB) on BagSync."
 L.HelpConfigWindow = "/bgs config - Opens the BagSync Config Window"
diff --git a/locale/esES.lua b/locale/esES.lua
index c9a2ed4..292039d 100644
--- a/locale/esES.lua
+++ b/locale/esES.lua
@@ -2,6 +2,8 @@
 local L = LibStub("AceLocale-3.0"):NewLocale("BagSync", "esES")
 if not L then return end

+--PLEASE LOOK AT enUS.lua for a complete localization list
+
 --special thanks to annthizze at Curse for the esES translations!

 L.TooltipBag = "Bolsas: %d"
@@ -14,7 +16,6 @@ L.TooltipReagent = "Reagentes: %d"
 L.TooltipAuction = "Subasta: %d"
 L.Search = "Buscar"
 L.TooltipTotal = "Total:"
-L.Tokens = "Fichas"
 L.Profiles = "Perfiles"
 L.Professions = "Profesiones"
 L.Blacklist = "Lista negra"
@@ -22,11 +23,10 @@ L.Gold = "Oro"
 L.Close = "Cerrar"
 L.FixDB = "Reparar BD"
 L.Config = "Configuración"
-L.DeleteWarning = "Seleccione el perfil a eliminar,\nNOTE: no se puede volver atrás"
+L.DeleteWarning = "Seleccione el perfil a eliminar,\nNOTE: no podrá volver atrás"
 L.Delete = "Eliminar"
 L.Confirm = "Confirmar"
 L.ToggleSearch = "Conmutar Búsqueda"
-L.ToggleTokens = "Conmutar Fichas"
 L.ToggleProfiles = "Conmutar Perfiles"
 L.ToggleProfessions = "Conmutar Profesiones"
 L.ToggleBlacklist = "Conmutar Lista negra"
@@ -35,18 +35,15 @@ L.ON = "Encender"
 L.OFF = "Apagar"
 L.LeftClickSearch = "Botón izquierdo = cuadro de búsqueda"
 L.RightClickBagSyncMenu = "Botón derecho = Menú"
-L.LeftClickViewTradeSkill = "Botón izquierdo = Enlace para visualizar profesiones"
-L.RightClickInsertTradeskill = "Botón derecho = Inserta el enlace de profesiones"
 L.ClickViewProfession = "Pincha para ver profesiones"
 L.ClickHere = "Pincha aquí"
 L.ErrorUserNotFound = "BagSync error: ¡usuario no encontrado!"
-L.EnterItemID = "Por favor, introduzca una ID de objeto"
+L.EnterItemID = "Por favor, introduzca una ID de objeto. (Use http://Wowhead.com/)"
 L.AddItemID = "Añadir ID de objeto"
 L.RemoveItemID = "Eliminar ID de objeto"
 L.SlashItemName = "[nombredeobjeto]"
 L.SlashSearch = "buscar"
 L.SlashGold = "oro"
-L.SlashTokens = "fichas"
 L.SlashFixDB = "repararbd"
 L.SlashProfiles = "perfiles"
 L.SlashProfessions = "profesiones"
@@ -54,22 +51,36 @@ L.SlashBlacklist = "listanegra"
 L.HelpSearchItemName = "/bgs [nombredeobjeto] - Realiza la búsqueda de un objeto."
 L.HelpSearchWindow = "/bgs buscar - Abre el cuado de búsqueda."
 L.HelpGoldTooltip = "/bgs oro - Muestra un cuadro de diálogo con el oro de tus personajes."
-L.HelpTokensWindow = "/bgs fichas - Abre una ventana con tus fichas/monedas."
 L.HelpProfilesWindow = "/bgs perfiles - Abre la ventana de perfiles."
 L.HelpFixDB = "/bgs repararbd - Inicia la reparación de la base de datos (reparar BD) de BagSync."
 L.HelpConfigWindow = "/bgs config - Abre la ventana de configuración de BagSync."
 L.HelpProfessionsWindow = "/bgs profesiones - Abre la ventana de profesiones."
 L.HelpBlacklistWindow = "/bgs listanegra - Abre la ventana con la lista negra."
-L.DisplayTotal = "Mostrar [Total] en los cuadros de diálogo y mostrar el oro."
-L.DisplayGuildName = "Mostrar [nombre hermandad] en los cuadros de diálogo."
-L.DisplayGuildBank = "Activar objetos del banco de hermandad."
-L.DisplayMailbox = "Activar objetos del correo."
-L.DisplayAuctionHouse = "Activar objetos de la casa de subastas."
+L.DisplayTotal = "Mostrar la cantidad [Total]."
+L.DisplayGuildName = "Mostrar [nombre de hermandad] para objetos del banco de hermandad."
+L.DisplayGuildBank = "Mostrar objetos del banco de hermandad."
+L.DisplayMailbox = "Mostrar objetos del correo."
+L.DisplayAuctionHouse = "Mostrar objetos de la casa de subastas."
 L.DisplayMinimap = "Mostrar el botón de BagSync en el minimapa."
 L.DisplayFaction = "Mostrar los objetos de ambas fracciones."
 L.DisplayClassColor = "Mostrar los colores de clase para los personajes."
-L.DisplayTooltipOnlySearch = "Mostrar las modificaciones de los cuadros de diálogo sólo en la ventana de búsqueda de BagSync."
-L.EnableBagSyncTooltip = "Activar los cuadros de diálogo de BagSync"
-L.DisplayLineSeperator = "Activar un separador de línea encima del cuadro de diálogo de BagSync"
-L.DisplayCrossRealm = "Activar objetos de personaje entre reinos."
-L.DisplayBNET = "Activar objetos de personajes de la cuenta de Battle.net actual|cFFDF2B2B(No recomendado)|r."
+L.DisplayTooltipOnlySearch = "Mostrar descripcion de BagSync SÓLO en la ventana de búsqueda."
+L.EnableBagSyncTooltip = "Activar Bagsync en las descripciones"
+L.DisplayLineSeperator = "Mostrar un separador de línea vacío."
+L.DisplayCrossRealm = "Mostrar objetos de personaje entre reinos."
+L.DisplayBNET = "Mostrar personajes de la cuenta de Battle.net |cFFDF2B2B(No recomendado)|r."
+L.ColorPrimary = "Color primario de BagSync en las descripciones."
+L.ColorSecondary = "Color secundario de BagSync en las descripciones."
+L.ColorTotal = "Color para mostar [Total] en la descripción de BagSync."
+L.ColorGuild = "Color para mostar [Guild] en la descripción de BagSync."
+L.ColorCrossRealm = "Color para mostar [entrereinos] en la descripción de BagSync."
+L.ColorBNET = "Color para mostar [Battle.Net] en la descripción de BagSync."
+L.ConfigHeader = "Ajustes de varias opciones de BagSync."
+L.ConfigDisplay = "Mostrar"
+L.ConfigTooltipHeader = "Ajustes de como mostrar la información de BagSync en la descrición"
+L.ConfigColor = "Color"
+L.ConfigColorHeader = "Ajustes de color de la información de BagSync en la descrición"
+L.ConfigMain = "Pincipal"
+L.ConfigMainHeader = "Configuración principal de BagSync."
+L.WarningItemSearch = "¡AVISO: %d objetos no se buscaron!\n\nBagSync esta esperando la respuesta del servidor/cache.\n\nPulse el boton de búsqueda para intentarlo de nuevo."
+L.WarningUpdatedDB = "¡Base de datos actualizada con su última versión!. ¡Necesitarás analizar tus personajes de nuevo!|r"
diff --git a/locale/frFR.lua b/locale/frFR.lua
index 077f13d..9f3c8c3 100644
--- a/locale/frFR.lua
+++ b/locale/frFR.lua
@@ -2,6 +2,8 @@
 local L = LibStub("AceLocale-3.0"):NewLocale("BagSync", "frFR")
 if not L then return end

+--PLEASE LOOK AT enUS.lua for a complete localization list
+
 --Really wish someone would do the french translation

 L.TooltipBag = "Sacs: %d"
diff --git a/locale/koKR.lua b/locale/koKR.lua
index 9a5f7cc..da1a300 100644
--- a/locale/koKR.lua
+++ b/locale/koKR.lua
@@ -2,6 +2,8 @@
 local L = LibStub("AceLocale-3.0"):NewLocale("BagSync", "koKR")
 if not L then return end

+--PLEASE LOOK AT enUS.lua for a complete localization list
+
 L.TooltipBag = "가방: %d"
 L.TooltipBank = "은행: %d"
 L.TooltipEquip = "착용중: %d"
@@ -12,7 +14,6 @@ L.TooltipReagent = "재료은행: %d"
 L.TooltipAuction = "경매장: %d"
 L.Search = "검색"
 L.TooltipTotal = "총:"
-L.Tokens = "문장"
 L.Profiles = "프로필"
 L.Professions = "전문기술"
 L.Blacklist = "차단목록"
@@ -23,15 +24,12 @@ L.DeleteWarning = "삭제할 프로필을 선택하세요.\nNOTE: 되돌릴수
 L.Delete = "삭제"
 L.Confirm = "확인"
 L.ToggleSearch = "검색 토글"
-L.ToggleTokens = "문장 토글"
 L.ToggleProfiles = "프로필 토글"
 L.ToggleProfessions = "전문기술 토글"
 L.ToggleBlacklist = "차단목록 토글"
 L.FixDBComplete = "BagSync에 FixDB가 실행되었습니다! 데이터베이스가 최적화됩니다!"
 L.LeftClickSearch = "클릭 = 검색창"
 L.RightClickBagSyncMenu = "오른쪽 클릭 = BagSync 메뉴"
-L.LeftClickViewTradeSkill = "클릭 = 전문기술 링크하기"
-L.RightClickInsertTradeskill = "오른쪽 클릭 = 전문기술 링크 삽입"
 L.ClickViewProfession = "클릭하여 볼 전문기술: "
 L.ClickHere = "클릭하세요"
 L.ErrorUserNotFound = "BagSync: 오류 사용자를 찾을 수 없음!"
@@ -42,7 +40,6 @@ L.SlashItemName = "[아이템이름]"
 L.HelpSearchItemName = "/bgs [아이템이름] - 빠른 아이템 찾기"
 L.HelpSearchWindow = "/bgs search - 검색창 열기"
 L.HelpGoldTooltip = "/bgs gold - 툴팁에 각 케릭터의 골드량을 표시합니다."
-L.HelpTokensWindow = "/bgs tokens - 문장/화폐창을 엽니다"
 L.HelpProfilesWindow = "/bgs profiles - 프로필 창을 엽니다."
 L.HelpFixDB = "/bgs fixdb - BagSync에 데이터베이스 개선 (FixDB) 실행"
 L.HelpConfigWindow = "/bgs config - BagSync 설정 창 열기"
diff --git a/locale/ptBR.lua b/locale/ptBR.lua
index b89b341..8f7c1ff 100644
--- a/locale/ptBR.lua
+++ b/locale/ptBR.lua
@@ -2,6 +2,8 @@
 local L = LibStub("AceLocale-3.0"):NewLocale("BagSync", "ptBR")
 if not L then return end

+--PLEASE LOOK AT enUS.lua for a complete localization list
+
 --special thanks to kubito from wowinterface.com

 L.TooltipBag = "Bolsa: %d"
@@ -14,7 +16,6 @@ L.TooltipReagent = "Banco de Reagentes: %d"
 L.TooltipAuction = "Casa de Leilão: %d"
 L.Search = "Pesquisar"
 L.TooltipTotal = "Total"
-L.Tokens = "Fichas"
 L.Profiles = "Perfis"
 L.Professions = "Profissões"
 L.Blacklist = "Lista Negra"
@@ -25,7 +26,6 @@ L.DeleteWarning = "Selecione o perfil para deletar.\nOBS: Isto é irreversível"
 L.Delete = "Deletar"
 L.Confirm = "Confirmar"
 L.ToggleSearch = "Ativar Pesquisa"
-L.ToggleTokens = "Ativar Fichas"
 L.ToggleProfiles = "Ativar Perfis"
 L.ToggleProfessions = "Ativar Profissões"
 L.ToggleBlacklist = "Ativar Lista Negra"
@@ -34,8 +34,6 @@ L.ON = "Ligar"
 L.OFF = "Desligar"
 L.LeftClickSearch = "Botão Esquerdo = Procurar na Janela"
 L.RightClickBagSyncMenu = "Botão Direito = Opções do BagSync"
-L.LeftClickViewTradeSkill = "Botão Esquerdo = Link para vizualizar profissão"
-L.RightClickInsertTradeskill = "Botão Direito = Inserir link de profissão"
 L.ClickViewProfession = "Clicar para vizualizar profissões"
 L.ClickHere = "Clique Aqui"
 L.ErrorUserNotFound = "BagSync: Erro, usuário não achado"
@@ -46,7 +44,6 @@ L.SlashItemName = "itemnome"
 L.SlashSearch = "pesquisar"
 L.SlashGold = "ouro"
 L.SlashConfig = "configuracao"
-L.SlashTokens = "ficha"
 L.SlashFixDB = "fixdb"
 L.SlashProfiles = "perfis"
 L.SlashProfessions = "profissoes"
@@ -54,7 +51,6 @@ L.SlashBlacklist = "listanegra"
 L.HelpSearchItemName = "/bgs [itemnome] - Faz uma rápida pesquisa para um item"
 L.HelpSearchWindow = "/bgs pesquisar - Abre a janela de pesquisar"
 L.HelpGoldTooltip = "/bgs ouro - Exibe em dica com a quantidade de ouro em cada personagem."
-L.HelpTokensWindow = "/bgs ficha - Abre uma janela com a quantidade de fichas/moedas."
 L.HelpProfilesWindow = "/bgs perfis - Abre uma janela de perfis."
 L.HelpFixDB = "/bgs fixdb - Executa a correção de banco de dados (FixDB) no BagSync."
 L.HelpConfigWindow = "/bgs configuracao - Abre uma janela de configuração do BagSync"
diff --git a/locale/ruRU.lua b/locale/ruRU.lua
index 806b48c..1e42d77 100644
--- a/locale/ruRU.lua
+++ b/locale/ruRU.lua
@@ -2,6 +2,8 @@
 local L = LibStub("AceLocale-3.0"):NewLocale("BagSync", "ruRU")
 if not L then return end

+--PLEASE LOOK AT enUS.lua for a complete localization list
+
 --special thanks to senryo

 L.TooltipBag = "В сумке: %d"
@@ -13,7 +15,6 @@ L.TooltipReagent = "Банк материалов: %d"
 L.TooltipAuction = "Аукцион: %d"
 L.Search = "Поиск"
 L.TooltipTotal = "Всего:"
-L.Tokens = "Токены"
 L.Profiles = "Профили"
 L.Professions = "Профессии"
 L.Blacklist = "Черный список"
@@ -33,7 +34,6 @@ L.RemoveItemID = "Удалить ItemID"
 L.HelpSearchItemName = "/bgs [имя предмета] - Быстрый поиск предмета."
 L.HelpSearchWindow = "/bgs search - Открыть окно поиска."
 L.HelpGoldTooltip = "/bgs gold - Показать количество золота на всех персонажах."
-L.HelpTokensWindow = "/bgs tokens - Открыть окно токенов/валюты."
 L.HelpProfilesWindow = "/bgs profiles - Открыть окно профилей."
 L.HelpFixDB = "/bgs fixdb - Запустить исправление БД в BagSync."
 L.HelpConfigWindow = "/bgs config - Открыть окно опций BagSync."
diff --git a/locale/zhCN.lua b/locale/zhCN.lua
index eb72cf0..a5a7a20 100644
--- a/locale/zhCN.lua
+++ b/locale/zhCN.lua
@@ -2,6 +2,8 @@
 local L = LibStub("AceLocale-3.0"):NewLocale("BagSync", "zhCN")
 if not L then return end

+--PLEASE LOOK AT enUS.lua for a complete localization list
+
 --special thanks to ytzyt at Curse for the zhCN and zhTW translations!

 L.TooltipBag = "背包: %d"
@@ -13,7 +15,6 @@ L.TooltipReagent = "材料银行: %d"
 L.TooltipAuction = "拍卖: %d"
 L.Search = "搜索"
 L.TooltipTotal = "总计: "
-L.Tokens = "货币"
 L.Profiles = "设定档"
 L.Professions = "专业"
 L.Blacklist = "忽略例表"
@@ -25,7 +26,6 @@ L.DeleteWarning = "选择要删除的设定档.\n注意: 不可逆!"
 L.Delete = "删除"
 L.Confirm = "确认"
 L.ToggleSearch = "切换搜索"
-L.ToggleTokens = "切换货币"
 L.ToggleProfiles = "切换设定档"
 L.ToggleProfessions = "切换专业"
 L.ToggleBlacklist = "切换忽略例表"
@@ -34,8 +34,6 @@ L.ON = "开[ON]"
 L.OFF = "关[OFF]"
 L.LeftClickSearch = "左键 = 搜索窗"
 L.RightClickBagSyncMenu = "右键 = 菜单"
-L.LeftClickViewTradeSkill = "左键 = 查看专业技能链接"
-L.RightClickInsertTradeskill = "右键 = 插入专业技能链接"
 L.ClickViewProfession = "点击查看专业"
 L.ClickHere = "点这里"
 L.ErrorUserNotFound = "BagSync: 错误,未找到用户!"
@@ -45,7 +43,6 @@ L.RemoveItemID = "移除物品ID"
 L.HelpSearchItemName = "/bgs [物品名称] - 快速搜索一件物品"
 L.HelpSearchWindow = "/bgs search - 开启搜索窗"
 L.HelpGoldTooltip = "/bgs gold - 显示各角色的金钱统计"
-L.HelpTokensWindow = "/bgs tokens - 开启货币窗口"
 L.HelpProfilesWindow = "/bgs profiles - 开启设置窗口"
 L.HelpFixDB = "/bgs fixdb - 优化BagSync数据库"
 L.HelpConfigWindow = "/bgs config - 设置"
diff --git a/locale/zhTW.lua b/locale/zhTW.lua
index 40eb04e..cfeac5e 100644
--- a/locale/zhTW.lua
+++ b/locale/zhTW.lua
@@ -2,6 +2,8 @@
 local L = LibStub("AceLocale-3.0"):NewLocale("BagSync", "zhTW")
 if not L then return end

+--PLEASE LOOK AT enUS.lua for a complete localization list
+
 --special thanks to ytzyt at Curse for the zhCN and zhTW translations!

 L.TooltipBag = "背包: %d"
@@ -14,7 +16,6 @@ L.TooltipReagent = "材料銀行: %d"
 L.TooltipAuction = "拍賣: %d"
 L.Search = "搜索"
 L.TooltipTotal = "總: "
-L.Tokens = "貨幣"
 L.Profiles = "設定檔"
 L.Professions = "專業"
 L.Blacklist = "忽略例表"
@@ -26,7 +27,6 @@ L.DeleteWarning = "選擇要刪除的設定檔.\n注意:此操作不可逆!"
 L.Delete = "刪除"
 L.Confirm = "確認"
 L.ToggleSearch = "切換搜索"
-L.ToggleTokens = "切換貨幣"
 L.ToggleProfiles = "切換設定檔"
 L.ToggleProfessions = "切換專業"
 L.ToggleBlacklist = "切換忽略例表"
@@ -35,7 +35,6 @@ L.ON = "開[ON]"
 L.OFF = "關[OFF]"
 L.LeftClickSearch = "左鍵 = 搜索窗"
 L.RightClickBagSyncMenu = "右鍵 = 選單"
-L.LeftClickViewTradeSkill = "左鍵 = 查看專業技能鏈接"
 L.RightClickInsertTradeskill = "右鍵 = 插入專業技能鏈接"
 L.ClickViewProfession = "點擊查看專業"
 L.ClickHere = "點這裡"
@@ -46,7 +45,6 @@ L.RemoveItemID = "移除物品ID"
 L.HelpSearchItemName = "/bgs [物品名稱] - 快速搜索一件物品"
 L.HelpSearchWindow = "/bgs search - 開啟搜索窗"
 L.HelpGoldTooltip = "/bgs gold - 顯示各角色的金錢統計提示"
-L.HelpTokensWindow = "/bgs tokens - 開啟貨幣視窗"
 L.HelpProfilesWindow = "/bgs profiles - 開啟設定檔視窗"
 L.HelpFixDB = "/bgs fixdb - 優化數據庫"
 L.HelpConfigWindow = "/bgs config - 設置"
diff --git a/modules/blacklist.lua b/modules/blacklist.lua
index 3ed36c3..5f3ad95 100644
--- a/modules/blacklist.lua
+++ b/modules/blacklist.lua
@@ -116,7 +116,7 @@ function Blacklist:RemoveItemID()
 	self:DisplayList()
 end

-function Blacklist:AddEntry(entry, counter)
+function Blacklist:AddEntry(entry)

 	local highlightColor = {1, 0, 0}
 	local label = AceGUI:Create("InteractiveLabel")
@@ -151,17 +151,22 @@ end
 function Blacklist:DisplayList()

 	self.scrollframe:ReleaseChildren() --clear out the scrollframe
-
+
+	local searchTable = {}
 	local count = 0

 	--loop through our blacklist
 	for k, v in pairs(BSYC.db.blacklist[BSYC.currentRealm]) do
-		self:AddEntry(k, count)
+		table.insert(searchTable, k)
 		count = count + 1
 	end

 	--show or hide the scrolling frame depending on count
 	if count > 0 then
+		table.sort(searchTable, function(a,b) return (a < b) end)
+		for i=1, #searchTable do
+			self:AddEntry(searchTable[i])
+		end
 		self.scrollframe.frame:Show()
 	else
 		self.scrollframe.frame:Hide()
diff --git a/modules/config.lua b/modules/config.lua
index 8ae23b6..bd16413 100644
--- a/modules/config.lua
+++ b/modules/config.lua
@@ -1,3 +1,4 @@
+local BSYC = select(2, ...) --grab the addon namespace
 local L = LibStub("AceLocale-3.0"):GetLocale("BagSync", true)
 local config = LibStub("AceConfig-3.0")
 local configDialog = LibStub("AceConfigDialog-3.0")
@@ -14,13 +15,13 @@ local function get(info)
 	local p, c = string.split(".", info.arg)

 	if p ~= "color" then
-		if BagSyncOpt[c] then --if this is nil then it will default to false
-			return BagSyncOpt[c]
+		if BSYC.options[c] then --if this is nil then it will default to false
+			return BSYC.options[c]
 		else
 			return false
 		end
 	elseif p == "color" then
-		return BagSyncOpt.colors[c].r, BagSyncOpt.colors[c].g, BagSyncOpt.colors[c].b
+		return BSYC.options.colors[c].r, BSYC.options.colors[c].g, BSYC.options.colors[c].b
 	end

 end
@@ -30,16 +31,16 @@ local function set(info, arg1, arg2, arg3, arg4)
 	local p, c = string.split(".", info.arg)

 	if p ~= "color" then
-		BagSyncOpt[c] = arg1
+		BSYC.options[c] = arg1
 		if p == "minimap" then
 			if arg1 then BagSync_MinimapButton:Show() else BagSync_MinimapButton:Hide() end
 		else
-			BagSync:resetTooltip()
+			BSYC:ResetTooltip()
 		end
 	elseif p == "color" then
-		BagSyncOpt.colors[c].r = arg1
-		BagSyncOpt.colors[c].g = arg2
-		BagSyncOpt.colors[c].b = arg3
+		BSYC.options.colors[c].r = arg1
+		BSYC.options.colors[c].g = arg2
+		BSYC.options.colors[c].b = arg3
 	end

 end
diff --git a/modules/currency.lua b/modules/currency.lua
new file mode 100644
index 0000000..92b47f4
--- /dev/null
+++ b/modules/currency.lua
@@ -0,0 +1,238 @@
+local L = LibStub("AceLocale-3.0"):GetLocale("BagSync", true)
+local tokensTable = {}
+local tRows, tAnchor = {}
+local currentPlayer = UnitName("player")
+local currentRealm = select(2, UnitFullName("player"))
+local GetItemInfo = _G["GetItemInfo"]
+
+local bgTokens = CreateFrame("Frame","BagSync_TokensFrame", UIParent)
+
+local function tooltipColor(color, str)
+  return string.format("|cff%02x%02x%02x%s|r", (color.r or 1) * 255, (color.g or 1) * 255, (color.b or 1) * 255, str)
+end
+
+local function LoadSlider()
+
+	local function OnEnter(self)
+		if self.name and self.tooltip then
+			GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
+			GameTooltip:AddLine(self.name)
+			GameTooltip:AddLine(" ")
+			for i=1, #self.tooltip do
+				GameTooltip:AddDoubleLine(tooltipColor(BagSyncOpt.colors.first, self.tooltip[i].name), tooltipColor(BagSyncOpt.colors.second, self.tooltip[i].count))
+			end
+			GameTooltip:Show()
+		end
+	end
+
+	local function OnLeave() GameTooltip:Hide() end
+
+	local EDGEGAP, ROWHEIGHT, ROWGAP, GAP = 40, 20, 2, 4
+	local FRAME_HEIGHT = bgTokens:GetHeight() - 50
+	local SCROLL_TOP_POSITION = -80
+	local totaltRows = math.floor((FRAME_HEIGHT-22)/(ROWHEIGHT + ROWGAP))
+
+	for i=1, totaltRows do
+		if not tRows[i] then
+			local row = CreateFrame("Button", nil, bgTokens)
+			if not tAnchor then row:SetPoint("BOTTOMLEFT", bgTokens, "TOPLEFT", 0, SCROLL_TOP_POSITION)
+			else row:SetPoint("TOP", tAnchor, "BOTTOM", 0, -ROWGAP) end
+			row:SetPoint("LEFT", EDGEGAP, 0)
+			row:SetPoint("RIGHT", -EDGEGAP*1-8, 0)
+			row:SetHeight(ROWHEIGHT)
+			row:SetHighlightTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
+			tAnchor = row
+			tRows[i] = row
+
+			local title = row:CreateFontString(nil, "BACKGROUND", "GameFontNormal")
+			title:SetPoint("LEFT")
+			title:SetJustifyH("LEFT")
+			title:SetWidth(row:GetWidth())
+			title:SetHeight(ROWHEIGHT)
+			row.title = title
+
+			local icon = row:CreateTexture(nil,"OVERLAY")
+			icon:SetPoint("LEFT", (ROWHEIGHT * -1) -3, 0)
+			icon:SetWidth(ROWHEIGHT)
+			icon:SetHeight(ROWHEIGHT)
+			icon:SetTexture("Interface\\Icons\\Spell_Shadow_Shadowbolt")
+			icon:Hide()
+			row.icon = icon
+
+			row:SetScript("OnEnter", OnEnter)
+			row:SetScript("OnLeave", OnLeave)
+		end
+	end
+
+	local offset = 0
+	local RefreshTokens = function()
+		if not BagSync_TokensFrame:IsVisible() then return end
+
+		for i,row in ipairs(tRows) do
+			if (i + offset) <= #tokensTable then
+				if tokensTable[i + offset] then
+
+					if tokensTable[i + offset].isHeader then
+						row.title:SetText("|cFFFFFFFF"..tokensTable[i + offset].name.."|r")
+					else
+						row.title:SetText(tokensTable[i + offset].name)
+					end
+
+					--header texture and parameters
+					if tokensTable[i + offset].isHeader then
+						row:LockHighlight()
+						row.title:SetJustifyH("CENTER")
+						row.tooltip = nil
+					else
+						row:UnlockHighlight()
+						row.title:SetJustifyH("LEFT")
+						row.name = row.title:GetText()
+						row.tooltip = tokensTable[i + offset].tooltip
+					end
+
+					row.icon:SetTexture(tokensTable[i + offset].icon or nil)
+					row.icon:Show()
+					row:Show()
+				end
+			else
+				row.icon:SetTexture(nil)
+				row.icon:Hide()
+				row:Hide()
+			end
+		end
+	end
+
+	RefreshTokens()
+
+	if not bgTokens.scrollbar then
+		bgTokens.scrollbar = LibStub("tekKonfig-Scroll").new(bgTokens, nil, #tRows/2)
+		bgTokens.scrollbar:ClearAllPoints()
+		bgTokens.scrollbar:SetPoint("TOP", tRows[1], 0, -16)
+		bgTokens.scrollbar:SetPoint("BOTTOM", tRows[#tRows], 0, 16)
+		bgTokens.scrollbar:SetPoint("RIGHT", -16, 0)
+	end
+
+	if #tokensTable > 0 then
+		bgTokens.scrollbar:SetMinMaxValues(0, math.max(0, #tokensTable - #tRows))
+		bgTokens.scrollbar:SetValue(0)
+		bgTokens.scrollbar:Show()
+	else
+		bgTokens.scrollbar:Hide()
+	end
+
+	local f = bgTokens.scrollbar:GetScript("OnValueChanged")
+	bgTokens.scrollbar:SetScript("OnValueChanged", function(self, value, ...)
+		offset = math.floor(value)
+		RefreshTokens()
+		return f(self, value, ...)
+	end)
+
+	bgTokens:EnableMouseWheel()
+	bgTokens:SetScript("OnMouseWheel", function(self, val)
+		bgTokens.scrollbar:SetValue(bgTokens.scrollbar:GetValue() - val*#tRows/2)
+	end)
+end
+
+local function DoTokens()
+	if not BagSync or not BagSyncTOKEN_DB then return end
+	if not BagSyncTOKEN_DB[currentRealm] then return end
+
+	tokensTable = {} --reset
+	local tmp = {}
+
+	--loop through our characters
+	-----------------------------------
+	if BagSyncTOKEN_DB[currentRealm] then
+		for k, v in pairs(BagSyncTOKEN_DB[currentRealm]) do
+
+			tmp = {}
+			--this will loop and store all characters whom have counts greater then zero,
+			--ignoring the icon and header table entry, then it sorts it by character name
+			for q, r in pairs(v) do
+				if q ~= "icon" and q ~= "header" and r > 0 then
+					--only show counts that are greater then zero
+					table.insert(tmp, { name=q, count=r} )
+				end
+			end
+			table.sort(tmp, function(a,b) return (a.name < b.name) end)
+
+			--now add it to master table to sort later
+			table.insert(tokensTable, {name=k, icon=v.icon, header=v.header, tooltip=tmp})
+		end
+	end
+	-----------------------------------
+
+	--sort it
+	table.sort(tokensTable, function(a,b)
+		if a.header < b.header then
+			return true;
+		elseif a.header == b.header then
+			return (a.name < b.name);
+		end
+	end)
+
+	--add headers
+	local lastHeader = ""
+	tmp = {} --reset
+
+	for i=1, #tokensTable do
+		if tokensTable[i].header ~= lastHeader then
+			lastHeader = tokensTable[i].header
+			table.insert(tmp, { name=lastHeader, header=lastHeader, isHeader=true } )
+			table.insert(tmp, tokensTable[i])
+		else
+			table.insert(tmp, tokensTable[i])
+		end
+	end
+	tokensTable = tmp
+
+	LoadSlider()
+end
+
+bgTokens:SetFrameStrata("HIGH")
+bgTokens:SetToplevel(true)
+bgTokens:EnableMouse(true)
+bgTokens:SetMovable(true)
+bgTokens:SetClampedToScreen(true)
+bgTokens:SetWidth(380)
+bgTokens:SetHeight(500)
+
+bgTokens:SetBackdrop({
+		bgFile = "Interface/Tooltips/UI-Tooltip-Background",
+		edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
+		tile = true,
+		tileSize = 16,
+		edgeSize = 32,
+		insets = { left = 5, right = 5, top = 5, bottom = 5 }
+})
+
+bgTokens:SetBackdropColor(0,0,0,1)
+bgTokens:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
+
+local addonTitle = bgTokens:CreateFontString(nil, "BACKGROUND", "GameFontNormal")
+addonTitle:SetPoint("CENTER", bgTokens, "TOP", 0, -20)
+addonTitle:SetText("|cFF99CC33BagSync|r |cFFFFFFFF("..L.Currency..")|r")
+
+local closeButton = CreateFrame("Button", nil, bgTokens, "UIPanelCloseButton");
+closeButton:SetPoint("TOPRIGHT", bgTokens, -15, -8);
+
+bgTokens:SetScript("OnShow", function(self) DoTokens(); LoadSlider(); end)
+bgTokens:SetScript("OnHide", function(self)
+	tokensTable = {}
+end)
+
+bgTokens:SetScript("OnMouseDown", function(frame, button)
+	if frame:IsMovable() then
+		frame.isMoving = true
+		frame:StartMoving()
+	end
+end)
+
+bgTokens:SetScript("OnMouseUp", function(frame, button)
+	if( frame.isMoving ) then
+		frame.isMoving = nil
+		frame:StopMovingOrSizing()
+	end
+end)
+
+bgTokens:Hide()
\ No newline at end of file
diff --git a/modules/minimap.lua b/modules/minimap.lua
index 0a6fa73..d05f746 100644
--- a/modules/minimap.lua
+++ b/modules/minimap.lua
@@ -43,23 +43,23 @@ bgsMinimapDD.initialize = function(self, level)
 		addButton(level, L.Search, nil, 1, nil, 'search', function(frame, ...)
 			BSYC:GetModule("Search").frame:Show()
 		end)
-		addButton(level, L.Tokens, nil, 1, nil, 'tokens', function(frame, ...)
+		addButton(level, L.Currency, nil, 1, nil, 'currency', function(frame, ...)
 			if BagSync_TokensFrame then BagSync_TokensFrame:Show() end
 		end)
 		addButton(level, L.Profiles, nil, 1, nil, 'profiles', function(frame, ...)
 			BSYC:GetModule("Profiles").frame:Show()
 		end)
 		addButton(level, L.Professions, nil, 1, nil, 'professions', function(frame, ...)
-			if BagSync_CraftsFrame then BagSync_CraftsFrame:Show() end
+			BSYC:GetModule("Professions").frame:Show()
 		end)
 		addButton(level, L.Blacklist, nil, 1, nil, 'blacklist', function(frame, ...)
 			BSYC:GetModule("Blacklist").frame:Show()
 		end)
 		addButton(level, L.Gold, nil, 1, nil, 'gold', function(frame, ...)
-			if BagSync then BagSync:ShowMoneyTooltip() end
+			BSYC:ShowMoneyTooltip()
 		end)
 		addButton(level, L.FixDB, nil, 1, nil, 'fixdb', function(frame, ...)
-			if BagSync then BagSync:FixDB_Data() end
+			BSYC:FixDB()
 		end)
 		addButton(level, L.Config, nil, 1, nil, 'config', function(frame, ...)
 			LibStub("AceConfigDialog-3.0"):Open("BagSync")
diff --git a/modules/professions.lua b/modules/professions.lua
index 886edad..9f5104c 100644
--- a/modules/professions.lua
+++ b/modules/professions.lua
@@ -1,238 +1,143 @@
+
+local BSYC = select(2, ...) --grab the addon namespace
+local Professions = BSYC:NewModule("Professions")
+
 local L = LibStub("AceLocale-3.0"):GetLocale("BagSync", true)
-local craftsTable = {}
-local tRows, tAnchor = {}
-local currentPlayer = UnitName("player")
-local currentRealm = select(2, UnitFullName("player"))
+local AceGUI = LibStub("AceGUI-3.0")
+
+function Professions:OnEnable()

-local bgCrafts = CreateFrame("Frame","BagSync_CraftsFrame", UIParent)
+	--lets create our widgets
+	local ProfessionsFrame = AceGUI:Create("Window")
+	Professions.frame = ProfessionsFrame

-local function LoadSlider()
+	ProfessionsFrame:SetTitle("BagSync "..L.Professions)
+	ProfessionsFrame:SetHeight(500)
+	ProfessionsFrame:SetWidth(380)
+	ProfessionsFrame:EnableResize(false)

-	local function OnEnter(self)
-		if self.canLink and self.owner then
-			GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
-			GameTooltip:AddLine(format("|cFF99CC33%s|r", self.owner))
-			GameTooltip:AddLine(L.LeftClickViewTradeSkill)
-			GameTooltip:AddLine(L.RightClickInsertTradeskill)
-			GameTooltip:Show()
-		end
-	end
+	local information = AceGUI:Create("Label")
+	information:SetText(L.ProfessionLeftClick)
+	information:SetFont("Fonts\\FRIZQT__.TTF", 12, THICKOUTLINE)
+	information:SetColor(1, 165/255, 0)
+	information:SetFullWidth(true)
+	ProfessionsFrame:AddChild(information)

-	local function OnLeave() GameTooltip:Hide() end
+	local scrollframe = AceGUI:Create("ScrollFrame");
+	scrollframe:SetFullWidth(true)
+	scrollframe:SetLayout("Flow")
+
+	Professions.scrollframe = scrollframe
+	ProfessionsFrame:AddChild(scrollframe)

-	local EDGEGAP, ROWHEIGHT, ROWGAP, GAP = 16, 20, 2, 4
-	local FRAME_HEIGHT = bgCrafts:GetHeight() - 50
-	local SCROLL_TOP_POSITION = -80
-	local totaltRows = math.floor((FRAME_HEIGHT-22)/(ROWHEIGHT + ROWGAP))
+	hooksecurefunc(ProfessionsFrame, "Show" ,function()
+		self:DisplayList()
+	end)

-	for i=1, totaltRows do
-		if not tRows[i] then
-			local row = CreateFrame("Button", nil, bgCrafts)
-			if not tAnchor then row:SetPoint("BOTTOMLEFT", bgCrafts, "TOPLEFT", 0, SCROLL_TOP_POSITION)
-			else row:SetPoint("TOP", tAnchor, "BOTTOM", 0, -ROWGAP) end
-			row:SetPoint("LEFT", EDGEGAP, 0)
-			row:SetPoint("RIGHT", -EDGEGAP*2-8, 0)
-			row:SetHeight(ROWHEIGHT)
-			row:SetHighlightTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
-			tAnchor = row
-			tRows[i] = row
-
-			local title = row:CreateFontString(nil, "BACKGROUND", "GameFontNormal")
-			title:SetPoint("LEFT")
-			title:SetJustifyH("LEFT")
-			title:SetWidth(row:GetWidth())
-			title:SetHeight(ROWHEIGHT)
-			row.title = title
-
-			row:RegisterForClicks("LeftButtonUp", "RightButtonUp")
-			row:SetScript("OnEnter", OnEnter)
-			row:SetScript("OnLeave", OnLeave)
-			row:SetScript("OnClick", function (self, button, down)
-				if self.link then
-					if button == "LeftButton" then
-						DEFAULT_CHAT_FRAME:AddMessage(format("%s|cFF99CC33%s|r ==> %s", L.ClickViewProfession, self.owner, self.link))
-					else
-						local editBox = ChatEdit_ChooseBoxForSend()
-
-						if editBox then
-							editBox:Insert(self.link)
-							ChatFrame_OpenChat(editBox:GetText())
-						end
-					end
-				end
-			end)
-		end
-	end
+	ProfessionsFrame:Hide()
+
+end

-	local offset = 0
-	local RefreshCrafts = function()
-		if not BagSync_CraftsFrame:IsVisible() then return end
-
-		for i,row in ipairs(tRows) do
-			if (i + offset) <= #craftsTable then
-				if craftsTable[i + offset] then
-
-					if craftsTable[i + offset].isHeader then
-						row.title:SetText("|cFFFFFFFF"..craftsTable[i + offset].name.."|r")
-					else
-						if craftsTable[i + offset].isLink then
-							row.title:SetText( format("|cFF99CC33%s|r |cFFFFFFFF(%s)|r", craftsTable[i + offset].name,  craftsTable[i + offset].level))
-						else
-							row.title:SetText( format("|cFF6699FF%s|r |cFFFFFFFF(%s)|r", craftsTable[i + offset].name,  craftsTable[i + offset].level))
-						end
-					end
-
-					--header texture and parameters
-					if craftsTable[i + offset].isHeader then
-						row:LockHighlight()
-						row.title:SetJustifyH("CENTER")
-						row.canLink = nil
-					else
-						row:UnlockHighlight()
-						row.title:SetJustifyH("LEFT")
-						row.canLink = craftsTable[i + offset].isLink
-						row.link = craftsTable[i + offset].link
-						row.owner = craftsTable[i + offset].owner
-					end
-
-				end
-			else
-				row:Hide()
-			end
-		end
-	end
+function Professions:AddEntry(entry, isHeader)

-	RefreshCrafts()
+	local highlightColor = {1, 0, 0}
+	local label = AceGUI:Create("InteractiveLabel")

-	if not bgCrafts.scrollbar then
-		bgCrafts.scrollbar = LibStub("tekKonfig-Scroll").new(bgCrafts, nil, #tRows/2)
-		bgCrafts.scrollbar:ClearAllPoints()
-		bgCrafts.scrollbar:SetPoint("TOP", tRows[1], 0, -16)
-		bgCrafts.scrollbar:SetPoint("BOTTOM", tRows[#tRows], 0, 16)
-		bgCrafts.scrollbar:SetPoint("RIGHT", -16, 0)
-	end
+	label.userdata.highlight = label.frame:CreateTexture(nil, "BACKGROUND") --userdata gets deleted when widget is recycled
+	label.userdata.highlight:SetAllPoints()
+	label.userdata.highlight:SetBlendMode("ADD")
+	label.userdata.highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight") --userdata gets deleted when widget is recycled
+	label.userdata.highlight:Hide()
+
+	label.userdata.color = {1, 1, 1}

-	if #craftsTable > 0 then
-		bgCrafts.scrollbar:SetMinMaxValues(0, math.max(0, #craftsTable - #tRows))
-		bgCrafts.scrollbar:SetValue(0)
-		bgCrafts.scrollbar:Show()
+	if isHeader then
+		label:SetText(entry.player)
+		label:SetFont("Fonts\\FRIZQT__.TTF", 14, THICKOUTLINE)
+		label:SetFullWidth(true)
+		label:SetColor(unpack(label.userdata.color))
+		label.userdata.highlight:Show()
+		label.label:SetJustifyH("CENTER") --don't like doing this until they update Ace3GUI
+		label.userdata.isHeader = isHeader
 	else
-		bgCrafts.scrollbar:Hide()
+		label:SetText(entry.name)
+		label:SetFont("Fonts\\FRIZQT__.TTF", 14, THICKOUTLINE)
+		label:SetFullWidth(true)
+		if entry.recipeIndex <= 2 then
+			label.userdata.color = {153/255,204/255,51/255} --primary profession color it green
+		else
+			label.userdata.color = {102/255,153/255,1} --gathering profession color it blue
+		end
+		label.userdata.highlight:Hide()
+		label:SetColor(unpack(label.userdata.color))
+		label.label:SetJustifyH("LEFT")--don't like doing this until they update Ace3GUI
+		label.userdata.isHeader = isHeader
 	end

-	local f = bgCrafts.scrollbar:GetScript("OnValueChanged")
-	bgCrafts.scrollbar:SetScript("OnValueChanged", function(self, value, ...)
-		offset = math.floor(value)
-		RefreshCrafts()
-		return f(self, value, ...)
-	end)
-
-	bgCrafts:EnableMouseWheel()
-	bgCrafts:SetScript("OnMouseWheel", function(self, val)
-		bgCrafts.scrollbar:SetValue(bgCrafts.scrollbar:GetValue() - val*#tRows/2)
-	end)
+	label:SetCallback(
+		"OnClick",
+		function (widget, sometable, button)
+			if "LeftButton" == button then
+				print("left")
+			end
+		end)
+	label:SetCallback(
+		"OnEnter",
+		function (widget, sometable)
+			label:SetColor(unpack(highlightColor))
+
+		end)
+	label:SetCallback(
+		"OnLeave",
+		function (widget, sometable)
+			label:SetColor(unpack(label.userdata.color))
+		end)
+
+	self.scrollframe:AddChild(label)
 end

-local function DoCrafts()
-	if not BagSync or not BagSyncCRAFT_DB then return end
-	if not BagSyncCRAFT_DB[currentRealm] then return end
+function Professions:DisplayList()
+
+	local professionsTable = {}
+	local tempList = {}
+	local count = 0
+
+	self.scrollframe:ReleaseChildren() --clear out the scrollframe

-	craftsTable = {} --reset
-	local tmp = {}
+	local xDB = BSYC:FilterDB(1) --dbSelect 1

 	--loop through our characters
-	-----------------------------------
-	if BagSyncCRAFT_DB[currentRealm] then
-		for k, v in pairs(BagSyncCRAFT_DB[currentRealm]) do
-
-			tmp = {}
-			for q, r in pairs(v) do
-				if type(r) == "string" then
-					local trName, trSkillLevel = strsplit(",", r)
-					if trName and trSkillLevel then
-						table.insert(tmp, { name=trName, level=trSkillLevel, isLink=false, owner=k} )
-					end
-				elseif type(r) == "table" and r[1] and r[2] and r[3] then
-					table.insert(tmp, { name=r[1], link=r[2], level=r[3], isLink=true, owner=k} )
-				end
-			end
-			table.sort(tmp, function(a,b) return (a.name < b.name) end)
-
-			--now add it to master table to sort later, only add if we have something to add
-			if #tmp > 0 then
-				table.insert(craftsTable, {header=k, info=tmp})
+	--k = player, v = stored data for player
+	for k, v in pairs(xDB) do
+
+		local tmp = {}
+		local yName, yRealm  = strsplit("^", k)
+		local playerName = BSYC:GetCharacterRealmInfo(yName, yRealm)
+
+		for q, r in pairs(v) do
+			local tName, tLevel = strsplit(",", r)
+			table.insert(tmp, { name=tName, level=tLevel, player=playerName, recipeIndex=q } )
+			count = count + 1
+		end
+
+		--add to master table
+		table.insert(professionsTable, { player=playerName, info=tmp } )
+	end
+
+	--show or hide the scrolling frame depending on count
+	if count > 0 then
+		table.sort(professionsTable, function(a,b) return (a.player < b.player) end)
+		for i=1, #professionsTable do
+			self:AddEntry(professionsTable[i], true) --add header
+			for z=1, #professionsTable[i].info do
+				self:AddEntry(professionsTable[i].info[z], false)
 			end
 		end
+		self.scrollframe.frame:Show()
+	else
+		self.scrollframe.frame:Hide()
 	end
-	-----------------------------------

-	--sort it
-	table.sort(craftsTable, function(a,b)
-		if a.header < b.header then
-			return true;
-		end
-	end)

-	--now that the header names are sorted lets add all headers and info to master table
-	tmp = {} --reset

-	for i=1, #craftsTable do
-		--insert header
-		table.insert(tmp, { name=craftsTable[i].header, isHeader=true } )
-		--insert sub information :)
-		for y=1, #craftsTable[i].info do
-			table.insert(tmp, craftsTable[i].info[y])
-		end
-	end
-	craftsTable = tmp
-
-	LoadSlider()
-end
-
-bgCrafts:SetFrameStrata("HIGH")
-bgCrafts:SetToplevel(true)
-bgCrafts:EnableMouse(true)
-bgCrafts:SetMovable(true)
-bgCrafts:SetClampedToScreen(true)
-bgCrafts:SetWidth(380)
-bgCrafts:SetHeight(500)
-
-bgCrafts:SetBackdrop({
-		bgFile = "Interface/Tooltips/UI-Tooltip-Background",
-		edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
-		tile = true,
-		tileSize = 16,
-		edgeSize = 32,
-		insets = { left = 5, right = 5, top = 5, bottom = 5 }
-})
-
-bgCrafts:SetBackdropColor(0,0,0,1)
-bgCrafts:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
-
-local addonTitle = bgCrafts:CreateFontString(nil, "BACKGROUND", "GameFontNormal")
-addonTitle:SetPoint("CENTER", bgCrafts, "TOP", 0, -20)
-addonTitle:SetText("|cFF99CC33BagSync|r |cFFFFFFFF("..L.Professions..")|r")
-
-local closeButton = CreateFrame("Button", nil, bgCrafts, "UIPanelCloseButton");
-closeButton:SetPoint("TOPRIGHT", bgCrafts, -15, -8);
-
-bgCrafts:SetScript("OnShow", function(self) DoCrafts(); LoadSlider(); end)
-bgCrafts:SetScript("OnHide", function(self)
-	craftsTable = {}
-end)
-
-bgCrafts:SetScript("OnMouseDown", function(frame, button)
-	if frame:IsMovable() then
-		frame.isMoving = true
-		frame:StartMoving()
-	end
-end)
-
-bgCrafts:SetScript("OnMouseUp", function(frame, button)
-	if( frame.isMoving ) then
-		frame.isMoving = nil
-		frame:StopMovingOrSizing()
-	end
-end)
-
-bgCrafts:Hide()
\ No newline at end of file
+end
\ No newline at end of file
diff --git a/modules/search.lua b/modules/search.lua
index ba0b3b6..e879e53 100644
--- a/modules/search.lua
+++ b/modules/search.lua
@@ -119,7 +119,7 @@ function Search:StartSearch(searchStr)
 	self:DoSearch(searchStr)
 end

-function Search:AddEntry(entry, counter)
+function Search:AddEntry(entry)

 	local highlightColor = {1, 0, 0}
 	local label = AceGUI:Create("InteractiveLabel")
@@ -163,6 +163,7 @@ function Search:DoSearch(searchStr)
 	local searchStr = searchStr or self.searchbar:GetText()
 	searchStr = searchStr:lower()

+	local searchTable = {}
 	local tempList = {}
 	local previousGuilds = {}
 	local count = 0
@@ -214,12 +215,12 @@ function Search:DoSearch(searchStr)
 										if dName then
 											--are we checking in our bank,void, etc?
 											if playerSearch and string.sub(searchStr, 2) == q and string.sub(searchStr, 2) ~= "guild" and yName == BSYC.currentPlayer and not tempList[dblink] then
-												self:AddEntry({ name=dName, link=dItemLink, rarity=dRarity, texture=dTexture }, count)
+												table.insert(searchTable, { name=dName, link=dItemLink, rarity=dRarity, texture=dTexture } )
 												tempList[dblink] = dName
 												count = count + 1
 											--we found a match
 											elseif not playerSearch and not tempList[dblink] and ItemSearch:Matches(dItemLink, searchStr) then
-												self:AddEntry({ name=dName, link=dItemLink, rarity=dRarity, texture=dTexture }, count)
+												table.insert(searchTable, { name=dName, link=dItemLink, rarity=dRarity, texture=dTexture } )
 												tempList[dblink] = dName
 												count = count + 1
 											end
@@ -250,12 +251,12 @@ function Search:DoSearch(searchStr)
 									local dName, dItemLink, dRarity, _, _, _, _, _, _, dTexture = GetItemInfo(dblink)
 									if dName then
 										if playerSearch and string.sub(searchStr, 2) == "guild" and BSYC.db.player.guild and guildN == BSYC.db.player.guild and not tempList[dblink] then
-											self:AddEntry({ name=dName, link=dItemLink, rarity=dRarity, texture=dTexture }, count)
+											table.insert(searchTable, { name=dName, link=dItemLink, rarity=dRarity, texture=dTexture } )
 											tempList[dblink] = dName
 											count = count + 1
 										--we found a match
 										elseif not playerSearch and not tempList[dblink] and ItemSearch:Matches(dItemLink, searchStr) then
-											self:AddEntry({ name=dName, link=dItemLink, rarity=dRarity, texture=dTexture }, count)
+											table.insert(searchTable, { name=dName, link=dItemLink, rarity=dRarity, texture=dTexture } )
 											tempList[dblink] = dName
 											count = count + 1
 										end
@@ -274,6 +275,14 @@ function Search:DoSearch(searchStr)

 		end

+		--display the rows
+		if count > 0 then
+			table.sort(searchTable, function(a,b) return (a.name < b.name) end)
+			for i=1, #searchTable do
+				self:AddEntry(searchTable[i])
+			end
+		end
+
 		--show warning window if the server hasn't queried all the items yet
 		if countWarning > 0 then
 			self.warninglabel:SetText(L.WarningItemSearch:format(countWarning))
diff --git a/modules/test.lua b/modules/test.lua
index 740ab93..2a81ca1 100644
--- a/modules/test.lua
+++ b/modules/test.lua
@@ -1,219 +1,118 @@
+
 local BSYC = select(2, ...) --grab the addon namespace
-local L = LibStub("AceLocale-3.0"):GetLocale("BagSync", true)
-local testTable = {}
-local rows, anchor = {}
-local currentRealm = select(2, UnitFullName("player"))
-local GetItemInfo = _G["GetItemInfo"]
-local currentPlayer = UnitName("player")
+local Testing = BSYC:NewModule("Testing")

+local L = LibStub("AceLocale-3.0"):GetLocale("BagSync", true)
 local AceGUI = LibStub("AceGUI-3.0")
-local customSearch = LibStub('CustomSearch-1.0')
-local ItemSearch = LibStub("LibItemSearch-1.2")

-local frame = AceGUI:Create("Frame")
+function Testing:OnEnable()
+
+	--lets create our widgets
+	local TestingFrame = AceGUI:Create("Window")
+	Testing.frame = TestingFrame

-frame:SetTitle("Example Frame")
-frame:SetStatusText("AceGUI-3.0 Example Container Frame")
-frame:EnableResize(false)
+	TestingFrame:SetTitle("Testing")
+	TestingFrame:SetHeight(500)
+	TestingFrame:SetWidth(380)
+	TestingFrame:EnableResize(false)
+
+	local refreshbutton = AceGUI:Create("Button")
+	refreshbutton:SetText(L.Refresh)
+	refreshbutton:SetWidth(100)
+	refreshbutton:SetHeight(20)
+	refreshbutton:SetCallback("OnClick", function()
+		self:DisplayList()
+	end)
+	TestingFrame:AddChild(refreshbutton)
+
+	local scrollframe = AceGUI:Create("ScrollFrame");
+	scrollframe:SetFullWidth(true)
+	scrollframe:SetLayout("Flow")

-local scrollframe = AceGUI:Create("ScrollFrame");
-scrollframe:SetFullWidth(true)
-scrollframe:SetLayout("Flow")
+	Testing.scrollframe = scrollframe
+	TestingFrame:AddChild(scrollframe)

-frame:AddChild(scrollframe)
+	TestingFrame:Hide()
+end

---:ReleaseChildren()

-
-local function addEntry(entry, counter)
+function Testing:AddEntry(entry)

-	local color = {0.7, 0.7, 0.7}
+	local name, recipeID = entry.name, entry.recipeID
+
 	local highlightColor = {1, 0, 0}
 	local label = AceGUI:Create("InteractiveLabel")

-	local name, link, rarity, texture = entry.name, entry.link, entry.rarity, entry.texture
-
 	label:SetText(name)
 	label:SetFont("Fonts\\FRIZQT__.TTF", 14, THICKOUTLINE)
 	label:SetFullWidth(true)
-	label:SetColor(unpack(color))
-	label:SetImage(texture)
+	label:SetColor( 1,1,1)
 	label:SetCallback(
 		"OnClick",
 		function (widget, sometable, button)
-			if "LeftButton" == button then
-				print("left")
-			elseif "RightButton" == button then
-				print("right")
-			end
+			ChatEdit_InsertLink(GetSpellLink(recipeID))
 		end)
 	label:SetCallback(
 		"OnEnter",
 		function (widget, sometable)
 			label:SetColor(unpack(highlightColor))
+			GameTooltip:SetOwner(label.frame, "ANCHOR_BOTTOMRIGHT")
+			GameTooltip:SetSpellByID(recipeID)
+			GameTooltip:Show()
 		end)
 	label:SetCallback(
 		"OnLeave",
 		function (widget, sometable)
-			label:SetColor(unpack(color))
+			label:SetColor(1,1,1)
+			GameTooltip:Hide()
 		end)

-	scrollframe:AddChild(label)
-
+	self.scrollframe:AddChild(label)
 end

-local function DoSearch()
-	local searchStr = "red"
+function Testing:DisplayList()

-	searchStr = searchStr:lower()
+	self.scrollframe:ReleaseChildren() --clear out the scrollframe

-	local tempList = {}
-	local previousGuilds = {}
+	local searchTable = {}
 	local count = 0
-	local playerSearch = false
-	local countWarning = 0

-	if strlen(searchStr) > 0 then
-
-		scrollframe:ReleaseChildren() --clear out the scrollframe
-
-		local playerFaction = UnitFactionGroup("player")
-		local allowList = {
-			["bag"] = 0,
-			["bank"] = 0,
-			["equip"] = 0,
-			["mailbox"] = 0,
-			["void"] = 0,
-			["auction"] = 0,
-			["guild"] = 0,
-			["reagentbank"] = 0,
-		}
-
-		if string.len(searchStr) > 1 and string.find(searchStr, "@") and allowList[string.sub(searchStr, 2)] ~= nil then playerSearch = true end
-
-		local xDB = BSYC:FilterDB()
-
-		--loop through our characters
-		--k = player, v = stored data for player
-		for k, v in pairs(xDB) do
-
-			local pFaction = v.faction or playerFaction --just in case ;) if we dont know the faction yet display it anyways
-			local yName, yRealm  = strsplit("^", k)
+	--loop through our Testing
+	for k, v in pairs(BSYC.db.profession[BSYC.currentRealm]) do
+		if k == "test1" then
+			local tName, tlevel, tValues = strsplit(",", v)
+			local valuesList = {strsplit("|", tValues)}

-			--check if we should show both factions or not
-			if BSYC.options.enableFaction or pFaction == playerFaction then
-
-				--now count the stuff for the user
-				--q = bag name, r = stored data for bag name
-				for q, r in pairs(v) do
-					--only loop through table items we want
-					if allowList[q] and type(r) == "table" then
-						--bagID = bag name bagID, bagInfo = data of specific bag with bagID
-						for bagID, bagInfo in pairs(r) do
-							--slotID = slotid for specific bagid, itemValue = data of specific slotid
-							if type(bagInfo) == "table" then
-								for slotID, itemValue in pairs(bagInfo) do
-									local dblink, dbcount = strsplit(",", itemValue)
-									if dblink then
-										local dName, dItemLink, dRarity, _, _, _, _, _, _, dTexture = GetItemInfo(dblink)
-										if dName then
-											--are we checking in our bank,void, etc?
-											if playerSearch and string.sub(searchStr, 2) == q and string.sub(searchStr, 2) ~= "guild" and yName == currentPlayer and not tempList[dblink] then
-												addEntry({ name=dName, link=dItemLink, rarity=dRarity, texture=dTexture }, count)
-												tempList[dblink] = dName
-												count = count + 1
-											--we found a match
-											elseif not playerSearch and not tempList[dblink] and ItemSearch:Matches(dItemLink, searchStr) then
-												addEntry({ name=dName, link=dItemLink, rarity=dRarity, texture=dTexture }, count)
-												tempList[dblink] = dName
-												count = count + 1
-											end
-										else
-											countWarning = countWarning + 1
-										end
-									end
-								end
-							end
-						end
-					end
-				end
+			for idx = 1, #valuesList do
+
+				local recipe_info = _G.C_TradeSkillUI.GetRecipeInfo(valuesList[idx])
+				local craftName = valuesList[idx]

-				if BSYC.options.enableGuild then
-					local guildN = v.guild or nil
-
-					--check the guild bank if the character is in a guild
-					if guildN and BSYC.db.guild[v.realm][guildN] then
-						--check to see if this guild has already been done through this run (so we don't do it multiple times)
-						--check for XR/B.Net support
-						local gName = BSYC:GetGuildRealmInfo(guildN, v.realm)
-
-						if not previousGuilds[gName] then
-							--we only really need to see this information once per guild
-							for q, r in pairs(BagSyncGUILD_DB[v.realm][guildN]) do
-								local dblink, dbcount = strsplit(",", r)
-								if dblink then
-									local dName, dItemLink, dRarity, _, _, _, _, _, _, dTexture = GetItemInfo(dblink)
-									if dName then
-										if playerSearch and string.sub(searchStr, 2) == "guild" and GetGuildInfo("player") and guildN == GetGuildInfo("player") and not tempList[dblink] then
-											addEntry({ name=dName, link=dItemLink, rarity=dRarity, texture=dTexture }, count)
-											tempList[dblink] = dName
-											count = count + 1
-										--we found a match
-										elseif not playerSearch and not tempList[dblink] and ItemSearch:Matches(dItemLink, searchStr) then
-											addEntry({ name=dName, link=dItemLink, rarity=dRarity, texture=dTexture }, count)
-											tempList[dblink] = dName
-											count = count + 1
-										end
-									else
-										countWarning = countWarning + 1
-									end
-								end
-							end
-							previousGuilds[gName] = true
-						end
-					end
+				if recipe_info and recipe_info.name then
+					craftName = recipe_info.name
+				elseif GetSpellInfo(valuesList[idx]) then
+					craftName = GetSpellInfo(valuesList[idx])
+				else
+					craftName = L.ProfessionsFailedRequest:format(valuesList[idx])
 				end

+				table.insert(searchTable, {name=craftName, recipeID=valuesList[idx]})
 			end
-
+			count = count + 1
 		end
-		print("countWarning: ".. countWarning)
-		--table.sort(searchTable, function(a,b) return (a.name < b.name) end)
 	end
-
-end
-
-
-local OKbutton = AceGUI:Create("Button")
-OKbutton:SetText("Search")
-OKbutton:SetCallback("OnClick", function()
-      DoSearch()
-   end
-)
-frame:AddChild(OKbutton)
-
---lets create the warning frame.
-
-local warning = AceGUI:Create("Window")
-warning:SetTitle(L.WarningHeader)
-warning:SetWidth(300)
-warning:SetHeight(170)
-warning.frame:SetParent(frame.frame)
-warning:SetLayout("Flow")
-warning:EnableResize(false)
-
-local warningLabel = AceGUI:Create("Label")
-warningLabel:SetText(L.WarningItemSearch)
-warningLabel:SetFont("Fonts\\FRIZQT__.TTF", 14, THICKOUTLINE)
-warningLabel:SetColor(1, 165/255, 0) --orange, red is just too much sometimes
-warningLabel:SetFullWidth(true)
-warning:AddChild(warningLabel)

-warning:Hide()
-
-
-frame.warningFrame = warning
-
-frame:Hide()
-
-
\ No newline at end of file
+	--show or hide the scrolling frame depending on count
+	if count > 0 then
+		table.sort(searchTable, function(a,b) return (a.name < b.name) end)
+		for i=1, #searchTable do
+			self:AddEntry(searchTable[i])
+		end
+		self.scrollframe.frame:Show()
+	else
+		self.scrollframe.frame:Hide()
+	end
+
+	--169080
+	--GetSpellInfo(169080)
+end
\ No newline at end of file
diff --git a/modules/tokens.lua b/modules/tokens.lua
deleted file mode 100644
index adbae12..0000000
--- a/modules/tokens.lua
+++ /dev/null
@@ -1,238 +0,0 @@
-local L = LibStub("AceLocale-3.0"):GetLocale("BagSync", true)
-local tokensTable = {}
-local tRows, tAnchor = {}
-local currentPlayer = UnitName("player")
-local currentRealm = select(2, UnitFullName("player"))
-local GetItemInfo = _G["GetItemInfo"]
-
-local bgTokens = CreateFrame("Frame","BagSync_TokensFrame", UIParent)
-
-local function tooltipColor(color, str)
-  return string.format("|cff%02x%02x%02x%s|r", (color.r or 1) * 255, (color.g or 1) * 255, (color.b or 1) * 255, str)
-end
-
-local function LoadSlider()
-
-	local function OnEnter(self)
-		if self.name and self.tooltip then
-			GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
-			GameTooltip:AddLine(self.name)
-			GameTooltip:AddLine(" ")
-			for i=1, #self.tooltip do
-				GameTooltip:AddDoubleLine(tooltipColor(BagSyncOpt.colors.first, self.tooltip[i].name), tooltipColor(BagSyncOpt.colors.second, self.tooltip[i].count))
-			end
-			GameTooltip:Show()
-		end
-	end
-
-	local function OnLeave() GameTooltip:Hide() end
-
-	local EDGEGAP, ROWHEIGHT, ROWGAP, GAP = 40, 20, 2, 4
-	local FRAME_HEIGHT = bgTokens:GetHeight() - 50
-	local SCROLL_TOP_POSITION = -80
-	local totaltRows = math.floor((FRAME_HEIGHT-22)/(ROWHEIGHT + ROWGAP))
-
-	for i=1, totaltRows do
-		if not tRows[i] then
-			local row = CreateFrame("Button", nil, bgTokens)
-			if not tAnchor then row:SetPoint("BOTTOMLEFT", bgTokens, "TOPLEFT", 0, SCROLL_TOP_POSITION)
-			else row:SetPoint("TOP", tAnchor, "BOTTOM", 0, -ROWGAP) end
-			row:SetPoint("LEFT", EDGEGAP, 0)
-			row:SetPoint("RIGHT", -EDGEGAP*1-8, 0)
-			row:SetHeight(ROWHEIGHT)
-			row:SetHighlightTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
-			tAnchor = row
-			tRows[i] = row
-
-			local title = row:CreateFontString(nil, "BACKGROUND", "GameFontNormal")
-			title:SetPoint("LEFT")
-			title:SetJustifyH("LEFT")
-			title:SetWidth(row:GetWidth())
-			title:SetHeight(ROWHEIGHT)
-			row.title = title
-
-			local icon = row:CreateTexture(nil,"OVERLAY")
-			icon:SetPoint("LEFT", (ROWHEIGHT * -1) -3, 0)
-			icon:SetWidth(ROWHEIGHT)
-			icon:SetHeight(ROWHEIGHT)
-			icon:SetTexture("Interface\\Icons\\Spell_Shadow_Shadowbolt")
-			icon:Hide()
-			row.icon = icon
-
-			row:SetScript("OnEnter", OnEnter)
-			row:SetScript("OnLeave", OnLeave)
-		end
-	end
-
-	local offset = 0
-	local RefreshTokens = function()
-		if not BagSync_TokensFrame:IsVisible() then return end
-
-		for i,row in ipairs(tRows) do
-			if (i + offset) <= #tokensTable then
-				if tokensTable[i + offset] then
-
-					if tokensTable[i + offset].isHeader then
-						row.title:SetText("|cFFFFFFFF"..tokensTable[i + offset].name.."|r")
-					else
-						row.title:SetText(tokensTable[i + offset].name)
-					end
-
-					--header texture and parameters
-					if tokensTable[i + offset].isHeader then
-						row:LockHighlight()
-						row.title:SetJustifyH("CENTER")
-						row.tooltip = nil
-					else
-						row:UnlockHighlight()
-						row.title:SetJustifyH("LEFT")
-						row.name = row.title:GetText()
-						row.tooltip = tokensTable[i + offset].tooltip
-					end
-
-					row.icon:SetTexture(tokensTable[i + offset].icon or nil)
-					row.icon:Show()
-					row:Show()
-				end
-			else
-				row.icon:SetTexture(nil)
-				row.icon:Hide()
-				row:Hide()
-			end
-		end
-	end
-
-	RefreshTokens()
-
-	if not bgTokens.scrollbar then
-		bgTokens.scrollbar = LibStub("tekKonfig-Scroll").new(bgTokens, nil, #tRows/2)
-		bgTokens.scrollbar:ClearAllPoints()
-		bgTokens.scrollbar:SetPoint("TOP", tRows[1], 0, -16)
-		bgTokens.scrollbar:SetPoint("BOTTOM", tRows[#tRows], 0, 16)
-		bgTokens.scrollbar:SetPoint("RIGHT", -16, 0)
-	end
-
-	if #tokensTable > 0 then
-		bgTokens.scrollbar:SetMinMaxValues(0, math.max(0, #tokensTable - #tRows))
-		bgTokens.scrollbar:SetValue(0)
-		bgTokens.scrollbar:Show()
-	else
-		bgTokens.scrollbar:Hide()
-	end
-
-	local f = bgTokens.scrollbar:GetScript("OnValueChanged")
-	bgTokens.scrollbar:SetScript("OnValueChanged", function(self, value, ...)
-		offset = math.floor(value)
-		RefreshTokens()
-		return f(self, value, ...)
-	end)
-
-	bgTokens:EnableMouseWheel()
-	bgTokens:SetScript("OnMouseWheel", function(self, val)
-		bgTokens.scrollbar:SetValue(bgTokens.scrollbar:GetValue() - val*#tRows/2)
-	end)
-end
-
-local function DoTokens()
-	if not BagSync or not BagSyncTOKEN_DB then return end
-	if not BagSyncTOKEN_DB[currentRealm] then return end
-
-	tokensTable = {} --reset
-	local tmp = {}
-
-	--loop through our characters
-	-----------------------------------
-	if BagSyncTOKEN_DB[currentRealm] then
-		for k, v in pairs(BagSyncTOKEN_DB[currentRealm]) do
-
-			tmp = {}
-			--this will loop and store all characters whom have counts greater then zero,
-			--ignoring the icon and header table entry, then it sorts it by character name
-			for q, r in pairs(v) do
-				if q ~= "icon" and q ~= "header" and r > 0 then
-					--only show counts that are greater then zero
-					table.insert(tmp, { name=q, count=r} )
-				end
-			end
-			table.sort(tmp, function(a,b) return (a.name < b.name) end)
-
-			--now add it to master table to sort later
-			table.insert(tokensTable, {name=k, icon=v.icon, header=v.header, tooltip=tmp})
-		end
-	end
-	-----------------------------------
-
-	--sort it
-	table.sort(tokensTable, function(a,b)
-		if a.header < b.header then
-			return true;
-		elseif a.header == b.header then
-			return (a.name < b.name);
-		end
-	end)
-
-	--add headers
-	local lastHeader = ""
-	tmp = {} --reset
-
-	for i=1, #tokensTable do
-		if tokensTable[i].header ~= lastHeader then
-			lastHeader = tokensTable[i].header
-			table.insert(tmp, { name=lastHeader, header=lastHeader, isHeader=true } )
-			table.insert(tmp, tokensTable[i])
-		else
-			table.insert(tmp, tokensTable[i])
-		end
-	end
-	tokensTable = tmp
-
-	LoadSlider()
-end
-
-bgTokens:SetFrameStrata("HIGH")
-bgTokens:SetToplevel(true)
-bgTokens:EnableMouse(true)
-bgTokens:SetMovable(true)
-bgTokens:SetClampedToScreen(true)
-bgTokens:SetWidth(380)
-bgTokens:SetHeight(500)
-
-bgTokens:SetBackdrop({
-		bgFile = "Interface/Tooltips/UI-Tooltip-Background",
-		edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
-		tile = true,
-		tileSize = 16,
-		edgeSize = 32,
-		insets = { left = 5, right = 5, top = 5, bottom = 5 }
-})
-
-bgTokens:SetBackdropColor(0,0,0,1)
-bgTokens:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
-
-local addonTitle = bgTokens:CreateFontString(nil, "BACKGROUND", "GameFontNormal")
-addonTitle:SetPoint("CENTER", bgTokens, "TOP", 0, -20)
-addonTitle:SetText("|cFF99CC33BagSync|r |cFFFFFFFF("..L.Tokens..")|r")
-
-local closeButton = CreateFrame("Button", nil, bgTokens, "UIPanelCloseButton");
-closeButton:SetPoint("TOPRIGHT", bgTokens, -15, -8);
-
-bgTokens:SetScript("OnShow", function(self) DoTokens(); LoadSlider(); end)
-bgTokens:SetScript("OnHide", function(self)
-	tokensTable = {}
-end)
-
-bgTokens:SetScript("OnMouseDown", function(frame, button)
-	if frame:IsMovable() then
-		frame.isMoving = true
-		frame:StartMoving()
-	end
-end)
-
-bgTokens:SetScript("OnMouseUp", function(frame, button)
-	if( frame.isMoving ) then
-		frame.isMoving = nil
-		frame:StopMovingOrSizing()
-	end
-end)
-
-bgTokens:Hide()
\ No newline at end of file