Quantcast

The "addon" table now has seven new sub-tables: custom_list, mob_list, quest_list, reputation_list, trainer_list, seasonal_list, and vendor_list - this was done in an effort to be rid of the practice of passing tables to other files via function parameters.

torhal [11-19-09 - 03:31]
The "addon" table now has seven new sub-tables: custom_list, mob_list, quest_list, reputation_list, trainer_list, seasonal_list, and vendor_list - this was done in an effort to be rid of the practice of passing tables to other files via function parameters.
New file: Player.lua - contains functions which were ripped from other files and re-worked or re-written to support the notion that the player is its own entity.
addon:DisplayFrame() now only has one parameter, down from nine, due to no longer passing tables between files in that manner.
Replaced all occurrences of "playerData" with "Player", and all of its subtables named "playerWhatever" are now simply "Whatever".
Removed addon:SetRepDB() - it was never used anywhere and was only a wrapper function anyway.
Tidied up CheckDisplayFaction() a bit.
Removed some "local globals" and replaced them with per-use definitions where applicable.
SetProgressBar() no longer has a parameter.
In addon:DisplayFrame(): Removed a call to WipeDisplayStrings(), since initDisplayStrings() calls it itself.
In AckisRecipeList.lua: Renamed NUM_FLAGS to NUM_FILTER_FLAGS.
Filename
ARLFrame.lua
AckisRecipeList.lua
AckisRecipeList.toc
Player.lua
diff --git a/ARLFrame.lua b/ARLFrame.lua
index a94f058..ce30d10 100644
--- a/ARLFrame.lua
+++ b/ARLFrame.lua
@@ -73,6 +73,7 @@ local L			= LibStub("AceLocale-3.0"):GetLocale(MODNAME)
 local QTip		= LibStub("LibQTip-1.0")

 local MainPanel		= CreateFrame("Frame", "AckisRecipeList.Frame", UIParent)
+local Player		= addon.Player

 -------------------------------------------------------------------------------
 -- Constants
@@ -84,22 +85,29 @@ local SEASONAL_CATEGORY = GetCategoryInfo(155)	-- Localized string - "World Even
 -- Variables
 -------------------------------------------------------------------------------
 local currentProfIndex = 0
-local currentProfession = ""
 local FilterValueMap		-- Assigned in addon:InitializeFrame()
 local DisplayStrings = {}
-local myFaction = ""

 -------------------------------------------------------------------------------
 -- Tables assigned in addon:DisplayFrame()
 -------------------------------------------------------------------------------
-local recipeDB, trainerDB, vendorDB, questDB, repDB, seasonDB, customDB, mobDB
-
 local allSpecTable
-local playerData

 local sortedRecipeIndex

 -------------------------------------------------------------------------------
+-- TODO: Get rid of this shit. None of these should be "local globals", as it
+-- encourages thoughtless coding practices. -Torhal
+-------------------------------------------------------------------------------
+local customDB	= addon.custom_list
+local mobDB	= addon.mob_list
+local questDB	= addon.quest_list
+local recipeDB	= addon.recipe_list
+local seasonDB	= addon.seasonal_list
+local trainerDB	= addon.trainer_list
+local vendorDB	= addon.vendor_list
+
+-------------------------------------------------------------------------------
 -- Fonts
 -------------------------------------------------------------------------------
 local narrowFont
@@ -263,7 +271,7 @@ end
 -- skill level or faction to learn it.
 -------------------------------------------------------------------------------
 local function ColourSkillLevel(recipeEntry, hasFaction, recStr)
-	local playerSkill = playerData.playerProfessionLevel
+	local playerSkill = Player.ProfessionLevel
 	local recipeSkill = recipeEntry["Level"]
 	local recipeOrange = recipeEntry["Orange"]
 	local recipeYellow = recipeEntry["Yellow"]
@@ -301,17 +309,15 @@ local factionNeutral	= BFAC["Neutral"]
 local A_TRAINER, A_VENDOR, A_MOB, A_QUEST, A_SEASONAL, A_REPUTATION, A_WORLD_DROP, A_CUSTOM, A_PVP, A_MAX = 1, 2, 3, 4, 5, 6, 7, 8, 9, 9

 local function CheckDisplayFaction(filterDB, faction)
-
-	if (filterDB.general.faction ~= true) then
-		if ((faction == BFAC[myFaction]) or (faction == factionNeutral) or (faction == nil)) then
-			return true
-		else
-			return false
-		end
-	else
+	if filterDB.general.faction then
 		return true
 	end

+	if not faction or faction == BFAC[Player["Faction"]] or faction == factionNeutral then
+		return true
+	else
+		return false
+	end
 end

 do
@@ -369,6 +375,7 @@ do
 		local mapvendor = addon.db.profile.mapvendor
 		local mapmob = addon.db.profile.mapmob
 		local display = false
+		local myFaction = Player["Faction"]

 		-- Trainers - Display if it's your faction or neutral.
 		if (maptrainer) then
@@ -580,7 +587,7 @@ do
 --[[
 		-- Get the proper icon to put on the mini-map
 		for i, k in pairs(SortedProfessions) do
-			if (k["name"] == playerData.playerProfession) then
+			if (k["name"] == Player["Profession"]) then
 				icontext = "Interface\\AddOns\\AckisRecipeList\\img\\" .. k["texture"] .. "_up"
 				break
 			end
@@ -706,52 +713,6 @@ end -- do block
 -------------------------------------------------------------------------------
 -- DisplayString methods.
 -------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--- Description: Function to determine if the player has an appropiate level of faction.
--- Expected result: A boolean value determing if the player can learn the recipe based on faction
--- Input: The database, the index of the recipe, the players faction and reputation levels
--- Output: A boolean indicating if they can learn the recipe or not
-------------------------------------------------------------------------------
-local HasProperRepLevel
-do
-	------------------------------------------------------------------------------
-	-- Reputation constants for special cases.
-	------------------------------------------------------------------------------
-	local REP_MAGHAR	= 941
-	local REP_HONOR_HOLD	= 946
-	local REP_THRALLMAR	= 947
-	local REP_KURENI	= 978
-
-	function HasProperRepLevel(recipeIndex)
-		local has_faction = true
-		local acquire_info = recipeDB[recipeIndex]["Acquire"]
-		local is_alliance = playerData.playerFaction == factionAlliance
-		local player_rep = playerData["Reputation"]
-
-		for index in pairs(acquire_info) do
-			if acquire_info[index]["Type"] == A_REPUTATION then
-				local rep_id = acquire_info[index]["ID"]
-
-				if rep_id == REP_HONOR_HOLD or rep_id == REP_THRALLMAR then
-					rep_id = is_alliance and REP_HONOR_HOLD or REP_THRALLMAR
-				elseif rep_id == REP_MAGHAR or rep_id == REP_KURENI then
-					rep_id = is_alliance and REP_KURENI or REP_MAGHAR
-				end
-				local rep_name = repDB[rep_id]["Name"]
-
-				if not player_rep[rep_name] or player_rep[rep_name] < acquire_info[index]["RepLevel"] then
-					has_faction = false
-				else
-					-- The player's faction level is high enough to learn the recipe. Set to true and break out.
-					has_faction = true
-					break
-				end
-			end
-		end
-		return has_faction
-	end
-end	--do
-
 local function WipeDisplayStrings()
 	for i = 1, #DisplayStrings do
 		ReleaseTable(DisplayStrings[i])
@@ -781,7 +742,7 @@ local function initDisplayStrings(expand_acquires)
 			recStr = (sort_type == "SkillAsc" or sort_type == "SkillDesc") and ("[" .. recipeSkill .. "] - " .. recStr) or (recStr .. " - [" .. recipeSkill .. "]")

 			local t = AcquireTable()
-			t.String = ColourSkillLevel(recipeEntry, HasProperRepLevel(recipeIndex), recStr)
+			t.String = ColourSkillLevel(recipeEntry, Player:HasProperRepLevel(recipeIndex), recStr)

 			t.sID = recipeIndex
 			t.IsRecipe = true
@@ -931,7 +892,7 @@ local function GenerateTooltipContent(owner, rIndex)
 	clr1 = addon:hexcolor("NORMAL")

 	local recipeSkill = recipeDB[rIndex]["Level"]
-	local playerSkill = playerData.playerProfessionLevel
+	local playerSkill = Player.ProfessionLevel

 	if recipeSkill > playerSkill then
 		clr2 = addon:hexcolor("RED")
@@ -977,7 +938,8 @@ local function GenerateTooltipContent(owner, rIndex)
 	-- obtain info
 	ttAdd(0, -1, 0, L["Obtained From"] .. " : ", addon:hexcolor("NORMAL"))

-	local playerFaction = playerData.playerFaction
+	local playerFaction = Player["Faction"]
+	local rep_list = addon.reputation_list

 	-- loop through acquire methods, display each
 	for k, v in pairs(recipeDB[rIndex]["Acquire"]) do
@@ -1135,7 +1097,7 @@ local function GenerateTooltipContent(owner, rIndex)
 			-- RepLevel				RepVendor
 			-- RepVendorZone			RepVendorCoords

-			local repfac = repDB[v["ID"]]
+			local repfac = rep_list[v["ID"]]
 			local repname = repfac["Name"] -- name
 			local rplvl = v["RepLevel"]
 			local repvndr = vendorDB[v["RepVendor"]]
@@ -1409,22 +1371,22 @@ do
 			end

 			-- If the recipe total is at 0, it means we have not scanned the profession yet
-			if playerData.recipes_total == 0 then
+			if Player.recipes_total == 0 then
 				if showpopup then
 					StaticPopup_Show("ARL_NOTSCANNED")
 				end
 				-- We know all the recipes
-			elseif playerData.recipes_known == playerData.recipes_total then
+			elseif Player.recipes_known == Player.recipes_total then
 				if showpopup then
 					StaticPopup_Show("ARL_ALLKNOWN")
 				end
 				-- Our filters are actually filtering something
-			elseif ((playerData.recipes_total_filtered - playerData.recipes_known_filtered) == 0) then
+			elseif ((Player.recipes_total_filtered - Player.recipes_known_filtered) == 0) then
 				if showpopup then
 					StaticPopup_Show("ARL_ALLFILTERED")
 				end
 				-- Our exclusion list is preventing something from being displayed
-			elseif playerData.excluded_recipes_unknown ~= 0 then
+			elseif Player.excluded_recipes_unknown ~= 0 then
 				if showpopup then
 					StaticPopup_Show("ARL_ALLEXCLUDED")
 				end
@@ -1434,15 +1396,15 @@ do
 			else
 				addon:Print(L["NO_DISPLAY"])
 				addon:Print("DEBUG: recipes_total check for 0")
-				addon:Print("DEBUG: recipes_total: " .. playerData.recipes_total)
+				addon:Print("DEBUG: recipes_total: " .. Player.recipes_total)
 				addon:Print("DEBUG: recipes_total check for equal to recipes_total")
-				addon:Print("DEBUG: recipes_known: " .. playerData.recipes_known)
-				addon:Print("DEBUG: recipes_total: " .. playerData.recipes_total)
+				addon:Print("DEBUG: recipes_known: " .. Player.recipes_known)
+				addon:Print("DEBUG: recipes_total: " .. Player.recipes_total)
 				addon:Print("DEBUG: recipes_total_filtered - recipes_known_filtered = 0")
-				addon:Print("DEBUG: recipes_total_filtered: " .. playerData.recipes_total_filtered)
-				addon:Print("DEBUG: recipes_known_filtered: " .. playerData.recipes_known_filtered)
+				addon:Print("DEBUG: recipes_total_filtered: " .. Player.recipes_total_filtered)
+				addon:Print("DEBUG: recipes_known_filtered: " .. Player.recipes_known_filtered)
 				addon:Print("DEBUG: excluded_recipes_unknown ~= 0")
-				addon:Print("DEBUG: excluded_recipes_unknown: " .. playerData.excluded_recipes_unknown)
+				addon:Print("DEBUG: excluded_recipes_unknown: " .. Player.excluded_recipes_unknown)
 			end
 		end
 	end
@@ -1450,22 +1412,22 @@ end	-- do

 -- Description: Updates the progress bar based on the number of known / total recipes

-local function SetProgressBar(playerData)
+local function SetProgressBar()

 	local pbCur, pbMax

 	if (addon.db.profile.includefiltered == true) then
-		pbCur = playerData.recipes_known
-		pbMax = playerData.recipes_total
+		pbCur = Player.recipes_known
+		pbMax = Player.recipes_total
 	-- We're removing filtered recipes from the final count
 	else
-		pbCur = playerData.recipes_known_filtered
-		pbMax = playerData.recipes_total_filtered
+		pbCur = Player.recipes_known_filtered
+		pbMax = Player.recipes_total_filtered
 	end

 	if (not addon.db.profile.includeexcluded and not addon.db.profile.ignoreexclusionlist) then
-		pbCur = pbCur - playerData.excluded_recipes_unknown
-		pbMax = pbMax - playerData.excluded_recipes_known
+		pbCur = pbCur - Player.excluded_recipes_unknown
+		pbMax = pbMax - Player.excluded_recipes_known
 	end

 	ARL_ProgressBar:SetMinMaxValues(0, pbMax)
@@ -1618,10 +1580,10 @@ local function ReDisplay()
 	addon:UpdateFilters()
 	sortedRecipeIndex = SortMissingRecipes(recipeDB)

-	playerData.excluded_recipes_known, playerData.excluded_recipes_unknown = addon:GetExclusions(playerData.playerProfession)
+	Player:MarkExclusions()

 	initDisplayStrings(false)
-	SetProgressBar(playerData)
+	SetProgressBar()

 	-- Make sure our expand all button is set to expandall
 	ARL_ExpandButton:SetText(L["EXPANDALL"])
@@ -1825,9 +1787,6 @@ function addon:CreateExpCB(bName, bTex, panelIndex)
 end

 do
-
-	local currentProfession = nil
-
 	-- Description: Provides logic for when you are clicking the scan button.
 	-- Expected result: Does appropiate task depending on what button has been clicked and the current state.
 	-- Input: None.
@@ -1836,6 +1795,7 @@ do
 	function addon:ToggleFrame()
 		-- What profession is opened?
 		local cprof = GetTradeSkillLine()
+		local current_prof = Player.Profession

 		-- The frame is visible
 		if MainPanel:IsVisible() then
@@ -1846,16 +1806,16 @@ do
 			elseif not IsShiftKeyDown() and IsAltKeyDown() and not IsControlKeyDown() then
 				self:ClearMap()
 			-- If we have the same profession open, then we close the scanned window
-			elseif not IsShiftKeyDown() and not IsAltKeyDown() and not IsControlKeyDown() and currentProfession == cprof then
+			elseif not IsShiftKeyDown() and not IsAltKeyDown() and not IsControlKeyDown() and current_prof == cprof then
 				MainPanel:Hide()
 			-- If we have a different profession open we do a scan
 			elseif not IsShiftKeyDown() and not IsAltKeyDown() and not IsControlKeyDown() then
 				self:Scan(false)
 				self:SetupMap()
-				currentProfession = cprof
+				current_prof = cprof
 			end
 		else
-			currentProfession = cprof
+			current_prof = cprof
 			-- Shift only (Text dump)
 			if IsShiftKeyDown() and not IsAltKeyDown() and not IsControlKeyDown() then
 				self:Scan(true)
@@ -1882,6 +1842,7 @@ local function expandEntry(dsIndex)
 	local filterDB = addon.db.profile.filters
 	local obtainDB = filterDB.obtain
 	local recipeIndex = DisplayStrings[dsIndex].sID
+	local rep_list = addon.reputation_list
 	local pad = "  "

 	dsIndex = dsIndex + 1
@@ -2027,7 +1988,7 @@ local function expandEntry(dsIndex)
 			local rep_vendor = vendorDB[v["RepVendor"]]

 			if CheckDisplayFaction(filterDB, rep_vendor["Faction"]) then
-				t.String = pad .. addon:Rep(L["Reputation"] .. " : ") .. repDB[v["ID"]]["Name"]
+				t.String = pad .. addon:Rep(L["Reputation"] .. " : ") .. rep_list[v["ID"]]["Name"]
 				tinsert(DisplayStrings, dsIndex, t)
 				dsIndex = dsIndex + 1

@@ -2910,7 +2871,7 @@ function addon:InitializeFrame()
 	-- Check to see if we're Horde or Alliance, and change the displayed
 	-- reputation strings to be faction-correct.
 	-------------------------------------------------------------------------------
-	local isAlliance = (myFaction == "Alliance")
+	local isAlliance = (Player.Faction == "Alliance")

 	local HonorHold_Thrallmar_FactionText = isAlliance and BFAC["Honor Hold"] or BFAC["Thrallmar"]
 	local Kurenai_Maghar_FactionText = isAlliance and BFAC["Kurenai"] or BFAC["The Mag'har"]
@@ -3006,7 +2967,7 @@ function addon:InitializeFrame()

 	mode_button:SetScript("OnClick",
 				     function(self, button, down)
-					     -- Known professions should be in playerData["Professions"]
+					     -- Known professions should be in Player["Professions"]

 					     -- This loop is gonna be weird. The reason is because we need to
 					     -- ensure that we cycle through all the known professions, but also
@@ -3038,7 +2999,7 @@ function addon:InitializeFrame()
 						     while (index ~= endLoop) do
 							     if index > NUM_PROFESSIONS then
 								     index = 1
-							     elseif playerData["Professions"][SortedProfessions[index].name] then
+							     elseif Player["Professions"][SortedProfessions[index].name] then
 								     displayProf = index
 								     currentProfIndex = index
 								     break
@@ -3060,7 +3021,7 @@ function addon:InitializeFrame()
 						     while index ~= endLoop do
 							     if index < 1 then
 								     index = NUM_PROFESSIONS
-							     elseif playerData["Professions"][SortedProfessions[index].name] then
+							     elseif Player["Professions"][SortedProfessions[index].name] then
 								     displayProf = index
 								     currentProfIndex = index
 								     break
@@ -3072,11 +3033,10 @@ function addon:InitializeFrame()

 					     -- Redisplay the button with the new skill
 					     self:ChangeTexture(SortedProfessions[currentProfIndex].texture)
-					     playerData.playerProfession = SortedProfessions[currentProfIndex].name
-					     currentProfession = playerData.playerProfession
+					     Player["Profession"] = SortedProfessions[currentProfIndex].name

 					     local is_shown = TradeSkillFrame:IsVisible()
-					     CastSpellByName(currentProfession)
+					     CastSpellByName(Player.Profession)
 					     addon:Scan()

 					     if not is_shown then
@@ -3103,8 +3063,8 @@ function addon:InitializeFrame()
 					     for i = 1, NumSkillLines, 1 do
 						     local skillName, _, _, skillRank = GetSkillLineInfo(i)

-						     if skillName == currentProfession then
-							     playerData.playerProfessionLevel = skillRank
+						     if skillName == Player.Profession then
+							     Player["ProfessionLevel"] = skillRank
 							     break
 						     end
 					     end
@@ -4642,45 +4602,12 @@ end
 -------------------------------------------------------------------------------
 -- Displays the main recipe frame.
 -------------------------------------------------------------------------------
-function addon:DisplayFrame(
-	cPlayer,	-- playerdata
-	asTable,	-- AllSpecialtiesTable
-	trList,		-- TrainerList
-	vList,		-- VendorList
-	qList,		-- QuestList
-	rList,		-- ReputationList
-	sList,		-- SeasonalList
-	mList,		-- MobList
-	cList)		-- Customlist
-	-------------------------------------------------------------------------------
-	-- cPlayer is a table containing:
-	--	.playerProfession == player profession which has been opened
-	--	.playerProfessionLevel == skill level of profession
-	--	.playerSpecialty == Specialty if any or ""
-	--	.totalRecipes == Total recipes added to the database
-	--	.foundRecipes == Total recipes found that the player knows
-	--	.playerFaction == Faction of the player
-	--	["Professions"] == list of all professions with the ones the player knows set as true
-	--	["Reputation"] == Reputation levels, what I had in current ARLform was if you didn't have the rep level, it would display it in red
-	-------------------------------------------------------------------------------
-	myFaction = cPlayer.playerFaction
-
+function addon:DisplayFrame(asTable)	-- AllSpecialtiesTable
 	allSpecTable = asTable
-	playerData = cPlayer
-	currentProfession = playerData.playerProfession
-	trainerDB = trList
-	vendorDB = vList
-	questDB = qList
-	repDB = rList
-	seasonDB = sList
-	mobDB = mList
-	customDB = cList
-
-	WipeDisplayStrings()	-- reset current display items

 	-- get our current profession's index
 	for k, v in pairs(SortedProfessions) do
-		if v.name == currentProfession then
+		if v.name == Player.Profession then
 			currentProfIndex = k
 			break
 		end
@@ -4695,13 +4622,12 @@ function addon:DisplayFrame(
 	MainPanel:ResetTitle()
 	MainPanel.mode_button:ChangeTexture(SortedProfessions[currentProfIndex].texture)

-	-- Acquire the list, then sort it
-	recipeDB = self.recipe_list
+	-- Sort the list
 	sortedRecipeIndex = SortMissingRecipes(recipeDB)

 	-- Fill the DisplayStrings from the sorted list and update the progressbar
 	initDisplayStrings(false)
-	SetProgressBar(cPlayer)
+	SetProgressBar()

 	-- And update our scrollframe
 	RecipeList_Update()
@@ -4764,10 +4690,10 @@ function MainPanel:ResetTitle()
 				total = total + 1
 			end
 		end
-		new_title = "ARL (v." .. addon.version .. ") - " .. currentProfession ..
+		new_title = "ARL (v." .. addon.version .. ") - " .. Player["Profession"] ..
 			" (" .. active .. "/" .. total .. " " .. L["Filters"] .. ")"
 	else
-		new_title = "ARL (v." .. addon.version .. ") - " .. currentProfession
+		new_title = "ARL (v." .. addon.version .. ") - " .. Player["Profession"]
 	end
 	self.HeadingText:SetText(addon:Normal(new_title))
 end
diff --git a/AckisRecipeList.lua b/AckisRecipeList.lua
index 4545486..e950786 100644
--- a/AckisRecipeList.lua
+++ b/AckisRecipeList.lua
@@ -74,7 +74,7 @@ local A_TRAINER, A_VENDOR, A_MOB, A_QUEST, A_SEASONAL, A_REPUTATION, A_WORLD_DRO
 ------------------------------------------------------------------------------
 -- Constants.
 ------------------------------------------------------------------------------
-local NUM_FLAGS = 128
+local NUM_FILTER_FLAGS = 128
 local PROFESSION_INITS = {}	-- Professions initialization functions.

 ------------------------------------------------------------------------------
@@ -91,16 +91,27 @@ local VendorList = {}
 local AllSpecialtiesTable = {}
 local SpecialtyTable

+addon.custom_list	= CustomList
+addon.mob_list		= MobList
+addon.quest_list	= QuestList
+addon.recipe_list	= RecipeList
+addon.reputation_list	= ReputationList
+addon.trainer_list	= TrainerList
+addon.seasonal_list	= SeasonalList
+addon.vendor_list	= VendorList
+
+
 ------------------------------------------------------------------------------
 -- Data which is stored regarding a players statistics (luadoc copied from Collectinator, needs updating)
 ------------------------------------------------------------------------------
 -- @class table
--- @name playerData
+-- @name Player
 -- @field known_filtered Total number of items known filtered during the scan.
--- @field playerFaction Players faction
--- @field playerClass Players class
+-- @field Faction Player's faction
+-- @field Class Player's class
 -- @field ["Reputation"] Listing of players reputation levels
-local playerData = {}
+local Player = {}
+addon.Player = Player

 -- Global Frame Variables
 addon.optionsFrame = {}
@@ -440,8 +451,6 @@ function addon:OnInitialize()
 	self:InitSeasons(SeasonalList)
 	self:InitVendor(VendorList)

-	self.recipe_list = RecipeList
-
 	-------------------------------------------------------------------------------
 	-- Hook GameTooltip so we can show information on mobs that drop/sell/train
 	-------------------------------------------------------------------------------
@@ -479,7 +488,7 @@ function addon:OnInitialize()
 				       for spell_id in pairs(vendor["SellList"]) do
 					       local recipe = RecipeList[spell_id]

-					       if (not recipe["Known"] or shifted) and addon.IsCorrectFaction(playerData.playerFaction, recipe["Flags"]) then
+					       if (not recipe["Known"] or shifted) and Player:IsCorrectFaction(recipe["Flags"]) then
 						       local _, _, _, hex = GetItemQualityColor(recipe["Rarity"])

 						       self:AddLine("Sells: "..hex..recipe["Name"].."|r")
@@ -493,7 +502,7 @@ function addon:OnInitialize()
 				       for spell_id in pairs(trainer["TrainList"]) do
 					       local recipe = RecipeList[spell_id]

-					       if (not recipe["Known"] or shifted) and addon.IsCorrectFaction(playerData.playerFaction, recipe["Flags"]) then
+					       if (not recipe["Known"] or shifted) and Player:IsCorrectFaction(recipe["Flags"]) then
 						       local _, _, _, hex = GetItemQualityColor(recipe["Rarity"])

 						       self:AddLine("Trains: "..hex..recipe["Name"].."|r")
@@ -541,26 +550,29 @@ function addon:OnEnable()
 		ExpandTradeSkillSubClass = function(...) return Skillet:ExpandTradeSkillSubClass(...) end
 	end
 ]]--
-	-- Populate the reputation level
-	self:GetFactionLevels()
-
 	-------------------------------------------------------------------------------
-	-- Initialize the main panel frame
+	-- Initialize the main panel frame.
 	-------------------------------------------------------------------------------
 	self:InitializeFrame()
 	self.InitializeFrame = nil

 	-------------------------------------------------------------------------------
-	-- Initialize the player's data
+	-- Initialize the player's data.
 	-------------------------------------------------------------------------------
 	do
-		playerData.playerFaction = UnitFactionGroup("player")
-		playerData.playerClass = select(2, UnitClass("player"))
+		Player.Faction = UnitFactionGroup("player")
+		Player.Class = select(2, UnitClass("player"))

-		playerData["Reputation"] = {}
-		self:GetFactionLevels(playerData["Reputation"])
+		-------------------------------------------------------------------------------
+		-- Get the player's reputation levels.
+		-------------------------------------------------------------------------------
+		Player["Reputation"] = {}
+		Player:SetReputationLevels()

-		playerData["Professions"] = {
+		-------------------------------------------------------------------------------
+		---Scan first 25 spellbook slots to identify all applicable professions
+		-------------------------------------------------------------------------------
+		Player["Professions"] = {
 			[GetSpellInfo(51304)] = false, -- Alchemy
 			[GetSpellInfo(51300)] = false, -- Blacksmithing
 			[GetSpellInfo(51296)] = false, -- Cooking
@@ -574,11 +586,7 @@ function addon:OnEnable()
 			[GetSpellInfo(45363)] = false, -- Inscription
 			[GetSpellInfo(53428)] = false, -- Runeforging
 		}
-
-		-------------------------------------------------------------------------------
-		---Scan first 25 spellbook slots to identify all applicable professions
-		-------------------------------------------------------------------------------
-		local profession_list = playerData["Professions"]
+		local profession_list = Player["Professions"]

 		-- Reset the table, they may have unlearnt a profession
 		for i in pairs(profession_list) do
@@ -754,64 +762,6 @@ function addon:TRADE_SKILL_CLOSE()
 end

 -------------------------------------------------------------------------------
--- Player Data Acquisition Functions
--------------------------------------------------------------------------------
-
-do
-	local GetNumFactions = GetNumFactions
-	local GetFactionInfo = GetFactionInfo
-	local CollapseFactionHeader = CollapseFactionHeader
-	local ExpandFactionHeader = ExpandFactionHeader
-	local rep_list = {}
-
-	---Scans all reputations to get reputation levels to determine if the player can learn a reputation recipe
-	function addon:GetFactionLevels(RepTable)
-
-		-- Bug here when I reload UI
-		if not RepTable then
-			return
-		end
-		twipe(rep_list)
-
-		-- Number of factions before we expand
-		local numfactions = GetNumFactions()
-
-		-- Lets expand all the headers
-		for i = numfactions, 1, -1 do
-			local name, _, _, _, _, _, _, _, _, isCollapsed = GetFactionInfo(i)
-
-			if isCollapsed then
-				ExpandFactionHeader(i)
-				rep_list[name] = true
-			end
-		end
-
-		-- Number of factions with everything expanded
-		numfactions = GetNumFactions()
-
-		-- Get the rep levels
-		for i = 1, numfactions, 1 do
-			local name, _, replevel = GetFactionInfo(i)
-
-			-- If the rep is greater than neutral
-			if replevel > 4 then
-				-- We use levels of 0, 1, 2, 3, 4 internally for reputation levels, make it correspond here
-				RepTable[name] = replevel - 4
-			end
-		end
-
-		-- Collapse the headers again
-		for i = numfactions, 1, -1 do
-			local name = GetFactionInfo(i)
-
-			if rep_list[name] then
-				CollapseFactionHeader(i)
-			end
-		end
-	end
-end	-- do block
-
--------------------------------------------------------------------------------
 -- Tradeskill functions
 -- Recipe DB Structures are defined in Documentation.lua
 -------------------------------------------------------------------------------
@@ -874,7 +824,7 @@ function addon:addTradeSkill(RecipeDB, SpellID, SkillLevel, ItemID, Rarity, Prof
 	end

 	-- Set all the flags to be false, will also set the padding spaces to false as well.
-	for i = 1, NUM_FLAGS, 1 do
+	for i = 1, NUM_FILTER_FLAGS, 1 do
 		recipe["Flags"][i] = false
 	end
 end
@@ -1110,15 +1060,6 @@ end	-- do
 do
 	local F_ALLIANCE, F_HORDE = 1, 2

-	function addon.IsCorrectFaction(player_faction, flags)
-		if player_faction == BFAC["Alliance"] and flags[F_HORDE] and not flags[F_ALLIANCE] then
-			return false
-		elseif player_faction == BFAC["Horde"] and flags[F_ALLIANCE] and not flags[F_HORDE] then
-			return false
-		end
-		return true
-	end
-
 	-------------------------------------------------------------------------------
 	-- Item "rarity"
 	-------------------------------------------------------------------------------
@@ -1157,22 +1098,12 @@ do
 		-------------------------------------------------------------------------------

 		-- Display both horde and alliance factions?
-		if not general_filters.faction then
-			if playerData.playerFaction == BFAC["Alliance"] then
-				-- Filter out Horde only
-				if not recipe_flags[F_ALLIANCE] and recipe_flags[F_HORDE] then
-					return false
-				end
-			else
-				-- Filter out Alliance only
-				if not recipe_flags[F_HORDE] and recipe_flags[F_ALLIANCE] then
-					return false
-				end
-			end
+		if not general_filters.faction and not Player:IsCorrectFaction(recipe_flags) then
+			return false
 		end

 		-- Display all skill levels?
-		if not general_filters.skill and recipe["Level"] > playerData.playerProfessionLevel then
+		if not general_filters.skill and recipe["Level"] > Player["ProfessionLevel"] then
 			return false
 		end

@@ -1180,7 +1111,7 @@ do
 		if not general_filters.specialty then
 			local specialty = recipe["Specialty"]

-			if specialty and specialty ~= playerData.playerSpecialty then
+			if specialty and specialty ~= Player["Specialty"] then
 				return false
 			end
 		end
@@ -1394,7 +1325,7 @@ do
 		local recipes_total_filtered = 0
 		local recipes_known_filtered = 0
 		local can_display = false
-		local current_profession = playerData.playerProfession
+		local current_profession = Player["Profession"]

 		for recipe_id, recipe in pairs(RecipeList) do
 			if recipe["Profession"] == current_profession then
@@ -1421,10 +1352,10 @@ do
 			end
 			RecipeList[recipe_id]["Display"] = can_display
 		end
-		playerData.recipes_total = recipes_total
-		playerData.recipes_known = recipes_known
-		playerData.recipes_total_filtered = recipes_total_filtered
-		playerData.recipes_known_filtered = recipes_known_filtered
+		Player.recipes_total = recipes_total
+		Player.recipes_known = recipes_known
+		Player.recipes_total_filtered = recipes_total_filtered
+		Player.recipes_known_filtered = recipes_known_filtered
 		end

 end	-- do
@@ -1489,13 +1420,6 @@ do
 	local UnitClass = UnitClass
 	local UnitFactionGroup = UnitFactionGroup

-	---Updates the reputation table.  This only happens more seldom so I'm not worried about efficiency
-	function addon:SetRepDB()
-		if playerData and playerData["Reputation"] then
-			self:GetFactionLevels(playerData["Reputation"])
-		end
-	end
-
 	-- List of tradeskill headers, used in addon:Scan()
 	local header_list = {}

@@ -1510,25 +1434,25 @@ do
 			return
 		end
 		-- Get the name of the currently opened trade skill, along with the current level of the skill.
-		playerData.playerProfession, playerData.playerProfessionLevel = GetTradeSkillLine()
+		Player["Profession"], Player["ProfessionLevel"] = GetTradeSkillLine()

 		-- Get the current profession Specialty
-		local specialty = SpecialtyTable[playerData.playerProfession]
+		local specialty = SpecialtyTable[Player["Profession"]]

 		for index = 1, 25, 1 do
 			local spellName = GetSpellName(index, BOOKTYPE_SPELL)

 			if not spellName or index == 25 then
-				playerData.playerSpecialty = nil
+				Player["Specialty"] = nil
 				break
 			elseif specialty and specialty[spellName] then
-				playerData.playerSpecialty = specialty[spellName]
+				Player["Specialty"] = specialty[spellName]
 				break
 			end
 		end

 		-- Add the recipes to the database
-		playerData.totalRecipes = InitializeRecipe(playerData.playerProfession)
+		Player.totalRecipes = InitializeRecipe(Player["Profession"])

 		--- Set the known flag to false for every recipe in the database.
 		for SpellID in pairs(RecipeList) do
@@ -1602,19 +1526,15 @@ do
 				end
 			end
 		end
-		playerData.foundRecipes = recipes_found
+		Player.foundRecipes = recipes_found

 		self:UpdateFilters()
-
-		-- Mark excluded recipes
-		playerData.excluded_recipes_known, playerData.excluded_recipes_unknown = self:GetExclusions(playerData.playerProfession)
+		Player:MarkExclusions()

 		if textdump then
-			self:DisplayTextDump(RecipeList, playerData.playerProfession)
+			self:DisplayTextDump(RecipeList, Player.Profession)
 		else
-			self:DisplayFrame(playerData, AllSpecialtiesTable,
-					  TrainerList, VendorList, QuestList, ReputationList,
-					  SeasonalList, MobList, CustomList)
+			self:DisplayFrame(AllSpecialtiesTable)
 		end
 	end
 end
@@ -1622,35 +1542,6 @@ end
 -------------------------------------------------------------------------------
 -- Recipe Exclusion Functions
 -------------------------------------------------------------------------------
----Marks all exclusions in the recipe database to not be displayed
-function addon:GetExclusions(prof)
-	local exclusionlist = addon.db.profile.exclusionlist
-	local ignored = not addon.db.profile.ignoreexclusionlist
-	local known_count = 0
-	local unknown_count = 0
-
-	for i in pairs(exclusionlist) do
-		local recipe = RecipeList[i]
-
-		-- We may have an item in the exclusion list that has not been scanned yet
-		-- check if the entry exists in DB first
-		if recipe then
-			if ignored then
-				recipe["Display"] = false
-			end
-
-			local tmpprof = GetSpellInfo(recipe["Profession"])
-
-			if not recipe["Known"] and tmpprof == prof then
-				known_count = known_count + 1
-			elseif tmpprof == prof then
-				unknown_count = unknown_count + 1
-			end
-		end
-	end
-	return known_count, unknown_count
-end
-
 ---Removes or adds a recipe to the exclusion list.
 function addon:ToggleExcludeRecipe(SpellID)
 	local exclusion_list = addon.db.profile.exclusionlist
@@ -1719,7 +1610,7 @@ do
 				local prev

 				-- Find out which flags are marked as "true"
-				for i = 1, NUM_FLAGS, 1 do
+				for i = 1, NUM_FILTER_FLAGS, 1 do
 					if recipe_flags[i] then
 						if prev then
 							tinsert(text_table, ",")
diff --git a/AckisRecipeList.toc b/AckisRecipeList.toc
index 11e86e8..7f58cb4 100644
--- a/AckisRecipeList.toc
+++ b/AckisRecipeList.toc
@@ -67,6 +67,7 @@ ARLConfig.lua
 ARLFrame.lua
 ARLColour.lua
 ARLDatamine.lua
+Player.lua

 # Recipe database files
 database.xml
diff --git a/Player.lua b/Player.lua
new file mode 100644
index 0000000..0550a17
--- /dev/null
+++ b/Player.lua
@@ -0,0 +1,192 @@
+-------------------------------------------------------------------------------
+-- Player.lua		Player functions and data for AckisRecipeList.
+-------------------------------------------------------------------------------
+-- File date: @file-date-iso@
+-- File revision: @file-revision@
+-- Project revision: @project-revision@
+-- Project version: @project-version@
+-------------------------------------------------------------------------------
+-- Please see http://www.wowace.com/projects/arl/for more information.
+-------------------------------------------------------------------------------
+-- License:
+--	Please see LICENSE.txt
+
+-- This source code is released under All Rights Reserved.
+-------------------------------------------------------------------------------
+--- **AckisRecipeList** provides an interface for scanning professions for missing recipes.
+-- There are a set of functions which allow you make use of the ARL database outside of ARL.
+-- ARL supports all professions currently in World of Warcraft 3.2
+-- @class file
+-- @name Player.lua
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Localized Lua globals.
+-------------------------------------------------------------------------------
+local _G = getfenv(0)
+
+local table = _G.table
+local twipe = table.wipe
+
+local pairs = _G.pairs
+
+-------------------------------------------------------------------------------
+-- Localized Blizzard API.
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- AddOn namespace.
+-------------------------------------------------------------------------------
+local LibStub = LibStub
+
+local MODNAME		= "Ackis Recipe List"
+local addon		= LibStub("AceAddon-3.0"):GetAddon(MODNAME)
+
+local BFAC		= LibStub("LibBabble-Faction-3.0"):GetLookupTable()
+local L			= LibStub("AceLocale-3.0"):GetLocale(MODNAME)
+
+local Player		= addon.Player
+
+-------------------------------------------------------------------------------
+-- Constants
+-------------------------------------------------------------------------------
+local F_ALLIANCE, F_HORDE = 1, 2
+local A_TRAINER, A_VENDOR, A_MOB, A_QUEST, A_SEASONAL, A_REPUTATION, A_WORLD_DROP, A_CUSTOM, A_PVP, A_MAX = 1, 2, 3, 4, 5, 6, 7, 8, 9, 9
+
+-------------------------------------------------------------------------------
+-- Variables
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Functions
+-------------------------------------------------------------------------------
+-- Marks all exclusions in the recipe database to not be displayed, updating the
+-- player's known and unknown counts.
+function Player:MarkExclusions()
+	local exclusion_list = addon.db.profile.exclusionlist
+	local ignored = not addon.db.profile.ignoreexclusionlist
+	local recipe_list = addon.recipe_list
+	local known_count = 0
+	local unknown_count = 0
+
+	for i in pairs(exclusion_list) do
+		local recipe = recipe_list[i]
+
+		-- We may have an item in the exclusion list that has not been scanned yet
+		-- check if the entry exists in DB first
+		if recipe then
+			if ignored then
+				recipe["Display"] = false
+			end
+
+			local tmp_prof = GetSpellInfo(recipe["Profession"])
+
+			if not recipe["Known"] and tmp_prof == prof then
+				known_count = known_count + 1
+			elseif tmp_prof == prof then
+				unknown_count = unknown_count + 1
+			end
+		end
+	end
+	self.excluded_recipes_known = known_count
+	self.excluded_recipes_unknown = unknown_count
+end
+
+
+-- Determines if the player has an appropiate level in any applicable faction
+-- to learn the recipe.
+function Player:HasProperRepLevel(recipe_index)
+	-- Reputation constants for special cases.
+	local REP_MAGHAR	= 941
+	local REP_HONOR_HOLD	= 946
+	local REP_THRALLMAR	= 947
+	local REP_KURENI	= 978
+
+	local has_faction = true
+	local is_alliance = self["Faction"] == factionAlliance
+	local player_rep = self["Reputation"]
+	local acquire_info = addon.recipe_list[recipe_index]["Acquire"]
+	local reputations = addon.reputation_list
+
+	for index in pairs(acquire_info) do
+		if acquire_info[index]["Type"] == A_REPUTATION then
+			local rep_id = acquire_info[index]["ID"]
+
+			if rep_id == REP_HONOR_HOLD or rep_id == REP_THRALLMAR then
+				rep_id = is_alliance and REP_HONOR_HOLD or REP_THRALLMAR
+			elseif rep_id == REP_MAGHAR or rep_id == REP_KURENI then
+				rep_id = is_alliance and REP_KURENI or REP_MAGHAR
+			end
+			local rep_name = reputations[rep_id]["Name"]
+
+			if not player_rep[rep_name] or player_rep[rep_name] < acquire_info[index]["RepLevel"] then
+				has_faction = false
+			else
+				-- The player's faction level is high enough to learn the recipe. Set to true and break out.
+				has_faction = true
+				break
+			end
+		end
+	end
+	return has_faction
+end
+
+function Player:IsCorrectFaction(recipe_flags)
+	if self["Faction"] == BFAC["Alliance"] and recipe_flags[F_HORDE] and not recipe_flags[F_ALLIANCE] then
+		return false
+	elseif self["Faction"] == BFAC["Horde"] and recipe_flags[F_ALLIANCE] and not recpie_flags[F_HORDE] then
+		return false
+	end
+	return true
+end
+
+
+do
+	local GetNumFactions = GetNumFactions
+	local GetFactionInfo = GetFactionInfo
+	local CollapseFactionHeader = CollapseFactionHeader
+	local ExpandFactionHeader = ExpandFactionHeader
+	local rep_list = {}
+
+	-- Determines if the player can learn a reputation recipe.
+	-- TODO: This is currently only used in addon:OnEnable(), which means that reputation gains are NOT tracked. This function should be used to do so. -Torhal
+	function Player:SetReputationLevels()
+		twipe(rep_list)
+
+		-- Number of factions before we expand
+		local num_factions = GetNumFactions()
+
+		-- Lets expand all the headers
+		for i = num_factions, 1, -1 do
+			local name, _, _, _, _, _, _, _, _, isCollapsed = GetFactionInfo(i)
+
+			if isCollapsed then
+				ExpandFactionHeader(i)
+				rep_list[name] = true
+			end
+		end
+
+		-- Number of factions with everything expanded
+		num_factions = GetNumFactions()
+
+		-- Get the rep levels
+		for i = 1, num_factions, 1 do
+			local name, _, replevel = GetFactionInfo(i)
+
+			-- If the rep is greater than neutral
+			if replevel > 4 then
+				-- We use levels of 0, 1, 2, 3, 4 internally for reputation levels, make it correspond here
+				self["Reputation"][name] = replevel - 4
+			end
+		end
+
+		-- Collapse the headers again
+		for i = num_factions, 1, -1 do
+			local name = GetFactionInfo(i)
+
+			if rep_list[name] then
+				CollapseFactionHeader(i)
+			end
+		end
+	end
+end	-- do block