Quantcast

Updated .toc in preparation for moving recipes to a character-local saved variable.

pschifferer [12-14-09 - 03:33]
Updated .toc in preparation for moving recipes to a character-local saved variable.
Backed out all changes since r179 and re-applied all of them except memory optimization, partly to address a nasty lock-up that appeared in r185.
Added a re-scanning feature when Cauldron is unable to get reagent info for a recipe.
Added some locale strings for the rescanning feature.
Filename
Cauldron.toc
CauldronMain.lua
CauldronMainUI.lua
CauldronQueue.lua
CauldronShoppingListUI.lua
CauldronTradeskill.lua
Locale/Cauldron-enUS.lua
diff --git a/Cauldron.toc b/Cauldron.toc
index 31cca56..f13cc9d 100755
--- a/Cauldron.toc
+++ b/Cauldron.toc
@@ -6,7 +6,7 @@
 ## RequiredDeps:
 ## OptionalDeps: LibStub, AceAddon-3.0, AceEvent-3.0, AceTimer-3.0, AceConsole-3.0, AceHook-3.0, LibLogger-1.0, LibDataBroker-1.1
 ## SavedVariables: CauldronDB
-## SavedVariablesPerCharacter:
+## SavedVariablesPerCharacter: CauldronLocalDB
 ## DefaultState: enabled
 ## X-Name: Cauldron
 ## X-Category: Tradeskill
diff --git a/CauldronMain.lua b/CauldronMain.lua
index e3d8b2a..07747fa 100644
--- a/CauldronMain.lua
+++ b/CauldronMain.lua
@@ -29,10 +29,17 @@ Cauldron.libs.GUI = LibStub("AceGUI-3.0");
 Cauldron:SetLogLevel(Cauldron.logLevels.INFO);
 -- Cauldron:SetLogLevel(Cauldron.logLevels.DEBUG);

+if not CauldronLocalDB then
+	CauldronLocalDB = {
+		recipes = {},
+		window = {},
+	};
+end
+
 CURRENT_TRADESKILL = "";

 function Cauldron:OnInitialize()
-	local dbDefaults = {
+	local globalDbDefaults = {
 		profile = {
 		},
 		realm = {
@@ -40,11 +47,11 @@ function Cauldron:OnInitialize()
 		},
 		global = {
 			difficulty = {}, -- Stores at what level difficulty is changed for all recipes.
-			recipes = {}, -- Stores the global list of recipes.
 		}
-	}
+	};

-	self.db = LibStub("AceDB-3.0"):New("CauldronDB", dbDefaults)
+	self.db = LibStub("AceDB-3.0"):New("CauldronDB", globalDbDefaults);
+--	self.localDb = LibStub("AceDB-3.0"):New("CauldronLocalDB", localDbDefaults);

 	-- set up slash command options
 	local options = {
@@ -83,7 +90,7 @@ function Cauldron:OnInitialize()
 				type = 'toggle',
 				get = function() return Cauldron:GetLogLevel(); end,
 				set = function(val)
-						self:info("val: "..tostring(val));
+						self:debug("val: "..tostring(val));
 						if val == "debug" then
 							Cauldron:SetLogLevel(Cauldron.logLevels.DEBUG);
 						else
@@ -146,10 +153,17 @@ function Cauldron:OnInitialize()
 end

 function Cauldron:InitPlayer()
-	--@alpha@
+--@alpha@
 	self:debug("InitPlayer enter");
-	--@end-alpha@
+--@end-alpha@

+	-- check if the database needs to be updated
+	if self.db.global.version then
+		-- TODO: future checks
+	else
+		-- TODO: future checks
+	end
+
 	if not self.vars.playername then
 		self.vars.playername = UnitName("player");
 		if not self.db.realm.userdata[self.vars.playername] then
@@ -173,80 +187,25 @@ function Cauldron:InitPlayer()
 		if not self.db.realm.shopping then
 			self.db.realm.shopping = CauldronShopping:NewList();
 		end
-	end
-
-	-- check if the skill database needs to be moved to the new location
-	if not self.db.global.recipes then
-		self.db.global.recipes = {};
-	end
-	-- iterate over each skill for this character
-	for skillName,skillList in pairs(self.db.realm.userdata[self.vars.playername].skills) do
-		-- skip linked tradeskills
-		if not (string.find(skillName, "Linked-")) then
-			-- create the table for the skill
-			if not self.db.global.recipes[skillName] then
-				self.db.global.recipes[skillName] = {};
-			end
-
-			-- iterate over each recipe in the skill
-			for recipeName,recipeInfo in pairs(skillList.recipes) do
-				-- check if the recipe is in not the global list
-				if not self.db.global.recipes[skillName][recipeName] then
-					if recipeInfo.itemLink then
-						-- copy it to the global list
-						self.db.global.recipes[skillName][recipeName] = CopyTable(recipeInfo);
-
-						-- check if we need to reduce this recipe info to character-specific only
-						skillList.recipes[recipeName] = {
-							["index"] = recipeInfo.index,
-							["tradeskill"] = recipeInfo.tradeskill,
-							["difficulty"] = recipeInfo.difficulty,
-							["categories"] = recipeInfo.categories or "",
-							["minMade"] = recipeInfo.minMade,
-							["maxMade"] = recipeInfo.maxMade,
-							["available"] = recipeInfo.available,
-							["reagents"] = {},
-						};
-
-						-- copy reagent skill indexes
-						for _,r in ipairs(recipeInfo.reagents) do
-							table.insert(skillList.recipes[recipeName].reagents, {
-								skillIndex = r.skillIndex,
-							});
-						end
-					end
-				end
-			end
+		--[[
+		if not self.localDb.recipes then
+			self.localDb.recipes = {};
 		end
+		--]]
 	end

-	if not self.db.global.reagentMap then
-		self.db.global.reagentMap = {};
-	end
-	-- iterate over the reagent map for this character
-	if self.db.realm.userdata[self.vars.playername].reagentMap then
-		for recipeName,reagentList in pairs(self.db.realm.userdata[self.vars.playername].reagentMap) do
-			if not self.db.global.reagentMap[recipeName] then
-				self.db.global.reagentMap[recipeName] = {};
-			end
-			for _,info in ipairs(reagentList) do
-				-- add to the global table
-				table.insert(self.db.global.reagentMap[recipeName], info);
-			end
-		end
-		-- remove the character-local reagent map
-		self.db.realm.userdata[self.vars.playername].reagentMap = nil;
-	end
+	-- store the current revision in the database
+	self.db.global.version = Cauldron.version;

-	--@alpha@
+--@alpha@
 	self:debug("InitPlayer exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:OnEnable()
-	--@alpha@
+--@alpha@
 	self:debug("OnEnable enter");
-	--@end-alpha@
+--@end-alpha@

 	-- set init flag, for some callbacks
 	self.initializing = true;
@@ -297,25 +256,25 @@ function Cauldron:OnEnable()
 	-- clear init flag
 	self.initializing = false;

-	--@alpha@
+--@alpha@
 	self:debug("OnEnable exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:OnDisable()
-	--@alpha@
+--@alpha@
 	self:debug("OnDisable enter");
-	--@end-alpha@
+--@end-alpha@

-	--@alpha@
+--@alpha@
 	self:debug("OnDisable exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:OnAddonLoaded(event, addon)
-	--@alpha@
+--@alpha@
 	self:debug("OnAddonLoaded enter");
-	--@end-alpha@
+--@end-alpha@

 	-- show the shopping list?
 	if self.db.profile.showShoppingList then
@@ -326,15 +285,15 @@ function Cauldron:OnAddonLoaded(event, addon)
 		end
 	end

-	--@alpha@
+--@alpha@
 	self:debug("OnAddonLoaded exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:OnEvent(event, ...)
-	--@alpha@
+--@alpha@
 	self:debug("OnEvent enter");
-	--@end-alpha@
+--@end-alpha@

 	if event == "UNIT_PORTRAIT_UPDATE" then
 		local arg1 = ...;
@@ -343,9 +302,9 @@ function Cauldron:OnEvent(event, ...)
 		end
 	end

-	--@alpha@
+--@alpha@
 	self:debug("OnEvent exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:OnTradeShow()
@@ -376,21 +335,21 @@ function Cauldron:OnTradeUpdate()
 end

 function Cauldron:OnTradeClose()
-	--@alpha@
+--@alpha@
 	self:debug("OnTradeClose enter");
-	--@end-alpha@
+--@end-alpha@

 	self:Frame_Hide();

-	--@alpha@
+--@alpha@
 	self:debug("OnTradeClose exit");
-	--@end-alpha@
+--@end-alpha@
 end

-function Cauldron:OnSkillUpdate(event, arg1, arg2)
-	--@alpha@
+function Cauldron:OnSkillUpdate()
+--@alpha@
 	self:debug("OnSkillUpdate enter");
-	--@end-alpha@
+--@end-alpha@

 	if CURRENT_TRADESKILL ~= "" then
 		if not Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[CURRENT_TRADESKILL] then
@@ -410,15 +369,15 @@ function Cauldron:OnSkillUpdate(event, arg1, arg2)

 	self:Frame_Update();

-	--@alpha@
+--@alpha@
 	self:debug("OnSkillUpdate exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:OnTradeSkillRecast()
-	--@alpha@
+--@alpha@
 	self:debug("OnTradeSkillRecast enter");
-	--@end-alpha@
+--@end-alpha@

 	-- keep the processing flag set
 	self.processing = true;
@@ -429,9 +388,9 @@ function Cauldron:OnTradeSkillRecast()

 	self:Frame_Update();

-	--@alpha@
+--@alpha@
 	self:debug("OnTradeSkillRecast exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:OnBagUpdate(event, bagid)
@@ -485,7 +444,7 @@ function Cauldron:OnBagUpdate(event, bagid)
 					local counts = Cauldron:ReagentCount(item);
 					local amount = math.min(counts.has, rItem.amount);
 					local str = string.format("%s: %s: %d/%d", L["Reagent"], item, amount, rItem.amount);
-					if (counts.has - itemCount) < rItem.amount then
+					if amount <= rItem.amount then
 						UIErrorsFrame:AddMessage(str, 0.0, 0.9, 0.0, 86, 3);
 					end
 				end
@@ -537,33 +496,33 @@ function Cauldron:OnBagUpdate(event, bagid)
 end

 function Cauldron:OnCraftShow()
-	--@alpha@
+--@alpha@
 	self:debug("OnCraftShow enter");
-	--@end-alpha@
+--@end-alpha@

 --	TODO

-	--@alpha@
+--@alpha@
 	self:debug("OnCraftShow exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:OnCraftClose()
-	--@alpha@
+--@alpha@
 	self:debug("OnCraftClose enter");
-	--@end-alpha@
+--@end-alpha@

 --	TODO

-	--@alpha@
+--@alpha@
 	self:debug("OnCraftClose exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:OnMerchantShow()
-	--@alpha@
+--@alpha@
 	self:debug("OnMerchantShow enter");
-	--@end-alpha@
+--@end-alpha@

 	-- check if there's anything in the shopping list
 	if CauldronShopping:ContainsItems(Cauldron.db.realm.shopping) then
@@ -574,78 +533,78 @@ function Cauldron:OnMerchantShow()
 		end
 	end

-	--@alpha@
+--@alpha@
 	self:debug("OnMerchantShow exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:OnMerchantClose()
-	--@alpha@
+--@alpha@
 	self:debug("OnMerchantClose enter");
-	--@end-alpha@
+--@end-alpha@

 	if not CauldronShopping:ContainsItems(Cauldron.db.realm.shopping) then
 		Cauldron:HideShoppingList();
 	end

-	--@alpha@
+--@alpha@
 	self:debug("OnMerchantClose exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:OnBankOpened()
-	--@alpha@
+--@alpha@
 	self:debug("OnBankOpened enter");
-	--@end-alpha@
+--@end-alpha@

 	-- check if there's anything in the shopping list
 	if CauldronShopping:ContainsItems(Cauldron.db.realm.shopping) then
 		Cauldron:ShowShoppingList();
 	end

-	--@alpha@
+--@alpha@
 	self:debug("OnBankOpened exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:OnBankClosed()
-	--@alpha@
+--@alpha@
 	self:debug("OnBankClosed enter");
-	--@end-alpha@
+--@end-alpha@

 	if not CauldronShopping:ContainsItems(Cauldron.db.realm.shopping) then
 		Cauldron:HideShoppingList();
 	end

-	--@alpha@
+--@alpha@
 	self:debug("OnBankClosed exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:OnQuestLogChanged()
-	--@alpha@
+--@alpha@
 	self:debug("OnQuestLogChanged enter");
-	--@end-alpha@
+--@end-alpha@

 	-- TODO

-	--@alpha@
+--@alpha@
 	self:debug("OnQuestLogChanged exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:OnAchievementEarned()
-	--@alpha@
+--@alpha@
 	self:debug("OnAchievementEarned enter");
-	--@end-alpha@
+--@end-alpha@

 	-- update the achievement skill map
 	Cauldron:CreateAchievementSkillMap();
 	Cauldron:UpdateSkillList();

-	--@alpha@
+--@alpha@
 	self:debug("OnAchievementEarned exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:OnSpellcastStart(event, unit, spell, rank)
@@ -728,36 +687,35 @@ function Cauldron:OnSpellcastInterrupt(event, unit, spell, rank)
 end

 function Cauldron:OnError()
-	--@alpha@
+--@alpha@
 	self:debug("OnError enter");
-	--@end-alpha@
+--@end-alpha@

 --	TODO

-	--@alpha@
+--@alpha@
 	self:debug("OnError exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:TradeSkillFrame_SetSelection(id)
-	--@alpha@
+--@alpha@
 	self:debug("TradeSkillFrame_SetSelection enter");
-	--@end-alpha@
+--@end-alpha@

 	-- TODO

-	--@alpha@
+--@alpha@
 	self:debug("TradeSkillFrame_SetSelection exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:GetSelectedSkill()
-	--@alpha@
+--@alpha@
 	self:debug("GetSelectedSkill enter");
-	--@end-alpha@
+--@end-alpha@

 	local skillName = CURRENT_TRADESKILL;
-	local baseSkillName = skillName;
 	if IsTradeSkillLinked() then
 		skillName = "Linked-"..skillName;
 	end
@@ -771,27 +729,26 @@ function Cauldron:GetSelectedSkill()

 	for name, info in pairs(self.db.realm.userdata[self.vars.playername].skills[skillName].recipes) do
 		if selected == info.index then
-			return self.db.global.recipes[baseSkillName][name];
+			return info;
 		end
 	end

-	--@alpha@
+--@alpha@
 	self:debug("GetSelectedSkill exit");
-	--@end-alpha@
+--@end-alpha@

 	return nil;
 end

 function Cauldron:QueueAllTradeSkillItem()
-	--@alpha@
+--@alpha@
 	self:debug("QueueAllTradeSkillItem enter");
-	--@end-alpha@
+--@end-alpha@

 	local skillInfo = Cauldron:GetSelectedSkill();
-	local skillData = Cauldron:GetSkillDataForSkill(skillInfo);

-	if skillInfo and skillData then
-		local amount = skillData.available;
+	if skillInfo then
+		local amount = skillInfo.available;
 		local potential = Cauldron:GetPotentialCraftCount(skillInfo);
 		local queueAmount = 0;

@@ -818,15 +775,15 @@ function Cauldron:QueueAllTradeSkillItem()
 		end
 	end

-	--@alpha@
+--@alpha@
 	self:debug("QueueAllTradeSkillItem exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:QueueTradeSkillItem()
-	--@alpha@
+--@alpha@
 	self:debug("QueueTradeSkillItem enter");
-	--@end-alpha@
+--@end-alpha@

 	local skillInfo = Cauldron:GetSelectedSkill();

@@ -843,50 +800,48 @@ function Cauldron:QueueTradeSkillItem()
 		Cauldron:UpdateShoppingListFromQueue();
 	end

-	--@alpha@
+--@alpha@
 	self:debug("QueueTradeSkillItem exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:CreateAllTradeSkillItem()
-	--@alpha@
+--@alpha@
 	self:debug("CreateAllTradeSkillItem enter");
-	--@end-alpha@
+--@end-alpha@

 	if ( (not PartialPlayTime()) and (not NoPlayTime()) ) then
 		CauldronAmountInputBox:ClearFocus();

 		local skillInfo = Cauldron:GetSelectedSkill();
-		local skillData = Cauldron:GetSkillDataForSkill(skillInfo);

-		CauldronAmountInputBox:SetNumber(skillData.available);
+		CauldronAmountInputBox:SetNumber(skillInfo.available);

-		DoTradeSkill(skillData.index, skillData.available);
+		DoTradeSkill(skillInfo.index, skillInfo.available);
 	end

-	--@alpha@
+--@alpha@
 	self:debug("CreateAllTradeSkillItem exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:CreateTradeSkillItem()
-	--@alpha@
+--@alpha@
 	self:debug("CreateTradeSkillItem enter");
-	--@end-alpha@
+--@end-alpha@

 	if ( (not PartialPlayTime()) and (not NoPlayTime()) ) then
 		CauldronAmountInputBox:ClearFocus();

 		local skillInfo = Cauldron:GetSelectedSkill();
 		local amount = CauldronAmountInputBox:GetNumber();
-		local skillData = Cauldron:GetSkillDataForSkill(skillInfo);

-		DoTradeSkill(skillData.index, amount);
+		DoTradeSkill(skillInfo.index, amount);
 	end

-	--@alpha@
+--@alpha@
 	self:debug("CreateTradeSkillItem exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:ProcessQueue()
@@ -915,12 +870,11 @@ function Cauldron:ProcessQueue()
 		queueInfo = queue[1];
 		self:debug("ProcessQueue: queueInfo="..queueInfo.name);
 		skillInfo = Cauldron:GetSkillInfo(queueInfo.tradeskill, queueInfo.name);
-		local skillData = Cauldron:GetSkillDataForSkill(skillInfo);
 		self:debug("ProcessQueue: skillInfo="..tostring(skillInfo));

-		if skillData.available > 0 then
-			self:debug("First item in main queue can be made "..skillData.available.." times");
-			self:SubmitItemToProcess(queueInfo, skillInfo, math.min(skillData.available, queueInfo.amount));
+		if skillInfo.available > 0 then
+			self:debug("First item in main queue can be made "..skillInfo.available.." times");
+			self:SubmitItemToProcess(queueInfo, skillInfo, math.min(skillInfo.available, queueInfo.amount));
 			return;
 --[[		else
 			-- see if queue contains other items that can be made if the first can't be
@@ -930,7 +884,7 @@ function Cauldron:ProcessQueue()
 					skillInfo = Cauldron:GetSkillInfo(queueInfo.tradeskill, queueInfo.name);
 					self:debug("ProcessQueue: skillInfo="..tostring(skillInfo));

-					if skillData.available > 0 then
+					if skillInfo.available > 0 then
 						-- present dialog to user to move item to top of queue
 						Cauldron:ConfirmDialog(L["Confirm"], L["message"],
 							L["Okay"],
@@ -1004,9 +958,7 @@ function Cauldron:SubmitItemToProcess(queueInfo, skillInfo, amount)
 end

 function Cauldron:ProcessItem(skillInfo, queueInfo, amount)
-	--@alpha@
 	self:debug("ProcessItem enter");
-	--@end-alpha@

 	if not skillInfo then
 		self:error("ProcessItem: Missing skill info!");
@@ -1019,11 +971,11 @@ function Cauldron:ProcessItem(skillInfo, queueInfo, amount)

 	if ((not PartialPlayTime()) and (not NoPlayTime())) then
 		-- record the item we're making
-		self:info("skillInfo.itemLink: "..tostring(skillInfo.itemLink));
+		self:debug("skillInfo.itemLink: "..tostring(skillInfo.itemLink));
 		self.makingItem = Cauldron:GetNameFromLink(queueInfo.link);
-		self:info("makingItem: "..tostring(self.makingItem));
+		self:debug("makingItem: "..tostring(self.makingItem));
 --		self.makingItemId = Cauldron:GetIdFromLink(skillInfo.itemLink);
---		self:info("makingItemId: "..tostring(self.makingItemId));
+--		self:debug("makingItemId: "..tostring(self.makingItemId));
 		self.itemCurrentCount = GetItemCount(skillInfo.itemLink);

 		self.makingItemSpell = Cauldron:GetNameFromLink(queueInfo.link);
@@ -1034,16 +986,13 @@ function Cauldron:ProcessItem(skillInfo, queueInfo, amount)
 		self:Print(string.format(L["Crafting %1$d of %2$s..."], amount, queueInfo.link));

 		-- do it
-		local skillData = Cauldron:GetSkillDataForSkill(skillInfo);
 		self.processing = true;
-		DoTradeSkill(skillData.index, amount);
+		DoTradeSkill(skillInfo.index, amount);
 	else
 		-- TODO: notify player?
 	end

-	--@alpha@
 	self:debug("ProcessItem exit");
-	--@end-alpha@
 end

 function Cauldron:RemoveQueueItem(name)
@@ -1067,9 +1016,9 @@ function Cauldron:IncreaseItemCount(name)
 end

 function Cauldron:GetQueue(player)
-	--@alpha@
+--@alpha@
 	self:debug("GetQueue enter");
-	--@end-alpha@
+--@end-alpha@

 	if not player then
 		player = self.vars.playername;
@@ -1081,9 +1030,9 @@ function Cauldron:GetQueue(player)
 		self.db.realm.userdata[player].queue = queue;
 	end

-	--@alpha@
+--@alpha@
 	self:debug("GetQueue enter");
-	--@end-alpha@
+--@end-alpha@

 	return queue;
 end
@@ -1176,17 +1125,16 @@ function Cauldron:AddToTooltip(tooltip, id)
 					favInfo = " ";
 				end
 				local skillInfo = Cauldron:GetSkillInfoForLink(skillLink);
-				local skillData = Cauldron:GetSkillDataForSkill(skillInfo);
 				local color;
 				if TradeSkillTypeColor then
-					color = TradeSkillTypeColor[skillData.difficulty];
+					color = TradeSkillTypeColor[skillInfo.difficulty];
 				else
 					local colorMap = {
 						optimal = {r=1.0, g=0.5, b=0.25},
 						medium = {r=1.0, g=1.0, b=0.0},
 						easy = {r=0.25, g=0.75, b=0.25},
 					};
-					color = colorMap[skillData.difficulty];
+					color = colorMap[skillInfo.difficulty];
 				end
 				local colorStr = "|r";
 				if color then
@@ -1213,10 +1161,9 @@ function Cauldron:AddToTooltip(tooltip, id)
 					levelInfo = " ";
 				end
 				local skillInfo = Cauldron:GetSkillInfoForLink(skillLink);
-				local skillData = Cauldron:GetSkillDataForSkill(skillInfo);
 				local color;
 				if TradeSkillTypeColor then
-					color = TradeSkillTypeColor[skillData.difficulty];
+					color = TradeSkillTypeColor[skillInfo.difficulty];
 --				else
 --					color = {r=1.0, g=1.0, b=1.0};
 				end
@@ -1277,10 +1224,9 @@ function filterSkillups(skillList)
 	for i,skill in ipairs(skillList) do
 		local skillName, skillLink = string.split(";", skill, 2);
 		local skillInfo = Cauldron:GetSkillInfoForLink(skillLink);
-		local skillData = Cauldron:GetSkillDataForSkill(skillInfo);

-		if skillInfo and skillData then
-			if difficulty[skillData.difficulty] > 1 then
+		if skillInfo then
+			if difficulty[skillInfo.difficulty] > 1 then
 				table.insert(skillups, skill);
 			end
 		end
@@ -1509,8 +1455,6 @@ end
 			["<reagent name>"] = <amount>,
 		},
 	},
-	["global"] = {
-	},

 --]]

diff --git a/CauldronMainUI.lua b/CauldronMainUI.lua
index 5fd4d84..36e0837 100644
--- a/CauldronMainUI.lua
+++ b/CauldronMainUI.lua
@@ -41,8 +41,8 @@ function Cauldron:Frame_Show()
 			TradeSkillFrame:SetFrameLevel(1);
 			-- set the tradeskill frame's width to match ours
 --			TradeSkillFrame:SetWidth(692);
-
-			--[[
+
+			--[[
 			-- remove the tradeskill frame from the special frame list
 			for i,t in ipairs(UISpecialFrames) do
 				if t == TradeSkillFrame:GetName() then
@@ -276,8 +276,6 @@ function Cauldron:UpdateSkillList()
 		--@alpha@
 		self:debug("UpdateSkillList: i="..i);
 		--@end-alpha@
-
-		local skillData = Cauldron:GetSkillDataForSkill(skillInfo);

 		local skillFrame = _G["CauldronSkillItem"..i];

@@ -321,10 +319,10 @@ function Cauldron:UpdateSkillList()
 		end

 		skillFrame:SetID(i);
-		skillFrame.skillIndex = skillData.index;
+		skillFrame.skillIndex = skillInfo.index;

 		-- set selection
-		if self.db.realm.userdata[self.vars.playername].skills[skillName].window.selected == skillData.index then
+		if self.db.realm.userdata[self.vars.playername].skills[skillName].window.selected == skillInfo.index then
 			_G["CauldronSkillItem"..i.."Selection"]:Show();
 		else
 			_G["CauldronSkillItem"..i.."Selection"]:Hide();
@@ -337,10 +335,10 @@ function Cauldron:UpdateSkillList()
 		frame = _G["CauldronSkillItem"..i.."SkillName"];
 		local nameText = skillInfo.name;
 		local potentialCount = Cauldron:GetPotentialCraftCount(skillInfo);
-		if (potentialCount > 0) and (potentialCount > skillData.available) then
-			nameText = nameText.." ["..skillData.available.."/"..potentialCount.."]";
-		elseif skillData.available > 0 then
-			nameText = nameText.." ["..skillData.available.."]";
+		if (potentialCount > 0) and (potentialCount > skillInfo.available) then
+			nameText = nameText.." ["..skillInfo.available.."/"..potentialCount.."]";
+		elseif skillInfo.available > 0 then
+			nameText = nameText.." ["..skillInfo.available.."]";
 		end
 		local achievements = Cauldron:GetAchievementsForSkill(skillInfo);
 		if achievements and #achievements > 0 then
@@ -348,7 +346,7 @@ function Cauldron:UpdateSkillList()
 		end
 		frame:SetText(nameText);
 		if TradeSkillTypeColor then
-			local color = TradeSkillTypeColor[skillData.difficulty];
+			local color = TradeSkillTypeColor[skillInfo.difficulty];
 			if color then
 				frame:SetFontObject(color.font);
 				frame.r = color.r;
@@ -371,11 +369,10 @@ function Cauldron:UpdateSkillList()
 		frame = _G["CauldronSkillItem"..i.."FavoriteButton"];
 		frame:SetChecked(self.db.realm.userdata[self.vars.playername].skills[skillName].window.skills[skillInfo.name].favorite);
 		frame.skillInfo = skillInfo;
-		frame.skillData = skillData;

 		-- set cooldown
 		frame = _G["CauldronSkillItem"..i.."SkillCooldown"];
-		local cooldown = GetTradeSkillCooldown(skillData.index);
+		local cooldown = GetTradeSkillCooldown(skillInfo.index);
 		if cooldown then
 			if not frame:IsVisible() then
 				frame:Show();
@@ -391,16 +388,11 @@ function Cauldron:UpdateSkillList()
 		frame = _G["CauldronSkillItem"..i.."SkillIcon"];
 		frame:SetNormalTexture(skillInfo.icon);
 		frame.itemLink = skillInfo.link;
-		frame.skillIndex = skillData.index;
-
-		--[[
-		frame = _G["CauldronSkillItem"..i.."SkillNameTooltipFrame"];
 		frame.skillIndex = skillInfo.index;
-		--]]
-
+
 		-- set the craft count
 		frame = _G["CauldronSkillItem"..i.."SkillIconCount"];
-		local minMade, maxMade = skillData.minMade, skillData.maxMade;
+		local minMade, maxMade = skillInfo.minMade, skillInfo.maxMade;
 		if maxMade > 1 then
 			if minMade == maxMade then
 				frame:SetText(minMade);
@@ -417,34 +409,33 @@ function Cauldron:UpdateSkillList()
 		-- set the disclosure button texture
 		frame = _G["CauldronSkillItem"..i.."DiscloseButton"];
 		frame.skillInfo = skillInfo;
-		frame.skillData = skillData;
-		--@alpha@
+--@alpha@
 		self:debug("UpdateSkillList: skillInfo.name="..skillInfo.name);
-		--@end-alpha@
+--@end-alpha@
 		local reagentsExpanded = self.db.realm.userdata[self.vars.playername].skills[skillName].window.skills[skillInfo.name].expanded;
-		--@alpha@
+--@alpha@
 		self:debug("UpdateSkillList: reagentsExpanded="..tostring(reagentsExpanded));
-		--@end-alpha@
+--@end-alpha@
 		if reagentsExpanded then
 			frame:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-Up");

 			_G["CauldronSkillItem"..i.."Reagents"]:Show();

 			-- fill in the tools info
-			local spellFocus = BuildColoredListString(GetTradeSkillTools(skillData.index));
+			local spellFocus = BuildColoredListString(GetTradeSkillTools(skillInfo.index));
 			local toolsFrame = _G["CauldronSkillItem"..i.."ReagentsToolsInfo"];
 			if spellFocus then
-				--@alpha@
+--@alpha@
 				self:debug("UpdateSkillList: skill has a spell focus");
-				--@end-alpha@
+--@end-alpha@

 				toolsFrame:Show();
 				toolsFrame:SetText(L["Requires"]..": "..spellFocus);
 				toolsFrame:SetHeight(15);
 			else
-				--@alpha@
+--@alpha@
 				self:debug("UpdateSkillList: skill doesn't have a spell focus");
-				--@end-alpha@
+--@end-alpha@

 				toolsFrame:Hide();
 				toolsFrame:SetText("");
@@ -465,20 +456,19 @@ function Cauldron:UpdateSkillList()
 					reagentFrame:Hide();
 				else
 					local reagentInfo = reagents[j];
-					local reagentData = skillData.reagents[j];

-					reagentFrame.skillIndex = skillData.index;
+					reagentFrame.skillIndex = skillInfo.index;
 					reagentFrame.reagentIndex = reagentInfo.index;
-					reagentFrame.link = reagentData.link or reagentInfo.link;
+					reagentFrame.link = reagentInfo.link;

 					local reagentNameFrame = _G["CauldronSkillItem"..i.."ReagentsItemDetail"..j.."Name"];
 					local reagentCountFrame = _G["CauldronSkillItem"..i.."ReagentsItemDetail"..j.."Count"];

 					reagentFrame:Show();
 					SetItemButtonTexture(reagentFrame, reagentInfo.icon);
-					reagentNameFrame:SetText(reagentData.name or reagentInfo.name);
+					reagentNameFrame:SetText(reagentInfo.name);

-					local playerReagentCount = GetItemCount(reagentData.name or reagentInfo.name);
+					local playerReagentCount = GetItemCount(reagentInfo.name);

 					if playerReagentCount < reagentInfo.numRequired then
 						-- Grayout items
@@ -554,9 +544,9 @@ function Cauldron:UpdateSkillList()
 end

 function Cauldron:UpdateButtons()
-	--@alpha@
+--@alpha@
 	self:debug("UpdateButtons enter");
-	--@end-alpha@
+--@end-alpha@

 	if IsTradeSkillLinked() then
 		CauldronQueueAllButton:Hide();
@@ -582,9 +572,8 @@ function Cauldron:UpdateButtons()
 	end

 	local skillInfo = Cauldron:GetSelectedSkill();
-	local skillData = Cauldron:GetSkillDataForSkill(skillInfo);

-	if skillInfo and skillData then
+	if skillInfo then
 		CauldronCreateButton:SetText(skillInfo.verb or CREATE);

 		CauldronQueueAllButton:Enable();
@@ -595,7 +584,7 @@ function Cauldron:UpdateButtons()
 		else
 			CauldronCreateButton:Show();

-			if skillData.available > 0 then
+			if skillInfo.available > 0 then
 				CauldronCreateAllButton:Enable();
 				CauldronCreateButton:Enable();
 			else
@@ -620,9 +609,9 @@ function Cauldron:UpdateButtons()
 		end
 	end

-	--@alpha@
+--@alpha@
 	self:debug("UpdateButtons exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:UpdateQueue()
@@ -724,7 +713,6 @@ function Cauldron:UpdateQueue()
 		_G["CauldronQueueItem"..i.."AddToShoppingList"]:SetScale(0.5);

 		local skillInfo = Cauldron:GetSkillInfo(queueInfo.tradeskill, queueInfo.name);
-		local skillData = Cauldron:GetSkillDataForSkill(skillInfo);
 		if not skillInfo then
 			-- the skill isn't available (character doesn't know it?)
 			self:warn("No skill available for "..queueInfo.name.." ("..queueInfo.tradeskill..")");
@@ -739,12 +727,12 @@ function Cauldron:UpdateQueue()
 		self:debug("frame: "..tostring(frame).." ("..frame:GetName()..")");
 		--@end-alpha@
 		local nameText = queueInfo.name;
-		if skillInfo and (skillData.available > 0) then
-			nameText = nameText.." ["..skillData.available.."]";
+		if skillInfo and (skillInfo.available > 0) then
+			nameText = nameText.." ["..skillInfo.available.."]";
 		end
 		frame:SetText(nameText);
-		if skillInfo and skillData then
-			local color = TradeSkillTypeColor[skillData.difficulty];
+		if skillInfo then
+			local color = TradeSkillTypeColor[skillInfo.difficulty];
 			if color then
 				frame:SetFontObject(color.font);
 				frame:SetTextColor(color.r, color.g, color.b, 1.0);
@@ -770,31 +758,31 @@ function Cauldron:UpdateQueue()

 		-- set the icon
 		frame = _G["CauldronQueueItem"..i.."Icon"];
-		--@alpha@
+--@alpha@
 		self:debug("frame: "..tostring(frame).." ("..frame:GetName()..")");
-		--@end-alpha@
+--@end-alpha@
 		frame:SetNormalTexture(queueInfo.icon);
 		frame.link = queueInfo.link;

 		-- set the amount
 		frame = _G["CauldronQueueItem"..i.."IconCount"];
-		--@alpha@
+--@alpha@
 		self:debug("frame: "..tostring(frame).." ("..frame:GetName()..")");
-		--@end-alpha@
+--@end-alpha@
 		frame:SetText(queueInfo.amount);

 		-- place the frame in the scroll view
 		if i > 1 then
 			-- anchor to the frame above
-			--@alpha@
+--@alpha@
 			self:debug("UpdateQueue: anchor frame to top left of frame above");
-			--@end-alpha@
+--@end-alpha@
 			queueItemFrame:SetPoint("TOPLEFT", _G["CauldronQueueItem"..(i-1)], "BOTTOMLEFT", 0, 0);
 		else
 			-- anchor to the parent
-			--@alpha@
+--@alpha@
 			self:debug("UpdateQueue: anchor frame to parent");
-			--@end-alpha@
+--@end-alpha@
 			queueItemFrame:SetPoint("TOPLEFT", CauldronQueueFrameScrollFrameQueueSectionsMainItems, "TOPLEFT", 0, 0);
 		end

@@ -802,9 +790,9 @@ function Cauldron:UpdateQueue()
 --		self:debug("UpdateQueue: height="..height);

 		-- show the frame
-		--@alpha@
+--@alpha@
 		self:debug("UpdateQueue: show the frame");
-		--@end-alpha@
+--@end-alpha@
 		queueItemFrame:Show();
 	end

@@ -837,9 +825,9 @@ function Cauldron:UpdateQueue()

 	-- display intermediate queue, maybe
 	if #intQueue == 0 then
-		--@alpha@
+--@alpha@
 		self:debug("UpdateQueue: intermediate queue is empty, hide header and item frames");
-		--@end-alpha@
+--@end-alpha@
 		CauldronQueueFrameScrollFrameQueueSectionsSecondaryItemsHeader:SetHeight(1);
 		CauldronQueueFrameScrollFrameQueueSectionsSecondaryItemsHeaderText:SetText("");
 		CauldronQueueFrameScrollFrameQueueSectionsSecondaryItems:SetHeight(1);
@@ -852,9 +840,9 @@ function Cauldron:UpdateQueue()
 		local intHeight = 0;

 		for i, queueInfo in ipairs(intQueue) do
-			--@alpha@
+--@alpha@
 			self:debug("intQueue: name="..queueInfo.name);
-			--@end-alpha@
+--@end-alpha@

 			local queueItemFrame = _G["CauldronQueueIntItem"..i];

@@ -890,7 +878,6 @@ function Cauldron:UpdateQueue()
 			_G["CauldronQueueIntItem"..i.."AddToShoppingList"]:SetScale(0.5);

 			local skillInfo = Cauldron:GetSkillInfo(queueInfo.tradeskill, queueInfo.name);
-			local skillData = Cauldron:GetSkillDataForSkill(skillInfo);
 			if not skillInfo then
 				-- the skill isn't available (character doesn't know it?)
 				-- TODO
@@ -905,13 +892,13 @@ function Cauldron:UpdateQueue()
 			-- set name and difficulty color
 			frame = _G["CauldronQueueIntItem"..i.."ItemName"];
 			local nameText = queueInfo.name;
-			if skillInfo and skillData then
-				if (skillData.available > 0) then
-					nameText = nameText.." ["..skillData.available.."]";
+			if skillInfo then
+				if (skillInfo.available > 0) then
+					nameText = nameText.." ["..skillInfo.available.."]";
 				end
 				frame:SetText(nameText);

-				local color = TradeSkillTypeColor[skillData.difficulty];
+				local color = TradeSkillTypeColor[skillInfo.difficulty];
 				if color then
 					frame:SetFontObject(color.font);
 					frame:SetTextColor(color.r, color.g, color.b, 1.0);
@@ -956,15 +943,15 @@ function Cauldron:UpdateQueue()
 			-- place the frame in the scroll view
 			if i > 1 then
 				-- anchor to the frame above
-				--@alpha@
+--@alpha@
 				self:debug("UpdateQueue: anchor frame to top left of frame above");
-				--@end-alpha@
+--@end-alpha@
 				queueItemFrame:SetPoint("TOPLEFT", _G["CauldronQueueIntItem"..(i-1)], "BOTTOMLEFT", 0, 0);
 			else
 				-- anchor to the parent
-				--@alpha@
+--@alpha@
 				self:debug("UpdateQueue: anchor frame to parent");
-				--@end-alpha@
+--@end-alpha@
 				queueItemFrame:SetPoint("TOPLEFT", CauldronQueueFrameScrollFrameQueueSectionsSecondaryItems, "TOPLEFT", 0, 0);
 			end

@@ -974,9 +961,9 @@ function Cauldron:UpdateQueue()
 --			CauldronQueueFrameScrollFrameQueueSectionsSecondaryItems:SetHeight(intHeight);

 			-- show the frame
-			--@alpha@
+--@alpha@
 			self:debug("UpdateQueue: show the frame");
-			--@end-alpha@
+--@end-alpha@
 			queueItemFrame:Show();
 		end
 	end
@@ -1009,9 +996,9 @@ function Cauldron:UpdateQueue()
 	local reagentHeight = 0;

 	for i, queueInfo in ipairs(reagentList) do
-		--@alpha@
+--@alpha@
 		self:debug("reagentList: "..queueInfo.name);
-		--@end-alpha@
+--@end-alpha@

 		local queueItemFrame = _G["CauldronQueueReagentItem"..i];

@@ -1053,7 +1040,6 @@ function Cauldron:UpdateQueue()
 		_G["CauldronQueueReagentItem"..i.."AddToShoppingList"]:SetScale(0.5);

 		local skillInfo = Cauldron:GetSkillInfo(queueInfo.tradeskill, queueInfo.name);
-		local skillData = Cauldron:GetSkillDataForSkill(skillInfo);
 		if not skillInfo then
 			-- TODO
 		end
@@ -1106,15 +1092,15 @@ function Cauldron:UpdateQueue()
 		-- place the frame in the scroll view
 		if i > 1 then
 			-- anchor to the frame above
-			--@alpha@
+--@alpha@
 			self:debug("UpdateQueue: anchor frame to top left of frame above");
-			--@end-alpha@
+--@end-alpha@
 			queueItemFrame:SetPoint("TOPLEFT", _G["CauldronQueueReagentItem"..(i-1)], "BOTTOMLEFT", 0, 0);
 		else
 			-- anchor to the parent
-			--@alpha@
+--@alpha@
 			self:debug("UpdateQueue: anchor frame to parent");
-			--@end-alpha@
+--@end-alpha@
 			queueItemFrame:SetPoint("TOPLEFT", CauldronQueueFrameScrollFrameQueueSectionsReagents, "TOPLEFT", 0, 0);
 		end

@@ -1124,9 +1110,9 @@ function Cauldron:UpdateQueue()
 --		CauldronQueueFrameScrollFrameQueueSectionsReagents:SetHeight(reagentHeight);

 		-- show the frame
-		--@alpha@
+--@alpha@
 		self:debug("UpdateQueue: show the frame");
-		--@end-alpha@
+--@end-alpha@
 		queueItemFrame:Show();
 	end

@@ -1160,27 +1146,27 @@ function Cauldron:UpdateQueue()
 	CauldronQueueFrameScrollFrameQueueSections:SetHeight(h);
 	CauldronQueueFrameScrollFrame:UpdateScrollChildRect();

-	--@alpha@
+--@alpha@
 	self:debug("UpdateQueue exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:SaveFramePosition()
-	--@alpha@
+--@alpha@
  	self:debug("SaveFramePosition enter");
-	--@end-alpha@
+--@end-alpha@

 -- TODO

-	--@alpha@
+--@alpha@
  	self:debug("SaveFramePosition exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:OnCauldronUpdate()
-	--@alpha@
+--@alpha@
 	self:debug("OnCauldronUpdate enter");
-	--@end-alpha@
+--@end-alpha@

 	--[[
 --	self:Search();
@@ -1192,15 +1178,15 @@ function Cauldron:OnCauldronUpdate()
  	end
  	--]]

-	--@alpha@
+--@alpha@
 	self:debug("OnCauldronUpdate exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:FilterDropDown_OnLoad(dropdown)
-	--@alpha@
+--@alpha@
 	self:debug("FilterDropDown_OnLoad enter");
-	--@end-alpha@
+--@end-alpha@

 --[[
 	if CURRENT_TRADESKILL == "" or CURRENT_TRADESKILL == "UNKNOWN" then
@@ -1211,9 +1197,9 @@ function Cauldron:FilterDropDown_OnLoad(dropdown)
 	UIDropDownMenu_Initialize(dropdown, Cauldron.FilterDropDown_Initialize);
 	UIDropDownMenu_SetText(CauldronFiltersFilterDropDown, L["Filters"]);

-	--@alpha@
+--@alpha@
 	self:debug("FilterDropDown_OnLoad exit");
-	--@end-alpha@
+--@end-alpha@
 end

 function Cauldron:InvSlotDropDown_OnLoad(dropdown)
@@ -2085,10 +2071,9 @@ function Cauldron:CollapseItemButton_OnClick(button)
 	end

 	local skillInfo = button.skillInfo;
-	local skillData = Cauldron:GetSkillDataForSkill(skillInfo);

 	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.skills[skillInfo.name].expanded = not Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.skills[skillInfo.name].expanded;
-	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.selected = skillData.index;
+	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.selected = skillInfo.index;

 	-- update the UI
 	Cauldron:UpdateSkillList();
diff --git a/CauldronQueue.lua b/CauldronQueue.lua
index 0c7eac3..8059500 100644
--- a/CauldronQueue.lua
+++ b/CauldronQueue.lua
@@ -104,8 +104,7 @@ function CauldronQueue:GetIntermediates(queue)
 --		else
 			local t = CopyTable(item);
 			local skillInfo = Cauldron:GetSkillInfo(t.tradeskill, t.name);
-			local skillData = Cauldron:GetSkillDataForSkill(skillInfo);
-			if skillInfo and skillData and (skillData.available > 0) then
+			if skillInfo and (skillInfo.available > 0) then
 				-- increase the priority of items that can be crafted, so that they appear at the top of the list
 				t.priority = t.priority + 1000;
 			end
@@ -230,15 +229,14 @@ function CauldronQueue:CalculateRequiredItems(queue, skillInfo, amount, priority
 			if amount > 0 then
 				-- adjust the amount if the item produces more than one per execution
 				local intSkillInfo = Cauldron:GetSkillInfoForItem(reagent.name);
-				local intSkillData = Cauldron:GetSkillDataForSkill(intSkillInfo);
-				if intSkillInfo and intSkillData then
-					if intSkillData.minMade > 1 then
+				if intSkillInfo then
+					if intSkillInfo.minMade > 1 then
 						-- we ignore maxMade, since if it is greater than minMade, then the amount
 						-- produced is variable, so we err on the side of caution and account for
 						-- only ever making the minimum possible; besides, each execution of the
 						-- skill will cause the reagent list to be reassessed, so producing more
 						-- will be handled appropriately
-						amount = math.ceil(amount / intSkillData.minMade);
+						amount = math.ceil(amount / intSkillInfo.minMade);
 					end
 				end

diff --git a/CauldronShoppingListUI.lua b/CauldronShoppingListUI.lua
index 71587fd..bf4deeb 100644
--- a/CauldronShoppingListUI.lua
+++ b/CauldronShoppingListUI.lua
@@ -125,13 +125,13 @@ function Cauldron:UpdateShoppingList()
 												   CauldronShoppingListFrameItemsScrollFrameScrollChild,
 												   "CauldronShoppingListItemTemplate");
 				end
-
-				local _,link,_,_,_,_,_,_,_,_ = GetItemInfo(item);
+
+--				local _,link,_,_,_,_,_,_,_,_ = GetItemInfo(item);
 				local str = string.format("%s, %d", item, amount);

 				shoppingListItem.itemName = item;
 				shoppingListItem.requestor = requestor;
-
+
 				_G["CauldronShoppingListItem"..itemIndex.."Item"]:SetText(str);
 				_G["CauldronShoppingListItem"..itemIndex.."Item"]:SetWidth(width - 25);

diff --git a/CauldronTradeskill.lua b/CauldronTradeskill.lua
index 103ee4f..9c64ecd 100644
--- a/CauldronTradeskill.lua
+++ b/CauldronTradeskill.lua
@@ -1,6 +1,8 @@
 -- $Revision$
 -- Cauldron tradeskill functions

+local L = LibStub("AceLocale-3.0"):GetLocale("Cauldron")
+
 function Cauldron:UpdateSkills()
 	self:debug("UpdateSkills enter");

@@ -33,9 +35,6 @@ function Cauldron:UpdateSkills()
 	if not self.db.realm.userdata[self.vars.playername].reagentMap then
 		self.db.realm.userdata[self.vars.playername].reagentMap = {};
 	end
-	if not self.db.global.reagentMap then
-		self.db.global.reagentMap = {};
-	end

 	-- save the skill entry in a local var
 	local skillDB = self.db.realm.userdata[self.vars.playername].skills[skillName];
@@ -43,13 +42,7 @@ function Cauldron:UpdateSkills()
 		skillDB.recipes = {};
 	end

-	-- initialize the global recipe list
-	if not self.db.global.recipes then
-		self.db.global.recipes = {};
-	end
-	if not self.db.global.recipes[baseSkillName] then
-		self.db.global.recipes[baseSkillName] = {};
-	end
+	local rescanNotify = false;

 	-- initialize window information, if necessary
 	if not skillDB.window then
@@ -67,7 +60,7 @@ function Cauldron:UpdateSkills()
 				sortDifficulty = false,
 				sortAlpha = false,
 				sortBenefit = false,
-				sortItemLevel = true,
+				sortItemLevel = false,
 	   			sortRequiredLevel = false,
 	   			sortFavorites = false,
 				favorites = false,
@@ -98,8 +91,15 @@ function Cauldron:UpdateSkills()
 			-- adjust min/max made for specialities
 			-- TODO

-			-- check if we're updating or adding
-			if skillDB.recipes[name] then
+			-- check if we're rescanning, updating or adding
+			local rescan = false;
+			if skillDB.rescan then
+				if skillDB.rescan.failedRecipes[name] then
+					rescan = true;
+				end
+			end
+
+			if skillDB.recipes[name] and not rescan then
 				-- update the recipe info
 				skillDB.recipes[name].index = i;
 				skillDB.recipes[name].difficulty = difficulty;
@@ -108,69 +108,37 @@ function Cauldron:UpdateSkills()
 				skillDB.recipes[name].maxMade = maxMade;

 				-- update reagent skill index
-				if skillDB.recipes[name].reagents then
-					for j,r in ipairs(skillDB.recipes[name].reagents) do
-						local customName = nil;
-						local customLink = nil;
-						local rName, _, _, _ = GetTradeSkillReagentInfo(i, j);
-						local rLink = GetTradeSkillReagentItemLink(i, j);
-
-						-- compare stored name to this name
-						if self.db.global.recipes[baseSkillName][name] and self.db.global.recipes[baseSkillName][name].reagents[j] then
-							if rName ~= self.db.global.recipes[baseSkillName][name].reagents[j].name then
-								customName = rName;
-								customLink = rLink;
-							end
-						end
-
-						r.name = customName;
-						r.link = customLink;
-						r.skillIndex = i;
-					end
-				else
-					-- create the local reagent list
-					skillDB.recipes[name].reagents = {};
-					if self.db.global.recipes[baseSkillName][name] and self.db.global.recipes[baseSkillName][name].reagents then
-						for j=1,#self.db.global.recipes[baseSkillName][name].reagents do
-							table.insert(skillDB.recipes[name].reagents, {
-								['skillIndex'] = skillDB.recipes[name].index,
-							});
-						end
-					end
---					Cauldron:error("No reagent list found for recipe: "..name.."!");
+				for _,r in ipairs(skillDB.recipes[name].reagents) do
+					r.skillIndex = i;
 				end
 			else
+				if rescan then
+					local msg = string.format(L["Rescanning recipe: %1$s..."], name);
+					Cauldron:Print(msg);
+
+					-- remove it from the list (we're optimistic!)
+					skillDB.rescan.failedRecipes[name] = false;
+				end
+
 				-- add the recipe info and other miscellaneous info
 				local itemLink = GetTradeSkillItemLink(i);
 				local recipeLink = GetTradeSkillRecipeLink(i);
 				local _, _, _, _, _, _, _, _, slot, _ = GetItemInfo(itemLink);

 				local keywords = name;
-
-				-- fill in the character db entry
+
+				-- fill in the db entry
 				skillDB.recipes[name] = {
 					['index'] = i,
-					['tradeskill'] = baseSkillName,
-					['difficulty'] = difficulty,
-					['available'] = avail,
-					['minMade'] = minMade,
-					['maxMade'] = maxMade,
-					['categories'] = "",
-					['reagents'] = {},
-				};
-
-				-- fill in the global db entry
-				self.db.global.recipes[baseSkillName][name] = {
---					['index'] = i,
 					['name'] = name,
 					['itemLink'] = itemLink,
 					['recipeLink'] = recipeLink,
 					['icon'] = GetTradeSkillIcon(i),
 					['tradeskill'] = baseSkillName,
---					['difficulty'] = difficulty,
---					['available'] = avail,
---					['minMade'] = minMade,
---					['maxMade'] = maxMade,
+					['difficulty'] = difficulty,
+					['available'] = avail,
+					['minMade'] = minMade,
+					['maxMade'] = maxMade,

 					-- filter information
 					['slot'] = slot,
@@ -180,7 +148,7 @@ function Cauldron:UpdateSkills()
 				};

 				-- set the action verb for this skill
-				self.db.global.recipes[baseSkillName][name].verb = verb;
+				skillDB.recipes[name].verb = verb;

 				-- make sure the skill window info is initialized
 				if not skillDB.window.skills[name] then
@@ -222,16 +190,35 @@ function Cauldron:UpdateSkills()
 					local key = not Cauldron:IsVendorItem(rItemId);

 					if (not rName) or (not rIcon) or (not rLink) then
+						rescanNotify = true;
+
+						-- store the info if it's not already from rescanning
+						if not rescan then
+							-- store rescan info
+							if not skillDB.rescan then
+								skillDB.rescan = {
+									failedRecipes = {},
+								};
+							end
+
+							-- record the failed recipe
+							skillDB.rescan.failedRecipes[name] = true;
+						end
+
+						--[[
 						Cauldron:debug("First attempt to get reagent info failed.  Trying again.  (skill: "..name..", reagentIndex: "..j..", name: "..tostring(rName)..", icon: "..tostring(rIcon)..", link: "..tostring(rLink)..")");
 						-- be persisent about getting the info
 						rName, rIcon, _, _ = GetTradeSkillReagentInfo(i, j);
 						rLink = GetTradeSkillReagentItemLink(i, j);
+						]]
 					end
-
+
+					--[[
 					if (not rName) or (not rIcon) or (not rLink) then
 						-- be persisent about getting the info
 						Cauldron:error("Can't get name/icon/link for reagent! (skill: "..name..", reagentIndex: "..j..", name: "..tostring(rName)..", icon: "..tostring(rIcon)..", link: "..tostring(rLink)..")");
 					end
+					--]]

 					local r = {
 						["index"] = j,
@@ -243,28 +230,22 @@ function Cauldron:UpdateSkills()
 						["key"] = key,
 					};

-					-- add to the global reagent table
-					table.insert(self.db.global.recipes[baseSkillName][name].reagents, r);
-
-					-- add to the local reagent table
-					table.insert(skillDB.recipes[name].reagents, {
-						['skillIndex'] = i,
-					});
+					table.insert(skillDB.recipes[name].reagents, r);

 					-- add the reagent to the reagent map

 					if rName then
-						if not self.db.global.reagentMap[rName] then
-							self.db.global.reagentMap[rName] = {};
+						if not self.db.realm.userdata[self.vars.playername].reagentMap[rName] then
+							self.db.realm.userdata[self.vars.playername].reagentMap[rName] = {};
 						end
-						table.insert(self.db.global.reagentMap[rName], skillName..";"..recipeLink);
+						table.insert(self.db.realm.userdata[self.vars.playername].reagentMap[rName], skillName..";"..recipeLink);

 						keywords = keywords..","..rName;
 					end
 				end
-
+
 				-- fill in the keywords db entry
-				self.db.global.recipes[baseSkillName][name].keywords = keywords;
+				skillDB.recipes[name].keywords = keywords;
 			end
 	    else
 	    	-- save the header name
@@ -279,6 +260,12 @@ function Cauldron:UpdateSkills()
 		end
 	end

+	if rescanNotify then
+		Cauldron:error(L["Cauldron had issues with some recipes for this profession."]);
+		local msg = string.format(L["Please close and re-open the %1$s window again to re-scan."], baseSkillName);
+		Cauldron:info(msg);
+	end
+
 	self:debug("UpdateSkills exit");
 end

@@ -357,9 +344,6 @@ function Cauldron:GetSkillList(playername, skillName)

 	for name, recipe in pairs(self.db.realm.userdata[playername].skills[skillName].recipes) do
 		self:debug("GetSkillList: name="..name);
-
-		-- get the details of the recipe from the global list
-		local recipeInfo = self.db.global.recipes[skillName][name];

 		local add = true;

@@ -387,7 +371,7 @@ function Cauldron:GetSkillList(playername, skillName)
 				minLevel = tonumber(minLevel) or 0;
 				maxLevel = tonumber(maxLevel) or 0;

-				local _,_,_,itemLevel,reqLevel,_,_,_,_,_ = GetItemInfo(recipeInfo.itemLink);
+				local _,_,_,itemLevel,reqLevel,_,_,_,_,_ = GetItemInfo(recipe.itemLink);
 				if itemLevel and (matchItemLevel == "i") then
 					itemLevel = tonumber(itemLevel) or 0;
 					self:debug("GetSkillList: match by item level");
@@ -406,8 +390,8 @@ function Cauldron:GetSkillList(playername, skillName)
 			else
 				-- match name or reagents
 				self:debug("GetSkillList: match by name or reagents");
-				if not string.find(string.lower(recipeInfo.keywords or ""), string.lower(search)) then
-					self:debug("skipping recipe: "..name.." (keywords: "..tostring(recipeInfo.keywords)..")");
+				if not string.find(string.lower(recipe.keywords or ""), string.lower(search)) then
+					self:debug("skipping recipe: "..name.." (keywords: "..tostring(recipe.keywords)..")");
 					add = false;
 				end
 			end
@@ -421,9 +405,9 @@ function Cauldron:GetSkillList(playername, skillName)
 		end

 		-- check categories
-		local catInfo = self.db.realm.userdata[playername].skills[skillName].window.categories[recipeInfo.defaultCategory];
+		local catInfo = self.db.realm.userdata[playername].skills[skillName].window.categories[recipe.defaultCategory];
 		if catInfo and (not catInfo.shown) then
-			self:debug("skipping recipe: "..name.." (category: "..recipeInfo.defaultCategory..")");
+			self:debug("skipping recipe: "..name.." (category: "..recipe.defaultCategory..")");
 			add = false;
 		end

@@ -447,7 +431,7 @@ function Cauldron:GetSkillList(playername, skillName)
 			end
 		elseif self.db.realm.userdata[playername].skills[skillName].window.filter.haveKeyReagents then
 			-- check if the reagent count for key reagents is 0
-			for _, rinfo in ipairs(recipeInfo.reagents) do
+			for _, rinfo in ipairs(recipe.reagents) do
 				-- check possession count
 				if (GetItemCount(rinfo.link, false) < rinfo.numRequired) and (rinfo.key) then
 					add = false;
@@ -456,7 +440,7 @@ function Cauldron:GetSkillList(playername, skillName)
 		elseif self.db.realm.userdata[playername].skills[skillName].window.filter.haveAnyReagents then
 			-- check if the reagent count for any reagent is > 0
 			add = false;
-			for _, rinfo in ipairs(recipeInfo.reagents) do
+			for _, rinfo in ipairs(recipe.reagents) do
 				-- check possession count
 				if GetItemCount(rinfo.link, false) > 0 then
 					add = true;
@@ -466,9 +450,9 @@ function Cauldron:GetSkillList(playername, skillName)

 		-- check favorites filter
 		if self.db.realm.userdata[playername].skills[skillName].window.filter.favorites then
-			if not self.db.realm.userdata[playername].skills[skillName].window.skills[recipeInfo.name].favorite then
+			if not self.db.realm.userdata[playername].skills[skillName].window.skills[recipe.name].favorite then
 				--@alpha@
-				self:debug("skipping recipe: "..name.." (favorite: "..tostring(self.db.realm.userdata[playername].skills[skillName].window.skills[recipeInfo.name].favorite)..")");
+				self:debug("skipping recipe: "..name.." (favorite: "..tostring(self.db.realm.userdata[playername].skills[skillName].window.skills[recipe.name].favorite)..")");
 				--@end-alpha@
 				add = false;
 			end
@@ -476,10 +460,10 @@ function Cauldron:GetSkillList(playername, skillName)

 		-- check achievements filter
 		if self.db.realm.userdata[playername].skills[skillName].window.filter.achievements then
-			local achievements = Cauldron:GetAchievementsForSkill(recipeInfo);
+			local achievements = Cauldron:GetAchievementsForSkill(recipe);
 			if (not achievements) or (#achievements == 0) then
 				--@alpha@
-				self:debug("skipping recipe: "..name.." (achievements: "..tostring(self.db.realm.userdata[playername].skills[skillName].window.skills[recipeInfo.name].achievements)..")");
+				self:debug("skipping recipe: "..name.." (achievements: "..tostring(self.db.realm.userdata[playername].skills[skillName].window.skills[recipe.name].achievements)..")");
 				--@end-alpha@
 				add = false;
 			end
@@ -487,7 +471,7 @@ function Cauldron:GetSkillList(playername, skillName)

 		-- we got here, add the recipe to the list
 		if add then
-			table.insert(skills, recipeInfo);
+			table.insert(skills, recipe);
 		end
 	end

@@ -591,12 +575,11 @@ function Cauldron:GetSkillInfo(tradeskill, skill)
 		return nil;
 	end

-	local skillInfo = self.db.global.recipes[tradeskill][skill];
---	local skillInfo = self.db.realm.userdata[self.vars.playername].skills[tradeskill].recipes[skill];
+	local skillInfo = self.db.realm.userdata[self.vars.playername].skills[tradeskill].recipes[skill];
 	if not skillInfo then
 		-- couldn't find a skill with the item name, so scan the list for skills that craft
 		-- the item
-		for _, recipe in pairs(self.db.global.recipes[tradeskill]) do
+		for _, recipe in pairs(self.db.realm.userdata[self.vars.playername].skills[tradeskill].recipes) do
 			local name, _ = GetItemInfo(recipe.itemLink);
 			if name == skill then
 				return recipe;
@@ -619,8 +602,7 @@ function Cauldron:GetSkillInfoForItem(item)
 	for tradeskill, list in pairs(self.db.realm.userdata[self.vars.playername].skills) do
 		-- skip linked skills
 		if not (string.find(tradeskill, "Linked-")) then
-			for recipeName, recipe in pairs(list.recipes) do
-				local recipeInfo = self.db.global.recipes[tradeskill][recipeName];
+			for _, recipeInfo in pairs(list.recipes) do
 				local name, _ = GetItemInfo(recipeInfo.itemLink);
 				if name == item then
 					return recipeInfo;
@@ -642,8 +624,7 @@ function Cauldron:GetSkillInfoForLink(recipeLink)
 	for tradeskill, list in pairs(self.db.realm.userdata[self.vars.playername].skills) do
 		-- skip linked skills
 		if not (string.find(tradeskill, "Linked-")) then
-			for recipeName, recipe in pairs(list.recipes) do
-				local recipeInfo = self.db.global.recipes[tradeskill][recipeName];
+			for _, recipeInfo in pairs(list.recipes) do
 				local id = Cauldron:GetIdFromLink(recipeLink);
 				local recipeId = Cauldron:GetIdFromLink(recipeInfo.recipeLink);
 				if id == recipeId then
@@ -666,10 +647,8 @@ function Cauldron:GetSkillInfoByIndex(itemIndex)
 	for tradeskill, list in pairs(self.db.realm.userdata[self.vars.playername].skills) do
 		-- skip linked skills
 		if not (string.find(tradeskill, "Linked-")) then
-			for recipeName, recipe in pairs(list.recipes) do
-				local recipeInfo = self.db.global.recipes[tradeskill][recipeName];
-				local recipeData = Cauldron:GetSkillDataForSkill(recipeInfo);
-				if recipeData.index == itemIndex then
+			for _, recipeInfo in pairs(list.recipes) do
+				if recipeInfo.index == itemIndex then
 					return recipeInfo;
 				end
 			end
@@ -700,31 +679,6 @@ function Cauldron:GetReagentInfoByIndex(item, reagentIndex)
 	return nil;
 end

-function Cauldron:GetSkillDataForSkill(skillInfo)
-
-	if not skillInfo then
-		return nil;
-	end
-
-	local skillData = nil;
-
-	if self.db.realm.userdata[self.vars.playername].skills[skillInfo.tradeskill] and
-	   self.db.realm.userdata[self.vars.playername].skills[skillInfo.tradeskill].recipes[skillInfo.name] then
-	   	skillData = self.db.realm.userdata[self.vars.playername].skills[skillInfo.tradeskill].recipes[skillInfo.name];
-	else
-		skillData = {
-			index = 0,
-			difficulty = "unknown",
-			available = 0,
-			minMade = 0,
-			maxMade = 0,
-			categories = "",
-		};
-	end
-
-	return skillData;
-end
-
 function Cauldron:GetRequiredItems(skillInfo, amount)

 	local intermediates = {};
@@ -873,12 +827,12 @@ function Cauldron:GetSkillsForReagent(id)
 	local itemName,itemInfo,_ = GetItemInfo(id);
 	local skillList = {};

-	if not Cauldron.db.global.reagentMap then
+	if not Cauldron.db.realm.userdata[Cauldron.vars.playername].reagentMap then
 		return {};
 	end

 	-- find the reagent in the map
-	local reagentMap = Cauldron.db.global.reagentMap[itemName];
+	local reagentMap = Cauldron.db.realm.userdata[Cauldron.vars.playername].reagentMap[itemName];
 	if reagentMap then
 		for _,skill in ipairs(reagentMap) do
 			table.insert(skillList, skill);
diff --git a/Locale/Cauldron-enUS.lua b/Locale/Cauldron-enUS.lua
index f1a9c8d..a56d202 100644
--- a/Locale/Cauldron-enUS.lua
+++ b/Locale/Cauldron-enUS.lua
@@ -33,6 +33,10 @@ L["enabled"] = true
 L["disabled"] = true
 L["skills"] = true

+L["Cauldron had issues with some recipes for this profession."] = true
+L["Please close and re-open the %1$s window again to re-scan."] = true
+L["Rescanning recipe: %1$s..."] = true
+
 L["Auto-buy?"] = true
 L["If this option is checked, then any item that is in the list will be automatically purchased when a vendor window is opened, if that vendor has the items."] = true