| 
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@116
 | 
    72 	-- Gives the total number of craftable items
 | 
| 
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@116
 | 
    78 		local n1 = 0
 | 
| 
contrebasse@116
 | 
    79 		local n2 = 0
 | 
| 
contrebasse@116
 | 
    80 		local m
 | 
| 
contrebasse@116
 | 
    81 		local approx = nil
 | 
| 
contrebasse@108
 | 
    82 		for _,recipe in pairs(A.data[reagentID]) do
 | 
| 
contrebasse@116
 | 
    83 			-- number of times the recipe is makable
 | 
| 
contrebasse@116
 | 
    84 			m = A.numRecipeMakable(recipe[1],recipe[2])
 | 
| 
contrebasse@116
 | 
    85 			if not m then return end
 | 
| 
contrebasse@116
 | 
    86 
 | 
| 
contrebasse@116
 | 
    87 			-- number of items it gives
 | 
| 
contrebasse@116
 | 
    88 			if not recipe[3] or recipe[3]==1 then
 | 
| 
contrebasse@116
 | 
    89 				n1 = n1 + m
 | 
| 
contrebasse@116
 | 
    90 				n2 = n2 + m
 | 
| 
contrebasse@116
 | 
    91 			elseif recipe[3]<1 then
 | 
| 
contrebasse@116
 | 
    92 				approx = approx or m>0 -- 0 is not approx
 | 
| 
contrebasse@116
 | 
    93 				n1 = n1 + m*recipe[3]
 | 
| 
contrebasse@116
 | 
    94 				n2 = n2 + m*recipe[3]
 | 
| 
contrebasse@116
 | 
    95 			elseif recipe[4] then
 | 
| 
contrebasse@116
 | 
    96 				n1 = n1 + m*recipe[3]
 | 
| 
contrebasse@116
 | 
    97 				n2 = n2 + m*recipe[4]
 | 
| 
contrebasse@116
 | 
    98 			else
 | 
| 
contrebasse@116
 | 
    99 				n1 = n1 + m*recipe[3]
 | 
| 
contrebasse@116
 | 
   100 				n2 = n2 + m*recipe[3]				
 | 
| 
contrebasse@116
 | 
   101 			end
 | 
| 
contrebasse@108
 | 
   102 		end -- for
 | 
| 
contrebasse@116
 | 
   103 		return n1,n2,approx
 | 
| 
contrebasse@108
 | 
   104 	end -- function
 | 
| 
contrebasse@16
 | 
   105 
 | 
| 
contrebasse@16
 | 
   106 	-- Find the first tradeskill index of the recipe to make an item
 | 
| 
contrebasse@16
 | 
   107 	function A.findSkillIndex(itemID)
 | 
| 
contrebasse@110
 | 
   108 		if not itemID then return end
 | 
| 
contrebasse@16
 | 
   109 		for i = 1,GetNumTradeSkills() do
 | 
| 
contrebasse@110
 | 
   110 			if select(2,GetTradeSkillInfo(i)) ~= "header" and A.link2ID(GetTradeSkillItemLink(i)) == itemID then
 | 
| 
contrebasse@110
 | 
   111 				return i
 | 
| 
contrebasse@110
 | 
   112 			end -- if
 | 
| 
contrebasse@110
 | 
   113 		end -- for
 | 
| 
contrebasse@110
 | 
   114 	end -- function
 | 
| 
contrebasse@110
 | 
   115 
 | 
| 
contrebasse@110
 | 
   116 	-- Find the exact tradeskill index of the recipe to make an item
 | 
| 
contrebasse@111
 | 
   117 	function A.findExactSkillIndex(itemID,recipeLink)
 | 
| 
contrebasse@111
 | 
   118 		if not itemID or not recipeLink then return end
 | 
| 
contrebasse@110
 | 
   119 		for i = 1,GetNumTradeSkills() do
 | 
| 
contrebasse@111
 | 
   120 			if select(2,GetTradeSkillInfo(i)) ~= "header" and GetTradeSkillRecipeLink(i)==recipeLink and A.link2ID(GetTradeSkillItemLink(i)) == itemID then
 | 
| 
contrebasse@110
 | 
   121 				return i
 | 
| 
contrebasse@3
 | 
   122 			end -- if
 | 
| 
contrebasse@16
 | 
   123 		end -- for
 | 
| 
contrebasse@16
 | 
   124 	end -- function
 | 
| 
contrebasse@16
 | 
   125 end -- do
 | 
| 
contrebasse@24
 | 
   126 
 | 
| 
contrebasse@24
 | 
   127 
 | 
| 
contrebasse@110
 | 
   128 -- Bypass filters and collpsed headers
 | 
| 
contrebasse@24
 | 
   129 do
 | 
| 
contrebasse@24
 | 
   130 	local selectedTradeSkillIndex
 | 
| 
contrebasse@107
 | 
   131 	local stateSaved
 | 
| 
contrebasse@107
 | 
   132 	local filtersState = {}
 | 
| 
contrebasse@24
 | 
   133 	local headersState = {}
 | 
| 
contrebasse@24
 | 
   134 
 | 
| 
contrebasse@107
 | 
   135 	local function ApplyFilters()
 | 
| 
contrebasse@107
 | 
   136 		TradeSkillOnlyShowSkillUps(TradeSkillFrame.filterTbl.hasSkillUp);
 | 
| 
contrebasse@107
 | 
   137 		TradeSkillOnlyShowMakeable(TradeSkillFrame.filterTbl.hasMaterials);
 | 
| 
contrebasse@107
 | 
   138 		SetTradeSkillSubClassFilter(TradeSkillFrame.filterTbl.subClassValue, 1, 1);
 | 
| 
contrebasse@107
 | 
   139 		SetTradeSkillInvSlotFilter(TradeSkillFrame.filterTbl.slotValue, 1, 1);
 | 
| 
contrebasse@107
 | 
   140 		TradeSkillUpdateFilterBar();
 | 
| 
contrebasse@107
 | 
   141 		CloseDropDownMenus();
 | 
| 
contrebasse@107
 | 
   142 	end
 | 
| 
contrebasse@107
 | 
   143 
 | 
| 
contrebasse@82
 | 
   144 	function A.SaveActiveFilters(headerName)
 | 
| 
contrebasse@82
 | 
   145 		A.blockScan = true
 | 
| 
contrebasse@82
 | 
   146 
 | 
| 
contrebasse@111
 | 
   147 		-- Save position
 | 
| 
contrebasse@111
 | 
   148 		filtersState.positionOffset = FauxScrollFrame_GetOffset(TradeSkillListScrollFrame)
 | 
| 
contrebasse@111
 | 
   149 		filtersState.positionValue = TradeSkillListScrollFrameScrollBar:GetValue()
 | 
| 
contrebasse@111
 | 
   150 
 | 
| 
contrebasse@107
 | 
   151 		-- Save filters
 | 
| 
contrebasse@108
 | 
   152 		filtersState.text = GetTradeSkillItemNameFilter()
 | 
| 
contrebasse@108
 | 
   153 		filtersState.minLevel, filtersState.maxLevel = GetTradeSkillItemLevelFilter()
 | 
| 
contrebasse@107
 | 
   154 		filtersState.hasMaterials = TradeSkillFrame.filterTbl.hasMaterials
 | 
| 
contrebasse@107
 | 
   155 		filtersState.hasSkillUp = TradeSkillFrame.filterTbl.hasSkillUp
 | 
| 
contrebasse@107
 | 
   156 		filtersState.subClassValue = TradeSkillFrame.filterTbl.subClassValue
 | 
| 
contrebasse@107
 | 
   157 		filtersState.slotValue = TradeSkillFrame.filterTbl.slotValue
 | 
| 
contrebasse@24
 | 
   158 
 | 
| 
contrebasse@107
 | 
   159 		-- Remove all filters
 | 
| 
contrebasse@108
 | 
   160 		SetTradeSkillItemNameFilter(nil)
 | 
| 
contrebasse@108
 | 
   161 		SetTradeSkillItemLevelFilter(0, 0)
 | 
| 
contrebasse@107
 | 
   162 		TradeSkillFrame.filterTbl.hasMaterials = false
 | 
| 
contrebasse@107
 | 
   163 		TradeSkillFrame.filterTbl.hasSkillUp = false
 | 
| 
contrebasse@107
 | 
   164 		TradeSkillFrame.filterTbl.subClassValue = -1
 | 
| 
contrebasse@107
 | 
   165 		TradeSkillFrame.filterTbl.slotValue = -1
 | 
| 
contrebasse@107
 | 
   166 		ApplyFilters()
 | 
| 
contrebasse@24
 | 
   167 
 | 
| 
contrebasse@24
 | 
   168 		-- Headers
 | 
| 
contrebasse@107
 | 
   169 		headersState.headerName = headerName
 | 
| 
contrebasse@24
 | 
   170 		for i = GetNumTradeSkills(), 1, -1 do		-- 1st pass, expand all categories
 | 
| 
contrebasse@82
 | 
   171 			local skillName, skillType, _, isExpanded  = GetTradeSkillInfo(i)
 | 
| 
contrebasse@108
 | 
   172 			if (skillType == "header") and skillName==headerName then
 | 
| 
contrebasse@108
 | 
   173 				if not isExpanded then
 | 
| 
contrebasse@108
 | 
   174 					ExpandTradeSkillSubClass(i)
 | 
| 
contrebasse@111
 | 
   175 					tinsert(headersState,true)
 | 
| 
contrebasse@108
 | 
   176 				else
 | 
| 
contrebasse@111
 | 
   177 					tinsert(headersState,false)
 | 
| 
contrebasse@24
 | 
   178 				end
 | 
| 
contrebasse@108
 | 
   179 			end
 | 
| 
contrebasse@24
 | 
   180 		end
 | 
| 
contrebasse@24
 | 
   181 
 | 
| 
contrebasse@108
 | 
   182 		stateSaved = true
 | 
| 
contrebasse@108
 | 
   183 		A.blockScan = nil
 | 
| 
contrebasse@24
 | 
   184 	end
 | 
| 
contrebasse@24
 | 
   185 
 | 
| 
contrebasse@24
 | 
   186 	function A.RestoreActiveFilters()
 | 
| 
contrebasse@107
 | 
   187 		if not stateSaved then return end
 | 
| 
contrebasse@82
 | 
   188 		A.blockScan = true
 | 
| 
contrebasse@82
 | 
   189 
 | 
| 
contrebasse@107
 | 
   190 		-- restore headers
 | 
| 
contrebasse@24
 | 
   191 		for i = GetNumTradeSkills(), 1, -1 do
 | 
| 
contrebasse@107
 | 
   192 			local skillName, skillType  = GetTradeSkillInfo(i)
 | 
| 
contrebasse@111
 | 
   193 			if (skillType == "header") and skillName==headersState.headerName and tremove(headersState,1) then
 | 
| 
contrebasse@24
 | 
   194 					CollapseTradeSkillSubClass(i)
 | 
| 
contrebasse@24
 | 
   195 			end
 | 
| 
contrebasse@24
 | 
   196 		end
 | 
| 
contrebasse@24
 | 
   197 		wipe(headersState)
 | 
| 
contrebasse@107
 | 
   198 
 | 
| 
contrebasse@107
 | 
   199 		-- restore filters
 | 
| 
contrebasse@108
 | 
   200 		SetTradeSkillItemNameFilter(filtersState.text)
 | 
| 
contrebasse@108
 | 
   201 		SetTradeSkillItemLevelFilter(filtersState.minLevel, filtersState.maxLevel)
 | 
| 
contrebasse@107
 | 
   202 		TradeSkillFrame.filterTbl.hasMaterials = filtersState.hasMaterials
 | 
| 
contrebasse@107
 | 
   203 		TradeSkillFrame.filterTbl.hasSkillUp = filtersState.hasSkillUp
 | 
| 
contrebasse@107
 | 
   204 		TradeSkillFrame.filterTbl.subClassValue = filtersState.subClassValue
 | 
| 
contrebasse@107
 | 
   205 		TradeSkillFrame.filterTbl.slotValue = filtersState.slotValue
 | 
| 
contrebasse@107
 | 
   206 		ApplyFilters()
 | 
| 
contrebasse@107
 | 
   207 
 | 
| 
contrebasse@111
 | 
   208 		-- Re set position
 | 
| 
contrebasse@111
 | 
   209 		FauxScrollFrame_SetOffset(TradeSkillListScrollFrame,filtersState.positionOffset)
 | 
| 
contrebasse@111
 | 
   210 		TradeSkillListScrollFrameScrollBar:SetValue(filtersState.positionValue)
 | 
| 
contrebasse@111
 | 
   211 
 | 
| 
contrebasse@108
 | 
   212 		stateSaved = nil
 | 
| 
contrebasse@108
 | 
   213 		A.blockScan = nil
 | 
| 
contrebasse@24
 | 
   214 	end
 | 
| 
contrebasse@24
 | 
   215 end
 | 
| 
contrebasse@73
 | 
   216 
 | 
| 
contrebasse@73
 | 
   217 function A.isRecipeUnique(itemData)
 | 
| 
contrebasse@73
 | 
   218 	local unique = true
 | 
| 
contrebasse@107
 | 
   219 
 | 
| 
contrebasse@73
 | 
   220 	-- Check if the item is made by only one recipe. If not, return
 | 
| 
contrebasse@73
 | 
   221 	if #itemData>1 then
 | 
| 
contrebasse@73
 | 
   222 		local spellLink
 | 
| 
contrebasse@73
 | 
   223 		for _,v in ipairs(itemData) do
 | 
| 
contrebasse@73
 | 
   224 			if not spellLink then
 | 
| 
contrebasse@73
 | 
   225 				spellLink = v.spellLink
 | 
| 
contrebasse@73
 | 
   226 			else
 | 
| 
contrebasse@73
 | 
   227 				if v.spellLink ~= spellLink then
 | 
| 
contrebasse@73
 | 
   228 					unique = nil
 | 
| 
contrebasse@73
 | 
   229 					break
 | 
| 
contrebasse@73
 | 
   230 				end
 | 
| 
contrebasse@73
 | 
   231 			end
 | 
| 
contrebasse@73
 | 
   232 		end
 | 
| 
contrebasse@73
 | 
   233 	end
 | 
| 
contrebasse@107
 | 
   234 
 | 
| 
contrebasse@73
 | 
   235 	return unique
 | 
| 
contrebasse@73
 | 
   236 end
 | 
| 
contrebasse@76
 | 
   237 
 | 
| 
contrebasse@76
 | 
   238 --[[
 | 
| 
contrebasse@76
 | 
   239 function A.isTradeskillUnique(itemData)
 | 
| 
contrebasse@110
 | 
   240 	local tradeskillName = itemData[1].tradeskillName
 | 
| 
contrebasse@107
 | 
   241 
 | 
| 
contrebasse@76
 | 
   242 	-- Check if the item is made by only one recipe. If not, return
 | 
| 
contrebasse@76
 | 
   243 	if #itemData>1 then
 | 
| 
contrebasse@76
 | 
   244 		for _,v in ipairs(itemData) do
 | 
| 
contrebasse@110
 | 
   245 			if v.tradeskillName ~= tradeskillName then
 | 
| 
contrebasse@110
 | 
   246 				tradeskillName = nil
 | 
| 
contrebasse@76
 | 
   247 				break
 | 
| 
contrebasse@76
 | 
   248 			end
 | 
| 
contrebasse@76
 | 
   249 		end
 | 
| 
contrebasse@76
 | 
   250 	end
 | 
| 
contrebasse@89
 | 
   251 
 | 
| 
contrebasse@110
 | 
   252 	return tradeskillName
 | 
| 
contrebasse@76
 | 
   253 end
 | 
| 
contrebasse@107
 | 
   254 --]]
 |