Quantcast
-- $Revision$
-- Cauldron user interface logic

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

-- CauldronUI = LibStub("AceAddon-3.0"):NewAddon("CauldronUI", "AceEvent-3.0", "AceConsole-3.0", "LibDebugLog-1.0")

local SLOT_NONE = "none";

function CauldronFrame_Show()
	Cauldron:Frame_Show();
end

function Cauldron:Frame_Show()

	if Cauldron.vars.enabled and not(IsShiftKeyDown() and IsControlKeyDown()) then
 		CloseDropDownMenus();

		if TradeSkillFrame then
			-- place our frame over the original frame
--			CauldronFrame:SetPoint("TOPLEFT", TradeSkillFrame:GetLeft(), TradeSkillFrame:GetTop());

			-- hide the original tradeskill frame
			if not Cauldron.vars.origFrameStrata then
				Cauldron.vars.origFrameStrata = TradeSkillFrame:GetFrameStrata();
			end
			if not Cauldron.vars.origFrameLevel then
				Cauldron.vars.origFrameLevel = TradeSkillFrame:GetFrameLevel();
			end

			TradeSkillFrame:SetAlpha(0);
--			TradeSkillFrame:ClearAllPoints();
--			TradeSkillFrame:SetPoint("TOPLEFT", 0, 900);
			TradeSkillFrame:SetFrameStrata("BACKGROUND");
			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
					table.remove(UISpecialFrames, i);
					break;
				end
			end
--			table.remove(
			--]]

		end

		-- put localized text in various labels
		CauldronSkillInfoFrameQueueLabel:SetText(L["Queue"]);
		CauldronQueueAllButton:SetText(L["Queue All"]);
		CauldronQueueButton:SetText(L["Queue"]);
		CauldronProcessButton:SetText(L["Process"]);
		CauldronClearQueueButton:SetText(L["Clear Queue"]);

 		ShowUIPanel(CauldronFrame);
-- 		tinsert(UISpecialFrames, CauldronFrame:GetName());

	 	self:RegisterMessage("Cauldron_Update", "OnCauldronUpdate");

		self:Frame_Update();
	end

end

function Cauldron:Frame_Hide()

 	self:UnregisterEvent("Cauldron_Update")
 	HideUIPanel(CauldronFrame);

 	if TradeSkillFrame then
 		TradeSkillFrame:SetAlpha(1.0);
 		TradeSkillFrame:SetFrameStrata(Cauldron.vars.origFrameStrata or "MEDIUM");
 		TradeSkillFrame:SetFrameLevel(Cauldron.vars.origFrameLevel or 5);
 	end

end

function Cauldron:Frame_Toggle()

 	if CauldronFrame:IsVisible() then
 		Cauldron:Frame_Hide();
 	else
 		Cauldron:Frame_Show();
 	end

end

function CauldronFrame_Update()
	Cauldron:Frame_Update();
end

function Cauldron:Frame_Update()

	local numTradeSkills = GetNumTradeSkills();
	local name, rank, maxRank = GetTradeSkillLine();

	if name == "UNKNOWN" then
		return;
	end

	Cauldron:UpdateSkills();

	if CURRENT_TRADESKILL ~= name then

		StopTradeSkillRepeat();

		if CURRENT_TRADESKILL ~= "" then
			-- To fix problem with switching between two tradeskills
--			UIDropDownMenu_Initialize(TradeSkillInvSlotDropDown, TradeSkillInvSlotDropDown_Initialize);
--			UIDropDownMenu_SetSelectedID(TradeSkillInvSlotDropDown, 1);

--			UIDropDownMenu_Initialize(TradeSkillSubClassDropDown, TradeSkillSubClassDropDown_Initialize);
--			UIDropDownMenu_SetSelectedID(TradeSkillSubClassDropDown, 1);
		end
		CURRENT_TRADESKILL = name;
	end

	-- display skill name, level/progress
	self:UpdateSkillInfo(name, rank, maxRank);

	-- update search text box
	self:UpdateSearchText();

	-- TODO: update dropdowns
	self:UpdateFilterDropDowns();

	-- display list of matching skills
	self:UpdateSkillList();

	-- display queue
	self:UpdateQueue();

	-- update buttons
	self:UpdateButtons();

end

function Cauldron:UpdateSkillInfo(skillName, rank, maxRank)
	--@alpha@
	self:debug("UpdateSkillInfo enter");
	--@end-alpha@

	local skillCount = Cauldron:GetSkillCount(skillName);
	CauldronRankFrameSkillName:SetText(skillName.." ("..skillCount.." "..L["skills"]..")");

	CauldronRankFrame:SetStatusBarColor(0.0, 0.0, 1.0, 0.5);
	CauldronRankFrameBackground:SetVertexColor(0.0, 0.0, 0.75, 0.5);
	CauldronRankFrame:SetMinMaxValues(0, maxRank);
	CauldronRankFrame:SetValue(rank);
	CauldronRankFrameSkillRank:SetText(rank.."/"..maxRank);

end

function Cauldron:UpdateSearchText()

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

	if (not skillName or skillName == "UNKNOWN") or
	   (not self.vars.playername) or
	   (not self.db.realm.userdata[self.vars.playername]) or
	   (not self.db.realm.userdata[self.vars.playername].skills[skillName]) then
		return;
	end

	local searchText = self.db.realm.userdata[self.vars.playername].skills[skillName].window.search or "";
	if searchText == "" then
		searchText = SEARCH;
	end
	CauldronFiltersSearchEditBox:SetText(searchText);

end

function Cauldron:UpdateFilterDropDowns()

	-- TODO

end

function Cauldron:UpdateSkillList()

--	Cauldron:info("Updating skill list: "..debugstack());

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

	local skillList = Cauldron:GetSkillList(self.vars.playername, skillName);
	if not skillList then
		return;
	end

	local height = 0;

	-- iterate over the list of skills
	for i, skillInfo in ipairs(skillList) do

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

		-- check if we have a frame for this position
		if not skillFrame then
			-- create a new frame for the skill information
			skillFrame = CreateFrame("Button",
									 "CauldronSkillItem"..i,
									 CauldronSkillListFrameScrollFrameScrollChild,
									 "CauldronSkillItemFrameTemplate");
		end

		if self.db.realm.userdata[self.vars.playername].options.compactView then
		    -- set the height of frame
		    skillFrame:SetHeight(25);
		    _G["CauldronSkillItem"..i.."SkillCooldown"]:SetHeight(25);

		    -- rescale the icon frame
		    _G["CauldronSkillItem"..i.."SkillIcon"]:SetWidth(18);
		    _G["CauldronSkillItem"..i.."SkillIcon"]:SetHeight(18);

		    -- reposition the name
		    _G["CauldronSkillItem"..i.."SkillName"]:SetPoint("TOPLEFT", 43, -4);

		    -- hide the category info
		    _G["CauldronSkillItem"..i.."SkillCategory"]:Hide();
		else
		    -- set the height of frame
		    skillFrame:SetHeight(50);
		    _G["CauldronSkillItem"..i.."SkillCooldown"]:SetHeight(50);

		    -- rescale the icon frame
		    _G["CauldronSkillItem"..i.."SkillIcon"]:SetWidth(37);
		    _G["CauldronSkillItem"..i.."SkillIcon"]:SetHeight(37);

		    -- reposition the name
		    _G["CauldronSkillItem"..i.."SkillName"]:SetPoint("TOPLEFT", 62, -4);

		    -- show the category info
		    _G["CauldronSkillItem"..i.."SkillCategory"]:Show();
		end

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

		-- set selection
		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();
		end

		-- populate the frame
		local frame = nil;

		-- set name and difficulty color
		frame = _G["CauldronSkillItem"..i.."SkillName"];
		local nameText = skillInfo.name;
		local potentialCount = Cauldron:GetPotentialCraftCount(skillInfo);
		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
			nameText = nameText.." [A]";
		end
		frame:SetText(nameText);
		if TradeSkillTypeColor then
			local color = TradeSkillTypeColor[skillInfo.difficulty];
			if color then
				frame:SetFontObject(color.font);
				frame.r = color.r;
				frame.g = color.g;
				frame.b = color.b;
			end
		end

		-- set category
		frame = _G["CauldronSkillItem"..i.."SkillCategory"];
		frame:SetText(skillInfo.defaultCategory);
		if TradeSkillTypeColor then
			frame:SetFontObject(TradeSkillTypeColor.header.font);
			frame.r = TradeSkillTypeColor.header.r;
			frame.g = TradeSkillTypeColor.header.g;
			frame.b = TradeSkillTypeColor.header.b;
		end

		-- set favorite check button
		frame = _G["CauldronSkillItem"..i.."FavoriteButton"];
		frame:SetChecked(self.db.realm.userdata[self.vars.playername].skills[skillName].window.skills[skillInfo.name].favorite);
		frame.skillInfo = skillInfo;

		-- set cooldown
		frame = _G["CauldronSkillItem"..i.."SkillCooldown"];
		local cooldown = GetTradeSkillCooldown(skillInfo.index);
		if cooldown then
			if not frame:IsVisible() then
				frame:Show();
			end
			frame:SetText(SecondsToTime(cooldown));
		else
			if frame:IsVisible() then
				frame:Hide();
			end
		end

		-- set the icon
		frame = _G["CauldronSkillItem"..i.."SkillIcon"];
		frame:SetNormalTexture(skillInfo.icon);
		frame.itemLink = skillInfo.link;
		frame.skillIndex = skillInfo.index;

		-- set the craft count
		frame = _G["CauldronSkillItem"..i.."SkillIconCount"];
		local minMade, maxMade = skillInfo.minMade, skillInfo.maxMade;
		if maxMade > 1 then
			if minMade == maxMade then
				frame:SetText(minMade);
			else
				frame:SetText(minMade.."-"..maxMade);
			end
			if frame:GetWidth() > 39 then
				frame:SetText("~"..floor((minMade + maxMade)/2));
			end
		else
			frame:SetText("");
		end

		-- set the disclosure button texture
		frame = _G["CauldronSkillItem"..i.."DiscloseButton"];
		frame.skillInfo = skillInfo;
		local reagentsExpanded = self.db.realm.userdata[self.vars.playername].skills[skillName].window.skills[skillInfo.name].expanded;
		if reagentsExpanded then
			frame:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-Up");

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

			-- fill in the tools info
			local spellFocus = BuildColoredListString(GetTradeSkillTools(skillInfo.index));
			local toolsFrame = _G["CauldronSkillItem"..i.."ReagentsToolsInfo"];
			if spellFocus then
				toolsFrame:Show();
				toolsFrame:SetText(L["Requires"]..": "..spellFocus);
				toolsFrame:SetHeight(15);
			else
				toolsFrame:Hide();
				toolsFrame:SetText("");
				toolsFrame:SetHeight(0);
			end

			-- fill in the reagents
			_G["CauldronSkillItem"..i.."Reagents"]:SetScale(0.86);

			-- get reagents table
			local reagents = skillInfo.reagents;
			local reagentCount = #reagents;

			for j=1,8 do
				local reagentFrame = _G["CauldronSkillItem"..i.."ReagentsItemDetail"..j];

				if j > reagentCount then
					reagentFrame:Hide();
				else
					local reagentInfo = reagents[j];

					reagentFrame.skillIndex = skillInfo.index;
					reagentFrame.reagentIndex = reagentInfo.index;
					reagentFrame.link = reagentInfo.link;

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

					-- PARANOIA: check if the reagent name, icon, or link are missing
					if not reagentInfo.name or not reagentInfo.icon or not reagentInfo.link then
						Cauldron:error("Reagent info missing; marking recipe for rescan: "..skillInfo.name);
						Cauldron:MarkRecipeForRescan(self.db.realm.userdata[self.vars.playername].skills[skillName], skillInfo.name);
					end

					reagentFrame:Show();
					SetItemButtonTexture(reagentFrame, reagentInfo.icon);
					reagentNameFrame:SetText(reagentInfo.name);

					local playerReagentCount = GetItemCount(reagentInfo.name);

					if playerReagentCount < reagentInfo.numRequired then
						-- Gray out items
						SetItemButtonTextureVertexColor(reagentFrame, 0.5, 0.5, 0.5);
						reagentNameFrame:SetTextColor(GRAY_FONT_COLOR.r, GRAY_FONT_COLOR.g, GRAY_FONT_COLOR.b);
					else
						SetItemButtonTextureVertexColor(reagentFrame, 1.0, 1.0, 1.0);
						reagentNameFrame:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
					end
					if playerReagentCount >= 100 then
						playerReagentCount = "*";
					end
					reagentCountFrame:SetText(playerReagentCount.."/"..reagentInfo.numRequired);
				end
			end

			local reagentRows = math.floor((reagentCount - 1) / 2) + 1;
			_G["CauldronSkillItem"..i.."Reagents"]:SetHeight(toolsFrame:GetHeight() + (reagentRows * _G["CauldronSkillItem"..i.."ReagentsItemDetail1"]:GetHeight()));
			_G["CauldronSkillItem"..i]:SetHeight(_G["CauldronSkillItem"..i.."SkillIcon"]:GetHeight() + _G["CauldronSkillItem"..i.."Reagents"]:GetHeight());
		else
			_G["CauldronSkillItem"..i.."Reagents"]:Hide();

			frame:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-Up");
			_G["CauldronSkillItem"..i]:SetHeight(_G["CauldronSkillItem"..i.."SkillIcon"]:GetHeight());
		end

		-- place the frame in the scroll view
		if i > 1 then
			-- anchor to the frame above
			skillFrame:SetPoint("TOPLEFT", _G["CauldronSkillItem"..(i-1)], "BOTTOMLEFT", 0, -2);
		else
			-- anchor to the parent
			skillFrame:SetPoint("TOPLEFT", 0, 0);
		end

		-- adjust the scroll child size
		height = height + skillFrame:GetHeight();
		CauldronSkillListFrameScrollFrameScrollChild:SetHeight(height);

		-- show the frame
		skillFrame:Show();
	end

	-- hide any remaining frames
	local j = #skillList + 1;
	while true do
		local frame = _G["CauldronSkillItem"..j];
		if not frame then
			break;
		end

		frame:Hide();
		frame:SetHeight(0);

		j = j + 1;
	end

end

function Cauldron:UpdateButtons()

	if IsTradeSkillLinked() then
		CauldronQueueAllButton:Hide();
		CauldronQueueButton:Hide();
		CauldronAmountDecrementButton:Hide();
		CauldronAmountInputBox:Hide();
		CauldronAmountIncrementButton:Hide();
		CauldronCreateAllButton:Hide();
		CauldronCreateButton:Hide();
		CauldronProcessButton:Hide();
		CauldronClearQueueButton:Hide();
		return;
	else
		CauldronQueueAllButton:Show();
		CauldronQueueButton:Show();
		CauldronAmountDecrementButton:Show();
		CauldronAmountInputBox:Show();
		CauldronAmountIncrementButton:Show();
		CauldronCreateAllButton:Show();
		CauldronCreateButton:Show();
		CauldronProcessButton:Show();
		CauldronClearQueueButton:Show();
	end

	local skillInfo = Cauldron:GetSelectedSkill();

	if skillInfo then
		CauldronCreateButton:SetText(skillInfo.verb or CREATE);
		if skillInfo.verb then
			CauldronCreateAllButton:Hide();
		end

		CauldronQueueAllButton:Enable();
		CauldronQueueButton:Enable();

		CauldronCreateButton:Show();

		if skillInfo.available ~= 0 then
			CauldronCreateAllButton:Enable();
			CauldronCreateButton:Enable();
		else
			CauldronCreateAllButton:Disable();
			CauldronCreateButton:Disable();
		end
	else
		CauldronQueueAllButton:Disable();
		CauldronQueueButton:Disable();
		CauldronCreateAllButton:Disable();
		CauldronCreateButton:Disable();
	end

	if not IsTradeSkillLinked() then
		if #CauldronQueue:GetItems(self.db.realm.userdata[self.vars.playername].queue, CURRENT_TRADESKILL) > 0 then
			CauldronProcessButton:Enable();
			CauldronClearQueueButton:Enable();
		else
			CauldronProcessButton:Disable();
			CauldronClearQueueButton:Disable();
		end
	end

end

function Cauldron:UpdateQueue()

	if (not CauldronFrame) or (not CauldronFrame:IsShown()) then
		return;
	end

	local queue = self.db.realm.userdata[self.vars.playername].queue;
	local itemQueue = {};

	local skillName = CURRENT_TRADESKILL;
	if not IsTradeSkillLinked() then
		itemQueue = CauldronQueue:GetItems(queue);
	end

	if #itemQueue == 0 then
		-- queue is empty, display the empty message
		CauldronQueueFrameQueueEmpty:Show();
		CauldronQueueFrameScrollFrame:Hide();

		if IsTradeSkillLinked() then
			CauldronQueueFrameQueueEmptyText:SetText(L["No queue for linked tradeskills."]);
		else
			CauldronQueueFrameQueueEmptyText:SetText(L["The queue is empty!\nMake something."]);
		end

		return;
	end

	-- queue has items, show them
	CauldronQueueFrameQueueEmpty:Hide();
	CauldronQueueFrameScrollFrame:Show();

	local itemFrameHeight = 39;

	local height = 0;

	CauldronQueueFrameScrollFrameQueueSectionsMainItemsHeaderText:SetText(L["In order to make:"]);
	-- adjust the scroll child size
	CauldronQueueFrameScrollFrameQueueSectionsMainItems:SetHeight(#itemQueue * itemFrameHeight);

	for i, queueInfo in ipairs(itemQueue) do
		local queueItemFrame = _G["CauldronQueueItem"..i];
		self:debug("queueItemFrame: "..tostring(queueItemFrame));

		-- check if we have a frame for this position
		if not queueItemFrame then
			-- create a new frame for the queue information
			self:debug("create a new frame for item "..i..": "..queueInfo.name);
			queueItemFrame = CreateFrame("Button",
									 	 "CauldronQueueItem"..i,
									 	 CauldronQueueFrameScrollFrameQueueSectionsMainItems,
									 	 "CauldronQueueItemFrameTemplate");
	    else
	    	self:debug("use existing frame for item "..i..": "..queueInfo.name);

	    	-- set the frame's parent
	    	queueItemFrame:SetParent(CauldronQueueFrameScrollFrameQueueSectionsMainItems);
		end

		-- initialize the frame
--		queueItemFrame:SetAlpha(1.0);
--		queueItemFrame:SetHeight(itemFrameHeight);

		-- set some basic properties
		queueItemFrame:SetID(i);
		queueItemFrame.itemName = queueInfo.name;
		queueItemFrame.removeable = true;
		queueItemFrame.shoppable = false;
		queueItemFrame.inHoverButtons = false;

		_G["CauldronQueueItem"..i.."RemoveItem"]:Hide();
		_G["CauldronQueueItem"..i.."RemoveItem"]:SetScale(0.75);
		_G["CauldronQueueItem"..i.."IncreasePriority"]:Hide();
		_G["CauldronQueueItem"..i.."DecreasePriority"]:Hide();
		_G["CauldronQueueItem"..i.."DecrementCount"]:Hide();
		_G["CauldronQueueItem"..i.."IncrementCount"]:Hide();
		_G["CauldronQueueItem"..i.."IncrementCount"]:SetScale(0.75);
		_G["CauldronQueueItem"..i.."AddToShoppingList"]:Hide();
		_G["CauldronQueueItem"..i.."AddToShoppingList"]:SetScale(0.5);

		local skillInfo = Cauldron:GetSkillInfo(queueInfo.tradeskill, queueInfo.name);
		if not skillInfo then
			-- the skill isn't available (character doesn't know it?)
			self:warn("No skill available for "..queueInfo.name.." ("..queueInfo.tradeskill..")");
		end

		-- initialize the frame object
		local frame = nil;

		-- set name and difficulty color
		frame = _G["CauldronQueueItem"..i.."ItemName"];
		local nameText = queueInfo.name;
		if skillInfo and (skillInfo.available > 0) then
			nameText = nameText.." ["..skillInfo.available.."]";
		end
		frame:SetText(nameText);
		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);
				frame.r = color.r;
				frame.g = color.g;
				frame.b = color.b;
			end
		else
			-- TODO: default color info
			self:debug("Using default color info.");
		end

		-- set quantity info
		frame = _G["CauldronQueueItem"..i.."Info"];
		local infoText = queueInfo.tradeskill;
		-- TODO: alts/bank/etc.
		frame:SetText(infoText);
--		frame:SetTextColor(1.0, 1.0, 0.2, 1.0);
--		frame:SetShadowOffset(0, 0);

		-- set the icon
		frame = _G["CauldronQueueItem"..i.."Icon"];
		frame:SetNormalTexture(queueInfo.icon);
		frame.link = queueInfo.link;

		-- set the amount
		frame = _G["CauldronQueueItem"..i.."IconCount"];
		frame:SetText(queueInfo.amount);

		-- place the frame in the scroll view
		if i > 1 then
			-- anchor to the frame above
			queueItemFrame:SetPoint("TOPLEFT", _G["CauldronQueueItem"..(i-1)], "BOTTOMLEFT", 0, 0);
		else
			-- anchor to the parent
			queueItemFrame:SetPoint("TOPLEFT", CauldronQueueFrameScrollFrameQueueSectionsMainItems, "TOPLEFT", 0, 0);
		end

--		height = height + queueItemFrame:GetHeight() + 2;
--		self:debug("UpdateQueue: height="..height);

		-- show the frame
		queueItemFrame:Show();
	end

	-- hide any remaining frames
	local j = #itemQueue + 1;
	while true do
		local frame = _G["CauldronQueueItem"..j];
		if not frame then
			break;
		end

--		_G["CauldronQueueItem"..j] = nil;

		frame:SetParent(nil);
--		frame:SetAlpha(0.0);
		frame:Hide();
--		frame:SetHeight(0);

--		frame = nil;

		j = j + 1;
	end

	local intQueue = CauldronQueue:GetIntermediates(queue);
	local reagentList = CauldronQueue:GetReagents(queue);

	-- store the intermediate queue and the reagent list
--	self.db.realm.userdata[self.vars.playername].intQueue = intQueue;
--	self.db.realm.userdata[self.vars.playername].reagentList = reagentList;

	-- display intermediate queue, maybe
	if #intQueue == 0 then
		CauldronQueueFrameScrollFrameQueueSectionsSecondaryItemsHeader:SetHeight(1);
		CauldronQueueFrameScrollFrameQueueSectionsSecondaryItemsHeaderText:SetText("");
		CauldronQueueFrameScrollFrameQueueSectionsSecondaryItems:SetHeight(1);
	else
		CauldronQueueFrameScrollFrameQueueSectionsSecondaryItemsHeader:SetHeight(12);
		CauldronQueueFrameScrollFrameQueueSectionsSecondaryItemsHeaderText:SetText(L["You first have to make:"]);

		CauldronQueueFrameScrollFrameQueueSectionsSecondaryItems:SetHeight(#intQueue * itemFrameHeight);

		local intHeight = 0;

		for i, queueInfo in ipairs(intQueue) do
			local queueItemFrame = _G["CauldronQueueIntItem"..i];

			-- check if we have a frame for this position
			if not queueItemFrame then
				-- create a new frame for the skill information
				queueItemFrame = CreateFrame("Button",
											 "CauldronQueueIntItem"..i,
											 CauldronQueueFrameScrollFrameQueueSectionsSecondaryItems,
											 "CauldronQueueItemFrameTemplate");
			else
				self:debug("use existing frame for item "..i..": "..queueInfo.name);

				-- set the frame's parent
				queueItemFrame:SetParent(CauldronQueueFrameScrollFrameQueueSectionsSecondaryItems);
			end

			queueItemFrame:SetID(100 + i);
			queueItemFrame.itemName = queueInfo.name;
			queueItemFrame.removeable = false;
			queueItemFrame.shoppable = true;
			queueItemFrame.inHoverButtons = false;

			-- don't show the "hover" buttons
			_G["CauldronQueueIntItem"..i.."RemoveItem"]:Hide();
			_G["CauldronQueueIntItem"..i.."RemoveItem"]:SetScale(0.75);
			_G["CauldronQueueIntItem"..i.."IncreasePriority"]:Hide();
			_G["CauldronQueueIntItem"..i.."DecreasePriority"]:Hide();
			_G["CauldronQueueIntItem"..i.."DecrementCount"]:Hide();
			_G["CauldronQueueIntItem"..i.."IncrementCount"]:Hide();
			_G["CauldronQueueIntItem"..i.."IncrementCount"]:SetScale(0.75);
			_G["CauldronQueueIntItem"..i.."AddToShoppingList"]:Hide();
			_G["CauldronQueueIntItem"..i.."AddToShoppingList"]:SetScale(0.5);

			local skillInfo = Cauldron:GetSkillInfo(queueInfo.tradeskill, queueInfo.name);
			if not skillInfo then
				-- the skill isn't available (character doesn't know it?)
				-- TODO
				self:error("No skill info available for: "..queueInfo.name.."!");
			end

			queueItemFrame.link = skillInfo.recipeLink;

			-- populate the frame
			local frame = nil;

			-- set name and difficulty color
			frame = _G["CauldronQueueIntItem"..i.."ItemName"];
			local nameText = queueInfo.name;
			if skillInfo then
				if (skillInfo.available > 0) then
					nameText = nameText.." ["..skillInfo.available.."]";
				end
				frame:SetText(nameText);

				local color = TradeSkillTypeColor[skillInfo.difficulty];
				if color then
					frame:SetFontObject(color.font);
					frame:SetTextColor(color.r, color.g, color.b, 1.0);
					frame.r = color.r;
					frame.g = color.g;
					frame.b = color.b;
				end
			else
				frame:SetFont("GameFontNormal", 12);
--				frame:SetTextColor(1.0, 1.0, 1.0, 1.0);
				frame.r = 1.0;
				frame.g = 1.0;
				frame.b = 1.0;
			end

			-- set quantity info
			frame = _G["CauldronQueueIntItem"..i.."Info"];
			local countInfo = Cauldron:ReagentCount(queueInfo.name);
			local infoText = queueInfo.tradeskill;
			--[[ string.format(queueInfo.tradeskill.."; "..L["Have %d"], countInfo.has);
			if countInfo.bank > 0 then
				infoText = infoText..string.format(L[" (%d in bank)"], countInfo.bank);
			end
			local need = math.max(0, queueInfo.amount - countInfo.has);
			if need > 0 then
				infoText = infoText..string.format(L[", need %d"], need);
			end --]]
			-- alts/bank/etc.
			frame:SetText(infoText);
			frame:SetTextColor(0.1, 0.1, 0.1, 1.0);
			frame:SetShadowOffset(0, 0);

			-- set the icon
			frame = _G["CauldronQueueIntItem"..i.."Icon"];
			frame:SetNormalTexture(queueInfo.icon);
			frame.link = queueInfo.link;

			-- set the amount
			frame = _G["CauldronQueueIntItem"..i.."IconCount"];
			frame:SetText(queueInfo.amount);

			-- place the frame in the scroll view
			if i > 1 then
				-- anchor to the frame above
				queueItemFrame:SetPoint("TOPLEFT", _G["CauldronQueueIntItem"..(i-1)], "BOTTOMLEFT", 0, 0);
			else
				-- anchor to the parent
				queueItemFrame:SetPoint("TOPLEFT", CauldronQueueFrameScrollFrameQueueSectionsSecondaryItems, "TOPLEFT", 0, 0);
			end

			-- adjust the scroll child size
--			intHeight = intHeight + queueItemFrame:GetHeight() + 2;
--			self:debug("UpdateQueue: height="..height);
--			CauldronQueueFrameScrollFrameQueueSectionsSecondaryItems:SetHeight(intHeight);

			-- show the frame
			queueItemFrame:Show();
		end
	end

	-- hide any remaining frames
	j = #intQueue + 1;
	while true do
		local frame = _G["CauldronQueueIntItem"..j];
		if not frame then
			break;
		end

--		_G["CauldronQueueIntItem"..j] = nil;

		frame:SetParent(nil);
--		frame:SetAlpha(0.0);
		frame:Hide();
--		frame:SetHeight(0);

--		frame = nil;

		j = j + 1;
	end

	-- display reagent list

	CauldronQueueFrameScrollFrameQueueSectionsReagentsHeaderText:SetText(L["You will need:"]);
	CauldronQueueFrameScrollFrameQueueSectionsReagents:SetHeight(#reagentList * itemFrameHeight);

	local reagentHeight = 0;

	for i, queueInfo in ipairs(reagentList) do
		local queueItemFrame = _G["CauldronQueueReagentItem"..i];

		-- check if we have a frame for this position
		if not queueItemFrame then
			-- create a new frame for the skill information
			queueItemFrame = CreateFrame("Button",
										 "CauldronQueueReagentItem"..i,
										 CauldronQueueFrameScrollFrameQueueSectionsReagents,
										 "CauldronQueueItemFrameTemplate");
	    else
	    	self:debug("use existing frame for item "..i..": "..queueInfo.name);

	    	-- set the frame's parent
	    	queueItemFrame:SetParent(CauldronQueueFrameScrollFrameQueueSectionsReagents);
		end

		local countInfo = Cauldron:ReagentCount(queueInfo.name);
		local need = math.max(0, queueInfo.amount - countInfo.has);

		queueItemFrame:SetID(200 + i);
		queueItemFrame.skillIndex = queueInfo.skillIndex;
		queueItemFrame.index = queueInfo.index;
		queueItemFrame.itemName = queueInfo.name;
		queueItemFrame.removeable = false;
		queueItemFrame.shoppable = true;
		queueItemFrame.inHoverButtons = false;
		queueItemFrame.needAmount = need;

		-- don't show the "hover" buttons
		_G["CauldronQueueReagentItem"..i.."RemoveItem"]:Hide();
		_G["CauldronQueueReagentItem"..i.."RemoveItem"]:SetScale(0.75);
		_G["CauldronQueueReagentItem"..i.."IncreasePriority"]:Hide();
		_G["CauldronQueueReagentItem"..i.."DecreasePriority"]:Hide();
		_G["CauldronQueueReagentItem"..i.."DecrementCount"]:Hide();
		_G["CauldronQueueReagentItem"..i.."IncrementCount"]:Hide();
		_G["CauldronQueueReagentItem"..i.."IncrementCount"]:SetScale(0.75);
		_G["CauldronQueueReagentItem"..i.."AddToShoppingList"]:Hide();
		_G["CauldronQueueReagentItem"..i.."AddToShoppingList"]:SetScale(0.5);

		local skillInfo = Cauldron:GetSkillInfo(queueInfo.tradeskill, queueInfo.name);
		if not skillInfo then
			-- TODO
		end

		-- populate the frame
		local frame = nil;

		-- set name and difficulty color
		frame = _G["CauldronQueueReagentItem"..i.."ItemName"];
		frame:SetText(queueInfo.name);
		frame:SetShadowOffset(0, 0);
		frame:SetFont("GameFontNormal", 12);
		frame:SetTextColor(0.1, 0.1, 0.1, 1.0);
		frame.r = 1.0;
		frame.g = 1.0;
		frame.b = 1.0;

		-- set quantity info
		frame = _G["CauldronQueueReagentItem"..i.."Info"];
		local countInfo = Cauldron:ReagentCount(queueInfo.name);
		local qtyText = string.format(L["Have %d"], countInfo.has);
		if countInfo.bank > 0 then
			qtyText = qtyText..string.format(L[" (%d in bank)"], countInfo.bank);
		end
		if need > 0 then
			qtyText = qtyText..string.format(L[", need %d"], need);
		end
		-- TODO: alts/bank/etc.
		frame:SetText(qtyText);
		frame:SetTextColor(0.4, 0.4, 0.4, 1.0);
		frame:SetShadowOffset(0, 0);

		-- set the icon
		frame = _G["CauldronQueueReagentItem"..i.."Icon"];
		frame:SetNormalTexture(queueInfo.icon);
		frame.link = queueInfo.link;
--		local playerReagentCount = 0; -- TODO
--		if playerReagentCount < queueInfo.amount then
--			frame:SetVertexColor(0.5, 0.5, 0.5, 1.0);
--			frame:SetTextColor(GRAY_FONT_COLOR.r, GRAY_FONT_COLOR.g, GRAY_FONT_COLOR.b);
--		else
--			frame:SetVertexColor(1.0, 1.0, 1.0, 1.0);
--			frame:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
--		end

		-- set the amount
		frame = _G["CauldronQueueReagentItem"..i.."IconCount"];
		frame:SetText(queueInfo.amount);

		-- place the frame in the scroll view
		if i > 1 then
			-- anchor to the frame above
			queueItemFrame:SetPoint("TOPLEFT", _G["CauldronQueueReagentItem"..(i-1)], "BOTTOMLEFT", 0, 0);
		else
			-- anchor to the parent
			queueItemFrame:SetPoint("TOPLEFT", CauldronQueueFrameScrollFrameQueueSectionsReagents, "TOPLEFT", 0, 0);
		end

		-- adjust the scroll child size
--		reagentHeight = reagentHeight + queueItemFrame:GetHeight() + 2;
--		self:debug("UpdateQueue: height="..height);
--		CauldronQueueFrameScrollFrameQueueSectionsReagents:SetHeight(reagentHeight);

		-- show the frame
		queueItemFrame:Show();
	end

	-- hide any remaining frames
	j = #reagentList + 1;
	while true do
		local frame = _G["CauldronQueueReagentItem"..j];
		if not frame then
			break;
		end

--		_G["CauldronQueueReagentItem"..j] = nil;

		frame:SetParent(nil);
--		frame:SetAlpha(0.0);
		frame:Hide();
--		frame:SetHeight(0);

--		frame = nil;

		j = j + 1;
	end
--]]
	-- adjust the height of the scroll frame
	local h = CauldronQueueFrameScrollFrameQueueSectionsMainItemsHeader:GetHeight() +
			CauldronQueueFrameScrollFrameQueueSectionsMainItems:GetHeight() +
			CauldronQueueFrameScrollFrameQueueSectionsSecondaryItemsHeader:GetHeight() +
			CauldronQueueFrameScrollFrameQueueSectionsSecondaryItems:GetHeight() +
			CauldronQueueFrameScrollFrameQueueSectionsReagentsHeader:GetHeight() +
			CauldronQueueFrameScrollFrameQueueSectionsReagents:GetHeight();
	CauldronQueueFrameScrollFrameQueueSections:SetHeight(h);
	CauldronQueueFrameScrollFrame:UpdateScrollChildRect();

end

function Cauldron:SaveFramePosition()

-- TODO

end

function Cauldron:OnCauldronUpdate()

	--[[
--	self:Search();
 	local selectionIndex
 	if self.vars.selectionIndex == 0 then
 		selectionIndex = self:GetFirstTradeSkill();
 	else
 		selectionIndex = self.vars.selectionIndex;
 	end
 	--]]

end

function Cauldron:FilterDropDown_OnLoad(dropdown)

--[[
	if CURRENT_TRADESKILL == "" or CURRENT_TRADESKILL == "UNKNOWN" then
		return;
	end
--]]

	UIDropDownMenu_Initialize(dropdown, Cauldron.FilterDropDown_Initialize);
	UIDropDownMenu_SetText(CauldronFiltersFilterDropDown, L["Filters"]);

end

function Cauldron:InvSlotDropDown_OnLoad(dropdown)

--[[
	if CURRENT_TRADESKILL == "" or CURRENT_TRADESKILL == "UNKNOWN" then
		return;
	end
--]]

	UIDropDownMenu_Initialize(dropdown, Cauldron.InvSlotDropDown_Initialize);
	UIDropDownMenu_SetText(CauldronFiltersInvSlotDropDown, L["Slots"]);

end

function Cauldron:CategoryDropDown_OnLoad(dropdown)

--[[
	if CURRENT_TRADESKILL == "" or CURRENT_TRADESKILL == "UNKNOWN" then
		return;
	end
--]]

	UIDropDownMenu_Initialize(dropdown, Cauldron.CategoryDropDown_Initialize);
	UIDropDownMenu_SetText(CauldronFiltersCategoryDropDown, L["Categories"]);

end

function Cauldron:FilterDropDown_Initialize(level)

--[[
	if CURRENT_TRADESKILL == "" or CURRENT_TRADESKILL == "UNKNOWN" then
		return;
	end
--]]

	if not Cauldron.db then
		return;
	end

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

	UIDropDownMenu_SetText(CauldronFiltersFilterDropDown, L["Filters"]);

	-- reset item
	local resetFilters = {
		text = L["Reset filters"],
		checked = false,
		tooltipTitle = L["Reset filters"],
		tooltipText = L["Reset all filters on the skills list"],
		func = function(arg1, arg2) Cauldron:FilterDropDown_Reset(arg1) end,
		arg1 = "",
		arg2 = "",
	};
	UIDropDownMenu_AddButton(resetFilters);

	-- spacer
	UIDropDownMenu_AddButton({
		text = "",
		notClickable = true,
	});

	local miscTitle = {
		text = L["View"],
		isTitle = true,
		tooltipTitle = "",
		tooltipText = "",
	};
	UIDropDownMenu_AddButton(miscTitle);

	-- compact
	local compact = {
		text = L["Compact"],
		checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].options.compactView,
		tooltipTitle = L["Compact"],
		tooltipText = L["Display a compacted view of the skill list"],
		func = function(arg1, arg2) Cauldron.db.realm.userdata[Cauldron.vars.playername].options.compactView = not Cauldron.db.realm.userdata[Cauldron.vars.playername].options.compactView; Cauldron:UpdateSkillList(); end,
		arg1 = "compact",
		arg2 = "",
	};
	UIDropDownMenu_AddButton(compact);

	if not IsTradeSkillLinked() then
		-- favorites
		local faves = {
			text = L["Favorites"],
			checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.favorites,
			tooltipTitle = L["Favorites"],
			tooltipText = L["Display only favorite skills"],
			func = function(arg1, arg2) Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.favorites = not Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.favorites; Cauldron:UpdateSkillList(); end,
			arg1 = "favorite",
			arg2 = "",
		};
		UIDropDownMenu_AddButton(faves);

		-- achievements
		local achievements = {
			text = L["Achievements"],
			checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.achievements,
			tooltipTitle = L["Achievements"],
			tooltipText = L["Display only skills for achievements"],
			func = function(arg1, arg2) Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.achievements = not Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.achievements; Cauldron:UpdateSkillList(); end,
			arg1 = "achievement",
			arg2 = "",
		};
		UIDropDownMenu_AddButton(achievements);

		-- spacer
		UIDropDownMenu_AddButton({
			text = "",
			notClickable = true,
		});
	end

	-- sorting

	local sortingTitle = {
		text = L["Sort"],
		isTitle = true,
		tooltipTitle = "",
		tooltipText = "",
	};
	UIDropDownMenu_AddButton(sortingTitle);

	local sortDefault = {
		text = L["Default"],
		checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDefault,
		tooltipTitle = L["Default"],
		tooltipText = L["Set the sorting method to use on the skills list"],
		func = function(arg1, arg2) Cauldron:FilterDropDown_SetSort(arg1) end,
		arg1 = "default",
		arg2 = "",
	};
	UIDropDownMenu_AddButton(sortDefault);

	local sortAlpha = {
		text = L["Alphabetically"],
		checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortAlpha,
		tooltipTitle = L["Alphabetically"],
		tooltipText = L["Set the sorting method to use on the skills list"],
		func = function(arg1, arg2) Cauldron:FilterDropDown_SetSort(arg1) end,
		arg1 = "alpha",
		arg2 = "",
	};
	UIDropDownMenu_AddButton(sortAlpha);

	local sortDifficulty = {
		text = L["By difficulty"],
		checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDifficulty,
		tooltipTitle = L["By difficulty"],
		tooltipText = L["Set the sorting method to use on the skills list"],
		func = function(arg1, arg2) Cauldron:FilterDropDown_SetSort(arg1) end,
		arg1 = "difficulty",
		arg2 = "",
	};
	UIDropDownMenu_AddButton(sortDifficulty);

	local sortItemLevel = {
		text = L["By item level"],
		checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortItemLevel,
		tooltipTitle = L["By item level"],
		tooltipText = L["Set the sorting method to use on the skills list"],
		func = function(arg1, arg2) Cauldron:FilterDropDown_SetSort(arg1) end,
		arg1 = "itemlevel",
		arg2 = "",
	};
	UIDropDownMenu_AddButton(sortItemLevel);

	local sortReqLevel = {
		text = L["By required level"],
		checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortRequiredLevel,
		tooltipTitle = L["By required level"],
		tooltipText = L["Set the sorting method to use on the skills list"],
		func = function(arg1, arg2) Cauldron:FilterDropDown_SetSort(arg1) end,
		arg1 = "reqlevel",
		arg2 = "",
	};
	UIDropDownMenu_AddButton(sortReqLevel);

	--[[
	local sortFaves = {
		text = L["By favorites"],
		checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortFavorites,
		tooltipTitle = L["By favorites"],
		tooltipText = L["Set the sorting method to use on the skills list"],
		func = function(arg1, arg2) Cauldron:FilterDropDown_SetSort(arg1) end,
		arg1 = "favorite",
		arg2 = "",
	};
	UIDropDownMenu_AddButton(sortFaves);
	--]]

	--[[
	local sortBenefit = {
		text = L["By benefit"],
		checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[CURRENT_TRADESKILL].window.filter.sortBenefit,
		tooltipTitle = L["By benefit"],
		tooltipText = L["Set the sorting method to use on the skills list"],
		func = function(arg1, arg2) Cauldron:FilterDropDown_SetSort(arg1) end,
		arg1 = "benefit",
		arg2 = "",
	};
	UIDropDownMenu_AddButton(sortBenefit);
	--]]

	-- spacer
	UIDropDownMenu_AddButton({
		text = "",
		notClickable = true,
	});

	-- skill difficulty

	local difficultyTitle = {
		text = L["Difficulty"],
		isTitle = true,
		tooltipTitle = "",
		tooltipText = "",
	};
	UIDropDownMenu_AddButton(difficultyTitle);

	local difficultyOptimal = {
		text = L["Optimal"],
--		textR = 1.0,
--		textG = 1.0,
--		textB = 1.0,
		checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.optimal,
--		keepShownOnClick = true,
		tooltipTitle = L["Optimal"],
		tooltipText = L["Set whether items of this difficulty level should be shown"],
		func = function(arg1, arg2) Cauldron:FilterDropDown_ToggleDifficulty(arg1) end,
		arg1 = "optimal",
		arg2 = "",
	};
	UIDropDownMenu_AddButton(difficultyOptimal);

	local difficultyMedium = {
		text = L["Medium"],
--		textR = 1.0,
--		textG = 1.0,
--		textB = 1.0,
		checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.medium,
--		keepShownOnClick = true,
		tooltipTitle = L["Medium"],
		tooltipText = L["Set whether items of this difficulty level should be shown"],
		func = function(arg1, arg2) Cauldron:FilterDropDown_ToggleDifficulty(arg1) end,
		arg1 = "medium",
		arg2 = "",
	};
	UIDropDownMenu_AddButton(difficultyMedium);

	local difficultyEasy = {
		text = L["Easy"],
--		textR = 1.0,
--		textG = 1.0,
--		textB = 1.0,
		checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.easy,
--		keepShownOnClick = true,
		tooltipTitle = L["Easy"],
		tooltipText = L["Set whether items of this difficulty level should be shown"],
		func = function(arg1, arg2) Cauldron:FilterDropDown_ToggleDifficulty(arg1) end,
		arg1 = "easy",
		arg2 = "",
	};
	UIDropDownMenu_AddButton(difficultyEasy);

	local difficultyTrivial = {
		text = L["Trivial"],
--		textR = 1.0,
--		textG = 1.0,
--		textB = 1.0,
		checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.trivial,
--		keepShownOnClick = true,
		tooltipTitle = L["Trivial"],
		tooltipText = L["Set whether items of this difficulty level should be shown"],
		func = function(arg1, arg2) Cauldron:FilterDropDown_ToggleDifficulty(arg1) end,
		arg1 = "trivial",
		arg2 = "",
	};
	UIDropDownMenu_AddButton(difficultyTrivial);

	-- spacer
	UIDropDownMenu_AddButton({
		text = "",
		notClickable = true,
	});

	-- reagents availability

	local reagentsTitle = {
		text = L["Reagents"],
		isTitle = true,
		tooltipTitle = "",
		tooltipText = "",
	};
	UIDropDownMenu_AddButton(reagentsTitle);

	-- force check "normal" if the list is linked
	if IsTradeSkillLinked() then
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAllReagents = false;
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveKeyReagents = false;
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAnyReagents = false;
	end

	local normal = {
		text = L["Normal"],
		checked = Cauldron:ReagentsFilterNormalCheck(),
		tooltipTitle = L["Reagents"],
		tooltipText = L["Display the normal list of skills"],
		func = function(arg1, arg2) Cauldron:FilterDropDown_SetReagentFilter(arg1) end,
		arg1 = "normal",
		arg2 = "",
	};
	UIDropDownMenu_AddButton(normal);

	if not IsTradeSkillLinked() then

		local haveAllReagents = {
			text = L["Have all"],
			checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAllReagents,
			tooltipTitle = L["Reagents"],
			tooltipText = L["Set whether skills for which you have all the required reagents are shown in the list"],
			func = function(arg1, arg2) Cauldron:FilterDropDown_SetReagentFilter(arg1) end,
			arg1 = "all",
			arg2 = "",
		};
		UIDropDownMenu_AddButton(haveAllReagents);

		local haveKeyReagents = {
			text = L["Have key"],
			checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveKeyReagents,
			tooltipTitle = L["Reagents"],
			tooltipText = L["Set whether skills for which you have all key reagents (non-vendor available) are shown in the list"],
			func = function(arg1, arg2) Cauldron:FilterDropDown_SetReagentFilter(arg1) end,
			arg1 = "key",
			arg2 = "",
		};
		UIDropDownMenu_AddButton(haveKeyReagents);

		local haveAnyReagents = {
			text = L["Have any"],
			checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAnyReagents,
			tooltipTitle = L["Reagents"],
			tooltipText = L["Set whether skills for which you have any reagents are shown in the list"],
			func = function(arg1, arg2) Cauldron:FilterDropDown_SetReagentFilter(arg1) end,
			arg1 = "any",
			arg2 = "",
		};
		UIDropDownMenu_AddButton(haveAnyReagents);

	end

end

function Cauldron:FilterDropDown_Reset()

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

	-- sorting
	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDefault = true;
	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortAlpha = false;
	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDifficulty = false;
	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortBenefit = false;

	-- difficulty
	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.optimal = true;
	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.medium = true;
	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.easy = true;
	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.trivial = true;

	-- favorites
	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.favorites = false;
	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.favoritesAtTop = false;

	-- availability
	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAllReagents = false;
	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveKeyReagents = false;
	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAnyReagents = false;

	-- update the UI
	Cauldron:UpdateSkillList();

end

function Cauldron:FilterDropDown_SetSort(info)

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

	local sort = info.arg1;

	if sort == "default" then
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDefault = true;
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortAlpha = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDifficulty = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortItemLevel = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortRequiredLevel = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortFavorites = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortBenefit = false;
	elseif sort == "alpha" then
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDefault = false;
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortAlpha = true;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDifficulty = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortItemLevel = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortRequiredLevel = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortFavorites = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortBenefit = false;
	elseif sort == "difficulty" then
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDefault = false;
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortAlpha = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDifficulty = true;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortItemLevel = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortRequiredLevel = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortFavorites = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortBenefit = false;
	elseif sort == "itemlevel" then
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDefault = false;
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortAlpha = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDifficulty = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortItemLevel = true;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortRequiredLevel = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortFavorites = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortBenefit = false;
	elseif sort == "reqlevel" then
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDefault = false;
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortAlpha = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDifficulty = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortItemLevel = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortRequiredLevel = true;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortFavorites = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortBenefit = false;
	elseif sort == "benefit" then
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDefault = false;
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortAlpha = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDifficulty = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortItemLevel = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortRequiredLevel = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortFavorites = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortBenefit = true;
	elseif sort == "favorite" then
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDefault = false;
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortAlpha = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDifficulty = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortItemLevel = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortRequiredLevel = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortFavorites = true;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortBenefit = false;
	end

	-- update the UI
	Cauldron:UpdateSkillList();

end

function Cauldron:ReagentsFilterNormalCheck()

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

	local checked = true;

	if Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAllReagents or
	   Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveKeyReagents or
	   Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAnyReagents then
	   	checked = false;
	end

	return checked;
end

function Cauldron:FilterDropDown_SetReagentFilter(info)

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

	local reagents = info.arg1;

	if reagents == "normal" then
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAllReagents = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveKeyReagents = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAnyReagents = false;
	elseif reagents == "all" then
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAllReagents = true;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveKeyReagents = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAnyReagents = false;
	elseif reagents == "key" then
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAllReagents = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveKeyReagents = true;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAnyReagents = false;
	elseif reagents == "any" then
		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAllReagents = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveKeyReagents = false;
	   	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAnyReagents = true;
	end

	-- update the UI
	Cauldron:UpdateSkillList();

end

function Cauldron:FilterDropDown_ToggleDifficulty(info)

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

	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter[info.arg1] = not Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[CURRENT_TRADESKILL].window.filter[info.arg1];

	-- update the UI
	Cauldron:UpdateSkillList();

end

function Cauldron:InvSlotDropDown_Initialize(level)
	Cauldron:debug("InvSlotDropDown_Initialize enter");

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

	UIDropDownMenu_SetText(CauldronFiltersInvSlotDropDown, L["Slots"]);

	local all = UIDropDownMenu_CreateInfo();
	all.text = ALL_INVENTORY_SLOTS; -- L["All slots"],
	all.func = function(arg1, arg2) Cauldron:InvSlotDropDown_SetSlot(arg1) end;
	all.arg1 = "all";
	UIDropDownMenu_AddButton(all);

	local slots = Cauldron:GetSlots(Cauldron.vars.playername, skillName);
	Cauldron:debug("InvSlotDropDown_Initialize: slots="..#slots);

	--[[
	if slots["none"] then
		local none = UIDropDownMenu_CreateInfo();
		none.text = L["(None)"];
		none.checked = slots.none.checked;
		none.func = function(arg1, arg2) Cauldron:InvSlotDropDown_SetSlot(arg1) end;
		none.arg1 = "none";
		UIDropDownMenu_AddButton(none);
	end
	--]]

	for name, _ in pairs(slots) do
		Cauldron:debug("InvSlotDropDown_Initialize: name="..tostring(name));
		if name ~= "" then
			local slot = UIDropDownMenu_CreateInfo();
			slot.text = _G[name] or L["(None)"];
			slot.checked = slots[name].checked;
			slot.func = function(arg1, arg2) Cauldron:InvSlotDropDown_SetSlot(arg1) end;
			slot.arg1 = name;
			UIDropDownMenu_AddButton(slot);
		end
	end

	Cauldron:debug("InvSlotDropDown_Initialize exit");
end

function Cauldron:SlotsFilterAllCheck()
	Cauldron:debug("SlotsFilterAllCheck enter");

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

	local checked = true;

	if Cauldron.db then
		for name, slotInfo in pairs(Cauldron:GetSlots(Cauldron.vars.playername, skillName)) do
			if slotInfo.checked then
				checked = false;
				Cauldron:debug("breaking from slot check");
				break;
			end
		end
	end

	self:debug("SlotsFilterAllCheck exit");

	return checked;
end

function Cauldron:InvSlotDropDown_SetSlot(info)
	-- self:debug("InvSlotDropDown_SetSlot enter");

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

	Cauldron:debug("InvSlotDropDown_SetSlot: info.arg1="..info.arg1);

	local slots = Cauldron:GetSlots(Cauldron.vars.playername, skillName);

	if info.arg1 == "all" then
		Cauldron:debug("InvSlotDropDown_SetSlot: selecting all slots...");
--		slots["(None)"] = true;
		for name, slotInfo in pairs(slots) do
			Cauldron:debug("InvSlotDropDown_SetSlot: name="..name);
			slotInfo.checked = true;
		end
	--[[
	elseif info.arg1 == "none" then
		Cauldron:debug("InvSlotDropDown_SetSlot: selecting special 'none' slot...");
--		local slotName = "(None)";
		if not slots[slotName] then
			slots[slotName] = true;
		else
			slots[slotName] = not slots[slotName];
		end
	--]]
	else
		self:debug("InvSlotDropDown_SetSlot: select a specific slot: "..info.arg1);
		for name, slotInfo in pairs(slots) do
			Cauldron:debug("InvSlotDropDown_SetSlot: name="..name);
			slotInfo.checked = false;
		end
		slots[info.arg1].checked = true;
--		if not Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.slots[info.arg1] then
--			Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.slots[info.arg1] = true;
--		else
--			Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.slots[info.arg1] = not Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.slots[info.arg1];
--		end
	end

	Cauldron:UpdateSkillList();

	Cauldron:debug("InvSlotDropDown_SetSlot exit");
end

function Cauldron:CategoryDropDown_Initialize(level)

--[[
	if CURRENT_TRADESKILL == "" or CURRENT_TRADESKILL == "UNKNOWN" then
		return;
	end
--]]

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

	UIDropDownMenu_SetText(CauldronFiltersCategoryDropDown, L["Categories"]);

	local all = {
		text = L["All categories"],
		checked = false, -- Cauldron:CategoriesFilterAllCheck(),
		tooltipTitle = L["All categories"],
		func = function(arg1, arg2) Cauldron:CategoryDropDown_SetCategory(arg1) end,
		arg1 = "all",
		arg2 = "",
	};
	UIDropDownMenu_AddButton(all);

	local none = {
		text = L["No categories"],
		checked = false, -- Cauldron:CategoriesFilterAllCheck(),
		tooltipTitle = L["No categories"],
		func = function(arg1, arg2) Cauldron:CategoryDropDown_SetCategory(arg1) end,
		arg1 = "none",
		arg2 = "",
	};
	UIDropDownMenu_AddButton(none);

	local categories = Cauldron:GetDefaultCategories(Cauldron.vars.playername, skillName);

	-- sort the category list by alpha
	local c = {};
	for name, _ in pairs(categories) do
		table.insert(c, name);
	end

	table.sort(c);

	for i, name in ipairs(c) do
		local category = {
			text = name,
			checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.categories[name].shown,
			tooltipTitle = name,
			func = function(arg1, arg2) Cauldron:CategoryDropDown_SetCategory(arg1) end,
			arg1 = name,
			arg2 = "",
		};
		UIDropDownMenu_AddButton(category);
	end

end

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

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

	local checked = true;

	for name, _ in pairs(Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.categories) do
		if Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.categories[name] then
			checked = false;
			break;
		end
	end

	self:debug("CategoriesFilterAllCheck exit");

	return checked;
end
--]]

function Cauldron:CategoryDropDown_SetCategory(info)

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

	if info.arg1 == "all" or info.arg1 == "none" then
		for name, _ in pairs(Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.categories) do
			local checked = (info.arg1 == "all");
			Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.categories[name].shown = checked;
		end
	else
		if not IsShiftKeyDown() then
			-- uncheck everything
			for name, _ in pairs(Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.categories) do
				Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.categories[name].shown = false;
			end

			-- check the clicked item
			Cauldron.db.realm.userdata[self.vars.playername].skills[skillName].window.categories[info.arg1].shown = true;
		else
			Cauldron.db.realm.userdata[self.vars.playername].skills[skillName].window.categories[info.arg1].shown = not Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[CURRENT_TRADESKILL].window.categories[info.arg1].shown;
		end
	end

	-- update the UI
	Cauldron:UpdateSkillList();

end

function Cauldron:CollapseAllButton_OnClick(button)

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

    local expand = true;
    local skillCount = 0;
    local expandedCount = 0;
    local collapsedCount = 0;

    -- check if some items are expanded
	for name, info in pairs(Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.skills) do
		if info.expanded then
		    expandedCount = expandedCount + 1;
		else
		    collapsedCount = collapsedCount + 1;
		end
		skillCount = skillCount + 1;
	end

	if expandedCount == 0 then
	    expand = true;
	elseif collapsedCount == 0 then
	    expand = false;
	end

	-- reset all the expanded fields to false
	for name, info in pairs(Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.skills) do
		info.expanded = expand;
	end

	-- unselect the selected skill
	-- Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.selected = 0;

	-- update the UI
	Cauldron:UpdateSkillList();

end

function Cauldron:CollapseItemButton_OnClick(button)

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

	local skillInfo = button.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 = skillInfo.index;

	-- update the UI
	Cauldron:UpdateSkillList();

end

function Cauldron:SkillItem_OnEnter(frame)

	local id = frame:GetID();

	local name = _G["CauldronSkillItem"..id.."SkillName"];
	if name then
--		name:
	end

	-- TODO

end

function Cauldron:SkillItem_OnLeave(frame)

-- TODO

end

function Cauldron:SkillItem_OnClick(frame, button, down)

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

	-- select this frame
	if frame.skillIndex then
    	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.selected = frame.skillIndex;
    end

	-- update the UI
	Cauldron:UpdateSkillList();
	Cauldron:UpdateButtons();

end

function Cauldron:TradeSkillFilter_OnTextChanged(frame)

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

	if (not skillName or skillName == "UNKNOWN") or
	   (not self.vars.playername) or
	   (not self.db.realm.userdata[self.vars.playername]) or
	   (not self.db.realm.userdata[self.vars.playername].skills[skillName]) then
		return;
	end

	local text = frame:GetText();
	if text == SEARCH then
		text = "";
	end

	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.search = text;

	-- update the UI
	Cauldron:UpdateSkillList();

end

function Cauldron:AmountDecrement_OnClick()

	local num = CauldronAmountInputBox:GetNumber();
	num = math.max(1, num - 1);
	CauldronAmountInputBox:SetNumber(num);

end

function Cauldron:AmountIncrement_OnClick()

	local num = CauldronAmountInputBox:GetNumber();
	num = math.min(999, num + 1);
	CauldronAmountInputBox:SetNumber(num);

end

function Cauldron:FavoriteItemButton_OnClick(button)

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

	local skillInfo = button.skillInfo;

	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.skills[skillInfo.name].favorite = button:GetChecked();

end

function Cauldron:ConfirmDialog(title, message, okayBtn, okayBtnCB, cancelBtn, cancelBtnCB)

	local gui = Cauldron.libs.GUI;

	-- Create a container frame
	local f = gui:Create("Frame");
	f:SetCallback("OnClose", function(widget) gui:Release(widget) end);
	f:SetTitle(title);
	f:SetStatusText("");
	f:SetLayout("Flow");
	f:SetWidth(200);
	f:SetHeight(100);

	-- Create okay button
	local btn = gui:Create("Button")
	btn:SetWidth(170);
	btn:SetText(okayBtn);
	btn:SetCallback("OnClick", okayBtnCB); -- TODO wrap this callback in another that will close the window
	-- Add the button to the container
	f:AddChild(btn);

	-- Create cancel button
	local btn = gui:Create("Button")
	btn:SetWidth(170);
	btn:SetText(cancelBtn);
	btn:SetCallback("OnClick", cancelBtnCB); -- TODO wrap this callback in another that will close the window
	-- Add the button to the container
	f:AddChild(btn);

	f:Show();
end

function Cauldron:AppendToTooltip(tooltip, skillIndex)
	if not tooltip then
		return;
	end
	if not skillIndex then
		return;
	end


end