| contrebasse@0 | 1 local addonName, A = ... | 
| contrebasse@0 | 2 | 
| contrebasse@111 | 3 -- GLOBALS: UIErrorsFrame, UIErrorsFrame_OnEvent | 
| contrebasse@111 | 4 | 
| contrebasse@16 | 5 -- Lua functions | 
| contrebasse@16 | 6 local tonumber = tonumber | 
| contrebasse@16 | 7 local select = select | 
| contrebasse@16 | 8 local sfind = string.find | 
| contrebasse@111 | 9 local min = math.min | 
| contrebasse@111 | 10 local floor = math.floor | 
| contrebasse@111 | 11 local pairs = pairs | 
| contrebasse@111 | 12 local ipairs = ipairs | 
| contrebasse@111 | 13 local wipe = wipe | 
| contrebasse@111 | 14 local tinsert = tinsert | 
| contrebasse@111 | 15 local tremove = tremove | 
| contrebasse@16 | 16 | 
| contrebasse@16 | 17 -- Wow functions | 
| contrebasse@111 | 18 local GetItemCount = GetItemCount | 
| contrebasse@0 | 19 | 
| contrebasse@38 | 20 -- Messages to the user | 
| contrebasse@38 | 21 function A.Warn(msg) | 
| contrebasse@38 | 22 	if not msg then return end | 
| contrebasse@38 | 23 	local event = "UI_INFO_MESSAGE" | 
| contrebasse@38 | 24 	UIErrorsFrame_OnEvent(UIErrorsFrame, event, msg) | 
| contrebasse@38 | 25 end -- function | 
| contrebasse@38 | 26 function A.Error(msg) | 
| contrebasse@38 | 27 	if not msg then return end | 
| contrebasse@38 | 28 	local event = "UI_ERROR_MESSAGE" | 
| contrebasse@38 | 29 	UIErrorsFrame_OnEvent(UIErrorsFrame, event, msg) | 
| contrebasse@38 | 30 end -- function | 
| contrebasse@38 | 31 | 
| contrebasse@3 | 32 -- Returns the item ID from its link | 
| contrebasse@3 | 33 function A.link2ID(link) | 
| contrebasse@16 | 34 	return tonumber(select(3,sfind(link or "", "-*:(%d+)[:|].*")) or "") | 
| contrebasse@3 | 35 end -- function | 
| contrebasse@3 | 36 | 
| contrebasse@3 | 37 -- Returns the button number for the reagents buttons | 
| contrebasse@3 | 38 function A.buttonNumber(btn) | 
| contrebasse@3 | 39 	-- "TradeSkillReagentN" | 
| contrebasse@3 | 40 	return tonumber(btn:GetName():sub(-1)) | 
| contrebasse@0 | 41 end | 
| contrebasse@0 | 42 | 
| contrebasse@16 | 43 do | 
| contrebasse@16 | 44 	-- Wow functions | 
| contrebasse@16 | 45 	local GetTradeSkillInfo = GetTradeSkillInfo | 
| contrebasse@16 | 46 	local GetNumTradeSkills = GetNumTradeSkills | 
| contrebasse@16 | 47 	local GetTradeSkillItemLink = GetTradeSkillItemLink | 
| contrebasse@111 | 48 	local GetTradeSkillRecipeLink = GetTradeSkillRecipeLink | 
| contrebasse@0 | 49 | 
| contrebasse@110 | 50 	function A.numRecipeMakable(reagentIDIfUnique,reagents) | 
| contrebasse@111 | 51 		local itemCount | 
| contrebasse@110 | 52 		if reagentIDIfUnique then -- only one reagent | 
| contrebasse@110 | 53 			itemCount = GetItemCount(reagentIDIfUnique) | 
| contrebasse@110 | 54 			if not itemCount then return end | 
| contrebasse@111 | 55 			return floor(itemCount/reagents) | 
| contrebasse@110 | 56 		else -- many reagents | 
| contrebasse@110 | 57 			local m | 
| contrebasse@110 | 58 			for _,reagent in pairs(reagents) do | 
| contrebasse@110 | 59 				itemCount = GetItemCount(reagent[1]) | 
| contrebasse@110 | 60 				if not itemCount then return end | 
| contrebasse@110 | 61 				if not m then | 
| contrebasse@111 | 62 					m = floor(itemCount/reagent[2]) | 
| contrebasse@110 | 63 				else | 
| contrebasse@111 | 64 					m = min(m,floor(itemCount/reagent[2])) | 
| contrebasse@110 | 65 				end | 
| contrebasse@110 | 66 				if m==0 then break end | 
| contrebasse@110 | 67 			end | 
| contrebasse@110 | 68 			return m | 
| contrebasse@110 | 69 		end -- if | 
| contrebasse@110 | 70 	end | 
| contrebasse@110 | 71 | 
| contrebasse@111 | 72 	-- Gives the total number of craftable objects | 
| contrebasse@108 | 73 	function A.numMakable(reagentID) | 
| contrebasse@108 | 74 		-- No recipe | 
| contrebasse@108 | 75 		if not A.data[reagentID] then return 0 end | 
| contrebasse@108 | 76 | 
| contrebasse@108 | 77 		-- Many recipes | 
| contrebasse@108 | 78 		local n = 0 | 
| contrebasse@108 | 79 		local itemCount | 
| contrebasse@108 | 80 		for _,recipe in pairs(A.data[reagentID]) do | 
| contrebasse@110 | 81 			n = n + A.numRecipeMakable(recipe[1],recipe[2]) | 
| contrebasse@108 | 82 		end -- for | 
| contrebasse@108 | 83 		return n | 
| contrebasse@108 | 84 	end -- function | 
| contrebasse@16 | 85 | 
| contrebasse@16 | 86 	-- Find the first tradeskill index of the recipe to make an item | 
| contrebasse@16 | 87 	function A.findSkillIndex(itemID) | 
| contrebasse@110 | 88 		if not itemID then return end | 
| contrebasse@16 | 89 		for i = 1,GetNumTradeSkills() do | 
| contrebasse@110 | 90 			if select(2,GetTradeSkillInfo(i)) ~= "header" and A.link2ID(GetTradeSkillItemLink(i)) == itemID then | 
| contrebasse@110 | 91 				return i | 
| contrebasse@110 | 92 			end -- if | 
| contrebasse@110 | 93 		end -- for | 
| contrebasse@110 | 94 	end -- function | 
| contrebasse@110 | 95 | 
| contrebasse@110 | 96 	-- Find the exact tradeskill index of the recipe to make an item | 
| contrebasse@111 | 97 	function A.findExactSkillIndex(itemID,recipeLink) | 
| contrebasse@111 | 98 		if not itemID or not recipeLink then return end | 
| contrebasse@110 | 99 		for i = 1,GetNumTradeSkills() do | 
| contrebasse@111 | 100 			if select(2,GetTradeSkillInfo(i)) ~= "header" and GetTradeSkillRecipeLink(i)==recipeLink and A.link2ID(GetTradeSkillItemLink(i)) == itemID then | 
| contrebasse@110 | 101 				return i | 
| contrebasse@3 | 102 			end -- if | 
| contrebasse@16 | 103 		end -- for | 
| contrebasse@16 | 104 	end -- function | 
| contrebasse@16 | 105 end -- do | 
| contrebasse@24 | 106 | 
| contrebasse@24 | 107 | 
| contrebasse@110 | 108 -- Bypass filters and collpsed headers | 
| contrebasse@24 | 109 do | 
| contrebasse@24 | 110 	local selectedTradeSkillIndex | 
| contrebasse@107 | 111 	local stateSaved | 
| contrebasse@107 | 112 	local filtersState = {} | 
| contrebasse@24 | 113 	local headersState = {} | 
| contrebasse@24 | 114 | 
| contrebasse@107 | 115 	local function ApplyFilters() | 
| contrebasse@107 | 116 		TradeSkillOnlyShowSkillUps(TradeSkillFrame.filterTbl.hasSkillUp); | 
| contrebasse@107 | 117 		TradeSkillOnlyShowMakeable(TradeSkillFrame.filterTbl.hasMaterials); | 
| contrebasse@107 | 118 		SetTradeSkillSubClassFilter(TradeSkillFrame.filterTbl.subClassValue, 1, 1); | 
| contrebasse@107 | 119 		SetTradeSkillInvSlotFilter(TradeSkillFrame.filterTbl.slotValue, 1, 1); | 
| contrebasse@107 | 120 		TradeSkillUpdateFilterBar(); | 
| contrebasse@107 | 121 		CloseDropDownMenus(); | 
| contrebasse@107 | 122 	end | 
| contrebasse@107 | 123 | 
| contrebasse@82 | 124 	function A.SaveActiveFilters(headerName) | 
| contrebasse@82 | 125 		A.blockScan = true | 
| contrebasse@82 | 126 | 
| contrebasse@111 | 127 		-- Save position | 
| contrebasse@111 | 128 		filtersState.positionOffset = FauxScrollFrame_GetOffset(TradeSkillListScrollFrame) | 
| contrebasse@111 | 129 		filtersState.positionValue = TradeSkillListScrollFrameScrollBar:GetValue() | 
| contrebasse@111 | 130 | 
| contrebasse@107 | 131 		-- Save filters | 
| contrebasse@108 | 132 		filtersState.text = GetTradeSkillItemNameFilter() | 
| contrebasse@108 | 133 		filtersState.minLevel, filtersState.maxLevel = GetTradeSkillItemLevelFilter() | 
| contrebasse@107 | 134 		filtersState.hasMaterials = TradeSkillFrame.filterTbl.hasMaterials | 
| contrebasse@107 | 135 		filtersState.hasSkillUp = TradeSkillFrame.filterTbl.hasSkillUp | 
| contrebasse@107 | 136 		filtersState.subClassValue = TradeSkillFrame.filterTbl.subClassValue | 
| contrebasse@107 | 137 		filtersState.slotValue = TradeSkillFrame.filterTbl.slotValue | 
| contrebasse@24 | 138 | 
| contrebasse@107 | 139 		-- Remove all filters | 
| contrebasse@108 | 140 		SetTradeSkillItemNameFilter(nil) | 
| contrebasse@108 | 141 		SetTradeSkillItemLevelFilter(0, 0) | 
| contrebasse@107 | 142 		TradeSkillFrame.filterTbl.hasMaterials = false | 
| contrebasse@107 | 143 		TradeSkillFrame.filterTbl.hasSkillUp = false | 
| contrebasse@107 | 144 		TradeSkillFrame.filterTbl.subClassValue = -1 | 
| contrebasse@107 | 145 		TradeSkillFrame.filterTbl.slotValue = -1 | 
| contrebasse@107 | 146 		ApplyFilters() | 
| contrebasse@24 | 147 | 
| contrebasse@24 | 148 		-- Headers | 
| contrebasse@107 | 149 		headersState.headerName = headerName | 
| contrebasse@24 | 150 		for i = GetNumTradeSkills(), 1, -1 do		-- 1st pass, expand all categories | 
| contrebasse@82 | 151 			local skillName, skillType, _, isExpanded  = GetTradeSkillInfo(i) | 
| contrebasse@108 | 152 			if (skillType == "header") and skillName==headerName then | 
| contrebasse@108 | 153 				if not isExpanded then | 
| contrebasse@108 | 154 					ExpandTradeSkillSubClass(i) | 
| contrebasse@111 | 155 					tinsert(headersState,true) | 
| contrebasse@108 | 156 				else | 
| contrebasse@111 | 157 					tinsert(headersState,false) | 
| contrebasse@24 | 158 				end | 
| contrebasse@108 | 159 			end | 
| contrebasse@24 | 160 		end | 
| contrebasse@24 | 161 | 
| contrebasse@108 | 162 		stateSaved = true | 
| contrebasse@108 | 163 		A.blockScan = nil | 
| contrebasse@108 | 164 | 
| contrebasse@107 | 165 		--@todo Scroll down to the selected recipe | 
| contrebasse@107 | 166 		-- with TradeSkillSkillXX:Show() ? | 
| contrebasse@24 | 167 	end | 
| contrebasse@24 | 168 | 
| contrebasse@24 | 169 	function A.RestoreActiveFilters() | 
| contrebasse@107 | 170 		if not stateSaved then return end | 
| contrebasse@82 | 171 		A.blockScan = true | 
| contrebasse@82 | 172 | 
| contrebasse@107 | 173 		-- restore headers | 
| contrebasse@24 | 174 		for i = GetNumTradeSkills(), 1, -1 do | 
| contrebasse@107 | 175 			local skillName, skillType  = GetTradeSkillInfo(i) | 
| contrebasse@111 | 176 			if (skillType == "header") and skillName==headersState.headerName and tremove(headersState,1) then | 
| contrebasse@24 | 177 					CollapseTradeSkillSubClass(i) | 
| contrebasse@24 | 178 			end | 
| contrebasse@24 | 179 		end | 
| contrebasse@24 | 180 		wipe(headersState) | 
| contrebasse@107 | 181 | 
| contrebasse@107 | 182 		-- restore filters | 
| contrebasse@108 | 183 		SetTradeSkillItemNameFilter(filtersState.text) | 
| contrebasse@108 | 184 		SetTradeSkillItemLevelFilter(filtersState.minLevel, filtersState.maxLevel) | 
| contrebasse@107 | 185 		TradeSkillFrame.filterTbl.hasMaterials = filtersState.hasMaterials | 
| contrebasse@107 | 186 		TradeSkillFrame.filterTbl.hasSkillUp = filtersState.hasSkillUp | 
| contrebasse@107 | 187 		TradeSkillFrame.filterTbl.subClassValue = filtersState.subClassValue | 
| contrebasse@107 | 188 		TradeSkillFrame.filterTbl.slotValue = filtersState.slotValue | 
| contrebasse@107 | 189 		ApplyFilters() | 
| contrebasse@107 | 190 | 
| contrebasse@111 | 191 		-- Re set position | 
| contrebasse@111 | 192 		FauxScrollFrame_SetOffset(TradeSkillListScrollFrame,filtersState.positionOffset) | 
| contrebasse@111 | 193 		TradeSkillListScrollFrameScrollBar:SetValue(filtersState.positionValue) | 
| contrebasse@111 | 194 | 
| contrebasse@108 | 195 		stateSaved = nil | 
| contrebasse@108 | 196 		A.blockScan = nil | 
| contrebasse@107 | 197 | 
| contrebasse@108 | 198 		--@todo Scroll down to the selected recipe | 
| contrebasse@108 | 199 		-- with TradeSkillSkillXX:Show() ? | 
| contrebasse@24 | 200 	end | 
| contrebasse@24 | 201 end | 
| contrebasse@73 | 202 | 
| contrebasse@73 | 203 function A.isRecipeUnique(itemData) | 
| contrebasse@73 | 204 	local unique = true | 
| contrebasse@107 | 205 | 
| contrebasse@73 | 206 	-- Check if the item is made by only one recipe. If not, return | 
| contrebasse@73 | 207 	if #itemData>1 then | 
| contrebasse@73 | 208 		local spellLink | 
| contrebasse@73 | 209 		for _,v in ipairs(itemData) do | 
| contrebasse@73 | 210 			if not spellLink then | 
| contrebasse@73 | 211 				spellLink = v.spellLink | 
| contrebasse@73 | 212 			else | 
| contrebasse@73 | 213 				if v.spellLink ~= spellLink then | 
| contrebasse@73 | 214 					unique = nil | 
| contrebasse@73 | 215 					break | 
| contrebasse@73 | 216 				end | 
| contrebasse@73 | 217 			end | 
| contrebasse@73 | 218 		end | 
| contrebasse@73 | 219 	end | 
| contrebasse@107 | 220 | 
| contrebasse@73 | 221 	return unique | 
| contrebasse@73 | 222 end | 
| contrebasse@76 | 223 | 
| contrebasse@76 | 224 --[[ | 
| contrebasse@76 | 225 function A.isTradeskillUnique(itemData) | 
| contrebasse@110 | 226 	local tradeskillName = itemData[1].tradeskillName | 
| contrebasse@107 | 227 | 
| contrebasse@76 | 228 	-- Check if the item is made by only one recipe. If not, return | 
| contrebasse@76 | 229 	if #itemData>1 then | 
| contrebasse@76 | 230 		for _,v in ipairs(itemData) do | 
| contrebasse@110 | 231 			if v.tradeskillName ~= tradeskillName then | 
| contrebasse@110 | 232 				tradeskillName = nil | 
| contrebasse@76 | 233 				break | 
| contrebasse@76 | 234 			end | 
| contrebasse@76 | 235 		end | 
| contrebasse@76 | 236 	end | 
| contrebasse@89 | 237 | 
| contrebasse@110 | 238 	return tradeskillName | 
| contrebasse@76 | 239 end | 
| contrebasse@107 | 240 --]] |