Quantcast

-Restructured the addon and changed most functions to local ones.

Xruptor [12-09-11 - 14:30]
-Restructured the addon and changed most functions to local ones.
-Changed color coding for Professions.  Green = linkable, Blue = not-linkable
-Reworked how the void storage is checked.
Filename
BagSync.lua
BagSync_Crafts.lua
diff --git a/BagSync.lua b/BagSync.lua
index 50108ce..8fd5cb7 100644
--- a/BagSync.lua
+++ b/BagSync.lua
@@ -32,6 +32,10 @@ local BS_CD
 local MAX_GUILDBANK_SLOTS_PER_TAB = 98
 local doTokenUpdate = 0
 local guildTabQueryQueue = {}
+local atBank = false
+local atVoidBank = false
+local atGuildBank = false
+local isCheckingMail = false

 local SILVER = '|cffc7c7cf%s|r'
 local MOSS = '|cFF80FF00%s|r'
@@ -86,424 +90,11 @@ end)

 if IsLoggedIn() then BagSync:PLAYER_LOGIN() else BagSync:RegisterEvent('PLAYER_LOGIN') end

-------------------------------
---      Event Handlers      --
-------------------------------
-
-function BagSync:PLAYER_LOGIN()
-
-	 BINDING_HEADER_BAGSYNC = "BagSync"
-	 BINDING_NAME_BAGSYNCTOGGLESEARCH = L["Toggle Search"]
-	 BINDING_NAME_BAGSYNCTOGGLETOKENS = L["Toggle Tokens"]
-	 BINDING_NAME_BAGSYNCTOGGLEPROFILES = L["Toggle Profiles"]
-	 BINDING_NAME_BAGSYNCTOGGLECRAFTS = L["Toggle Professions"]
-
-
-	local ver = GetAddOnMetadata("BagSync","Version") or 0
-
-	--load our player info after login
-	currentPlayer = UnitName('player')
-	currentRealm = GetRealmName()
-	playerClass = select(2, UnitClass("player"))
-	playerFaction = UnitFactionGroup("player")
-
-	--initiate the db
-	self:StartupDB()
-
-	--do DB cleanup check by version number
-	if BagSyncDB.dbversion then
-		--remove old variable and replace with BagSyncOpt DB
-		BagSyncDB.dbversion = nil
-		BagSyncOpt.dbversion = ver
-		self:FixDB_Data()
-	elseif not BagSyncOpt.dbversion or BagSyncOpt.dbversion ~= ver then
-		self:FixDB_Data()
-		BagSyncOpt.dbversion = ver
-	end
-
-	--save the current user money (before bag update)
-	if BS_DB["gold:0:0"] then BS_DB["gold:0:0"] = nil end --remove old format
-	BS_DB.gold = GetMoney()
-
-	--save the class information
-	if BS_DB["class:0:0"] then BS_DB["class:0:0"] = nil end --remove old format
-	BS_DB.class = playerClass
-
-	--save the faction information
-	--"Alliance", "Horde" or nil
-	if BS_DB["faction:0:0"] then BS_DB["faction:0:0"] = nil end --remove old format
-	BS_DB.faction = playerFaction
-
-	--check for player not in guild
-	if IsInGuild() or GetNumGuildMembers(true) > 0 then
-		GuildRoster()
-	elseif BS_DB.guild then
-		BS_DB.guild = nil
-		self:FixDB_Data(true)
-	end
-
-	--save all inventory data, including backpack(0)
-	for i = BACKPACK_CONTAINER, BACKPACK_CONTAINER + NUM_BAG_SLOTS do
-		self:SaveBag('bag', i, true)
-	end
-
-	--force an equipment scan
-	self:SaveEquipment()
-
-	--force token scan
-	self:ScanTokens()
-
-	--clean up old auctions
-	self:RemoveExpiredAuctions()
-
-	--check for minimap toggle
-	if BagSyncOpt.enableMinimap and BagSync_MinimapButton and not BagSync_MinimapButton:IsVisible() then
-		BagSync_MinimapButton:Show()
-	elseif not BagSyncOpt.enableMinimap and BagSync_MinimapButton and BagSync_MinimapButton:IsVisible() then
-		BagSync_MinimapButton:Hide()
-	end
-
-	self:RegisterEvent('PLAYER_MONEY')
-	self:RegisterEvent('BANKFRAME_OPENED')
-	self:RegisterEvent('BANKFRAME_CLOSED')
-	self:RegisterEvent('GUILDBANKFRAME_OPENED')
-	self:RegisterEvent('GUILDBANKFRAME_CLOSED')
-	self:RegisterEvent('GUILDBANKBAGSLOTS_CHANGED')
-	self:RegisterEvent('BAG_UPDATE')
-	self:RegisterEvent('UNIT_INVENTORY_CHANGED')
-	self:RegisterEvent('GUILD_ROSTER_UPDATE')
-	self:RegisterEvent('MAIL_SHOW')
-	self:RegisterEvent('MAIL_INBOX_UPDATE')
-	self:RegisterEvent("AUCTION_HOUSE_SHOW")
-	self:RegisterEvent("AUCTION_OWNED_LIST_UPDATE")
-
-	--void storage is a pain, they didn't add events for opening and closing... seriously blizzard
-	self:RegisterEvent("VOID_STORAGE_UPDATE")
-	self:RegisterEvent("VOID_STORAGE_CONTENTS_UPDATE")
-	self:RegisterEvent("VOID_TRANSFER_DONE")
-
-	--this will be used for getting the tradeskill link
-	self:RegisterEvent("TRADE_SKILL_SHOW")
-
-	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["search"] then
-				if BagSync_SearchFrame:IsVisible() then
-					BagSync_SearchFrame:Hide()
-				else
-					BagSync_SearchFrame:Show()
-				end
-				return true
-			elseif c and c:lower() == L["gold"] then
-				self:ShowMoneyTooltip()
-				return true
-			elseif c and c:lower() == L["tokens"] then
-				if BagSync_TokensFrame:IsVisible() then
-					BagSync_TokensFrame:Hide()
-				else
-					BagSync_TokensFrame:Show()
-				end
-				return true
-			elseif c and c:lower() == L["profiles"] then
-				if BagSync_ProfilesFrame:IsVisible() then
-					BagSync_ProfilesFrame:Hide()
-				else
-					BagSync_ProfilesFrame:Show()
-				end
-				return true
-			elseif c and c:lower() == L["professions"] then
-				if BagSync_CraftsFrame:IsVisible() then
-					BagSync_CraftsFrame:Hide()
-				else
-					BagSync_CraftsFrame:Show()
-				end
-				return true
-			elseif c and c:lower() == L["fixdb"] then
-				self:FixDB_Data()
-				return true
-			elseif c and c:lower() == L["config"] then
-				InterfaceOptionsFrame_OpenToCategory("BagSync")
-				return true
-			elseif c and c:lower() ~= "" then
-				--do an item search
-				if BagSync_SearchFrame then
-					if not BagSync_SearchFrame:IsVisible() then BagSync_SearchFrame:Show() end
-					BagSync_SearchFrame.SEARCHBTN:SetText(msg)
-					BagSync_SearchFrame:initSearch()
-				end
-				return true
-			end
-		end
-
-		DEFAULT_CHAT_FRAME:AddMessage("BAGSYNC")
-		DEFAULT_CHAT_FRAME:AddMessage(L["/bgs [itemname] - Does a quick search for an item"])
-		DEFAULT_CHAT_FRAME:AddMessage(L["/bgs search - Opens the search window"])
-		DEFAULT_CHAT_FRAME:AddMessage(L["/bgs gold - Displays a tooltip with the amount of gold on each character."])
-		DEFAULT_CHAT_FRAME:AddMessage(L["/bgs tokens - Opens the tokens/currency window."])
-		DEFAULT_CHAT_FRAME:AddMessage(L["/bgs profiles - Opens the profiles window."])
-		DEFAULT_CHAT_FRAME:AddMessage(L["/bgs professions - Opens the professions window."])
-		DEFAULT_CHAT_FRAME:AddMessage(L["/bgs fixdb - Runs the database fix (FixDB) on BagSync."])
-		DEFAULT_CHAT_FRAME:AddMessage(L["/bgs config - Opens the BagSync Config Window"] )
-
-	end
-
-	DEFAULT_CHAT_FRAME:AddMessage("|cFF99CC33BagSync|r [v|cFFDF2B2B"..ver.."|r]   /bgs, /bagsync")
-
-	--we deleted someone with the Profile Window, display name of user deleted
-	if BagSyncOpt.delName then
-		print("|cFFFF0000BagSync: "..L["Profiles"].." "..L["Delete"].." ["..BagSyncOpt.delName.."]!|r")
-		BagSyncOpt.delName = nil
-	end
-
-	self:UnregisterEvent("PLAYER_LOGIN")
-	self.PLAYER_LOGIN = nil
-end
-
-function BagSync:GUILD_ROSTER_UPDATE()
-	if not IsInGuild() and BS_DB.guild then
-		BS_DB.guild = nil
-		self:FixDB_Data(true)
-	elseif IsInGuild() then
-		--if they don't have guild name store it or update it
-		if GetGuildInfo("player") then
-			if not BS_DB.guild or BS_DB.guild ~= GetGuildInfo("player") then
-				BS_DB.guild = GetGuildInfo("player")
-				self:FixDB_Data(true)
-			end
-		end
-	end
-end
-
-function BagSync:PLAYER_MONEY()
-	BS_DB.gold = GetMoney()
-end
-
-------------------------------
---      BANK	            --
-------------------------------
-
-function BagSync:BANKFRAME_OPENED()
-	self.atBank = true
-	self:ScanEntireBank()
-end
-
-function BagSync:BANKFRAME_CLOSED()
-	self.atBank = nil
-end
-
-------------------------------
---      VOID BANK	        --
-------------------------------
-
-local oldVoidFunction = CanUseVoidStorage
-function CanUseVoidStorage()
-	BagSync.atVoidBank = true
-	BagSync:ScanVoidBank()
-	return(oldVoidFunction())
-end
-
-local oldVoidCloseFunction = CloseVoidStorageFrame
-function CloseVoidStorageFrame()
-	BagSync.atVoidBank = nil
-	oldVoidCloseFunction()
-end
-
-function BagSync:VOID_STORAGE_UPDATE()
-	self:ScanVoidBank()
-end
-
-function BagSync:VOID_STORAGE_CONTENTS_UPDATE()
-	self:ScanVoidBank()
-end
-
-function BagSync:VOID_TRANSFER_DONE()
-	self:ScanVoidBank()
-end
-
-------------------------------
---      GUILD BANK	        --
-------------------------------
-
-function BagSync:GUILDBANKFRAME_OPENED()
-	self.atGuildBank = true
-	if not BagSyncOpt.enableGuild then return end
-
-	local numTabs = GetNumGuildBankTabs()
-	for tab = 1, numTabs do
-		-- add this tab to the queue to refresh; if we do them all at once the server bugs and sends massive amounts of events
-		guildTabQueryQueue[tab] = true
-	end
-end
-
-function BagSync:GUILDBANKFRAME_CLOSED()
-	self.atGuildBank = nil
-end
-
-function BagSync:GUILDBANKBAGSLOTS_CHANGED()
-	if not BagSyncOpt.enableGuild then return end
-
-	if self.atGuildBank then
-		-- check if we need to process the queue
-		local tab = next(guildTabQueryQueue)
-		if tab then
-			QueryGuildBankTab(tab)
-			guildTabQueryQueue[tab] = nil
-		else
-			-- the bank is ready for reading
-			self:ScanGuildBank()
-		end
-	end
-end
-
-------------------------------
---      MAILBOX  	        --
-------------------------------
-
-function BagSync:MAIL_SHOW()
-	if self.isCheckingMail then return end
-	if not BagSyncOpt.enableMailbox then return end
-	self:ScanMailbox()
-end
-
-function BagSync:MAIL_INBOX_UPDATE()
-	if self.isCheckingMail then return end
-	if not BagSyncOpt.enableMailbox then return end
-	self:ScanMailbox()
-end
-
-------------------------------
---     AUCTION HOUSE        --
-------------------------------
-
-function BagSync:AUCTION_HOUSE_SHOW()
-	if not BagSyncOpt.enableAuction then return end
-	self:CharRemoveExpired()
-	self:ScanAuctionHouse()
-end
-
-function BagSync:AUCTION_OWNED_LIST_UPDATE()
-	if not BagSyncOpt.enableAuction then return end
-	BS_DB.AH_LastScan = time()
-	self:ScanAuctionHouse()
-end
-
-------------------------------
---     TRADE SKILLS         --
-------------------------------
-
---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 function doRegularTradeSkill(numIndex, dbIdx)
-	local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(numIndex)
-	if name and skillLevel then
-		BS_CD[dbIdx] = format('%s,%s', name, skillLevel)
-	end
-end
-
-function BagSync:TRADE_SKILL_SHOW()
-	--IsTradeSkillLinked() returns true only if trade window was opened from chat link (meaning another player)
-	if (not IsTradeSkillLinked()) then
-
-		local tradename = _G.GetTradeSkillLine()
-		local prof1, prof2, archaeology, fishing, cooking, firstAid = GetProfessions()
-		if not tradename then return end
-
-		--prof1
-		if prof1 and (GetProfessionInfo(prof1) == tradename) and GetTradeSkillListLink() then
-			local skill = select(3, GetProfessionInfo(prof1))
-			BS_CD[1] = { tradename, GetTradeSkillListLink(), skill }
-		elseif prof1 and select(2, GetProfessionInfo(prof1)) and noLinkTS[select(2, GetProfessionInfo(prof1))] then
-			--only store if it's herbalism, skinning, or mining
-			doRegularTradeSkill(prof1, 1)
-		elseif not prof1 and BS_CD[1] then
-			--they removed a profession
-			BS_CD[1] = nil
-		end
-
-		--prof2
-		if prof2 and (GetProfessionInfo(prof2) == tradename) and GetTradeSkillListLink() then
-			local skill = select(3, GetProfessionInfo(prof2))
-			BS_CD[2] = { tradename, GetTradeSkillListLink(), skill }
-		elseif prof2 and select(2, GetProfessionInfo(prof2)) and noLinkTS[select(2, GetProfessionInfo(prof2))] then
-			--only store if it's herbalism, skinning, or mining
-			doRegularTradeSkill(prof2, 2)
-		elseif not prof2 and BS_CD[2] then
-			--they removed a profession
-			BS_CD[2] = nil
-		end
-
-		--archaeology
-		if archaeology then
-			doRegularTradeSkill(archaeology, 3)
-		elseif not archaeology and BS_CD[3] then
-			--they removed a profession
-			BS_CD[3] = nil
-		end
-
-		--fishing
-		if fishing then
-			doRegularTradeSkill(fishing, 4)
-		elseif not fishing and BS_CD[4] then
-			--they removed a profession
-			BS_CD[4] = nil
-		end
-
-		--cooking
-		if cooking and (GetProfessionInfo(cooking) == tradename) and GetTradeSkillListLink() then
-			local skill = select(3, GetProfessionInfo(cooking))
-			BS_CD[5] = { tradename, GetTradeSkillListLink(), skill }
-		elseif not cooking and BS_CD[5] then
-			--they removed a profession
-			BS_CD[5] = nil
-		end
-
-		--firstAid
-		if firstAid and (GetProfessionInfo(firstAid) == tradename) and GetTradeSkillListLink() then
-			local skill = select(3, GetProfessionInfo(firstAid))
-			BS_CD[6] = { tradename, GetTradeSkillListLink(), skill }
-		elseif not firstAid and BS_CD[6] then
-			--they removed a profession
-			BS_CD[6] = nil
-		end
-
-	end
-end
-
-------------------------------
---      BAG UPDATES  	    --
-------------------------------
-
-function BagSync:BAG_UPDATE(event, bagid)
-	--The new token bag or token currency tab has a bag number of -4, lets ignore this bag when new tokens are added
-	--http://www.wowwiki.com/API_TYPE_bagID
-	if bagid == -4 or bagid == -2 then return end --dont do tokens or keyring
-	--if not token bag then proceed
-	if not(bagid == BANK_CONTAINER or bagid > NUM_BAG_SLOTS) or self.atBank or self.atVoidBank then
-		self:OnBagUpdate(bagid)
-	end
-end
-
-function BagSync:UNIT_INVENTORY_CHANGED(event, unit)
-	if unit == 'player' then
-		self:SaveEquipment()
-	end
-end
-
 ----------------------
 --   DB Functions   --
 ----------------------

-function BagSync:StartupDB()
+local function StartupDB()
 	BagSyncDB = BagSyncDB or {}
 	BagSyncDB[currentRealm] = BagSyncDB[currentRealm] or {}
 	BagSyncDB[currentRealm][currentPlayer] = BagSyncDB[currentRealm][currentPlayer] or {}
@@ -627,6 +218,20 @@ end
 --      Local       --
 ----------------------

+--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 function doRegularTradeSkill(numIndex, dbIdx)
+	local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(numIndex)
+	if name and skillLevel then
+		BS_CD[dbIdx] = format('%s,%s', name, skillLevel)
+	end
+end
+
 local function GetBagSize(bagid)
 	if bagid == 'equip' then
 		return NUM_EQUIPMENT_SLOTS
@@ -669,8 +274,35 @@ end
 --  Bag Functions   --
 ----------------------

-function BagSync:SaveBag(bagname, bagid, rollupdate)
-	if not BS_DB then self:StartupDB() end
+local function SaveItem(bagname, bagid, slot)
+	local index = GetTag(bagname, bagid, slot)
+	if not index then return nil end
+
+	--reset our tooltip data since we scanned new items (we want current data not old)
+	lastItem = nil
+	lastDisplayed = {}
+
+	local texture, count = GetContainerItemInfo(bagid, slot)
+
+	if texture then
+		local link = ToShortLink(GetContainerItemLink(bagid, slot))
+		count = count > 1 and count or nil
+
+		--Example ["bag:0:1"] = link, count
+		if (link and count) then
+			BS_DB[index] = format('%s,%d', link, count)
+		else
+			BS_DB[index] = link
+		end
+
+		return
+	end
+
+	BS_DB[index] = nil
+end
+
+local function SaveBag(bagname, bagid, rollupdate)
+	if not BS_DB then StartupDB() end
 	--this portion of the code will save the bag data, (type of bag, size of bag, bag item link, etc..)
 	--this is used later to quickly grab bag data and size without having to go through the whole
 	--song and dance again
@@ -700,39 +332,12 @@ function BagSync:SaveBag(bagname, bagid, rollupdate)
 	--used to scan the entire bag and save it's item data
 	if rollupdate then
 		for slot = 1, GetBagSize(bagid) do
-			self:SaveItem(bagname, bagid, slot)
-		end
-	end
-end
-
-function BagSync:SaveItem(bagname, bagid, slot)
-	local index = GetTag(bagname, bagid, slot)
-	if not index then return nil end
-
-	--reset our tooltip data since we scanned new items (we want current data not old)
-	lastItem = nil
-	lastDisplayed = {}
-
-	local texture, count = GetContainerItemInfo(bagid, slot)
-
-	if texture then
-		local link = ToShortLink(GetContainerItemLink(bagid, slot))
-		count = count > 1 and count or nil
-
-		--Example ["bag:0:1"] = link, count
-		if (link and count) then
-			BS_DB[index] = format('%s,%d', link, count)
-		else
-			BS_DB[index] = link
+			SaveItem(bagname, bagid, slot)
 		end
-
-		return
 	end
-
-	BS_DB[index] = nil
 end

-function BagSync:OnBagUpdate(bagid)
+local function OnBagUpdate(bagid)

 	--this will update the bank/bag slots
 	local bagname
@@ -752,23 +357,23 @@ function BagSync:OnBagUpdate(bagid)
 		return
 	end

-	if self.atBank then
+	if atBank then
 		--force an update of the primary bank container (which is -1, in case something was moved)
 		--blizzard doesn't send a bag update for the -1 bank slot for some reason
 		--true = forces a rollupdate to scan entire bag
-		self:SaveBag('bank', BANK_CONTAINER, true)
+		SaveBag('bank', BANK_CONTAINER, true)
 	end

 	--save the bag data in case it was changed
-	self:SaveBag(bagname, bagid, false)
+	SaveBag(bagname, bagid, false)

 	--now save the item information in the bag
 	for slot = 1, GetBagSize(bagid) do
-		self:SaveItem(bagname, bagid, slot)
+		SaveItem(bagname, bagid, slot)
 	end
 end

-function BagSync:SaveEquipment()
+local function SaveEquipment()

 	--reset our tooltip data since we scanned new items (we want current data not old)
 	lastItem = nil
@@ -795,16 +400,16 @@ function BagSync:SaveEquipment()
 	end
 end

-function BagSync:ScanEntireBank()
+local function ScanEntireBank()
 	--scan the primary Bank Bag -1, for some reason Blizzard never sends updates on it
-	self:SaveBag('bank', BANK_CONTAINER, true)
+	SaveBag('bank', BANK_CONTAINER, true)
 	--NUM_BAG_SLOTS+1 to NUM_BAG_SLOTS+NUM_BANKBAGSLOTS are your bank bags
 	for i = NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + NUM_BANKBAGSLOTS do
-		self:SaveBag('bank', i, true)
+		SaveBag('bank', i, true)
 	end
 end

-function BagSync:ScanVoidBank()
+local function ScanVoidBank()
 	if VoidStorageFrame and VoidStorageFrame:IsShown() then
 		for i = 1, 80 do
 			itemID, textureName, locked, recentDeposit, isFiltered = GetVoidItemInfo(i)
@@ -819,7 +424,7 @@ function BagSync:ScanVoidBank()
 	end
 end

-function BagSync:ScanGuildBank()
+local function ScanGuildBank()
 	--GetCurrentGuildBankTab()
 	if not IsInGuild() then return end

@@ -851,10 +456,10 @@ function BagSync:ScanGuildBank()

 end

-function BagSync:ScanMailbox()
+local function ScanMailbox()
 	--this is to prevent buffer overflow from the CheckInbox() function calling ScanMailbox too much :)
-	if BagSync.isCheckingMail then return end
-	BagSync.isCheckingMail = true
+	if isCheckingMail then return end
+	isCheckingMail = true

 	 --used to initiate mail check from server, for some reason GetInboxNumItems() returns zero sometimes
 	 --even though the user has mail in the mailbox.  This can be attributed to lag.
@@ -905,10 +510,10 @@ function BagSync:ScanMailbox()
 	--store our mail count regardless
 	BS_DB[bChk] = mailCount

-	BagSync.isCheckingMail = nil
+	isCheckingMail = false
 end

-function BagSync:ScanAuctionHouse()
+local function ScanAuctionHouse()
 	local ahCount = 0
 	local numActiveAuctions = GetNumAuctionItems("owner")

@@ -956,7 +561,7 @@ function BagSync:ScanAuctionHouse()
 end

 --this method is global for all toons
-function BagSync:RemoveExpiredAuctions()
+local function RemoveExpiredAuctions()
 	local bChk = GetTag('bd', 'auction_count', 0)
 	local timestampChk = { 30*60, 2*60*60, 12*60*60, 48*60*60 }

@@ -1001,7 +606,7 @@ function BagSync:RemoveExpiredAuctions()
 end

 --this method is retricted to the current toon
-function BagSync:CharRemoveExpired()
+local function CharRemoveExpired()
 	if not BS_DB.AH_LastScan then return end

 	local bChk = GetTag('bd', 'auction_count', 0)
@@ -1044,6 +649,41 @@ end
 --   Money Tooltip    --
 ------------------------

+local function buildMoneyString(money, color)
+
+	local iconSize = 14
+	local goldicon = string.format("\124TInterface\\MoneyFrame\\UI-GoldIcon:%d:%d:1:0\124t ", iconSize, iconSize)
+	local silvericon = string.format("\124TInterface\\MoneyFrame\\UI-SilverIcon:%d:%d:1:0\124t ", iconSize, iconSize)
+	local coppericon = string.format("\124TInterface\\MoneyFrame\\UI-CopperIcon:%d:%d:1:0\124t ", iconSize, iconSize)
+	local moneystring
+	local g,s,c
+	local neg = false
+
+	if(money <0) then
+		neg = true
+		money = money * -1
+	end
+
+	g=floor(money/10000)
+	s=floor((money-(g*10000))/100)
+	c=money-s*100-g*10000
+	moneystring = g..goldicon..s..silvericon..c..coppericon
+
+	if(neg) then
+		moneystring = "-"..moneystring
+	end
+
+	if(color) then
+		if(neg) then
+			moneystring = "|cffff0000"..moneystring.."|r"
+		elseif(money ~= 0) then
+			moneystring = "|cff44dd44"..moneystring.."|r"
+		end
+	end
+
+	return moneystring
+end
+
 function BagSync:ShowMoneyTooltip()
 	local tooltip = getglobal("BagSyncMoneyTooltip") or nil

@@ -1091,61 +731,48 @@ function BagSync:ShowMoneyTooltip()
 	local gldTotal = 0

 	for i=1, table.getn(usrData) do
-		tooltip:AddDoubleLine(usrData[i].name, self:buildMoneyString(usrData[i].gold, false), 1, 1, 1, 1, 1, 1)
+		tooltip:AddDoubleLine(usrData[i].name, buildMoneyString(usrData[i].gold, false), 1, 1, 1, 1, 1, 1)
 		gldTotal = gldTotal + usrData[i].gold
 	end
 	if BagSyncOpt.showTotal and gldTotal > 0 then
 		tooltip:AddLine(" ")
-		tooltip:AddDoubleLine(format(TTL_C, L["Total:"]), self:buildMoneyString(gldTotal, false), 1, 1, 1, 1, 1, 1)
+		tooltip:AddDoubleLine(format(TTL_C, L["Total:"]), buildMoneyString(gldTotal, false), 1, 1, 1, 1, 1, 1)
 	end

 	tooltip:AddLine(" ")
 	tooltip:Show()
 end

-function BagSync:buildMoneyString(money, color)
-
-	local iconSize = 14
-	local goldicon = string.format("\124TInterface\\MoneyFrame\\UI-GoldIcon:%d:%d:1:0\124t ", iconSize, iconSize)
-	local silvericon = string.format("\124TInterface\\MoneyFrame\\UI-SilverIcon:%d:%d:1:0\124t ", iconSize, iconSize)
-	local coppericon = string.format("\124TInterface\\MoneyFrame\\UI-CopperIcon:%d:%d:1:0\124t ", iconSize, iconSize)
-	local moneystring
-	local g,s,c
-	local neg = false
-
-	if(money <0) then
-		neg = true
-		money = money * -1
-	end
-
-	g=floor(money/10000)
-	s=floor((money-(g*10000))/100)
-	c=money-s*100-g*10000
-	moneystring = g..goldicon..s..silvericon..c..coppericon
-
-	if(neg) then
-		moneystring = "-"..moneystring
+------------------------
+--      Tokens        --
+------------------------
+
+local function IsInBG()
+	if (GetNumBattlefieldScores() > 0) then
+		return true
 	end
-
-	if(color) then
-		if(neg) then
-			moneystring = "|cffff0000"..moneystring.."|r"
-		elseif(money ~= 0) then
-			moneystring = "|cff44dd44"..moneystring.."|r"
+	local status, mapName, instanceID, minlevel, maxlevel
+	for i=1, GetMaxBattlefieldID() do
+		status, mapName, instanceID, minlevel, maxlevel, teamSize = GetBattlefieldStatus(i)
+		if status == "active" then
+			return true
 		end
 	end
-
-	return moneystring
+	return false
+end
+
+local function IsInArena()
+	local a,b = IsActiveBattlefieldArena()
+	if (a == nil) then
+		return false
+	end
+	return true
 end

-------------------------
---      Tokens        --
-------------------------
-
-function BagSync:ScanTokens()
+local function ScanTokens()
 	--LETS AVOID TOKEN SPAM AS MUCH AS POSSIBLE
 	if doTokenUpdate == 1 then return end
-	if BagSync:IsInBG() or BagSync:IsInArena() or InCombatLockdown() or UnitAffectingCombat("player") then
+	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
 		doTokenUpdate = 1
 		BagSync:RegisterEvent('PLAYER_REGEN_ENABLED')
@@ -1179,37 +806,7 @@ function BagSync:ScanTokens()

 end

-function BagSync:PLAYER_REGEN_ENABLED()
-	if BagSync:IsInBG() or BagSync:IsInArena() or InCombatLockdown() or UnitAffectingCombat("player") then return end
-	self:UnregisterEvent("PLAYER_REGEN_ENABLED")
-	--were out of an arena or battleground scan the points
-	doTokenUpdate = 0
-	self:ScanTokens()
-end
-
-function BagSync:IsInBG()
-	if (GetNumBattlefieldScores() > 0) then
-		return true
-	end
-	local status, mapName, instanceID, minlevel, maxlevel
-	for i=1, GetMaxBattlefieldID() do
-		status, mapName, instanceID, minlevel, maxlevel, teamSize = GetBattlefieldStatus(i)
-		if status == "active" then
-			return true
-		end
-	end
-	return false
-end
-
-function BagSync:IsInArena()
-	local a,b = IsActiveBattlefieldArena()
-	if (a == nil) then
-		return false
-	end
-	return true
-end
-
-hooksecurefunc("BackpackTokenFrame_Update", BagSync.ScanTokens)
+hooksecurefunc("BackpackTokenFrame_Update", ScanTokens)

 ------------------------
 --      Tooltip!      --
@@ -1434,78 +1031,486 @@ local function AddOwners(frame, link)
 				table.insert(lastDisplayed, getNameColor(k or 'Unknown', pClass).."@"..(infoString or 'unknown'))
 			end

-		end
-
+		end
+
+	end
+
+	--show guildnames last
+	if BagSyncOpt.enableGuild and BagSyncOpt.showGuildNames then
+		for k, v in pairsByKeys(previousGuilds) do
+			--only print stuff higher then zero
+			if v > 0 then
+				frame:AddDoubleLine(format(GN_C, k), format(SILVER, v))
+				table.insert(lastDisplayed, format(GN_C, k).."@"..format(SILVER, v))
+			end
+		end
+	end
+
+	--show grand total if we have something
+	--don't show total if there is only one item
+	if BagSyncOpt.showTotal and grandTotal > 0 and getn(lastDisplayed) > 1 then
+		frame:AddDoubleLine(format(TTL_C, L["Total:"]), format(SILVER, grandTotal))
+		table.insert(lastDisplayed, format(TTL_C, L["Total:"]).."@"..format(SILVER, grandTotal))
+	end
+
+	frame:Show()
+end
+
+--Thanks to Aranarth from wowinterface.  Replaced HookScript with insecure hooks
+local orgTipSetItem = {}
+local orgTipOnUpdate = {}
+
+local function Tip_OnSetItem(self, ...)
+	orgTipSetItem[self](self, ...)
+	local _, itemLink = self:GetItem()
+	if itemLink and GetItemInfo(itemLink) then
+		local itemName = GetItemInfo(itemLink)
+		if not self.BagSyncThrottle then self.BagSyncThrottle = GetTime() end
+		if not self.BagSyncPrevious then self.BagSyncPrevious = itemName end
+		if not self.BagSyncShowOnce and self:GetName() == "GameTooltip" then self.BagSyncShowOnce = true end
+
+		if itemName ~= self.BagSyncPrevious then
+			self.BagSyncPrevious = itemName
+			self.BagSyncThrottle = GetTime()
+		end
+
+		if self:GetName() ~= "GameTooltip" or (GetTime() - self.BagSyncThrottle) >= 0.05 then
+			self.BagSyncShowOnce = nil
+			return AddOwners(self, itemLink)
+		end
+	end
+end
+
+local function Tip_OnUpdate(self, ...)
+	orgTipOnUpdate[self](self, ...)
+	if self:GetName() == "GameTooltip" and self.BagSyncShowOnce and self.BagSyncThrottle and (GetTime() - self.BagSyncThrottle) >= 0.05 then
+		local _, itemLink = self:GetItem()
+		self.BagSyncShowOnce = nil
+		if itemLink then
+			return AddOwners(self, itemLink)
+		end
+	end
+end
+
+for _, tip in next, { GameTooltip, ItemRefTooltip } do
+
+	orgTipSetItem[tip] = tip:GetScript"OnTooltipSetItem"
+	tip:SetScript("OnTooltipSetItem", Tip_OnSetItem)
+
+	if tip == ItemRefTooltip then
+		orgTipOnUpdate[tip] = tip.UpdateTooltip
+		tip.UpdateTooltip = Tip_OnUpdate
+	else
+		orgTipOnUpdate[tip] = tip:GetScript"OnUpdate"
+		tip:SetScript("OnUpdate", Tip_OnUpdate)
+	end
+end
+
+------------------------------
+--    LOGIN HANDLER         --
+------------------------------
+
+function BagSync:PLAYER_LOGIN()
+
+	 BINDING_HEADER_BAGSYNC = "BagSync"
+	 BINDING_NAME_BAGSYNCTOGGLESEARCH = L["Toggle Search"]
+	 BINDING_NAME_BAGSYNCTOGGLETOKENS = L["Toggle Tokens"]
+	 BINDING_NAME_BAGSYNCTOGGLEPROFILES = L["Toggle Profiles"]
+	 BINDING_NAME_BAGSYNCTOGGLECRAFTS = L["Toggle Professions"]
+
+
+	local ver = GetAddOnMetadata("BagSync","Version") or 0
+
+	--load our player info after login
+	currentPlayer = UnitName('player')
+	currentRealm = GetRealmName()
+	playerClass = select(2, UnitClass("player"))
+	playerFaction = UnitFactionGroup("player")
+
+	--initiate the db
+	StartupDB()
+
+	--do DB cleanup check by version number
+	if BagSyncDB.dbversion then
+		--remove old variable and replace with BagSyncOpt DB
+		BagSyncDB.dbversion = nil
+		BagSyncOpt.dbversion = ver
+		self:FixDB_Data()
+	elseif not BagSyncOpt.dbversion or BagSyncOpt.dbversion ~= ver then
+		self:FixDB_Data()
+		BagSyncOpt.dbversion = ver
+	end
+
+	--save the current user money (before bag update)
+	if BS_DB["gold:0:0"] then BS_DB["gold:0:0"] = nil end --remove old format
+	BS_DB.gold = GetMoney()
+
+	--save the class information
+	if BS_DB["class:0:0"] then BS_DB["class:0:0"] = nil end --remove old format
+	BS_DB.class = playerClass
+
+	--save the faction information
+	--"Alliance", "Horde" or nil
+	if BS_DB["faction:0:0"] then BS_DB["faction:0:0"] = nil end --remove old format
+	BS_DB.faction = playerFaction
+
+	--check for player not in guild
+	if IsInGuild() or GetNumGuildMembers(true) > 0 then
+		GuildRoster()
+	elseif BS_DB.guild then
+		BS_DB.guild = nil
+		self:FixDB_Data(true)
+	end
+
+	--save all inventory data, including backpack(0)
+	for i = BACKPACK_CONTAINER, BACKPACK_CONTAINER + NUM_BAG_SLOTS do
+		SaveBag('bag', i, true)
+	end
+
+	--force an equipment scan
+	SaveEquipment()
+
+	--force token scan
+	ScanTokens()
+
+	--clean up old auctions
+	RemoveExpiredAuctions()
+
+	--check for minimap toggle
+	if BagSyncOpt.enableMinimap and BagSync_MinimapButton and not BagSync_MinimapButton:IsVisible() then
+		BagSync_MinimapButton:Show()
+	elseif not BagSyncOpt.enableMinimap and BagSync_MinimapButton and BagSync_MinimapButton:IsVisible() then
+		BagSync_MinimapButton:Hide()
+	end
+
+	self:RegisterEvent('PLAYER_MONEY')
+	self:RegisterEvent('BANKFRAME_OPENED')
+	self:RegisterEvent('BANKFRAME_CLOSED')
+	self:RegisterEvent('GUILDBANKFRAME_OPENED')
+	self:RegisterEvent('GUILDBANKFRAME_CLOSED')
+	self:RegisterEvent('GUILDBANKBAGSLOTS_CHANGED')
+	self:RegisterEvent('BAG_UPDATE')
+	self:RegisterEvent('UNIT_INVENTORY_CHANGED')
+	self:RegisterEvent('GUILD_ROSTER_UPDATE')
+	self:RegisterEvent('MAIL_SHOW')
+	self:RegisterEvent('MAIL_INBOX_UPDATE')
+	self:RegisterEvent("AUCTION_HOUSE_SHOW")
+	self:RegisterEvent("AUCTION_OWNED_LIST_UPDATE")
+
+	--void storage
+	self:RegisterEvent('VOID_STORAGE_OPEN')
+	self:RegisterEvent('VOID_STORAGE_CLOSE')
+	self:RegisterEvent("VOID_STORAGE_UPDATE")
+	self:RegisterEvent("VOID_STORAGE_CONTENTS_UPDATE")
+	self:RegisterEvent("VOID_TRANSFER_DONE")
+
+	--this will be used for getting the tradeskill link
+	self:RegisterEvent("TRADE_SKILL_SHOW")
+
+	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["search"] then
+				if BagSync_SearchFrame:IsVisible() then
+					BagSync_SearchFrame:Hide()
+				else
+					BagSync_SearchFrame:Show()
+				end
+				return true
+			elseif c and c:lower() == L["gold"] then
+				self:ShowMoneyTooltip()
+				return true
+			elseif c and c:lower() == L["tokens"] then
+				if BagSync_TokensFrame:IsVisible() then
+					BagSync_TokensFrame:Hide()
+				else
+					BagSync_TokensFrame:Show()
+				end
+				return true
+			elseif c and c:lower() == L["profiles"] then
+				if BagSync_ProfilesFrame:IsVisible() then
+					BagSync_ProfilesFrame:Hide()
+				else
+					BagSync_ProfilesFrame:Show()
+				end
+				return true
+			elseif c and c:lower() == L["professions"] then
+				if BagSync_CraftsFrame:IsVisible() then
+					BagSync_CraftsFrame:Hide()
+				else
+					BagSync_CraftsFrame:Show()
+				end
+				return true
+			elseif c and c:lower() == L["fixdb"] then
+				self:FixDB_Data()
+				return true
+			elseif c and c:lower() == L["config"] then
+				InterfaceOptionsFrame_OpenToCategory("BagSync")
+				return true
+			elseif c and c:lower() ~= "" then
+				--do an item search
+				if BagSync_SearchFrame then
+					if not BagSync_SearchFrame:IsVisible() then BagSync_SearchFrame:Show() end
+					BagSync_SearchFrame.SEARCHBTN:SetText(msg)
+					BagSync_SearchFrame:initSearch()
+				end
+				return true
+			end
+		end
+
+		DEFAULT_CHAT_FRAME:AddMessage("BAGSYNC")
+		DEFAULT_CHAT_FRAME:AddMessage(L["/bgs [itemname] - Does a quick search for an item"])
+		DEFAULT_CHAT_FRAME:AddMessage(L["/bgs search - Opens the search window"])
+		DEFAULT_CHAT_FRAME:AddMessage(L["/bgs gold - Displays a tooltip with the amount of gold on each character."])
+		DEFAULT_CHAT_FRAME:AddMessage(L["/bgs tokens - Opens the tokens/currency window."])
+		DEFAULT_CHAT_FRAME:AddMessage(L["/bgs profiles - Opens the profiles window."])
+		DEFAULT_CHAT_FRAME:AddMessage(L["/bgs professions - Opens the professions window."])
+		DEFAULT_CHAT_FRAME:AddMessage(L["/bgs fixdb - Runs the database fix (FixDB) on BagSync."])
+		DEFAULT_CHAT_FRAME:AddMessage(L["/bgs config - Opens the BagSync Config Window"] )
+
 	end

-	--show guildnames last
-	if BagSyncOpt.enableGuild and BagSyncOpt.showGuildNames then
-		for k, v in pairsByKeys(previousGuilds) do
-			--only print stuff higher then zero
-			if v > 0 then
-				frame:AddDoubleLine(format(GN_C, k), format(SILVER, v))
-				table.insert(lastDisplayed, format(GN_C, k).."@"..format(SILVER, v))
+	DEFAULT_CHAT_FRAME:AddMessage("|cFF99CC33BagSync|r [v|cFFDF2B2B"..ver.."|r]   /bgs, /bagsync")
+
+	--we deleted someone with the Profile Window, display name of user deleted
+	if BagSyncOpt.delName then
+		print("|cFFFF0000BagSync: "..L["Profiles"].." "..L["Delete"].." ["..BagSyncOpt.delName.."]!|r")
+		BagSyncOpt.delName = nil
+	end
+
+	self:UnregisterEvent("PLAYER_LOGIN")
+	self.PLAYER_LOGIN = nil
+end
+
+------------------------------
+--      Event Handlers      --
+------------------------------
+
+function BagSync: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
+	doTokenUpdate = 0
+	ScanTokens()
+end
+
+function BagSync:GUILD_ROSTER_UPDATE()
+	if not IsInGuild() and BS_DB.guild then
+		BS_DB.guild = nil
+		self:FixDB_Data(true)
+	elseif IsInGuild() then
+		--if they don't have guild name store it or update it
+		if GetGuildInfo("player") then
+			if not BS_DB.guild or BS_DB.guild ~= GetGuildInfo("player") then
+				BS_DB.guild = GetGuildInfo("player")
+				self:FixDB_Data(true)
 			end
 		end
 	end
-
-	--show grand total if we have something
-	--don't show total if there is only one item
-	if BagSyncOpt.showTotal and grandTotal > 0 and getn(lastDisplayed) > 1 then
-		frame:AddDoubleLine(format(TTL_C, L["Total:"]), format(SILVER, grandTotal))
-		table.insert(lastDisplayed, format(TTL_C, L["Total:"]).."@"..format(SILVER, grandTotal))
+end
+
+function BagSync:PLAYER_MONEY()
+	BS_DB.gold = GetMoney()
+end
+
+------------------------------
+--      BAG UPDATES  	    --
+------------------------------
+
+function BagSync:BAG_UPDATE(event, bagid)
+	--The new token bag or token currency tab has a bag number of -4, lets ignore this bag when new tokens are added
+	--http://www.wowwiki.com/API_TYPE_bagID
+	if bagid == -4 or bagid == -2 then return end --dont do tokens or keyring
+	--if not token bag then proceed
+	if not(bagid == BANK_CONTAINER or bagid > NUM_BAG_SLOTS) or atBank or atVoidBank then
+		OnBagUpdate(bagid)
 	end
+end

-	frame:Show()
+function BagSync:UNIT_INVENTORY_CHANGED(event, unit)
+	if unit == 'player' then
+		SaveEquipment()
+	end
 end

---Thanks to Aranarth from wowinterface.  Replaced HookScript with insecure hooks
-local orgTipSetItem = {}
-local orgTipOnUpdate = {}
+------------------------------
+--      BANK	            --
+------------------------------

-local function Tip_OnSetItem(self, ...)
-	orgTipSetItem[self](self, ...)
-	local _, itemLink = self:GetItem()
-	if itemLink and GetItemInfo(itemLink) then
-		local itemName = GetItemInfo(itemLink)
-		if not self.BagSyncThrottle then self.BagSyncThrottle = GetTime() end
-		if not self.BagSyncPrevious then self.BagSyncPrevious = itemName end
-		if not self.BagSyncShowOnce and self:GetName() == "GameTooltip" then self.BagSyncShowOnce = true end
+function BagSync:BANKFRAME_OPENED()
+	atBank = true
+	ScanEntireBank()
+end

-		if itemName ~= self.BagSyncPrevious then
-			self.BagSyncPrevious = itemName
-			self.BagSyncThrottle = GetTime()
-		end
+function BagSync:BANKFRAME_CLOSED()
+	atBank = false
+end

-		if self:GetName() ~= "GameTooltip" or (GetTime() - self.BagSyncThrottle) >= 0.05 then
-			self.BagSyncShowOnce = nil
-			return AddOwners(self, itemLink)
-		end
+------------------------------
+--      VOID BANK	        --
+------------------------------
+
+function BagSync:VOID_STORAGE_OPEN()
+	atVoidBank = true
+	ScanVoidBank()
+end
+
+function BagSync:VOID_STORAGE_CLOSE()
+	atVoidBank = false
+end
+
+function BagSync:VOID_STORAGE_UPDATE()
+	ScanVoidBank()
+end
+
+function BagSync:VOID_STORAGE_CONTENTS_UPDATE()
+	ScanVoidBank()
+end
+
+function BagSync:VOID_TRANSFER_DONE()
+	ScanVoidBank()
+end
+
+------------------------------
+--      GUILD BANK	        --
+------------------------------
+
+function BagSync:GUILDBANKFRAME_OPENED()
+	atGuildBank = true
+	if not BagSyncOpt.enableGuild then return end
+
+	local numTabs = GetNumGuildBankTabs()
+	for tab = 1, numTabs do
+		-- add this tab to the queue to refresh; if we do them all at once the server bugs and sends massive amounts of events
+		guildTabQueryQueue[tab] = true
 	end
 end

-local function Tip_OnUpdate(self, ...)
-	orgTipOnUpdate[self](self, ...)
-	if self:GetName() == "GameTooltip" and self.BagSyncShowOnce and self.BagSyncThrottle and (GetTime() - self.BagSyncThrottle) >= 0.05 then
-		local _, itemLink = self:GetItem()
-		self.BagSyncShowOnce = nil
-		if itemLink then
-			return AddOwners(self, itemLink)
+function BagSync:GUILDBANKFRAME_CLOSED()
+	atGuildBank = false
+end
+
+function BagSync:GUILDBANKBAGSLOTS_CHANGED()
+	if not BagSyncOpt.enableGuild then return end
+
+	if atGuildBank then
+		-- check if we need to process the queue
+		local tab = next(guildTabQueryQueue)
+		if tab then
+			QueryGuildBankTab(tab)
+			guildTabQueryQueue[tab] = nil
+		else
+			-- the bank is ready for reading
+			ScanGuildBank()
 		end
 	end
 end

-for _, tip in next, { GameTooltip, ItemRefTooltip } do
-
-	orgTipSetItem[tip] = tip:GetScript"OnTooltipSetItem"
-	tip:SetScript("OnTooltipSetItem", Tip_OnSetItem)
-
-	if tip == ItemRefTooltip then
-		orgTipOnUpdate[tip] = tip.UpdateTooltip
-		tip.UpdateTooltip = Tip_OnUpdate
-	else
-		orgTipOnUpdate[tip] = tip:GetScript"OnUpdate"
-		tip:SetScript("OnUpdate", Tip_OnUpdate)
-	end
+------------------------------
+--      MAILBOX  	        --
+------------------------------
+
+function BagSync:MAIL_SHOW()
+	if isCheckingMail then return end
+	if not BagSyncOpt.enableMailbox then return end
+	ScanMailbox()
+end
+
+function BagSync:MAIL_INBOX_UPDATE()
+	if isCheckingMail then return end
+	if not BagSyncOpt.enableMailbox then return end
+	ScanMailbox()
+end
+
+------------------------------
+--     AUCTION HOUSE        --
+------------------------------
+
+function BagSync:AUCTION_HOUSE_SHOW()
+	if not BagSyncOpt.enableAuction then return end
+	CharRemoveExpired()
+	ScanAuctionHouse()
+end
+
+function BagSync:AUCTION_OWNED_LIST_UPDATE()
+	if not BagSyncOpt.enableAuction then return end
+	BS_DB.AH_LastScan = time()
+	ScanAuctionHouse()
 end

+------------------------------
+--     PROFESSION           --
+------------------------------
+
+function BagSync:TRADE_SKILL_SHOW()
+	--IsTradeSkillLinked() returns true only if trade window was opened from chat link (meaning another player)
+	if (not IsTradeSkillLinked()) then
+
+		local tradename = _G.GetTradeSkillLine()
+		local prof1, prof2, archaeology, fishing, cooking, firstAid = GetProfessions()
+		if not tradename then return end
+
+		--prof1
+		if prof1 and (GetProfessionInfo(prof1) == tradename) and GetTradeSkillListLink() then
+			local skill = select(3, GetProfessionInfo(prof1))
+			BS_CD[1] = { tradename, GetTradeSkillListLink(), skill }
+		elseif prof1 and select(2, GetProfessionInfo(prof1)) and noLinkTS[select(2, GetProfessionInfo(prof1))] then
+			--only store if it's herbalism, skinning, or mining
+			doRegularTradeSkill(prof1, 1)
+		elseif not prof1 and BS_CD[1] then
+			--they removed a profession
+			BS_CD[1] = nil
+		end
+
+		--prof2
+		if prof2 and (GetProfessionInfo(prof2) == tradename) and GetTradeSkillListLink() then
+			local skill = select(3, GetProfessionInfo(prof2))
+			BS_CD[2] = { tradename, GetTradeSkillListLink(), skill }
+		elseif prof2 and select(2, GetProfessionInfo(prof2)) and noLinkTS[select(2, GetProfessionInfo(prof2))] then
+			--only store if it's herbalism, skinning, or mining
+			doRegularTradeSkill(prof2, 2)
+		elseif not prof2 and BS_CD[2] then
+			--they removed a profession
+			BS_CD[2] = nil
+		end
+
+		--archaeology
+		if archaeology then
+			doRegularTradeSkill(archaeology, 3)
+		elseif not archaeology and BS_CD[3] then
+			--they removed a profession
+			BS_CD[3] = nil
+		end
+
+		--fishing
+		if fishing then
+			doRegularTradeSkill(fishing, 4)
+		elseif not fishing and BS_CD[4] then
+			--they removed a profession
+			BS_CD[4] = nil
+		end
+
+		--cooking
+		if cooking and (GetProfessionInfo(cooking) == tradename) and GetTradeSkillListLink() then
+			local skill = select(3, GetProfessionInfo(cooking))
+			BS_CD[5] = { tradename, GetTradeSkillListLink(), skill }
+		elseif not cooking and BS_CD[5] then
+			--they removed a profession
+			BS_CD[5] = nil
+		end
+
+		--firstAid
+		if firstAid and (GetProfessionInfo(firstAid) == tradename) and GetTradeSkillListLink() then
+			local skill = select(3, GetProfessionInfo(firstAid))
+			BS_CD[6] = { tradename, GetTradeSkillListLink(), skill }
+		elseif not firstAid and BS_CD[6] then
+			--they removed a profession
+			BS_CD[6] = nil
+		end
+
+	end
+end
diff --git a/BagSync_Crafts.lua b/BagSync_Crafts.lua
index ea6c716..e5dc424 100644
--- a/BagSync_Crafts.lua
+++ b/BagSync_Crafts.lua
@@ -75,7 +75,11 @@ local function LoadSlider()
 					if craftsTable[i + offset].isHeader then
 						row.title:SetText("|cFFFFFFFF"..craftsTable[i + offset].name.."|r")
 					else
-						row.title:SetText( format('|cFF99CC33%s|r |cFFFFFFFF(%s)|r', craftsTable[i + offset].name,  craftsTable[i + offset].level))
+						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