Quantcast

Standard Blizzard tradeskill window is now suppressed.

Paul Schifferer [12-12-10 - 20:07]
Standard Blizzard tradeskill window is now suppressed.
Queue buttons are now in the main window instead of the queue window.
Added checkmarks and some functionality to the slot and subclass filter items.
Added All and None locale strings.
Filename
CauldronMain.lua
CauldronMain.xml
CauldronMainUI.lua
CauldronQueue.xml
Locale/Cauldron-enUS.lua
diff --git a/CauldronMain.lua b/CauldronMain.lua
index 3b95302..7933ab3 100644
--- a/CauldronMain.lua
+++ b/CauldronMain.lua
@@ -315,12 +315,16 @@ function Cauldron:OnEnable()
 	-- initialize the achievement map
 	self:CreateAchievementSkillMap();

+	-- replace the "show" function for the standard tradeskill frame
+	LoadAddOn("Blizzard_TradeSkillUI");
+	self.blizzTradeSkillShow = TradeSkillFrame_Show;
+	TradeSkillFrame_Show = function()
+		-- Cauldron:info("TradeSkillFrame_Show");
+	end
+
 	-- clear init flag
 	self.initializing = false;

-	-- upset the standard tradeskill frame
-	UIPanelWindows["TradeSkillFrame"] = { area = "center" };
-
 end

 function Cauldron:OnDisable()
@@ -358,9 +362,10 @@ end
 function Cauldron:OnTradeShow()
 	self:debug("OnTradeShow enter");

+	TradeSkillFrame_Update(); -- seems to fix the early bailout of trade skill iterations
+
 	-- update our known skills
 	self:debug("OnTradeShow: update known skills");
---	self:ScheduleTimer(self.UpdateSkills,1,self);
 	if not Cauldron.updatingSkills then
 --		Cauldron:info("Requesting skill update on trade show");
 		Cauldron.updatingSkills = Cauldron:NeedsSkillUpdate();
diff --git a/CauldronMain.xml b/CauldronMain.xml
index 93aea26..801b900 100755
--- a/CauldronMain.xml
+++ b/CauldronMain.xml
@@ -823,11 +823,43 @@
 				</ScrollChild>
 			</ScrollFrame>

+			<!-- Queue All button -->
+			<Button name="CauldronQueueAllButton" inherits="CauldronButtonTemplate" text="Queue All">
+				<Anchors>
+					<Anchor point="BOTTOMLEFT">
+						<Offset x="0" y="5" />
+					</Anchor>
+				</Anchors>
+				<Scripts>
+					<OnLoad>
+						-- getglobal(self:GetName()):Disable();
+					</OnLoad>
+					<OnEnter>
+						GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT");
+						GameTooltip:ClearLines();
+						GameTooltip:AddLine(Cauldron:LocaleString("Click to queue the listed amount of this item"));
+						GameTooltip:AddLine(Cauldron:LocaleString("Shift-click to queue the listed potential amount of this item"));
+						GameTooltip:Show();
+						CursorUpdate(self);
+					</OnEnter>
+					<OnLeave>
+						GameTooltip:Hide();
+						ResetCursor();
+					</OnLeave>
+					<OnClick>
+						Cauldron:QueueAllTradeSkillItem();
+						Cauldron:UpdateButtons();
+					</OnClick>
+				</Scripts>
+			</Button>
+
 			<!-- Create all button -->
 			<Button name="CauldronCreateAllButton" inherits="CauldronButtonTemplate" text="CREATE_ALL">
 				<Size x="80" y="22"/>
 				<Anchors>
-					<Anchor point="BOTTOMLEFT" />
+					<Anchor point="LEFT" relativeTo="CauldronQueueAllButton" relativePoint="RIGHT">
+						<Offset x="3" y="0"/>
+					</Anchor>
 				</Anchors>
 				<Frames>
 					<Frame name="$parentMask" setAllPoints="true" enableMouse="true" hidden="true">
@@ -988,6 +1020,24 @@
 				</Scripts>
 			</Button>

+			<!-- Queue button -->
+			<Button name="CauldronQueueButton" inherits="CauldronButtonTemplate" text="Queue">
+				<Anchors>
+					<Anchor point="LEFT" relativeTo="CauldronCreateButton" relativePoint="RIGHT">
+						<Offset x="0" y="0" />
+					</Anchor>
+				</Anchors>
+				<Scripts>
+					<OnLoad>
+						-- getglobal(self:GetName()):Disable();
+					</OnLoad>
+					<OnClick>
+						Cauldron:QueueTradeSkillItem();
+						Cauldron:UpdateButtons();
+					</OnClick>
+				</Scripts>
+			</Button>
+
 			<!-- View guild crafters button -->

 			<!-- Show queue button -->
diff --git a/CauldronMainUI.lua b/CauldronMainUI.lua
index 564cde0..9c911d4 100644
--- a/CauldronMainUI.lua
+++ b/CauldronMainUI.lua
@@ -12,1297 +12,1276 @@ local L = LibStub("AceLocale-3.0"):GetLocale("Cauldron")

 local SLOT_NONE = "none";

-function CauldronFrame_OnLoad()
+function Cauldron:Frame_Show()

---	ButtonFrameTemplate_HideButtonBar(CauldronFrame);
-	ButtonFrameTemplate_HideAttic(CauldronFrame);
---	CauldronFrameInsetBg:Hide();
+self:debug("frame show: "..tostring(CauldronQueueWindowFrame));

-end
+	if Cauldron.vars.enabled and not(IsShiftKeyDown() and IsControlKeyDown()) then

-function CauldronFrame_OnEvent()
-end
+		-- show main UI
+		ShowUIPanel(CauldronFrame);
+		SetPortraitToTexture(CauldronFramePortrait, GetTradeSkillTexture());
+		CauldronInputBox:SetNumber(1);
+		CauldronFrameTitleText:SetText(L["Cauldron"].." "..Cauldron.version);
+
+		-- show queue UI
+		if Cauldron.vars.showQueue then
+			ShowUIPanel(CauldronQueueWindowFrame);
+			SetPortraitToTexture(CauldronQueueWindowFramePortrait, GetTradeSkillTexture());
+			CauldronQueueWindowFrameTitleText:SetText(L["Queue"]);
+		end
+
+		-- check if the filter structure is out of date
+		--[[
+		if not Cauldron.db.global.version or (tonumber(Cauldron.db.global.version) < tonumber(Cauldron.vars.filterVersion)) then
+			Cauldron.db.global.version = tonumber(Cauldron.vars.filterVersion);
+			Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter = {
+				-- sorting
+				sortDefault = true,
+				sortAlpha = false,
+				sortDifficulty = false,
+				sortBenefit = false,
+
+				-- difficulty
+				optimal = true,
+				medium = true,
+				easy = true,
+				trivial = true,
+
+				-- favorites
+				favorites = false,
+				favoritesAtTop = false,
+
+				-- availability
+				haveAllReagents = false,
+				haveKeyReagents = false,
+				haveAnyReagents = false,
+			};
+		end
+		--]]
+
+	 	self:RegisterMessage("Cauldron_Update", "OnCauldronUpdate");
+
+		self:Frame_Update();
+	else
+		-- show the Blizzard frame
+		Cauldron.blizzTradeSkillShow();
+	end

-function CauldronFrame_OnShow()
 end

-function CauldronFrame_OnHide()
+function Cauldron:Frame_Hide()
+
+ 	self:UnregisterEvent("Cauldron_Update");
+ 	HideUIPanel(CauldronQueueWindowFrame);
+ 	HideUIPanel(CauldronFrame);
+
+ 	--[[
+ 	if TradeSkillFrame then
+ 		TradeSkillFrame:SetAlpha(1.0);
+ 		TradeSkillFrame:SetFrameStrata(Cauldron.vars.origFrameStrata or "MEDIUM");
+ 		TradeSkillFrame:SetFrameLevel(Cauldron.vars.origFrameLevel or 5);
+ 	end
+ 	--]]
+
+ 	CloseTradeSkill();
+
 end

-function CauldronSearch_OnTextChanged()
-	Cauldron:TradeSkillFilter_OnTextChanged(CauldronSearchBox);
+function Cauldron:Frame_Toggle()
+
+ 	if CauldronQueueWindowFrame:IsVisible() then
+ 		Cauldron:Frame_Hide();
+ 	else
+ 		Cauldron:Frame_Show();
+ 	end
+
 end

 function CauldronFrame_Update()
+	Cauldron:Frame_Update();
 end

-function CauldronFrame_Show()
-	Cauldron:Frame_Show();
+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();
+		CURRENT_TRADESKILL = name;
+	end
+
+	-- display skill name, level/progress
+	self:UpdateSkillInfo(name, rank, maxRank);
+
+	-- update search text box
+	self:UpdateSearchText();
+
+	-- update filter information
+	self:UpdateStatus();
+--[==[
+	self:UpdateFilterDropDowns();
+--]==]
+
+	-- display list of matching skills
+	if CAULDRON_TRADESKILL_NAME ~= CURRENT_TRADESKILL then
+		CAULDRON_TRADESKILL_NAME = CURRENT_TRADESKILL;
+		self:UpdateSkillList();
+	end
+
+	-- display queue
+	self:UpdateQueue();
+
+	-- update buttons
+	self:UpdateButtons();
+
 end

-function CauldronFilterDropDown_OnLoad(self)
-	UIDropDownMenu_Initialize(self, CauldronFilterDropDown_Initialize, "MENU");
-	CauldronFilterDropDownText:SetJustifyH("CENTER");
-	CauldronFilterDropDownButton:Show();
+function Cauldron:UpdateSkillInfo(skillName, rank, maxRank)
+	--@alpha@
+	self:debug("UpdateSkillInfo enter");
+	--@end-alpha@
+
+	local skillCount = Cauldron:GetSkillCount(skillName);
+--[==[
+	CauldronRankFrameSkillName:SetText(skillName.." ("..skillCount.." "..L["skills"]..")");
+--]==]
+	CauldronSkillNameText:SetText(skillName);
+		local prof_title = "";
+		for i=1,#PROFESSION_RANKS do
+		    local value,title = PROFESSION_RANKS[i][1], PROFESSION_RANKS[i][2];
+			if maxRank < value then break end
+			prof_title = title;
+		end
+	CauldronRankInfoText:SetText(prof_title..", "..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);
+	CauldronRankFrameText:SetText(rank.."/"..maxRank);
+
 end

-function CauldronFilterDropDown_Initialize(self, level)
+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
+	CauldronSearchBox:SetText(searchText);
+
+end
+
+function Cauldron:UpdateStatus()
+
 	local skillName = CURRENT_TRADESKILL;
 	if IsTradeSkillLinked() then
 		skillName = "Linked-"..skillName;
 	end
+
+	local filters = {};
+	local filterTable = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter;

-	local info = UIDropDownMenu_CreateInfo();
+	if filterTable.haveAllReagents then
+		table.insert(filters, L["Have all"]);
+	elseif filterTable.haveKeyReagents then
+		table.insert(filters, L["Have key"]);
+	elseif filterTable.haveAnyReagents then
+		table.insert(filters, L["Have any"]);
+	end

-	if level == 1 then
+	local difficulties = {};
+	if not filterTable.optimal then
+		table.insert(difficulties, "!"..L["Optimal"]);
+	end
+	if not filterTable.medium then
+		table.insert(difficulties, "!"..L["Medium"]);
+	end
+	if not filterTable.easy then
+		table.insert(difficulties, "!"..L["Easy"]);
+	end
+	if not filterTable.trivial then
+		table.insert(difficulties, "!"..L["Trivial"]);
+	end
+	if #difficulties > 0 then
+		table.insert(filters, L["Difficulty"]..": "..Cauldron:JoinStrings(difficulties, ","));
+	end

-		if not IsTradeSkillLinked() and not IsTradeSkillGuild() then
-			-- favorites
-			local favorites = UIDropDownMenu_CreateInfo();
-			favorites.text = L["Favorites"];
-			favorites.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.favorites or false;
-			favorites.isNotRadio = true;
-			favorites.keepShownOnClick = true;
-			-- tooltipTitle = L["Favorites"],
-			-- tooltipText = L["Display only favorite skills"],
-			favorites.func = function()
-				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:info("updating skill list from favorites filter");
-				Cauldron:UpdateSkillList();
-				Cauldron:UpdateStatus();
-			end;
-			-- arg1 = "favorite",
-			-- arg2 = "",
-			UIDropDownMenu_AddButton(favorites, level);
+	if filterTable.favorites then
+		table.insert(filters, L["Favorites"]);
+	end
+	if filterTable.achievements then
+		table.insert(filters, L["Achievements"]);
+	end
+
+	if #filters > 0 then
+		local statusText = Cauldron:JoinStrings(filters, "; ");
+		CauldronStatusText:SetText(L["Filters"]..": "..statusText);
+		CauldronStatusFrame:Show();
+	else
+		CauldronStatusFrame:Hide();
+	end
+end

-			-- achievements
-			local achievements = UIDropDownMenu_CreateInfo();
-			achievements.text = L["Achievements"];
-			achievements.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.achievements or false;
-			achievements.isNotRadio = true;
-			achievements.keepShownOnClick = true;
-			-- tooltipTitle = L["Achievements"],
-			-- tooltipText = L["Display only skills for achievements"],
-			achievements.func = function()
-				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:info("updating skill list from achievements filter");
-				Cauldron:UpdateSkillList();
-				Cauldron:UpdateStatus();
-			end;
-			-- arg1 = "achievement",
-			-- arg2 = "",
-			UIDropDownMenu_AddButton(achievements, level);
-		end
+function Cauldron:UpdateFilterDropDowns()

-	--[==[
-		info.text = CRAFT_IS_MAKEABLE
-		info.func = 	function()
-							TradeSkillFrame.filterTbl.hasMaterials  = not TradeSkillFrame.filterTbl.hasMaterials;
-							TradeSkillOnlyShowMakeable(TradeSkillFrame.filterTbl.hasMaterials);
-							TradeSkillUpdateFilterBar();
-						end
-		info.keepShownOnClick = true;
-		info.checked = 	TradeSkillFrame.filterTbl.hasMaterials
-		info.isNotRadio = true;
-		UIDropDownMenu_AddButton(info, level)
-
-		if ( not IsTradeSkillGuild() ) then
-			info.text = TRADESKILL_FILTER_HAS_SKILL_UP;
-			info.func = 	function()
-								TradeSkillFrame.filterTbl.hasSkillUp  = not TradeSkillFrame.filterTbl.hasSkillUp;
-								TradeSkillOnlyShowSkillUps(TradeSkillFrame.filterTbl.hasSkillUp);
-								TradeSkillUpdateFilterBar();
-							end
-			info.keepShownOnClick = true;
-			info.checked = 	TradeSkillFrame.filterTbl.hasSkillUp;
-			info.isNotRadio = true;
-			UIDropDownMenu_AddButton(info, level);
-		end
-	--]==]
-
-		info.checked = 	nil;
-		info.isNotRadio = nil;
-
-		info.text = TRADESKILL_FILTER_SLOTS
-		info.func =  nil;
-		info.notCheckable = true;
-		info.keepShownOnClick = false;
-		info.hasArrow = true;
-		info.value = 1;
-		UIDropDownMenu_AddButton(info, level)
-
-		info.text = TRADESKILL_FILTER_SUBCLASS
-		info.func =  nil;
-		info.notCheckable = true;
-		info.keepShownOnClick = false;
-		info.hasArrow = true;
-		info.value = 2;
-		UIDropDownMenu_AddButton(info, level)
+	-- TODO

-		-- spacer
-		UIDropDownMenu_AddButton({
-			text = "",
-			notClickable = true,
-			isNotRadio = nil,
-			notCheckable = true,
-		}, level);
+end
+
+function Cauldron:UpdateSkillList()

-		-- skill difficulty
+	if Cauldron.updatingSkillList then
+		return;
+	end

-		local difficultyTitle = UIDropDownMenu_CreateInfo();
-		difficultyTitle.text = L["Difficulty"];
-		difficultyTitle.isTitle = true;
-		difficultyTitle.isNotRadio = nil;
-		difficultyTitle.notCheckable = true;
-		difficultyTitle.tooltipTitle = "";
-		difficultyTitle.tooltipText = "";
-		UIDropDownMenu_AddButton(difficultyTitle, level);
+	local skillName = CURRENT_TRADESKILL;
+	if IsTradeSkillLinked() then
+		skillName = "Linked-"..skillName;
+	end

-		local difficultyOptimal = UIDropDownMenu_CreateInfo();
-		difficultyOptimal.text = L["Optimal"];
---		textR = 1.0,
---		textG = 1.0,
---		textB = 1.0,
-		difficultyOptimal.isNotRadio = true;
-		difficultyOptimal.notCheckable = false;
-		difficultyOptimal.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.optimal;
-		difficultyOptimal.keepShownOnClick = true;
-		difficultyOptimal.tooltipTitle = L["Optimal"];
-		difficultyOptimal.tooltipText = L["Set whether items of this difficulty level should be shown"];
-		difficultyOptimal.func = function(arg1, arg2)
-			Cauldron:FilterDropDown_ToggleDifficulty(arg1);
-			Cauldron:UpdateStatus();
-		end;
-		difficultyOptimal.arg1 = "optimal";
-		difficultyOptimal.arg2 = "";
-		UIDropDownMenu_AddButton(difficultyOptimal, level);
+	local skillList = Cauldron:GetSkillList(self.vars.playername, skillName);
+	if not skillList then
+		return;
+	end

-		local difficultyMedium = UIDropDownMenu_CreateInfo();
-		difficultyMedium.text = L["Medium"];
---		textR = 1.0,
---		textG = 1.0,
---		textB = 1.0,
-		difficultyMedium.isNotRadio = true;
-		difficultyMedium.notCheckable = false;
-		difficultyMedium.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.medium;
-		difficultyMedium.keepShownOnClick = true;
-		difficultyMedium.tooltipTitle = L["Medium"];
-		difficultyMedium.tooltipText = L["Set whether items of this difficulty level should be shown"];
-		difficultyMedium.func = function(arg1, arg2)
-			Cauldron:FilterDropDown_ToggleDifficulty(arg1);
-			Cauldron:UpdateStatus();
-		end;
-		difficultyMedium.arg1 = "medium";
-		difficultyMedium.arg2 = "";
-		UIDropDownMenu_AddButton(difficultyMedium, level);
-
-		local difficultyEasy = UIDropDownMenu_CreateInfo();
-		difficultyEasy.text = L["Easy"];
---		textR = 1.0,
---		textG = 1.0,
---		textB = 1.0,
-		difficultyEasy.isNotRadio = true;
-		difficultyEasy.notCheckable = false;
-		difficultyEasy.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.easy;
-		difficultyEasy.keepShownOnClick = true;
-		difficultyEasy.tooltipTitle = L["Easy"];
-		difficultyEasy.tooltipText = L["Set whether items of this difficulty level should be shown"];
-		difficultyEasy.func = function(arg1, arg2)
-			Cauldron:FilterDropDown_ToggleDifficulty(arg1);
-			Cauldron:UpdateStatus();
-		end;
-		difficultyEasy.arg1 = "easy";
-		difficultyEasy.arg2 = "";
-		UIDropDownMenu_AddButton(difficultyEasy, level);
-
-		local difficultyTrivial = UIDropDownMenu_CreateInfo();
-		difficultyTrivial.text = L["Trivial"];
---		textR = 1.0,
---		textG = 1.0,
---		textB = 1.0,
-		difficultyTrivial.isNotRadio = true;
-		difficultyTrivial.notCheckable = false;
-		difficultyTrivial.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.trivial;
-		difficultyTrivial.keepShownOnClick = true;
-		difficultyTrivial.tooltipTitle = L["Trivial"];
-		difficultyTrivial.tooltipText = L["Set whether items of this difficulty level should be shown"];
-		difficultyTrivial.func = function(arg1, arg2)
-			Cauldron:FilterDropDown_ToggleDifficulty(arg1);
-			Cauldron:UpdateStatus();
-		end;
-		difficultyTrivial.arg1 = "trivial";
-		difficultyTrivial.arg2 = "";
-		UIDropDownMenu_AddButton(difficultyTrivial, level);
+	local height = 0;

-		-- spacer
-		UIDropDownMenu_AddButton({
-			text = "",
-			notClickable = true,
-			isNotRadio = nil,
-			notCheckable = true,
-		}, level);
+	Cauldron.updatingSkillList = true;

-		-- reagents availability
+	-- 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
+			if self.db.realm.userdata[self.vars.playername].options.compactView then
+				-- TODO
+			else
+				-- TODO
+			end
+			skillFrame = CreateFrame("Button",
+									 "CauldronSkillItem"..i,
+									 CauldronSkillListScrollFrameScrollChild,
+									 "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(CAULDRON_SKILLITEM_COLLAPSED_HEIGHT);
+		    -- TODO: set height if expanded
+		--[[
+		    _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
+		--]]

-		local reagentsTitle = UIDropDownMenu_CreateInfo();
-		reagentsTitle.text = L["Reagents"];
-		reagentsTitle.isTitle = true;
-		reagentsTitle.isNotRadio = nil;
-		reagentsTitle.notCheckable = true;
-		reagentsTitle.tooltipTitle = "";
-		reagentsTitle.tooltipText = "";
-		UIDropDownMenu_AddButton(reagentsTitle, level);
-
-		-- 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;
+		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
-
-		local normal = UIDropDownMenu_CreateInfo();
-		normal.text = L["Normal"];
-		normal.checked = Cauldron:ReagentsFilterNormalCheck();
-		normal.tooltipTitle = L["Reagents"];
-		normal.tooltipText = L["Display the normal list of skills"];
-		normal.func = function(arg1, arg2)
-			Cauldron:FilterDropDown_SetReagentFilter(arg1)
-			Cauldron:UpdateStatus();
-		end;
-		normal.arg1 = "normal";
-		normal.arg2 = "";
-		UIDropDownMenu_AddButton(normal, level);

-		if not IsTradeSkillLinked() then
-
-			local haveAllReagents = UIDropDownMenu_CreateInfo();
-			haveAllReagents.text = L["Have all"];
-			haveAllReagents.isNotRadio = nil;
-			haveAllReagents.notCheckable = false;
-			haveAllReagents.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAllReagents;
-			haveAllReagents.tooltipTitle = L["Reagents"];
-			haveAllReagents.tooltipText = L["Set whether skills for which you have all the required reagents are shown in the list"];
-			haveAllReagents.func = function(arg1, arg2)
-				Cauldron:FilterDropDown_SetReagentFilter(arg1);
-				Cauldron:UpdateStatus();
-			end;
-			haveAllReagents.arg1 = "all";
-			haveAllReagents.arg2 = "";
-			UIDropDownMenu_AddButton(haveAllReagents, level);
+		-- populate the frame
+		local frame = nil;

-			local haveKeyReagents = UIDropDownMenu_CreateInfo();
-			haveKeyReagents.text = L["Have key"];
-			haveKeyReagents.isNotRadio = nil;
-			haveKeyReagents.notCheckable = false;
-			haveKeyReagents.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveKeyReagents;
-			haveKeyReagents.tooltipTitle = L["Reagents"];
-			haveKeyReagents.tooltipText = L["Set whether skills for which you have all key reagents (non-vendor available) are shown in the list"];
-			haveKeyReagents.func = function(arg1, arg2)
-				Cauldron:FilterDropDown_SetReagentFilter(arg1);
-				Cauldron:UpdateStatus();
-			end;
-			haveKeyReagents.arg1 = "key";
-			haveKeyReagents.arg2 = "";
-			UIDropDownMenu_AddButton(haveKeyReagents, level);
-
-			local haveAnyReagents = UIDropDownMenu_CreateInfo();
-			haveAnyReagents.text = L["Have any"];
-			haveAnyReagents.isNotRadio = nil;
-			haveAnyReagents.notCheckable = false;
-			haveAnyReagents.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAnyReagents;
-			haveAnyReagents.tooltipTitle = L["Reagents"];
-			haveAnyReagents.tooltipText = L["Set whether skills for which you have any reagents are shown in the list"];
-			haveAnyReagents.func = function(arg1, arg2)
-				Cauldron:FilterDropDown_SetReagentFilter(arg1);
-				Cauldron:UpdateStatus();
-			end;
-			haveAnyReagents.arg1 = "any";
-			haveAnyReagents.arg2 = "";
-			UIDropDownMenu_AddButton(haveAnyReagents, level);
-
+		-- set name and difficulty color
+		frame = _G["CauldronSkillItem"..i.."SkillName"];
+		if frame then
+			local nameText = skillInfo.name;
+			local skillNamePrefix = "";
+			if ( ENABLE_COLORBLIND_MODE == "1" ) then
+				skillNamePrefix = TradeSkillTypePrefix[skillType].." " or "";
+			end
+			frame:SetText(skillNamePrefix..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
 		end

-		-- spacer
-		UIDropDownMenu_AddButton({
-			text = "",
-			notClickable = true,
-			isNotRadio = nil,
-			notCheckable = true,
-		}, level);
-
-		-- reset item
-		local resetFilters = UIDropDownMenu_CreateInfo();
-		resetFilters.text = L["Reset filters"];
-		resetFilters.checked = false;
-		resetFilters.isNotRadio = nil;
-		resetFilters.notCheckable = true;
-		resetFilters.tooltipTitle = L["Reset filters"];
-		resetFilters.tooltipText = L["Reset all filters on the skills list"];
-		resetFilters.func = function(arg1, arg2)
-			Cauldron:FilterDropDown_Reset();
-			Cauldron:UpdateStatus();
-		end;
-		UIDropDownMenu_AddButton(resetFilters, level);
-
-	elseif level == 2 then
-		if UIDROPDOWNMENU_MENU_VALUE == 1 then
-			local slots = { GetTradeSkillSubClassFilteredSlots(0) };
-			local subslots = {};
-			for i,slot in pairs(slots) do
-				info.text = slot;
-				info.func =  function()
-					-- TradeSkillSetFilter(0, i, "", slots[i]);
-				end;
-				info.notCheckable = true;
-				info.hasArrow = false;
-				UIDropDownMenu_AddButton(info, level);
+		-- set category
+		frame = _G["CauldronSkillItem"..i.."SkillCategory"];
+		if frame then
+			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
-		elseif UIDROPDOWNMENU_MENU_VALUE == 2 then
-			local subClasses = { GetTradeSkillSubClasses() };
-			local subslots = {};
-			for i,subClass in pairs(subClasses) do
-				info.text = subClass;
-				info.func =  function()
-					-- TradeSkillSetFilter(i, 0, subClasses[i], "");
+		end
+
+		-- set favorite check button
+		frame = _G["CauldronSkillItem"..i.."FavoriteButton"];
+		if frame then
+			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
-				info.notCheckable = true;
-				subslots  = { GetTradeSkillSubClassFilteredSlots(i) };
-				info.hasArrow = #subslots > 1;
-				info.value = i;
-				UIDropDownMenu_AddButton(info, level);
 			end
+			--]]
 		end
-	elseif level == 3 then
-		local subClasses = { GetTradeSkillSubClasses() };
-		local subslots  = { GetTradeSkillSubClassFilteredSlots(UIDROPDOWNMENU_MENU_VALUE) };
-		for i,slot in pairs(subslots) do
-			info.text = slot;
-			info.func =  function()
-				--[[
-				TradeSkillSetFilter(UIDROPDOWNMENU_MENU_VALUE, i, subClasses[UIDROPDOWNMENU_MENU_VALUE], subslots[i]);
-				--]]
-			end;
-			info.notCheckable = true;
-			info.value = {UIDROPDOWNMENU_MENU_VALUE, i};
-			UIDropDownMenu_AddButton(info, level);
-		end
-	end
-
-end

-function CauldronSortDropDown_OnLoad(self)
-	CauldronSortButton:SetText(L["Sort"]);
-	UIDropDownMenu_Initialize(self, CauldronSortDropDown_Initialize, "MENU");
-	CauldronSortDropDownText:SetJustifyH("CENTER");
-	CauldronSortDropDownButton:Show();
-end
+		-- set the icon
+		frame = _G["CauldronSkillItem"..i.."SkillIcon"];
+		if frame then
+			frame:SetNormalTexture(skillInfo.icon);
+			frame.itemLink = skillInfo.link;
+			frame.skillIndex = skillInfo.index;
+		end

-function CauldronSortDropDown_Initialize(self, level)
+		-- set the craft count
+		frame = _G["CauldronSkillItem"..i.."SkillIconCount"];
+		if frame then
+			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
+		end
+
+		-- set the disclosure button texture
+		frame = _G["CauldronSkillItem"..i.."DiscloseButton"];
+		if frame then
+			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
+				--]]

-	local skillName = CURRENT_TRADESKILL;
-	if IsTradeSkillLinked() then
-		skillName = "Linked-"..skillName;
-	end
-
-	local info = UIDropDownMenu_CreateInfo();
+				-- fill in the reagents
+				-- _G["CauldronSkillItem"..i.."Reagents"]:SetScale(0.86);
+
+				-- get reagents table
+				local reagents = skillInfo.reagents;
+				local reagentCount = #reagents;

-	if level == 1 then
-
-		-- title
-		--[[
-		local sortTitle = UIDropDownMenu_CreateInfo();
-		sortTitle.text = L["Sort"];
-		sortTitle.isTitle = true;
-		sortTitle.isNotRadio = nil;
-		sortTitle.notCheckable = true;
-		sortTitle.tooltipTitle = "";
-		sortTitle.tooltipText = "";
-		UIDropDownMenu_AddButton(sortTitle, level);
-		--]]
-
-		-- default
-		local sortDefault = UIDropDownMenu_CreateInfo();
-		sortDefault.text = L["Default"];
-		sortDefault.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDefault;
-		sortDefault.isNotRadio = nil;
-		sortDefault.keepShownOnClick = false;
-		sortDefault.func = function()
-			Cauldron:FilterDropDown_SetSort("default");
-		end;
-		UIDropDownMenu_AddButton(sortDefault, level);
+				for j=1,8 do
+					local reagentFrame = _G["CauldronSkillItem"..i.."ReagentsItemDetail"..j];

-	--[[
-	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 = "",
-	};
-	--]]
-
-		-- alpha
-		local sortAlpha = UIDropDownMenu_CreateInfo();
-		sortAlpha.text = L["Alphabetically"];
-		sortAlpha.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortAlpha;
-		sortAlpha.isNotRadio = nil;
-		sortAlpha.keepShownOnClick = false;
-		sortAlpha.func = function()
-			Cauldron:FilterDropDown_SetSort("alpha");
-		end;
-		UIDropDownMenu_AddButton(sortAlpha, level);
-
-	--[[
-	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 = "",
-	};
-	--]]
+					if reagentFrame then
+						if j > reagentCount then
+							reagentFrame:Hide();
+						else
+							local reagentInfo = reagents[j];

-		-- difficulty
-		local sortDifficulty = UIDropDownMenu_CreateInfo();
-		sortDifficulty.text = L["By difficulty"];
-		sortDifficulty.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDifficulty;
-		sortDifficulty.isNotRadio = nil;
-		sortDifficulty.keepShownOnClick = false;
-		sortDifficulty.func = function()
-			Cauldron:FilterDropDown_SetSort("difficulty");
-		end;
-		UIDropDownMenu_AddButton(sortDifficulty, level);
+							reagentFrame.skillIndex = skillInfo.index;
+							reagentFrame.reagentIndex = reagentInfo.index;
+							reagentFrame.link = reagentInfo.link;
+
+							local reagentNameFrame = _G["CauldronSkillItem"..i.."ReagentsItemDetail"..j.."Name"];
+							local reagentIconFrame = _G["CauldronSkillItem"..i.."ReagentsItemDetail"..j.."IconTexture"];
+							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);
+							if reagentNameFrame then
+								reagentNameFrame:SetText(reagentInfo.name);
+							end
+
+							local playerReagentCount = GetItemCount(reagentInfo.name);
+
+							if playerReagentCount < reagentInfo.numRequired then
+								-- Gray out items
+								SetItemButtonTextureVertexColor(reagentFrame, 0.5, 0.5, 0.5);
+								if reagentNameFrame then
+									reagentNameFrame:SetTextColor(GRAY_FONT_COLOR.r, GRAY_FONT_COLOR.g, GRAY_FONT_COLOR.b);
+								end
+							else
+								SetItemButtonTextureVertexColor(reagentFrame, 1.0, 1.0, 1.0);
+								if reagentNameFrame then
+									reagentNameFrame:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
+								end
+							end
+							if playerReagentCount >= 100 then
+								playerReagentCount = "*";
+							end
+							if reagentCountFrame then
+								reagentCountFrame:SetText(playerReagentCount.."/"..reagentInfo.numRequired);
+							end
+						end
+					end
+				end
+
+				--[[ TODO: only adjust height for expanded views
+				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
+			--]]
+		end

-	--[[
-	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 = "",
-	};
-	--]]
+		-- craft count
+		frame = _G["CauldronSkillItem"..i.."MiscInfoCount"];
+		if frame then
+			local potentialCount = Cauldron:GetPotentialCraftCount(skillInfo);
+			local text = "";
+			if (potentialCount > 0) and (potentialCount > skillInfo.available) then
+				text = skillInfo.available.."/"..potentialCount;
+			elseif skillInfo.available > 0 then
+				text = skillInfo.available;
+			end
+			frame:SetText(text);
+		end

-		-- item level
-		local sortItemLevel = UIDropDownMenu_CreateInfo();
-		sortItemLevel.text = L["By item level"];
-		sortItemLevel.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortItemLevel;
-		sortItemLevel.isNotRadio = nil;
-		sortItemLevel.keepShownOnClick = false;
-		sortItemLevel.func = function()
-			Cauldron:FilterDropDown_SetSort("itemlevel");
-		end;
-		UIDropDownMenu_AddButton(sortItemLevel, level);
+		-- special skill-ups
+		frame = _G["CauldronSkillItem"..i.."MiscInfoNumSkillUpsIcon"];
+		-- Cauldron:info("skill ups icon frame: "..tostring(frame));
+		if frame then
+			if IsTradeSkillGuild() or (skillInfo.difficulty ~= "optimal") or (not skillInfo.numSkillUps or (skillInfo.numSkillUps < 1)) then
+				frame:Hide();
+				_G["CauldronSkillItem"..i.."MiscInfoNumSkillUps"]:Hide();
+			else
+				frame:Show();
+				_G["CauldronSkillItem"..i.."MiscInfoNumSkillUps"]:Show();
+				_G["CauldronSkillItem"..i.."MiscInfoNumSkillUps"]:SetText(skillInfo.numSkillUps);
+			end
+		end

-	--[[
-	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 = "",
-	};
-	--]]
+		-- achievement indicator
+		frame = _G["CauldronSkillItem"..i.."MiscInfoAchievement"];
+		if frame then
+			local achievements = Cauldron:GetAchievementsForSkill(skillInfo);
+			local text = "";
+			if achievements and #achievements > 0 then
+				text = "A";
+			end
+			frame:SetText(text);
+		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

-		-- required level
-		local sortReqLevel = UIDropDownMenu_CreateInfo();
-		sortReqLevel.text = L["By required level"];
-		sortReqLevel.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortRequiredLevel;
-		sortReqLevel.isNotRadio = nil;
-		sortReqLevel.keepShownOnClick = false;
-		sortReqLevel.func = function()
-			Cauldron:FilterDropDown_SetSort("reqlevel");
-		end;
-		UIDropDownMenu_AddButton(sortReqLevel, level);
+		-- adjust the scroll child size
+		height = height + skillFrame:GetHeight();
+		CauldronSkillListScrollFrameScrollChild:SetHeight(height);

-	--[[
-	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 = "",
-	};
-	--]]
+		-- 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

-		-- favorites
-		-- TODO
+		frame:Hide();
+		frame:SetHeight(0);

-		-- benefit
-		-- TODO
-
+		j = j + 1;
 	end

-end
+	Cauldron.updatingSkillList = false;

---[==[
-function CauldronQueueWindowFrame_UpdateQueue()
 end

-function CauldronQueueWindowFrame_GetTopButton()
-end
+function Cauldron:UpdateButtons()

-function CauldronQueueWindowFrame_OnLoad()
-
-   --[[
-   self:SetBackdropColor(.05,.05,.05,.8);
-                self:SetBackdropBorderColor(.4,.4,.4,1);
-                --]]
-                -- tinsert(UISpecialFrames, self:GetName());
-                -- CauldronQueueWindowFrameTitleText:SetText(Cauldron:LocaleString("Tradeskill Queue").." "..Cauldron.version);
-
-	local scrollFrame = CauldronQueueFrameScrollFrame;
-	scrollFrame.update = CauldronQueueWindowFrame_UpdateQueue;
-	scrollFrame.dynamic = CauldronQueueWindowFrame_GetTopButton;
---	CauldronQueueFrameScrollFrameScrollBarTrack:Hide();
---	CauldronQueueFrameScrollFrameScrollBar.doNotHide = true;
-	HybridScrollFrame_CreateButtons(scrollFrame, "CauldronQueueFrameButtonTemplate");
-end
---]==]
+	if IsTradeSkillLinked() then
+		CauldronQueueAllButton:Disable();
+		CauldronQueueButton:Disable();
+		-- CauldronAmountDecrementButton:Hide();
+		-- CauldronAmountInputBox:Hide();
+		-- CauldronAmountIncrementButton:Hide();
+		-- CauldronCreateAllButton:Hide();
+		-- CauldronCreateButton:Hide();
+		CauldronProcessButton:Disable();
+		-- CauldronClearQueueButton:();
+		return;
+	end

-function Cauldron:Frame_Show()
+		CauldronQueueAllButton:Enable();
+		CauldronQueueButton:Enable();
+		-- CauldronAmountDecrementButton:Show();
+		-- CauldronAmountInputBox:Show();
+		-- CauldronAmountIncrementButton:Show();
+		-- CauldronCreateAllButton:Show();
+		-- CauldronCreateButton:Show();
+		-- CauldronProcessButton:();
+		-- CauldronClearQueueButton:Show();
+
+	local skillInfo = Cauldron:GetSelectedSkill();

-self:debug("frame show: "..tostring(CauldronQueueWindowFrame));
+--[[
+	if skillInfo then
+		CauldronCreateButton:SetText(skillInfo.verb or CREATE);
+		if skillInfo.verb then
+			CauldronCreateAllButton:Hide();
+		end

-	if Cauldron.vars.enabled and not(IsShiftKeyDown() and IsControlKeyDown()) then
--- 		CloseDropDownMenus();
+		CauldronQueueAllButton:Enable();
+		CauldronQueueButton:Enable();

---[==[
-		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"]);
---]==]
-
-		-- show main UI
-		ShowUIPanel(CauldronFrame);
-		SetPortraitToTexture(CauldronFramePortrait, GetTradeSkillTexture());
-		CauldronInputBox:SetNumber(1);
-		CauldronFrameTitleText:SetText(L["Cauldron"].." "..Cauldron.version);
+		CauldronCreateButton:Show();

-		-- show queue UI
-		if Cauldron.vars.showQueue then
-			ShowUIPanel(CauldronQueueWindowFrame);
-			SetPortraitToTexture(CauldronQueueWindowFramePortrait, GetTradeSkillTexture());
-			CauldronQueueWindowFrameTitleText:SetText(L["Queue"]);
-		end
-
-		-- check if the filter structure is out of date
-		--[[
-		if not Cauldron.db.global.version or (tonumber(Cauldron.db.global.version) < tonumber(Cauldron.vars.filterVersion)) then
-			Cauldron.db.global.version = tonumber(Cauldron.vars.filterVersion);
-			Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter = {
-				-- sorting
-				sortDefault = true,
-				sortAlpha = false,
-				sortDifficulty = false,
-				sortBenefit = false,
-
-				-- difficulty
-				optimal = true,
-				medium = true,
-				easy = true,
-				trivial = true,
-
-				-- favorites
-				favorites = false,
-				favoritesAtTop = false,
-
-				-- availability
-				haveAllReagents = false,
-				haveKeyReagents = false,
-				haveAnyReagents = false,
-			};
+		if skillInfo.available ~= 0 then
+			CauldronCreateAllButton:Enable();
+			CauldronCreateButton:Enable();
+		else
+			CauldronCreateAllButton:Disable();
+			CauldronCreateButton:Disable();
 		end
-		--]]
-
-	 	self:RegisterMessage("Cauldron_Update", "OnCauldronUpdate");
+	else
+		CauldronQueueAllButton:Disable();
+		CauldronQueueButton:Disable();
+		CauldronCreateAllButton:Disable();
+		CauldronCreateButton:Disable();
+	end
+--]]

-		self:Frame_Update();
+	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
+
+	if CauldronQueueWindowFrame:IsShown() then
+		CauldronShowQueueButton:Hide();
+	else
+		CauldronShowQueueButton:Show();
 	end

 end

-function Cauldron:Frame_Hide()
+function Cauldron:OnCauldronUpdate()

- 	self:UnregisterEvent("Cauldron_Update");
- 	HideUIPanel(CauldronQueueWindowFrame);
- 	HideUIPanel(CauldronFrame);
-
- 	--[[
- 	if TradeSkillFrame then
- 		TradeSkillFrame:SetAlpha(1.0);
- 		TradeSkillFrame:SetFrameStrata(Cauldron.vars.origFrameStrata or "MEDIUM");
- 		TradeSkillFrame:SetFrameLevel(Cauldron.vars.origFrameLevel or 5);
+	--[[
+--	self:Search();
+ 	local selectionIndex
+ 	if self.vars.selectionIndex == 0 then
+ 		selectionIndex = self:GetFirstTradeSkill();
+ 	else
+ 		selectionIndex = self.vars.selectionIndex;
  	end
  	--]]

 end

-function Cauldron:Frame_Toggle()
+function CauldronFrame_OnLoad()

- 	if CauldronQueueWindowFrame:IsVisible() then
- 		Cauldron:Frame_Hide();
- 	else
- 		Cauldron:Frame_Show();
- 	end
+--	ButtonFrameTemplate_HideButtonBar(CauldronFrame);
+	ButtonFrameTemplate_HideAttic(CauldronFrame);
+--	CauldronFrameInsetBg:Hide();

 end

-function CauldronFrame_Update()
-	Cauldron:Frame_Update();
+function CauldronFrame_OnEvent()
 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();
-
-	-- update filter information
-	self:UpdateStatus();
---[==[
-	self:UpdateFilterDropDowns();
---]==]
-
-	-- display list of matching skills
---						Cauldron:info("updating skill list from frame update");
-	if CAULDRON_TRADESKILL_NAME ~= CURRENT_TRADESKILL then
-		CAULDRON_TRADESKILL_NAME = CURRENT_TRADESKILL;
-		self:UpdateSkillList();
-	end
-
-	-- display queue
-	self:UpdateQueue();
-
-	-- update buttons
-	self:UpdateButtons();
-
+function CauldronFrame_OnShow()
 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"]..")");
---]==]
-	CauldronSkillNameText:SetText(skillName);
-		local prof_title = "";
-		for i=1,#PROFESSION_RANKS do
-		    local value,title = PROFESSION_RANKS[i][1], PROFESSION_RANKS[i][2];
-			if maxRank < value then break end
-			prof_title = title;
-		end
-	CauldronRankInfoText:SetText(prof_title..", "..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);
-	CauldronRankFrameText:SetText(rank.."/"..maxRank);
-
+function CauldronFrame_OnHide()
+	CloseTradeSkill();
 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
+function CauldronSearch_OnTextChanged()
+	Cauldron:TradeSkillFilter_OnTextChanged(CauldronSearchBox);
+end

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

+function CauldronFrame_Show()
+	Cauldron:Frame_Show();
 end

-function Cauldron:UpdateStatus()
+function CauldronFilterDropDown_OnLoad(self)
+	UIDropDownMenu_Initialize(self, CauldronFilterDropDown_Initialize, "MENU");
+	CauldronFilterDropDownText:SetJustifyH("CENTER");
+	CauldronFilterDropDownButton:Show();
+end

+function CauldronFilterDropDown_Initialize(self, level)
+
 	local skillName = CURRENT_TRADESKILL;
 	if IsTradeSkillLinked() then
 		skillName = "Linked-"..skillName;
 	end
+
+	local info = UIDropDownMenu_CreateInfo();

-	local filters = {};
-	local filterTable = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter;
-	--[[
-							["sortAlpha"] = false, -- should the list be sorted alphabetically (mutually-exclusive to "sortDifficulty" and "sortBenefit")
-							["sortDifficulty"] = true, -- should the list be sorted by difficulty  (mutually-exclusive to "sortAlpha" and "sortBenefit")
-							["sortBenefit"] = false, -- should the list be sorted by potentcy of the benefit the crafted item/enchantment grants  (mutually-exclusive to "sortDifficulty" and "sortAlpha") UNUSED
-							["haveAllReagents"] = false, -- should only items with all required reagents be shown in the list?
-							["haveKeyReagents"] = false, -- should only items with all key reagents be shown in the list?
-							["haveAnyReagents"] = false, -- should only items with any reagents be shown in the list?
-							["optimal"] = true, -- should optimal skills be shown?
-							["medium"] = true, -- should medium skills be shown?
-							["easy"] = true, -- should easy skills be shown?
-							["trivial"] = false, -- should trivial skills be shown?
-							["favorites"] = false, -- should only favorite skills be shown?
-	--]]
-	if filterTable.haveAllReagents then
-		table.insert(filters, L["Have all"]);
-	elseif filterTable.haveKeyReagents then
-		table.insert(filters, L["Have key"]);
-	elseif filterTable.haveAnyReagents then
-		table.insert(filters, L["Have any"]);
-	end
-
-	local difficulties = {};
-	if not filterTable.optimal then
-		table.insert(difficulties, "!"..L["Optimal"]);
-	end
-	if not filterTable.medium then
-		table.insert(difficulties, "!"..L["Medium"]);
-	end
-	if not filterTable.easy then
-		table.insert(difficulties, "!"..L["Easy"]);
-	end
-	if not filterTable.trivial then
-		table.insert(difficulties, "!"..L["Trivial"]);
-	end
-	if #difficulties > 0 then
-		table.insert(filters, L["Difficulty"]..": "..Cauldron:JoinStrings(difficulties, ","));
-	end
-
-	if filterTable.favorites then
-		table.insert(filters, L["Favorites"]);
-	end
-	if filterTable.achievements then
-		table.insert(filters, L["Achievements"]);
-	end
+	if level == 1 then

-	if #filters > 0 then
-		local statusText = Cauldron:JoinStrings(filters, "; ");
-		CauldronStatusText:SetText(L["Filters"]..": "..statusText);
-		CauldronStatusFrame:Show();
-	else
-		CauldronStatusFrame:Hide();
-	end
-end
-
-function Cauldron:UpdateFilterDropDowns()
+		if not IsTradeSkillLinked() and not IsTradeSkillGuild() then
+			-- favorites
+			local favorites = UIDropDownMenu_CreateInfo();
+			favorites.text = L["Favorites"];
+			favorites.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.favorites or false;
+			favorites.isNotRadio = true;
+			favorites.keepShownOnClick = true;
+			-- tooltipTitle = L["Favorites"],
+			-- tooltipText = L["Display only favorite skills"],
+			favorites.func = function()
+				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();
+				Cauldron:UpdateStatus();
+			end;
+			-- arg1 = "favorite",
+			-- arg2 = "",
+			UIDropDownMenu_AddButton(favorites, level);

-	-- TODO
+			-- achievements
+			local achievements = UIDropDownMenu_CreateInfo();
+			achievements.text = L["Achievements"];
+			achievements.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.achievements or false;
+			achievements.isNotRadio = true;
+			achievements.keepShownOnClick = true;
+			-- tooltipTitle = L["Achievements"],
+			-- tooltipText = L["Display only skills for achievements"],
+			achievements.func = function()
+				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();
+				Cauldron:UpdateStatus();
+			end;
+			-- arg1 = "achievement",
+			-- arg2 = "",
+			UIDropDownMenu_AddButton(achievements, level);
+		end

-end
+	--[==[
+		info.text = CRAFT_IS_MAKEABLE
+		info.func = 	function()
+							TradeSkillFrame.filterTbl.hasMaterials  = not TradeSkillFrame.filterTbl.hasMaterials;
+							TradeSkillOnlyShowMakeable(TradeSkillFrame.filterTbl.hasMaterials);
+							TradeSkillUpdateFilterBar();
+						end
+		info.keepShownOnClick = true;
+		info.checked = 	TradeSkillFrame.filterTbl.hasMaterials
+		info.isNotRadio = true;
+		UIDropDownMenu_AddButton(info, level)
+
+		if ( not IsTradeSkillGuild() ) then
+			info.text = TRADESKILL_FILTER_HAS_SKILL_UP;
+			info.func = 	function()
+								TradeSkillFrame.filterTbl.hasSkillUp  = not TradeSkillFrame.filterTbl.hasSkillUp;
+								TradeSkillOnlyShowSkillUps(TradeSkillFrame.filterTbl.hasSkillUp);
+								TradeSkillUpdateFilterBar();
+							end
+			info.keepShownOnClick = true;
+			info.checked = 	TradeSkillFrame.filterTbl.hasSkillUp;
+			info.isNotRadio = true;
+			UIDropDownMenu_AddButton(info, level);
+		end
+	--]==]
+
+		info.checked = 	nil;
+		info.isNotRadio = nil;
+
+		info.text = TRADESKILL_FILTER_SLOTS
+		info.func =  nil;
+		info.notCheckable = true;
+		info.keepShownOnClick = false;
+		info.hasArrow = true;
+		info.value = 1;
+		UIDropDownMenu_AddButton(info, level)
+
+		info.text = TRADESKILL_FILTER_SUBCLASS
+		info.func =  nil;
+		info.notCheckable = true;
+		info.keepShownOnClick = false;
+		info.hasArrow = true;
+		info.value = 2;
+		UIDropDownMenu_AddButton(info, level)

-function Cauldron:UpdateSkillList()
-
-	if Cauldron.updatingSkillList then
-		Cauldron:info("already updating skill list");
-		return;
-	end
-
-	local skillName = CURRENT_TRADESKILL;
-	if IsTradeSkillLinked() then
-		skillName = "Linked-"..skillName;
-	end
+		-- spacer
+		UIDropDownMenu_AddButton({
+			text = "",
+			notClickable = true,
+			isNotRadio = nil,
+			notCheckable = true,
+		}, level);

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

-	local height = 0;
+		local difficultyTitle = UIDropDownMenu_CreateInfo();
+		difficultyTitle.text = L["Difficulty"];
+		difficultyTitle.isTitle = true;
+		difficultyTitle.isNotRadio = nil;
+		difficultyTitle.notCheckable = true;
+		difficultyTitle.tooltipTitle = "";
+		difficultyTitle.tooltipText = "";
+		UIDropDownMenu_AddButton(difficultyTitle, level);

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

-	-- iterate over the list of skills
---	Cauldron:info("iterate over skill list of "..#skillList.." items");
-	for i, skillInfo in ipairs(skillList) do
-
-		local skillFrame = _G["CauldronSkillItem"..i];
---		Cauldron:info("asked for skill item frame "..i.."; frame: "..tostring(skillFrame));
-
-		-- check if we have a frame for this position
-		if not skillFrame then
-			-- create a new frame for the skill information
-			if self.db.realm.userdata[self.vars.playername].options.compactView then
-				-- TODO
-			else
-				-- TODO
-			end
-			skillFrame = CreateFrame("Button",
-									 "CauldronSkillItem"..i,
-									 CauldronSkillListScrollFrameScrollChild,
-									 "CauldronSkillItemFrameTemplate");
---			Cauldron:info("created new skill item frame for "..i.."; frame: "..tostring(skillFrame));
-		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(CAULDRON_SKILLITEM_COLLAPSED_HEIGHT);
-		    -- TODO: set height if expanded
-		--[[
-		    _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;
+		local difficultyMedium = UIDropDownMenu_CreateInfo();
+		difficultyMedium.text = L["Medium"];
+--		textR = 1.0,
+--		textG = 1.0,
+--		textB = 1.0,
+		difficultyMedium.isNotRadio = true;
+		difficultyMedium.notCheckable = false;
+		difficultyMedium.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.medium;
+		difficultyMedium.keepShownOnClick = true;
+		difficultyMedium.tooltipTitle = L["Medium"];
+		difficultyMedium.tooltipText = L["Set whether items of this difficulty level should be shown"];
+		difficultyMedium.func = function(arg1, arg2)
+			Cauldron:FilterDropDown_ToggleDifficulty(arg1);
+			Cauldron:UpdateStatus();
+		end;
+		difficultyMedium.arg1 = "medium";
+		difficultyMedium.arg2 = "";
+		UIDropDownMenu_AddButton(difficultyMedium, level);

-		-- set name and difficulty color
-		frame = _G["CauldronSkillItem"..i.."SkillName"];
-		if frame then
-			local nameText = skillInfo.name;
-			local skillNamePrefix = "";
-			if ( ENABLE_COLORBLIND_MODE == "1" ) then
-				skillNamePrefix = TradeSkillTypePrefix[skillType].." " or "";
-			end
-			frame:SetText(skillNamePrefix..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
-		end
+		local difficultyEasy = UIDropDownMenu_CreateInfo();
+		difficultyEasy.text = L["Easy"];
+--		textR = 1.0,
+--		textG = 1.0,
+--		textB = 1.0,
+		difficultyEasy.isNotRadio = true;
+		difficultyEasy.notCheckable = false;
+		difficultyEasy.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.easy;
+		difficultyEasy.keepShownOnClick = true;
+		difficultyEasy.tooltipTitle = L["Easy"];
+		difficultyEasy.tooltipText = L["Set whether items of this difficulty level should be shown"];
+		difficultyEasy.func = function(arg1, arg2)
+			Cauldron:FilterDropDown_ToggleDifficulty(arg1);
+			Cauldron:UpdateStatus();
+		end;
+		difficultyEasy.arg1 = "easy";
+		difficultyEasy.arg2 = "";
+		UIDropDownMenu_AddButton(difficultyEasy, level);

-		-- set category
-		frame = _G["CauldronSkillItem"..i.."SkillCategory"];
-		if frame then
-			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
-		end
+		local difficultyTrivial = UIDropDownMenu_CreateInfo();
+		difficultyTrivial.text = L["Trivial"];
+--		textR = 1.0,
+--		textG = 1.0,
+--		textB = 1.0,
+		difficultyTrivial.isNotRadio = true;
+		difficultyTrivial.notCheckable = false;
+		difficultyTrivial.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.trivial;
+		difficultyTrivial.keepShownOnClick = true;
+		difficultyTrivial.tooltipTitle = L["Trivial"];
+		difficultyTrivial.tooltipText = L["Set whether items of this difficulty level should be shown"];
+		difficultyTrivial.func = function(arg1, arg2)
+			Cauldron:FilterDropDown_ToggleDifficulty(arg1);
+			Cauldron:UpdateStatus();
+		end;
+		difficultyTrivial.arg1 = "trivial";
+		difficultyTrivial.arg2 = "";
+		UIDropDownMenu_AddButton(difficultyTrivial, level);
+
+		-- spacer
+		UIDropDownMenu_AddButton({
+			text = "",
+			notClickable = true,
+			isNotRadio = nil,
+			notCheckable = true,
+		}, level);
+
+		-- reagents availability

-		-- set favorite check button
-		frame = _G["CauldronSkillItem"..i.."FavoriteButton"];
-		if frame then
-			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
-			--]]
-		end
-
-		-- set the icon
-		frame = _G["CauldronSkillItem"..i.."SkillIcon"];
-		if frame then
-			frame:SetNormalTexture(skillInfo.icon);
-			frame.itemLink = skillInfo.link;
-			frame.skillIndex = skillInfo.index;
-		end
-
-		-- set the craft count
-		frame = _G["CauldronSkillItem"..i.."SkillIconCount"];
-		if frame then
-			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
+		local reagentsTitle = UIDropDownMenu_CreateInfo();
+		reagentsTitle.text = L["Reagents"];
+		reagentsTitle.isTitle = true;
+		reagentsTitle.isNotRadio = nil;
+		reagentsTitle.notCheckable = true;
+		reagentsTitle.tooltipTitle = "";
+		reagentsTitle.tooltipText = "";
+		UIDropDownMenu_AddButton(reagentsTitle, level);
+
+		-- 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
-
-		-- set the disclosure button texture
-		frame = _G["CauldronSkillItem"..i.."DiscloseButton"];
-		if frame then
-			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;
+		local normal = UIDropDownMenu_CreateInfo();
+		normal.text = L["Normal"];
+		normal.checked = Cauldron:ReagentsFilterNormalCheck();
+		normal.tooltipTitle = L["Reagents"];
+		normal.tooltipText = L["Display the normal list of skills"];
+		normal.func = function(arg1, arg2)
+			Cauldron:FilterDropDown_SetReagentFilter(arg1)
+			Cauldron:UpdateStatus();
+		end;
+		normal.arg1 = "normal";
+		normal.arg2 = "";
+		UIDropDownMenu_AddButton(normal, level);
+
+		if not IsTradeSkillLinked() then

-				for j=1,8 do
-					local reagentFrame = _G["CauldronSkillItem"..i.."ReagentsItemDetail"..j];
-
-					if reagentFrame then
-						if j > reagentCount then
-							reagentFrame:Hide();
-						else
-							local reagentInfo = reagents[j];
+			local haveAllReagents = UIDropDownMenu_CreateInfo();
+			haveAllReagents.text = L["Have all"];
+			haveAllReagents.isNotRadio = nil;
+			haveAllReagents.notCheckable = false;
+			haveAllReagents.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAllReagents;
+			haveAllReagents.tooltipTitle = L["Reagents"];
+			haveAllReagents.tooltipText = L["Set whether skills for which you have all the required reagents are shown in the list"];
+			haveAllReagents.func = function(arg1, arg2)
+				Cauldron:FilterDropDown_SetReagentFilter(arg1);
+				Cauldron:UpdateStatus();
+			end;
+			haveAllReagents.arg1 = "all";
+			haveAllReagents.arg2 = "";
+			UIDropDownMenu_AddButton(haveAllReagents, level);

-							reagentFrame.skillIndex = skillInfo.index;
-							reagentFrame.reagentIndex = reagentInfo.index;
-							reagentFrame.link = reagentInfo.link;
-
-							local reagentNameFrame = _G["CauldronSkillItem"..i.."ReagentsItemDetail"..j.."Name"];
-							local reagentIconFrame = _G["CauldronSkillItem"..i.."ReagentsItemDetail"..j.."IconTexture"];
-							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
+			local haveKeyReagents = UIDropDownMenu_CreateInfo();
+			haveKeyReagents.text = L["Have key"];
+			haveKeyReagents.isNotRadio = nil;
+			haveKeyReagents.notCheckable = false;
+			haveKeyReagents.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveKeyReagents;
+			haveKeyReagents.tooltipTitle = L["Reagents"];
+			haveKeyReagents.tooltipText = L["Set whether skills for which you have all key reagents (non-vendor available) are shown in the list"];
+			haveKeyReagents.func = function(arg1, arg2)
+				Cauldron:FilterDropDown_SetReagentFilter(arg1);
+				Cauldron:UpdateStatus();
+			end;
+			haveKeyReagents.arg1 = "key";
+			haveKeyReagents.arg2 = "";
+			UIDropDownMenu_AddButton(haveKeyReagents, level);
+
+			local haveAnyReagents = UIDropDownMenu_CreateInfo();
+			haveAnyReagents.text = L["Have any"];
+			haveAnyReagents.isNotRadio = nil;
+			haveAnyReagents.notCheckable = false;
+			haveAnyReagents.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAnyReagents;
+			haveAnyReagents.tooltipTitle = L["Reagents"];
+			haveAnyReagents.tooltipText = L["Set whether skills for which you have any reagents are shown in the list"];
+			haveAnyReagents.func = function(arg1, arg2)
+				Cauldron:FilterDropDown_SetReagentFilter(arg1);
+				Cauldron:UpdateStatus();
+			end;
+			haveAnyReagents.arg1 = "any";
+			haveAnyReagents.arg2 = "";
+			UIDropDownMenu_AddButton(haveAnyReagents, level);
+
+		end

-							reagentFrame:Show();
-							SetItemButtonTexture(reagentFrame, reagentInfo.icon);
-							if reagentNameFrame then
-								reagentNameFrame:SetText(reagentInfo.name);
-							end
-
-							local playerReagentCount = GetItemCount(reagentInfo.name);
-
-							if playerReagentCount < reagentInfo.numRequired then
-								-- Gray out items
-								SetItemButtonTextureVertexColor(reagentFrame, 0.5, 0.5, 0.5);
-								if reagentNameFrame then
-									reagentNameFrame:SetTextColor(GRAY_FONT_COLOR.r, GRAY_FONT_COLOR.g, GRAY_FONT_COLOR.b);
-								end
-							else
-								SetItemButtonTextureVertexColor(reagentFrame, 1.0, 1.0, 1.0);
-								if reagentNameFrame then
-									reagentNameFrame:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
-								end
-							end
-							if playerReagentCount >= 100 then
-								playerReagentCount = "*";
-							end
-							if reagentCountFrame then
-								reagentCountFrame:SetText(playerReagentCount.."/"..reagentInfo.numRequired);
-							end
-						end
-					end
-				end
+		-- spacer
+		UIDropDownMenu_AddButton({
+			text = "",
+			notClickable = true,
+			isNotRadio = nil,
+			notCheckable = true,
+		}, level);

-				--[[ TODO: only adjust height for expanded views
-				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();
+		-- reset item
+		local resetFilters = UIDropDownMenu_CreateInfo();
+		resetFilters.text = L["Reset filters"];
+		resetFilters.checked = false;
+		resetFilters.isNotRadio = nil;
+		resetFilters.notCheckable = true;
+		resetFilters.tooltipTitle = L["Reset filters"];
+		resetFilters.tooltipText = L["Reset all filters on the skills list"];
+		resetFilters.func = function(arg1, arg2)
+			Cauldron:FilterDropDown_Reset();
+			Cauldron:UpdateStatus();
+		end;
+		UIDropDownMenu_AddButton(resetFilters, level);

-				frame:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-Up");
-				_G["CauldronSkillItem"..i]:SetHeight(_G["CauldronSkillItem"..i.."SkillIcon"]:GetHeight());
+	elseif level == 2 then
+		if UIDROPDOWNMENU_MENU_VALUE == 1 then
+			local slots = { GetTradeSkillSubClassFilteredSlots(0) };
+			local subslots = {};
+			for i,slot in pairs(slots) do
+				local slotInfo = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.slots[slot];
+				if not slotInfo then
+					slotInfo = {
+						checked = true,
+					};
+				end
+
+				info.text = slot;
+				info.func =  function()
+					Cauldron:FilterDropDown_SetSlot(slots[i]);
+					-- TradeSkillSetFilter(0, i, "", slots[i]);
+					Cauldron:UpdateSkillList();
+				end;
+				info.notCheckable = false;
+				info.checked = slotInfo.checked;
+				info.hasArrow = false;
+				info.isNotRadio = true;
+				info.keepShownOnClick = true;
+				UIDropDownMenu_AddButton(info, level);
 			end
-			--]]
-		end
+		elseif UIDROPDOWNMENU_MENU_VALUE == 2 then
+			-- "all" sub-class
+			info.text = L["All"];
+			info.func = function()
+				Cauldron:FilterDropDown_SetSubclass("all", "");
+				Cauldron:UpdateSkillList();
+			end;
+			info.notCheckable = true;
+			info.hasArrow = false;
+			info.isNotRadio = true;
+			info.keepShownOnClick = false;
+			info.value = -1;
+			UIDropDownMenu_AddButton(info, level);
+
+			-- "none" sub-class
+			info.text = L["None"];
+			info.func = function()
+				Cauldron:FilterDropDown_SetSubclass("none", "");
+				Cauldron:UpdateSkillList();
+			end;
+			info.notCheckable = true;
+			info.hasArrow = false;
+			info.isNotRadio = true;
+			info.keepShownOnClick = false;
+			info.value = -2;
+			UIDropDownMenu_AddButton(info, level);
+
+			-- iterate over sub-classes
+			local subClasses = { GetTradeSkillSubClasses() };
+			local subslots = {};
+
+			for i,subClass in pairs(subClasses) do
+				info.text = subClass;
+				info.func =  function()
+					Cauldron:FilterDropDown_SetSubclass(subClasses[i], "");
+					-- TradeSkillSetFilter(i, 0, subClasses[i], "");
+					Cauldron:UpdateSkillList();
+				end
+				subslots  = { GetTradeSkillSubClassFilteredSlots(i) };
+				if #subslots > 1 then
+					info.notCheckable = true;
+					info.hasArrow = true;
+				else
+					local catInfo = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.categories[subClass];
+					if not catInfo then
+						catInfo = {
+							shown = true,
+							expanded = true,
+						};
+					end

-		-- craft count
-		frame = _G["CauldronSkillItem"..i.."MiscInfoCount"];
-		if frame then
-			local potentialCount = Cauldron:GetPotentialCraftCount(skillInfo);
-			local text = "";
-			if (potentialCount > 0) and (potentialCount > skillInfo.available) then
-				text = skillInfo.available.."/"..potentialCount;
-			elseif skillInfo.available > 0 then
-				text = skillInfo.available;
-			end
-			frame:SetText(text);
-		end
-
-		-- special skill-ups
-		frame = _G["CauldronSkillItem"..i.."MiscInfoNumSkillUpsIcon"];
-		Cauldron:info("skill ups icon frame: "..tostring(frame));
-		if frame then
-			if IsTradeSkillGuild() or (skillInfo.difficulty ~= "optimal") or (not skillInfo.numSkillUps or (skillInfo.numSkillUps < 1)) then
-				frame:Hide();
-				_G["CauldronSkillItem"..i.."MiscInfoNumSkillUps"]:Hide();
-			else
-				frame:Show();
-				_G["CauldronSkillItem"..i.."MiscInfoNumSkillUps"]:Show();
-				_G["CauldronSkillItem"..i.."MiscInfoNumSkillUps"]:SetText(skillInfo.numSkillUps);
+					info.notCheckable = false;
+					info.checked = catInfo.shown;
+					info.hasArrow = false;
+					info.isNotRadio = true;
+					info.keepShownOnClick = true;
+				end
+--				info.hasArrow = #subslots > 1;
+				info.value = i;
+				UIDropDownMenu_AddButton(info, level);
 			end
 		end
-
-		-- achievement indicator
-		frame = _G["CauldronSkillItem"..i.."MiscInfoAchievement"];
-		if frame then
-			local achievements = Cauldron:GetAchievementsForSkill(skillInfo);
-			local text = "";
-			if achievements and #achievements > 0 then
-				text = "A";
+	elseif level == 3 then
+		local subClasses = { GetTradeSkillSubClasses() };
+		local subslots  = { GetTradeSkillSubClassFilteredSlots(UIDROPDOWNMENU_MENU_VALUE) };
+		for i,slot in pairs(subslots) do
+			info.text = slot;
+			info.func =  function()
+				Cauldron:FilterDropDown_SetSubclass(subClasses[UIDROPDOWNMENU_MENU_VALUE], subslots[i]);
+				--[[
+				TradeSkillSetFilter(UIDROPDOWNMENU_MENU_VALUE, i, subClasses[UIDROPDOWNMENU_MENU_VALUE], subslots[i]);
+				--]]
+				Cauldron:UpdateSkillList();
+			end;
+			local catInfo = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.categories[subClasses[UIDROPDOWNMENU_MENU_VALUE]..";"..subslots[i]];
+			if not catInfo then
+				catInfo = {
+					shown = true,
+					expanded = true,
+				};
 			end
-			frame:SetText(text);
-		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();
-		CauldronSkillListScrollFrameScrollChild:SetHeight(height);
-
-		-- show the frame
-		skillFrame:Show();
-	end
-
-	-- hide any remaining frames
-	local j = #skillList + 1;
---	Cauldron:info("looking to hide remaining skill item frames: starting at "..j);
-	while true do
-		local frame = _G["CauldronSkillItem"..j];
---		Cauldron:info("hiding skill item frame "..j.."; frame: "..tostring(frame));
-		if not frame then
---			Cauldron:info("no frames left");
-			break;
+
+			info.notCheckable = false;
+			info.checked = catInfo.shown;
+			info.isNotRadio = true;
+			info.keepShownOnClick = true;
+			info.value = {UIDROPDOWNMENU_MENU_VALUE, i};
+			UIDropDownMenu_AddButton(info, level);
 		end
-
-		frame:Hide();
-		frame:SetHeight(0);
-
-		j = j + 1;
 	end

-	Cauldron.updatingSkillList = false;
-
 end

-function Cauldron:UpdateButtons()
+function CauldronSortDropDown_OnLoad(self)
+	CauldronSortButton:SetText(L["Sort"]);
+	UIDropDownMenu_Initialize(self, CauldronSortDropDown_Initialize, "MENU");
+	CauldronSortDropDownText:SetJustifyH("CENTER");
+	CauldronSortDropDownButton:Show();
+end

+function CauldronSortDropDown_Initialize(self, level)
+
+	local skillName = CURRENT_TRADESKILL;
 	if IsTradeSkillLinked() then
-		CauldronQueueAllButton:Disable();
-		CauldronQueueButton:Disable();
-		-- CauldronAmountDecrementButton:Hide();
-		-- CauldronAmountInputBox:Hide();
-		-- CauldronAmountIncrementButton:Hide();
-		-- CauldronCreateAllButton:Hide();
-		-- CauldronCreateButton:Hide();
-		CauldronProcessButton:Disable();
-		-- CauldronClearQueueButton:();
-		return;
+		skillName = "Linked-"..skillName;
 	end

-		CauldronQueueAllButton:Enable();
-		CauldronQueueButton:Enable();
-		-- CauldronAmountDecrementButton:Show();
-		-- CauldronAmountInputBox:Show();
-		-- CauldronAmountIncrementButton:Show();
-		-- CauldronCreateAllButton:Show();
-		-- CauldronCreateButton:Show();
-		-- CauldronProcessButton:();
-		-- CauldronClearQueueButton:Show();
+	local info = UIDropDownMenu_CreateInfo();

-	local skillInfo = Cauldron:GetSelectedSkill();
-
---[[
-	if skillInfo then
-		CauldronCreateButton:SetText(skillInfo.verb or CREATE);
-		if skillInfo.verb then
-			CauldronCreateAllButton:Hide();
-		end
+	if level == 1 then

-		CauldronQueueAllButton:Enable();
-		CauldronQueueButton:Enable();
+		-- title
+		--[[
+		local sortTitle = UIDropDownMenu_CreateInfo();
+		sortTitle.text = L["Sort"];
+		sortTitle.isTitle = true;
+		sortTitle.isNotRadio = nil;
+		sortTitle.notCheckable = true;
+		sortTitle.tooltipTitle = "";
+		sortTitle.tooltipText = "";
+		UIDropDownMenu_AddButton(sortTitle, level);
+		--]]

-		CauldronCreateButton:Show();
+		-- default
+		local sortDefault = UIDropDownMenu_CreateInfo();
+		sortDefault.text = L["Default"];
+		sortDefault.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDefault;
+		sortDefault.isNotRadio = nil;
+		sortDefault.keepShownOnClick = false;
+		sortDefault.func = function()
+			Cauldron:FilterDropDown_SetSort("default");
+		end;
+		UIDropDownMenu_AddButton(sortDefault, level);

-		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
---]]
+	--[[
+	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 = "",
+	};
+	--]]
+
+		-- alpha
+		local sortAlpha = UIDropDownMenu_CreateInfo();
+		sortAlpha.text = L["Alphabetically"];
+		sortAlpha.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortAlpha;
+		sortAlpha.isNotRadio = nil;
+		sortAlpha.keepShownOnClick = false;
+		sortAlpha.func = function()
+			Cauldron:FilterDropDown_SetSort("alpha");
+		end;
+		UIDropDownMenu_AddButton(sortAlpha, level);

-	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
-
-	if CauldronQueueWindowFrame:IsShown() then
-		CauldronShowQueueButton:Hide();
-	else
-		CauldronShowQueueButton:Show();
-	end
+	--[[
+	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 = "",
+	};
+	--]]
+
+		-- difficulty
+		local sortDifficulty = UIDropDownMenu_CreateInfo();
+		sortDifficulty.text = L["By difficulty"];
+		sortDifficulty.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortDifficulty;
+		sortDifficulty.isNotRadio = nil;
+		sortDifficulty.keepShownOnClick = false;
+		sortDifficulty.func = function()
+			Cauldron:FilterDropDown_SetSort("difficulty");
+		end;
+		UIDropDownMenu_AddButton(sortDifficulty, level);

-end
+	--[[
+	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 = "",
+	};
+	--]]
+
+		-- item level
+		local sortItemLevel = UIDropDownMenu_CreateInfo();
+		sortItemLevel.text = L["By item level"];
+		sortItemLevel.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortItemLevel;
+		sortItemLevel.isNotRadio = nil;
+		sortItemLevel.keepShownOnClick = false;
+		sortItemLevel.func = function()
+			Cauldron:FilterDropDown_SetSort("itemlevel");
+		end;
+		UIDropDownMenu_AddButton(sortItemLevel, level);

-function Cauldron:OnCauldronUpdate()
+	--[[
+	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 = "",
+	};
+	--]]
+
+		-- required level
+		local sortReqLevel = UIDropDownMenu_CreateInfo();
+		sortReqLevel.text = L["By required level"];
+		sortReqLevel.checked = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.sortRequiredLevel;
+		sortReqLevel.isNotRadio = nil;
+		sortReqLevel.keepShownOnClick = false;
+		sortReqLevel.func = function()
+			Cauldron:FilterDropDown_SetSort("reqlevel");
+		end;
+		UIDropDownMenu_AddButton(sortReqLevel, level);

 	--[[
---	self:Search();
- 	local selectionIndex
- 	if self.vars.selectionIndex == 0 then
- 		selectionIndex = self:GetFirstTradeSkill();
- 	else
- 		selectionIndex = self.vars.selectionIndex;
- 	end
- 	--]]
+	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 = "",
+	};
+	--]]
+
+		-- favorites
+		-- TODO
+
+		-- benefit
+		-- TODO
+
+	end

 end

+--[====[
 function Cauldron:FilterDropDown_OnLoad(dropdown)

 --[[
@@ -1395,7 +1374,6 @@ function Cauldron:FilterDropDown_Initialize(level)
 		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:info("updating skill list from compact view filter (old)");
 			Cauldron:UpdateSkillList();
 		end,
 		arg1 = "compact",
@@ -1412,7 +1390,6 @@ function Cauldron:FilterDropDown_Initialize(level)
 			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:info("updating skill list from favorites filter (old)");
 				Cauldron:UpdateSkillList();
 			end,
 			arg1 = "favorite",
@@ -1428,7 +1405,6 @@ function Cauldron:FilterDropDown_Initialize(level)
 			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:info("updating skill list from achievements filter (old)");
 				Cauldron:UpdateSkillList();
 			end,
 			arg1 = "achievement",
@@ -1682,6 +1658,7 @@ function Cauldron:FilterDropDown_Initialize(level)
 	end

 end
+--]====]

 function Cauldron:FilterDropDown_Reset()

@@ -1690,11 +1667,13 @@ function Cauldron:FilterDropDown_Reset()
 		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;
@@ -1702,9 +1681,10 @@ function Cauldron:FilterDropDown_Reset()
 	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
+	-- favorites/achievements
 	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;
+	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.achievements = false;

 	-- availability
 	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAllReagents = false;
@@ -1712,87 +1692,177 @@ function Cauldron:FilterDropDown_Reset()
 	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter.haveAnyReagents = false;

 	-- update the UI
-						Cauldron:info("updating skill list from filter dropdown reset");
 	Cauldron:UpdateSkillList();

 end

 function Cauldron:FilterDropDown_SetSort(sort)

-	Cauldron:info("filter dropdown set sort: "..tostring(sort));
-
 	local skillName = CURRENT_TRADESKILL;
 	if IsTradeSkillLinked() then
 		skillName = "Linked-"..skillName;
 	end

 --	local sort = info.arg1;
+	local filter = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter;

 	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;
+		filter.sortDefault = true;
+		filter.sortAlpha = false;
+	   	filter.sortDifficulty = false;
+	   	filter.sortItemLevel = false;
+	   	filter.sortRequiredLevel = false;
+	   	filter.sortFavorites = false;
+	   	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;
+		filter.sortDefault = false;
+		filter.sortAlpha = true;
+	   	filter.sortDifficulty = false;
+	   	filter.sortItemLevel = false;
+	   	filter.sortRequiredLevel = false;
+	   	filter.sortFavorites = false;
+	   	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;
+		filter.sortDefault = false;
+		filter.sortAlpha = false;
+	   	filter.sortDifficulty = true;
+	   	filter.sortItemLevel = false;
+	   	filter.sortRequiredLevel = false;
+	   	filter.sortFavorites = false;
+	   	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;
+		filter.sortDefault = false;
+		filter.sortAlpha = false;
+	   	filter.sortDifficulty = false;
+	   	filter.sortItemLevel = true;
+	   	filter.sortRequiredLevel = false;
+	   	filter.sortFavorites = false;
+	   	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;
+		filter.sortDefault = false;
+		filter.sortAlpha = false;
+	   	filter.sortDifficulty = false;
+	   	filter.sortItemLevel = false;
+	   	filter.sortRequiredLevel = true;
+	   	filter.sortFavorites = false;
+	   	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;
+		filter.sortDefault = false;
+		filter.sortAlpha = false;
+	   	filter.sortDifficulty = false;
+	   	filter.sortItemLevel = false;
+	   	filter.sortRequiredLevel = false;
+	   	filter.sortFavorites = false;
+	   	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;
+		filter.sortDefault = false;
+		filter.sortAlpha = false;
+	   	filter.sortDifficulty = false;
+	   	filter.sortItemLevel = false;
+	   	filter.sortRequiredLevel = false;
+	   	filter.sortFavorites = true;
+	   	filter.sortBenefit = false;
 	end

 	-- update the UI
-						Cauldron:info("updating skill list from sort change");
 	Cauldron:UpdateSkillList();
 	Cauldron:UpdateStatus();

 end

+function Cauldron:FilterDropDown_SetSlot(slot)
+
+	local skillName = CURRENT_TRADESKILL;
+	if IsTradeSkillLinked() then
+		skillName = "Linked-"..skillName;
+	end
+
+	Cauldron:info("set slot: "..tostring(slot));
+
+	local slotInfo = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.slots[slot];
+	if not slotInfo then
+		-- don't have slot info; create it
+		slotInfo = {
+			checked = true,
+		};
+
+		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.slots[slot] = slotInfo;
+	end
+
+	slotInfo.checked = not slotInfo.checked;
+
+end
+
+function Cauldron:FilterDropDown_SetSubclass(subclass, subslot)
+
+	local skillName = CURRENT_TRADESKILL;
+	if IsTradeSkillLinked() then
+		skillName = "Linked-"..skillName;
+	end
+
+	Cauldron:info("set subclass: "..tostring(subclass)..", subslot: "..tostring(subslot));
+
+	-- handle "special" sub-classes
+	if subclass == "all" or subclass == "none" then
+		local checkit = (subclass == "all");
+		local subClasses = { GetTradeSkillSubClasses() };
+		local subslots = {};
+
+		for i,subClass in pairs(subClasses) do
+			subslots  = { GetTradeSkillSubClassFilteredSlots(i) };
+			if #subslots > 1 then
+				for j,slot in pairs(subslots) do
+					local catInfo = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.categories[subClass..";"..subslots[j]];
+					if not catInfo then
+						catInfo = {
+							shown = checkit,
+							expanded = true,
+						};
+					else
+						catInfo.shown = checkit;
+					end
+
+					Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.categories[subClass..";"..subslots[j]] = catInfo;
+				end
+			else
+				local catInfo = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.categories[subClass];
+				if not catInfo then
+					catInfo = {
+						shown = checkit,
+						expanded = true,
+					};
+				else
+					catInfo.shown = checkit;
+				end
+
+				Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.categories[subClass] = catInfo;
+			end
+		end
+
+		return;
+	end
+
+	local catName = subclass;
+	if subslot ~= "" then
+		catName = subclass..";"..subslot;
+	end
+	Cauldron:info("catName: "..catName);
+
+	local catInfo = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.categories[catName];
+	if not catInfo then
+		-- don't have category info; create it
+		catInfo = {
+			shown = true,
+			expanded = true,
+		};
+
+		Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.categories[catName] = catInfo;
+	end
+
+	catInfo.shown = not catInfo.shown;
+
+end
+
 function Cauldron:ReagentsFilterNormalCheck()

 	local skillName = CURRENT_TRADESKILL;
@@ -1819,27 +1889,27 @@ function Cauldron:FilterDropDown_SetReagentFilter(info)
 	end

 	local reagents = info.arg1;
+	local filter = Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.filter;

 	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;
+		filter.haveAllReagents = false;
+	   	filter.haveKeyReagents = false;
+	   	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;
+		filter.haveAllReagents = true;
+	   	filter.haveKeyReagents = false;
+	   	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;
+		filter.haveAllReagents = false;
+	   	filter.haveKeyReagents = true;
+	   	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;
+		filter.haveAllReagents = false;
+	   	filter.haveKeyReagents = false;
+	   	filter.haveAnyReagents = true;
 	end

 	-- update the UI
-						Cauldron:info("updating skill list from reagent filter change");
 	Cauldron:UpdateSkillList();

 end
@@ -1854,11 +1924,11 @@ function Cauldron:FilterDropDown_ToggleDifficulty(info)
 	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:info("updating skill list from difficulty filter change");
 	Cauldron:UpdateSkillList();

 end

+--[====[
 function Cauldron:InvSlotDropDown_Initialize(level)
 	Cauldron:debug("InvSlotDropDown_Initialize enter");

@@ -1972,7 +2042,6 @@ function Cauldron:InvSlotDropDown_SetSlot(info)
 --		end
 	end

-						Cauldron:info("updating skill list from slot filter change");
 	Cauldron:UpdateSkillList();

 	Cauldron:debug("InvSlotDropDown_SetSlot exit");
@@ -2088,10 +2157,10 @@ function Cauldron:CategoryDropDown_SetCategory(info)
 	end

 	-- update the UI
-						Cauldron:info("updating skill list from category filter change");
 	Cauldron:UpdateSkillList();

 end
+--]====]

 function Cauldron:CollapseAllButton_OnClick(button)

@@ -2130,7 +2199,6 @@ function Cauldron:CollapseAllButton_OnClick(button)
 	-- Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.selected = 0;

 	-- update the UI
-						Cauldron:info("updating skill list from collapse all button click");
 	Cauldron:UpdateSkillList();

 end
@@ -2148,7 +2216,6 @@ function Cauldron:CollapseItemButton_OnClick(button)
 	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.selected = skillInfo.index;

 	-- update the UI
-						Cauldron:info("updating skill list from collapse item button click");
 	Cauldron:UpdateSkillList();

 end
@@ -2173,7 +2240,6 @@ function Cauldron:SkillItem_OnLeave(frame)
 end

 function Cauldron:SkillItem_OnClick(frame, button, down)
-	Cauldron:info("skill item click: frame="..tostring(frame)..", button="..tostring(button)..", down="..tostring(down));

 	local skillName = CURRENT_TRADESKILL;
 	if IsTradeSkillLinked() then
@@ -2186,7 +2252,6 @@ function Cauldron:SkillItem_OnClick(frame, button, down)
     end

 	-- update the UI
-						Cauldron:info("updating skill list from skill item selection");
 	Cauldron:UpdateSkillList();
 	Cauldron:UpdateButtons();

@@ -2214,7 +2279,6 @@ function Cauldron:TradeSkillFilter_OnTextChanged(frame)
 	Cauldron.db.realm.userdata[Cauldron.vars.playername].skills[skillName].window.search = text;

 	-- update the UI
-						Cauldron:info("updating skill list from tradeskill filter text change");
 	Cauldron:UpdateSkillList();

 end
@@ -2248,6 +2312,7 @@ function Cauldron:FavoriteItemButton_OnClick(button)

 end

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

 	local gui = Cauldron.libs.GUI;
@@ -2279,6 +2344,7 @@ function Cauldron:ConfirmDialog(title, message, okayBtn, okayBtnCB, cancelBtn, c

 	f:Show();
 end
+--]]

 function Cauldron:AppendToTooltip(tooltip, skillIndex)
 	if not tooltip then
diff --git a/CauldronQueue.xml b/CauldronQueue.xml
index 097e9f4..eebb84f 100644
--- a/CauldronQueue.xml
+++ b/CauldronQueue.xml
@@ -374,7 +374,7 @@
                 	</Frame>

 					<ScrollFrame name="CauldronQueueFrameScrollFrame" inherits="UIPanelScrollFrameTemplate" hidden="true">
-						<Size x="297" y="332" />
+						<Size x="294" y="332" />
 						<Anchors>
 							<Anchor point="TOPLEFT">
 								<Offset x="0" y="0"/>
@@ -563,7 +563,7 @@

             <!-- Buttons frame -->
             <Frame name="CauldronQueueButtonsFrame">
-                <Size x="357" y="25" />
+                <Size x="328" y="25" />
                 <Anchors>
                     <Anchor point="BOTTOMLEFT" relativeTo="CauldronQueueWindowFrame" relativePoint="BOTTOMLEFT">
                         <Offset x="2" y="0" />
@@ -572,62 +572,13 @@

                 <Frames>

-                    <!-- Queue All button -->
-                    <Button name="CauldronQueueAllButton" inherits="CauldronButtonTemplate" text="Queue All">
-                        <Anchors>
-                            <Anchor point="TOPLEFT">
-                                <Offset x="0" y="0" />
-                            </Anchor>
-                        </Anchors>
-                        <Scripts>
-                            <OnLoad>
-                                -- getglobal(self:GetName()):Disable();
-                            </OnLoad>
-							<OnEnter>
-								GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT");
-								GameTooltip:ClearLines();
-								GameTooltip:AddLine(Cauldron:LocaleString("Click to queue the listed amount of this item"));
-								GameTooltip:AddLine(Cauldron:LocaleString("Shift-click to queue the listed potential amount of this item"));
-								GameTooltip:Show();
-								CursorUpdate(self);
-							</OnEnter>
-							<OnLeave>
-								GameTooltip:Hide();
-								ResetCursor();
-							</OnLeave>
-                            <OnClick>
-                            	Cauldron:QueueAllTradeSkillItem();
-                            	Cauldron:UpdateButtons();
-                            </OnClick>
-                        </Scripts>
-                    </Button>
-
-                    <!-- Queue button -->
-                    <Button name="CauldronQueueButton" inherits="CauldronButtonTemplate" text="Queue">
-                        <Anchors>
-                            <Anchor point="LEFT" relativeTo="CauldronQueueAllButton" relativePoint="RIGHT">
-                                <Offset x="0" y="0" />
-                            </Anchor>
-                        </Anchors>
-                        <Scripts>
-                            <OnLoad>
-                                -- getglobal(self:GetName()):Disable();
-                            </OnLoad>
-							<OnClick>
-								Cauldron:QueueTradeSkillItem();
-                            	Cauldron:UpdateButtons();
-							</OnClick>
-                        </Scripts>
-                    </Button>
-
-                    <!-- spacer -->
-
                     <!-- Process button (disabled) -->
                     <Button name="CauldronProcessButton" inherits="CauldronButtonTemplate" text="Process">
+                    	<Size x="150" y="20" />
                         <Anchors>
-                            <Anchor point="LEFT" relativeTo="CauldronQueueButton" relativePoint="RIGHT">
-                                <Offset x="2" y="0" />
-                            </Anchor>
+							<Anchor point="TOPLEFT">
+								<Offset x="0" y="0" />
+							</Anchor>
                         </Anchors>
                         <Scripts>
                             <OnLoad>
@@ -643,7 +594,7 @@
                     <Button name="CauldronClearQueueButton" inherits="CauldronButtonTemplate" text="Clear Queue">
                         <Size x="90" y="20" />
                         <Anchors>
-                            <Anchor point="LEFT" relativeTo="CauldronProcessButton" relativePoint="RIGHT">
+                            <Anchor point="TOPRIGHT">
                                 <Offset x="0" y="0" />
                             </Anchor>
                         </Anchors>
diff --git a/Locale/Cauldron-enUS.lua b/Locale/Cauldron-enUS.lua
index b418b1a..b1aefcc 100644
--- a/Locale/Cauldron-enUS.lua
+++ b/Locale/Cauldron-enUS.lua
@@ -113,6 +113,9 @@ L["Have any"] = true
 L["Achievements"] = true
 L["Display only skills for achievements"] = true

+L["All"] = true
+L["None"] = true
+
 L["Slots"] = true
 L["All slots"] = true
 L["(None)"] = true