Quantcast
-- $Revision$
-- Cauldron tradeskill functions

local L = LibStub("AceLocale-3.0"):GetLocale("Cauldron")

function Cauldron:UpdateSkills()
	self:debug("UpdateSkills enter");

--	self:info("updating skills: "..debugstack());

--	self:info("updatingSkills="..tostring(self.updatingSkills));
	if not self.updatingSkills then
		self:debug("not updating skills; return");
		return;
	end

	local skillName = GetTradeSkillLine();
	local baseSkillName = skillName;
	self:debug("UpdateSkills: skillName="..skillName);

	if skillName == "UNKNOWN" then
		return;
	end

	if not Cauldron.scanningSkills then

		Cauldron.scanningSkills = true;

		if IsTradeSkillLinked() then
			skillName = "Linked-"..skillName;
		end

		-- initialize the trade skill entry
		if not self.db.realm.userdata[self.vars.playername].skills[skillName] then
			self.db.realm.userdata[self.vars.playername].skills[skillName] = {};
		end

		-- initialize the reagent map
		if not self.db.realm.userdata[self.vars.playername].reagentMap then
			self.db.realm.userdata[self.vars.playername].reagentMap = {};
		end

		-- save the skill entry in a local var
		local skillDB = self.db.realm.userdata[self.vars.playername].skills[skillName];
		if not skillDB.recipes then
			skillDB.recipes = {};
		end

		local rescanNotify = false;

		-- initialize window information, if necessary
		if not skillDB.window then
			skillDB.window = {
				search = "",
				filter = {
					optimal = true,
					medium = true,
					easy = true,
					trivial = true,
					haveAllReagents = false,
					haveKeyReagents = false,
					haveAnyReagents = false,
					sortDefault = true,
					sortDifficulty = false,
					sortAlpha = false,
					sortBenefit = false,
					sortItemLevel = false,
					sortRequiredLevel = false,
					sortFavorites = false,
					favorites = false,
					achievements = false,
				},
				skills = {},
				slots = {},
				categories = {},
				selected = 1,
			};
		end

		-- make sure we're getting a full list
		SetTradeSkillItemNameFilter(nil);
		SetTradeSkillItemLevelFilter(0, 0);

		local category = "";

		for i=1,GetNumTradeSkills() do
	--		self:info("i="..tostring(i));
			local name, difficulty, avail, expanded, verb = GetTradeSkillInfo(i);
	--		self:debug("UpdateSkills: name="..name.."; difficulty="..difficulty.."; avail="..avail);

			if name and difficulty ~= "header" then

				local minMade, maxMade = GetTradeSkillNumMade(i);

				-- adjust min/max made for specialities
				-- TODO

				-- 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;
					skillDB.recipes[name].available = avail;
					skillDB.recipes[name].minMade = minMade;
					skillDB.recipes[name].maxMade = maxMade;

					-- update reagent skill index
					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] = nil;
					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 db entry
					skillDB.recipes[name] = {
						['index'] = i,
						['name'] = name,
						['itemLink'] = itemLink,
						['recipeLink'] = recipeLink,
						['icon'] = GetTradeSkillIcon(i),
						['tradeskill'] = baseSkillName,
						['difficulty'] = difficulty,
						['available'] = avail,
						['minMade'] = minMade,
						['maxMade'] = maxMade,

						-- filter information
						['slot'] = slot,
						['defaultCategory'] = category,

						['reagents'] = {},
					};

					-- set the action verb for this skill
					skillDB.recipes[name].verb = verb;

					-- make sure the skill window info is initialized
					if not skillDB.window.skills[name] then
						skillDB.window.skills[name] = {
							['expanded'] = false,
							['favorite'] = false,
						};
					end

					-- make sure the category for the window is initialized
					if category ~= "" then
						if not skillDB.window.categories[category] then
							skillDB.window.categories[category] = {
								['shown'] = true,
								['expanded'] = true,
							};
						end
					end

					-- populate the slot list
					Cauldron:debug("slot: "..tostring(slot));
					if slot and (slot ~= "") then
						skillDB.window.slots[slot] = {
							checked = true,
						};
					else
						-- special slot representing items that don't have a slot
						skillDB.window.slots.none = {
							checked = true,
						};
					end

					-- populate the reagent list
					local num = GetTradeSkillNumReagents(i);
					for j=1,num do
						local rName, rIcon, rCount, _ = GetTradeSkillReagentInfo(i, j);
						local rLink = GetTradeSkillReagentItemLink(i, j);
						local rItemId = Cauldron:GetIdFromLink(rLink);
						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
								Cauldron:error("Failed to retrieve reagent info; marking recipe for rescan: "..name);
								Cauldron:MarkRecipeForRescan(skillDB, name);
							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,
							["name"] = rName,
							["numRequired"] = rCount,
							["skillIndex"] = i,
							["icon"] = rIcon,
							["link"] = rLink,
							["key"] = key,
						};

						table.insert(skillDB.recipes[name].reagents, r);

						-- add the reagent to the reagent map

						if rName then
							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.realm.userdata[self.vars.playername].reagentMap[rName], skillName..";"..recipeLink);

							keywords = keywords..","..rName;
						end
					end

					-- fill in the keywords db entry
					skillDB.recipes[name].keywords = keywords;
				end
			else
				-- save the header name
				if name then
					category = name;

					-- expand the header, so we get all the skills
					if not expanded then
						ExpandTradeSkillSubClass(i);
					end
				end
			end
		end

		Cauldron.scanningSkills = false;
	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

function Cauldron:GetDefaultCategories(player, skillName)
	self:debug("GetDefaultCategories enter");

	local categories = {};

	if self.db then
		for name, info in pairs(self.db.realm.userdata[player].skills[skillName].window.categories) do
			categories[name] = info.shown;
		end
	end

--	table.sort(categories);

	self:debug("GetDefaultCategories exit");

	return categories;
end

--[[
function Cauldron:GetCategories(skillList)
	self:debug("GetCategories enter");

	local categories = {};

	if not skillList then
		return categories;
	end

	for _, info in ipairs(skillList) do
		table.insert(categories, info.defaultCategory);
	end

	table.sort(categories);

	self:debug("GetCategories exit");

	return categories;
end
--]]

function Cauldron:GetSlots(player, skillName)

	local slots = {};

	if self.db then
		for name, info in pairs(self.db.realm.userdata[player].skills[skillName].window.slots) do
			slots[name] = info;
		end
	end

--	table.sort(slots);

	self:debug("GetSlots exit");

	return slots;
end

function Cauldron:GetSkillCount(skillName)

	if not skillName then
		skillName = CURRENT_TRADESKILL;
	end
	if not skillName then
		-- still couldn't get a skill name, so return 0
		return 0;
	end

	local skillCount = 0;

	if (self.db.realm.userdata[self.vars.playername]) and
	   (self.db.realm.userdata[self.vars.playername].skills[skillName]) then
		for _, _ in pairs(self.db.realm.userdata[self.vars.playername].skills[skillName].recipes) do
			skillCount = skillCount + 1;
		end
	end

	return skillCount;
end

function Cauldron:GetSkillList(playername, skillName)
	self:debug("GetSkillList enter");

	if (not playername) or
	   (not skillName) then
		self:warn("GetSkillList: playername ("..tostring(playername)..") or skillName ("..tostring(skillName)..") not set!");
		return;
	end
	if (not self.db.realm.userdata[playername]) or
	   (not self.db.realm.userdata[playername].skills[skillName]) then
		return;
	end

	local skills = {};

	for name, recipe in pairs(self.db.realm.userdata[playername].skills[skillName].recipes) do
		self:debug("GetSkillList: name="..name);

		local add = true;

		-- check the search text
		local search = self.db.realm.userdata[playername].skills[skillName].window.search or "";
		self:debug("GetSkillList: search="..search);
		if #search > 0 then
			-- check for numbers
			local minLevel, maxLevel;
--			local matchItemLevel = false;
			local approxLevel, matchItemLevel = strmatch(search, "^~(%d+)(i?)");
			-- self:debug("GetSkillList: approxLevel="..tostring(approxLevel));
			if approxLevel then
				minLevel = approxLevel - 2;
				maxLevel = approxLevel + 2;
			else
				minLevel, maxLevel, matchItemLevel = strmatch(search, "^(%d+)%s*-*%s*(%d*)(i?)$");
				-- self:debug("GetSkillList: minLevel="..tostring(minLevel).."; maxLevel="..tostring(maxLevel));
			end
			if minLevel then
				if maxLevel == "" or maxLevel == "i" or maxLevel < minLevel then
					maxLevel = minLevel;
				end
				-- cleanse the level values
				minLevel = tonumber(minLevel) or 0;
				maxLevel = tonumber(maxLevel) or 0;

				local _,_,_,itemLevel,reqLevel,_,_,_,_,_ = GetItemInfo(recipe.itemLink);
				if itemLevel and (matchItemLevel == "i") then
					itemLevel = tonumber(itemLevel) or 0;
					self:debug("GetSkillList: match by item level");
					if itemLevel < minLevel or itemLevel > maxLevel then
						self:debug("skipping recipe: "..name.." (level: "..tostring(itemLevel)..")");
						add = false;
					end
				elseif reqLevel then
					reqLevel = tonumber(reqLevel) or 0;
					self:debug("GetSkillList: match by required level");
					if reqLevel < minLevel or reqLevel > maxLevel then
						self:debug("skipping recipe: "..name.." (level: "..tostring(reqLevel)..")");
						add = false;
					end
				end
			else
				-- match name or reagents
				self:debug("GetSkillList: match by name or reagents");
				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

		end

		-- check difficulty filter
		if not self.db.realm.userdata[playername].skills[skillName].window.filter[recipe.difficulty] then
			self:debug("skipping recipe: "..name.." (difficulty: "..recipe.difficulty..")");
			add = false;
		end

		-- check categories
		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: "..recipe.defaultCategory..")");
			add = false;
		end

		-- check slot
		local slotName = recipe.slot;
		if (not slotName) or (slotName == "") then
			slotName = "none";
		end
		local slotInfo = self.db.realm.userdata[playername].skills[skillName].window.slots[slotName];
		self:debug("slotInfo: "..tostring(slotInfo));
		if slotInfo and not(slotInfo.checked) then
			self:debug("skipping recipe: "..name.." (slot: "..slotName..")");
			add = false;
		end

		-- check reagent filter
		if self.db.realm.userdata[playername].skills[skillName].window.filter.haveAllReagents then
			-- check if the available count is 0
			if recipe.available == 0 then
				add = false;
			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(recipe.reagents) do
				-- check possession count
				if (GetItemCount(rinfo.link, false) < rinfo.numRequired) and (rinfo.key) then
					add = false;
				end
			end
		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(recipe.reagents) do
				-- check possession count
				if GetItemCount(rinfo.link, false) > 0 then
					add = true;
				end
			end
		end

		-- 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[recipe.name].favorite then
				--@alpha@
				self:debug("skipping recipe: "..name.." (favorite: "..tostring(self.db.realm.userdata[playername].skills[skillName].window.skills[recipe.name].favorite)..")");
				--@end-alpha@
				add = false;
			end
		end

		-- check achievements filter
		if self.db.realm.userdata[playername].skills[skillName].window.filter.achievements then
			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[recipe.name].achievements)..")");
				--@end-alpha@
				add = false;
			end
		end

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

	-- sort the list
	table.sort(skills, function(r1, r2)
			if (not r1) or (not r2) then
				return true;
			end
			if not r1.name or not r2.name then
				return true;
			end

			--@alpha@
			self:debug("GetSkillList: sorting: r1.name="..r1.name.."; r2.name="..r2.name);
			--@end-alpha@
			if self.db.realm.userdata[playername].skills[skillName].window.filter.sortDefault then
				--@alpha@
				self:debug("GetSkillList: sorting by default (skill index)");
				--@end-alpha@
				local r1v = self.db.realm.userdata[playername].skills[skillName].recipes[r1.name].index;
				local r2v = self.db.realm.userdata[playername].skills[skillName].recipes[r2.name].index;
				return r1v < r2v;
			elseif self.db.realm.userdata[playername].skills[skillName].window.filter.sortAlpha then
				--@alpha@
				self:debug("GetSkillList: sorting by alpha");
				--@end-alpha@
				return r1.name < r2.name;
			elseif self.db.realm.userdata[playername].skills[skillName].window.filter.sortDifficulty then
				--@alpha@
				self:debug("GetSkillList: sorting by difficulty");
				--@end-alpha@
				local difficulty = {
					optimal = 4,
					medium = 3,
					easy = 2,
					trivial = 1,
				};

				local r1v = self.db.realm.userdata[playername].skills[skillName].recipes[r1.name].difficulty;
				local r2v = self.db.realm.userdata[playername].skills[skillName].recipes[r2.name].difficulty;
				--@alpha@
				self:debug("GetSkillList: r1.difficulty="..r1v);
				self:debug("GetSkillList: r2.difficulty="..r2v);
				--@end-alpha@
				return difficulty[r1v] > difficulty[r2v];
			elseif self.db.realm.userdata[playername].skills[skillName].window.filter.sortItemLevel then
				--@alpha@
				self:debug("GetSkillList: sorting by item level");
				--@end-alpha@

				-- get item info from item link
				local _,_,_,r1iLevel,_,_,_,_,_,_ = GetItemInfo(r1.itemLink);
				local _,_,_,r2iLevel,_,_,_,_,_,_ = GetItemInfo(r2.itemLink);

				return (r2iLevel or 0) < (r1iLevel or 0);
			elseif self.db.realm.userdata[playername].skills[skillName].window.filter.sortRequiredLevel then
				--@alpha@
				self:debug("GetSkillList: sorting by required level");
				--@end-alpha@

				-- get item info from item link
				local _,_,_,_,r1Level,_,_,_,_,_ = GetItemInfo(r1.itemLink);
				local _,_,_,_,r2Level,_,_,_,_,_ = GetItemInfo(r2.itemLink);

				return (r2Level or 0) < (r1Level or 0);
			elseif self.db.realm.userdata[playername].skills[skillName].window.filter.sortFavorites then
				--@alpha@
				self:debug("GetSkillList: sorting by favorites");
				--@end-alpha@

				local r1f = (self.db.realm.userdata[playername].skills[skillName].window.skills[r1.name].favorite and 100) or 1;
				local r2f = (self.db.realm.userdata[playername].skills[skillName].window.skills[r2.name].favorite and 100) or 1;

				return r2f < r1f;
			elseif self.db.realm.userdata[playername].skills[skillName].window.filter.sortBenefit then
				--@alpha@
				self:debug("GetSkillList: returning true for benefit sorting");
				--@end-alpha@
				return true; -- TODO
			end

			--@alpha@
			self:debug("GetSkillList: returning default true");
			--@end-alpha@
			return true;
		end);

	--@alpha@
	self:debug("GetSkillList exit");

	return skills;
end

function Cauldron:GetSkillInfo(tradeskill, skill)
	self:debug("GetSkillInfo enter");

	-- sanity checks
	if (not tradeskill) or (not skill) then
		self:warn("GetSkillInfo: missing tradeskill ("..tostring(tradeskill)..") or skill ("..tostring(skill)..")!");
		return nil;
	end

	if not self.db.realm.userdata[self.vars.playername].skills[tradeskill] then
		return nil;
	end

	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.realm.userdata[self.vars.playername].skills[tradeskill].recipes) do
			local name, _ = GetItemInfo(recipe.itemLink);
			if name == skill then
				return recipe;
			end
		end
	end

	self:debug("GetSkillInfo exit");

	return skillInfo;
end

function Cauldron:GetSkillInfoForItem(item)

	if not item then
		Cauldron:error("GetSkillInfoForItem: item is nil!");
		return nil;
	end

	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 _, recipeInfo in pairs(list.recipes) do
				local name, _ = GetItemInfo(recipeInfo.itemLink);
				if name == item then
					return recipeInfo;
				end
			end
		end
	end

	return nil;
end

function Cauldron:GetSkillInfoForLink(recipeLink)

	if not recipeLink then
		Cauldron:error("GetSkillInfoForLink: recipeLink is nil!");
		return nil;
	end

	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 _, recipeInfo in pairs(list.recipes) do
				local id = Cauldron:GetIdFromLink(recipeLink);
				local recipeId = Cauldron:GetIdFromLink(recipeInfo.recipeLink);
				if id == recipeId then
					return recipeInfo;
				end
			end
		end
	end

	return nil;
end

function Cauldron:GetSkillInfoByIndex(itemIndex)

	if not itemIndex then
		Cauldron:error("GetSkillInfoByIndex: itemIndex is nil!");
		return nil;
	end

	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 _, recipeInfo in pairs(list.recipes) do
				if recipeInfo.index == itemIndex then
					return recipeInfo;
				end
			end
		end
	end

	return nil;
end

function Cauldron:GetReagentInfoByIndex(item, reagentIndex)

	local skillInfo = nil;

	if type(item) == "table" then
		skillInfo = item;
	elseif type(item) == "number" then
		skillInfo = self:GetSkillInfoByIndex(tonumber(item));
	end

	if skillInfo then
		for i, reagentInfo in ipairs(skillInfo.reagents) do
			if reagentInfo.index == reagentIndex then
				return reagentInfo;
			end
		end
	end

	return nil;
end

function Cauldron:GetRequiredItems(skillInfo, amount)

	local intermediates = {};
	local reagents = {};

	-- sanity checks
	if not skillInfo then
		Cauldron:error("GetRequiredItems: no skillInfo provided!");
		return intermediates, reagents;
	end

	-- get a proper amount value
	amount = math.max(1, tonumber(amount) or 1);

	-- find out what the reagents are
	for i, reagent in ipairs(skillInfo.reagents) do

		-- copy the reagent info so we can modify the amounts
		local r = CopyTable(reagent);
		r.numRequired = r.numRequired * amount;

		-- see if the character can make the item
		local si = Cauldron:GetSkillInfoForItem(r.name);
		if si then
			table.insert(intermediates, r);
		else
			table.insert(reagents, r);
		end
	end

	return intermediates, reagents;
end

local function split(sep, str)
	local result = {};

	while str do
		local s1, rest = strsplit(sep, str, 2);
		table.insert(result, s1);
		str = rest;
	end

	return result;
end

--[==[
function Cauldron:GetReagentsForSkill(skillInfo)

	if not skillInfo then
		self:error("No skill info provided!");
		return {};
	end

	local reagents = {};

	local itemId = self:GetIdFromLink(skillInfo.itemLink);

	local skillName = CURRENT_TRADESKILL;
	local baseSkillName = CURRENT_TRADESKILL;
	if IsTradeSkillLinked() then
		skillName = "Linked-"..skillName;
	end

	-- check if the reagents are already populated
	if #skillInfo.reagents > 0 then
		return skillInfo.reagents;
	end

	-- check for the proper trade skill context
	if CURRENT_TRADESKILL == skillInfo.tradeskill then

		for i=1,GetTradeSkillNumReagents(skillInfo.index) do
			local name, icon, count, _ = GetTradeSkillReagentInfo(skillInfo.index, i);
			local link = GetTradeSkillReagentItemLink(skillInfo.index, i);
			local itemId = Cauldron:GetIdFromLink(link);
			local value, set = self.libs.PT:ItemInSet(itemId, "Tradeskill.Mat.BySource.Vendor");
			local key = true;
			if value then
				key = false;
			end

			local r = {
--				["toonHas"] = GetItemCount(link),
				["name"] = name,
				["numRequired"] = count,
				["skillIndex"] = skillInfo.index,
				["icon"] = icon,
				["link"] = link,
				["key"] = key,
			};

			table.insert(reagents, r);
		end

		-- save the reagent list
		skillInfo.reagents = reagents;
	else
		self:warn("No tradeskill context found; using PeriodicTable for reagent info!");

		-- check the standard skill
		local reagentStr = self.libs.PT:ItemInSet(itemId, "TradeskillResultMats.Forward."..skillInfo.tradeskill);
		if not reagentStr then
			-- lookup the mapped skill
			local skillMap = {
				['Mining'] = 'Smelting',
	--			['Inscription'] = 'Milling',
	--			['Jewelcrafting'] = 'Prospecting',
			};
			if skillMap[skillInfo.tradeskill] then
				reagentStr = self.libs.PT:ItemInSet(itemId, "TradeskillResultMats.Forward."..skillMap[skillInfo.tradeskill]);
			end
		end
		if not reagentStr then
			self:error("No reagents found for skill: "..skillInfo.name);
			return {};
		end

		-- split the reagent info
		for _, reagent in ipairs(split(";", reagentStr)) do
			local id, numRequired = strsplit("x", reagent);

			-- get item details for the reagent
			local name, link, _, _, _, _, _, _, _, icon = GetItemInfo(id);

			local r = {
--				["toonHas"] = GetItemCount(id),
				["name"] = name,
				["numRequired"] = tonumber(numRequired),
				["skillIndex"] = skillInfo.index,
				["icon"] = icon,
				["link"] = link,
			};

			table.insert(reagents, r);
		end
	end

	return reagents;
end
--]==]

function Cauldron:GetSkillsForReagent(id)
	if not id then
		return {};
	end

	local itemName,itemInfo,_ = GetItemInfo(id);
	local skillList = {};

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

	-- find the reagent in the map
	local reagentMap = Cauldron.db.realm.userdata[Cauldron.vars.playername].reagentMap[itemName];
	if reagentMap then
		for _,skill in ipairs(reagentMap) do
			table.insert(skillList, skill);
		end
	end

	return skillList;
end