| yellowfive@57 | 1 local Amr = LibStub("AceAddon-3.0"):GetAddon("AskMrRobot") | 
| yellowfive@57 | 2 local L = LibStub("AceLocale-3.0"):GetLocale("AskMrRobot", true) | 
| yellowfive@57 | 3 local AceGUI = LibStub("AceGUI-3.0") | 
| yellowfive@57 | 4 | 
| yellowfive@57 | 5 local _frameShop | 
| yellowfive@57 | 6 local _panelContent | 
| yellowfive@57 | 7 local _cboPlayers | 
| yellowfive@139 | 8 local _selectedSetup | 
| yellowfive@81 | 9 | 
| yellowfive@57 | 10 local _specs = { | 
| yellowfive@57 | 11 	[1] = true, | 
| yellowfive@81 | 12 	[2] = true, | 
| yellowfive@81 | 13 	[3] = true, | 
| yellowfive@81 | 14 	[4] = true, | 
| yellowfive@57 | 15 } | 
| yellowfive@81 | 16 | 
| yellowfive@57 | 17 local _isAhOpen = false | 
| yellowfive@57 | 18 | 
| yellowfive@89 | 19 local function incrementTableItem(tbl, key, inc) | 
| yellowfive@89 | 20 	tbl[key] = tbl[key] and tbl[key] + inc or inc | 
| yellowfive@89 | 21 end | 
| yellowfive@89 | 22 | 
| yellowfive@57 | 23 local function onShopFrameClose(widget) | 
| yellowfive@57 | 24 	AceGUI:Release(widget) | 
| yellowfive@57 | 25 	_frameShop = nil | 
| yellowfive@57 | 26 	_cboPlayers = nil | 
| yellowfive@57 | 27 	_panelContent = nil | 
| yellowfive@57 | 28 end | 
| yellowfive@57 | 29 | 
| yellowfive@57 | 30 function Amr:HideShopWindow() | 
| yellowfive@57 | 31 	if not _frameShop then return end | 
| yellowfive@57 | 32 	_frameShop:Hide() | 
| yellowfive@57 | 33 end | 
| yellowfive@57 | 34 | 
| yellowfive@57 | 35 local function onPlayerChange(widget, eventName, value) | 
| yellowfive@139 | 36 	_selectedSetup = value | 
| yellowfive@57 | 37 	Amr:RefreshShoppingUi() | 
| yellowfive@57 | 38 end | 
| yellowfive@57 | 39 | 
| yellowfive@57 | 40 local function onSpecClick(widget) | 
| yellowfive@57 | 41 	local spec = widget:GetUserData("spec") | 
| yellowfive@57 | 42 	_specs[spec] = not _specs[spec] | 
| yellowfive@57 | 43 | 
| yellowfive@57 | 44 	Amr:RefreshShoppingUi() | 
| yellowfive@57 | 45 end | 
| yellowfive@57 | 46 | 
| yellowfive@57 | 47 local function onItemClick(widget) | 
| yellowfive@57 | 48 	local name = widget:GetUserData("itemName") | 
| yellowfive@57 | 49 	if name then | 
| yellowfive@57 | 50 		QueryAuctionItems(name) | 
| yellowfive@57 | 51 	end | 
| yellowfive@57 | 52 end | 
| yellowfive@57 | 53 | 
| yellowfive@124 | 54 | 
| yellowfive@57 | 55 function Amr:ShowShopWindow() | 
| yellowfive@124 | 56 | 
| yellowfive@57 | 57 	if not _frameShop then | 
| yellowfive@57 | 58 		_frameShop = AceGUI:Create("AmrUiFrame") | 
| yellowfive@57 | 59 		_frameShop:SetStatusTable(Amr.db.profile.shopWindow) -- window position is remembered in db | 
| yellowfive@57 | 60 		_frameShop:SetCallback("OnClose", onShopFrameClose) | 
| yellowfive@57 | 61 		_frameShop:SetLayout("None") | 
| yellowfive@57 | 62 		_frameShop:SetWidth(500) | 
| yellowfive@57 | 63 		_frameShop:SetHeight(500) | 
| yellowfive@57 | 64 		_frameShop:SetBorderColor(Amr.Colors.BorderBlue) | 
| yellowfive@57 | 65 		_frameShop:SetBackgroundColor(Amr.Colors.Bg) | 
| yellowfive@57 | 66 | 
| yellowfive@61 | 67 		if Amr.db.profile.options.uiScale ~= 1 then | 
| yellowfive@61 | 68 			local scale = tonumber(Amr.db.profile.options.uiScale) | 
| yellowfive@61 | 69 			_frameShop:SetScale(scale) | 
| yellowfive@61 | 70 		end | 
| yellowfive@61 | 71 | 
| yellowfive@57 | 72 		local lbl = AceGUI:Create("AmrUiLabel") | 
| yellowfive@124 | 73 		_frameShop:AddChild(lbl) | 
| yellowfive@57 | 74 		lbl:SetWidth(400) | 
| yellowfive@57 | 75 		lbl:SetFont(Amr.CreateFont("Bold", 28, Amr.Colors.White)) | 
| yellowfive@57 | 76 		lbl:SetText(L.ShopTitle) | 
| yellowfive@57 | 77 		lbl:SetWordWrap(false) | 
| yellowfive@57 | 78 		lbl:SetJustifyH("CENTER") | 
| yellowfive@57 | 79 		lbl:SetPoint("TOP", _frameShop.content, "TOP", 0, 30) | 
| yellowfive@57 | 80 | 
| yellowfive@57 | 81 		lbl:SetCallback("OnMouseDown", function(widget) _frameShop:StartMove() end) | 
| yellowfive@57 | 82 		lbl:SetCallback("OnMouseUp", function(widget) _frameShop:EndMove() end) | 
| yellowfive@57 | 83 | 
| yellowfive@57 | 84 		-- player picker | 
| yellowfive@57 | 85 		_cboPlayers = AceGUI:Create("AmrUiDropDown") | 
| yellowfive@57 | 86 		_cboPlayers:SetWidth(400) | 
| yellowfive@124 | 87 		_frameShop:AddChild(_cboPlayers) | 
| yellowfive@57 | 88 		_cboPlayers:SetPoint("TOPLEFT", _frameShop.content, "TOPLEFT", 0, -30) | 
| yellowfive@57 | 89 | 
| yellowfive@57 | 90 		_panelContent = AceGUI:Create("AmrUiPanel") | 
| yellowfive@57 | 91 		_panelContent:SetLayout("None") | 
| yellowfive@57 | 92 		_panelContent:SetTransparent() | 
| yellowfive@124 | 93 		_frameShop:AddChild(_panelContent) | 
| yellowfive@139 | 94 		_panelContent:SetPoint("TOPLEFT", _cboPlayers.frame, "BOTTOMLEFT", 0, -10) | 
| yellowfive@57 | 95 		_panelContent:SetPoint("BOTTOMRIGHT", _frameShop.content, "BOTTOMRIGHT") | 
| yellowfive@57 | 96 | 
| yellowfive@57 | 97 		-- update shopping list data | 
| yellowfive@57 | 98 		local player = Amr:ExportCharacter() | 
| yellowfive@57 | 99 		Amr:UpdateShoppingData(player) | 
| yellowfive@57 | 100 | 
| yellowfive@57 | 101 		-- fill player list | 
| yellowfive@57 | 102 		local playerList = {} | 
| yellowfive@139 | 103 		local firstData = nil | 
| yellowfive@139 | 104 		for name, v in pairs(Amr.db.global.Shopping2) do | 
| yellowfive@139 | 105 			for setupName, data in pairs(v.setups) do | 
| yellowfive@139 | 106 				table.insert(playerList, { text = name .. " " .. setupName, value = name .. "@" .. setupName }) | 
| yellowfive@139 | 107 				if not firstData then | 
| yellowfive@139 | 108 					firstData = name .. "@" .. setupName | 
| yellowfive@139 | 109 				end | 
| yellowfive@139 | 110 			end | 
| yellowfive@57 | 111 		end | 
| yellowfive@57 | 112 		_cboPlayers:SetItems(playerList) | 
| yellowfive@57 | 113 | 
| yellowfive@57 | 114 		-- set default selected player | 
| yellowfive@139 | 115 		local playerData = Amr.db.global.Shopping2[player.Name .. "-" .. player.Realm] | 
| yellowfive@139 | 116 		if playerData and playerData.setups then | 
| yellowfive@139 | 117 			_selectedSetup = Amr:GetActiveSetupLabel() | 
| yellowfive@139 | 118 			if not _selectedSetup then | 
| yellowfive@139 | 119 				Amr:PickFirstSetupForSpec() | 
| yellowfive@139 | 120 				_selectedSetup = Amr:GetActiveSetupLabel() | 
| yellowfive@139 | 121 			end | 
| yellowfive@139 | 122 			if _selectedSetup and not playerData.setups[_selectedSetup] then | 
| yellowfive@139 | 123 				_selectedSetup = nil | 
| yellowfive@139 | 124 			else | 
| yellowfive@139 | 125 				_selectedSetup = player.Name .. "-" .. player.Realm .. "@" .. _selectedSetup | 
| yellowfive@139 | 126 			end | 
| yellowfive@139 | 127 		end | 
| yellowfive@139 | 128 | 
| yellowfive@139 | 129 		if not _selectedSetup then | 
| yellowfive@139 | 130 			if playerData and playerData.setups then | 
| yellowfive@139 | 131 				for k,v in pairs(playerData.setups) do | 
| yellowfive@139 | 132 					_selectedSetup = player.Name .. "-" .. player.Realm .. "@" .. k | 
| yellowfive@139 | 133 					break | 
| yellowfive@139 | 134 				end | 
| yellowfive@139 | 135 			else | 
| yellowfive@139 | 136 				_selectedSetup = firstData | 
| yellowfive@139 | 137 			end | 
| yellowfive@139 | 138 		end | 
| yellowfive@139 | 139 		_cboPlayers:SelectItem(_selectedSetup) | 
| yellowfive@57 | 140 | 
| yellowfive@57 | 141 		Amr:RefreshShoppingUi() | 
| yellowfive@57 | 142 | 
| yellowfive@57 | 143 		-- set event on dropdown after UI has been initially rendered | 
| yellowfive@57 | 144 		_cboPlayers:SetCallback("OnChange", onPlayerChange) | 
| yellowfive@139 | 145 | 
| yellowfive@139 | 146 		-- set a timer to refresh a bit after opening b/c sometimes some item info isn't available | 
| yellowfive@139 | 147 		Amr.Wait(2, function() | 
| yellowfive@139 | 148 			if _frameShop then | 
| yellowfive@139 | 149 				Amr:RefreshShoppingUi() | 
| yellowfive@139 | 150 			end | 
| yellowfive@139 | 151 		end) | 
| yellowfive@57 | 152 	else | 
| yellowfive@57 | 153 		_frameShop:Show() | 
| yellowfive@57 | 154 		Amr:RefreshShoppingUi() | 
| yellowfive@57 | 155 	end | 
| yellowfive@57 | 156 | 
| yellowfive@57 | 157 	_frameShop:Raise() | 
| yellowfive@57 | 158 end | 
| yellowfive@57 | 159 | 
| yellowfive@57 | 160 -- helper to render a section of the shopping list | 
| yellowfive@57 | 161 local function renderShopSection(list, scroll, header) | 
| yellowfive@57 | 162 	if not list or next(list) == nil then return end | 
| yellowfive@57 | 163 | 
| yellowfive@57 | 164 	local w = 440 | 
| yellowfive@57 | 165 | 
| yellowfive@57 | 166 	local panel = AceGUI:Create("AmrUiPanel") | 
| yellowfive@57 | 167 	panel:SetLayout("None") | 
| yellowfive@57 | 168 	panel:SetTransparent() | 
| yellowfive@57 | 169 	panel:SetWidth(w) | 
| yellowfive@57 | 170 	panel:SetHeight(40) | 
| yellowfive@57 | 171 	scroll:AddChild(panel) | 
| yellowfive@57 | 172 | 
| yellowfive@57 | 173 	local lbl = AceGUI:Create("AmrUiLabel") | 
| yellowfive@124 | 174 	panel:AddChild(lbl) | 
| yellowfive@57 | 175 	lbl:SetWidth(w) | 
| yellowfive@57 | 176 	lbl:SetFont(Amr.CreateFont("Regular", 18, Amr.Colors.TextHeaderActive)) | 
| yellowfive@57 | 177 	lbl:SetText(header) | 
| yellowfive@57 | 178 	lbl:SetPoint("BOTTOMLEFT", panel.content, "BOTTOMLEFT") | 
| yellowfive@57 | 179 | 
| yellowfive@57 | 180 	for itemId, count in pairs(list) do | 
| yellowfive@57 | 181 		panel = AceGUI:Create("AmrUiPanel") | 
| yellowfive@57 | 182 		panel:SetLayout("None") | 
| yellowfive@57 | 183 		panel:SetTransparent() | 
| yellowfive@57 | 184 		panel:SetWidth(w) | 
| yellowfive@57 | 185 		panel:SetHeight(30) | 
| yellowfive@57 | 186 		scroll:AddChild(panel) | 
| yellowfive@57 | 187 | 
| yellowfive@57 | 188 		lbl = AceGUI:Create("AmrUiLabel") | 
| yellowfive@124 | 189 		panel:AddChild(lbl) | 
| yellowfive@89 | 190 		lbl:SetWidth(40) | 
| yellowfive@57 | 191 		lbl:SetWordWrap(false) | 
| yellowfive@57 | 192 		lbl:SetFont(Amr.CreateFont("Bold", 20, Amr.Colors.White)) | 
| yellowfive@57 | 193 		lbl:SetText(count .. "x") | 
| yellowfive@57 | 194 		lbl:SetPoint("LEFT", panel.content, "LEFT") | 
| yellowfive@57 | 195 | 
| yellowfive@57 | 196 		local icon = AceGUI:Create("AmrUiIcon") | 
| yellowfive@57 | 197 		icon:SetBorderWidth(1) | 
| yellowfive@57 | 198 		icon:SetIconBorderColor(Amr.Colors.White) | 
| yellowfive@57 | 199 		icon:SetWidth(18) | 
| yellowfive@57 | 200 		icon:SetHeight(18) | 
| yellowfive@124 | 201 		panel:AddChild(icon) | 
| yellowfive@57 | 202 		icon:SetPoint("LEFT", lbl.frame, "RIGHT", 5, 0) | 
| yellowfive@57 | 203 | 
| yellowfive@57 | 204 		local btn = AceGUI:Create("AmrUiTextButton") | 
| yellowfive@57 | 205 		btn:SetWidth(w - 30 - 18 - 15) | 
| yellowfive@57 | 206 		btn:SetJustifyH("LEFT") | 
| yellowfive@57 | 207 		btn:SetWordWrap(false) | 
| yellowfive@57 | 208 		btn:SetFont(Amr.CreateFont("Bold", 14, Amr.Colors.White)) | 
| yellowfive@57 | 209 		btn:SetHoverFont(Amr.CreateFont("Bold", 14, Amr.Colors.White)) | 
| yellowfive@57 | 210 		btn:SetCallback("OnClick", onItemClick) | 
| yellowfive@57 | 211 		panel:AddChild(btn) | 
| yellowfive@124 | 212 		btn:SetPoint("LEFT", icon.frame, "RIGHT", 5, 0) | 
| yellowfive@57 | 213 | 
| yellowfive@131 | 214 		local item = Item:CreateFromItemID(itemId) | 
| yellowfive@131 | 215 		if item then | 
| yellowfive@131 | 216 			local itemLink = item:GetItemLink() | 
| yellowfive@131 | 217 			if itemLink then | 
| yellowfive@131 | 218 				icon:SetIcon(item:GetItemIcon()) | 
| yellowfive@131 | 219 				btn:SetText(itemLink:gsub("%[", ""):gsub("%]", "")) | 
| yellowfive@131 | 220 				btn:SetUserData("itemName", item:GetItemName()) | 
| yellowfive@131 | 221 				Amr:SetItemTooltip(btn, itemLink) | 
| yellowfive@131 | 222 			end | 
| yellowfive@131 | 223 		end | 
| yellowfive@57 | 224 	end | 
| yellowfive@57 | 225 | 
| yellowfive@57 | 226 end | 
| yellowfive@57 | 227 | 
| yellowfive@89 | 228 -- get the number of a specified gem/enchant/material that the player currently owns | 
| yellowfive@57 | 229 local function getOwnedCount(itemId) | 
| yellowfive@57 | 230 	local ret = 0 | 
| yellowfive@57 | 231 | 
| yellowfive@57 | 232 	local list = Amr.db.char.BagItemsAndCounts | 
| yellowfive@57 | 233 	if list and list[itemId] then | 
| yellowfive@57 | 234 		ret = ret + list[itemId] | 
| yellowfive@57 | 235 	end | 
| yellowfive@57 | 236 | 
| yellowfive@124 | 237 	local bankBags = Amr.db.char.BankItemsAndCounts | 
| yellowfive@124 | 238 	if bankBags then | 
| yellowfive@124 | 239 		for bagId,bagList in pairs(bankBags) do | 
| yellowfive@124 | 240 			if bagList[itemId] then | 
| yellowfive@124 | 241 				ret = ret + bagList[itemId] | 
| yellowfive@124 | 242 			end | 
| yellowfive@124 | 243 		end | 
| yellowfive@57 | 244 	end | 
| yellowfive@57 | 245 | 
| yellowfive@57 | 246 	return ret | 
| yellowfive@57 | 247 end | 
| yellowfive@57 | 248 | 
| yellowfive@89 | 249 local function removeOwned(list, owned) | 
| yellowfive@89 | 250 | 
| yellowfive@89 | 251 	for itemId, count in pairs(list) do | 
| yellowfive@89 | 252 		-- load up how many of an item we have | 
| yellowfive@89 | 253 		if not owned.loaded[itemId] then | 
| yellowfive@89 | 254 			owned.counts[itemId] = getOwnedCount(itemId) | 
| yellowfive@89 | 255 			owned.loaded[itemId] = true | 
| yellowfive@89 | 256 		end | 
| yellowfive@89 | 257 | 
| yellowfive@89 | 258 		-- see how many we can remove from the required count | 
| yellowfive@89 | 259 		local used = math.min(owned.counts[itemId], count) | 
| yellowfive@89 | 260 | 
| yellowfive@89 | 261 		-- update owned count so we can't double-use something | 
| yellowfive@89 | 262 		owned.counts[itemId] = owned.counts[itemId] - used; | 
| yellowfive@89 | 263 | 
| yellowfive@89 | 264 		-- reduce the requirement, removing entirely if we have it completely covered | 
| yellowfive@89 | 265 		list[itemId] = list[itemId] - used; | 
| yellowfive@89 | 266 		if list[itemId] == 0 then | 
| yellowfive@89 | 267 			list[itemId] = nil | 
| yellowfive@89 | 268 		end | 
| yellowfive@89 | 269 	end | 
| yellowfive@89 | 270 end | 
| yellowfive@89 | 271 | 
| yellowfive@89 | 272 function Amr:RefreshShoppingUi() | 
| yellowfive@89 | 273 | 
| yellowfive@89 | 274 	-- clear out any previous data | 
| yellowfive@89 | 275 	_panelContent:ReleaseChildren() | 
| yellowfive@89 | 276 | 
| yellowfive@139 | 277 	local parts = { strsplit("@", _selectedSetup) } | 
| yellowfive@139 | 278 | 
| yellowfive@139 | 279 	local data = Amr.db.global.Shopping2[parts[1]].setups[parts[2]] | 
| yellowfive@89 | 280 	if not data then | 
| yellowfive@89 | 281 		_panelContent:SetLayout("None") | 
| yellowfive@89 | 282 | 
| yellowfive@89 | 283 		local lbl = AceGUI:Create("AmrUiLabel") | 
| yellowfive@124 | 284 		_panelContent:AddChild(lbl) | 
| yellowfive@89 | 285 		lbl:SetFont(Amr.CreateFont("Italic", 18, Amr.Colors.TextTan)) | 
| yellowfive@89 | 286 		lbl:SetText(L.ShopEmpty) | 
| yellowfive@89 | 287 		lbl:SetJustifyH("CENTER") | 
| yellowfive@89 | 288 		lbl:SetPoint("TOP", _panelContent.content, "TOP", 0, -30) | 
| yellowfive@89 | 289 	else | 
| yellowfive@89 | 290 		local allStuff = { gems = {}, enchants = {}, materials = {} } | 
| yellowfive@89 | 291 		local hasStuff = false | 
| yellowfive@89 | 292 		local visited = {} | 
| yellowfive@89 | 293 | 
| yellowfive@139 | 294 		for inventoryId, stuff in pairs(data) do | 
| yellowfive@139 | 295 			hasStuff = true | 
| yellowfive@139 | 296 			if not visited[inventoryId] then | 
| yellowfive@139 | 297 				if stuff.gems then | 
| yellowfive@139 | 298 					for itemId, count in pairs(stuff.gems) do | 
| yellowfive@139 | 299 						incrementTableItem(allStuff.gems, itemId, count) | 
| yellowfive@89 | 300 					end | 
| yellowfive@89 | 301 				end | 
| yellowfive@89 | 302 | 
| yellowfive@139 | 303 				if stuff.enchants then | 
| yellowfive@139 | 304 					for itemId, count in pairs(stuff.enchants) do | 
| yellowfive@139 | 305 						incrementTableItem(allStuff.enchants, itemId, count) | 
| yellowfive@139 | 306 					end | 
| yellowfive@139 | 307 				end | 
| yellowfive@139 | 308 | 
| yellowfive@139 | 309 				if stuff.materials then | 
| yellowfive@139 | 310 					for itemId, count in pairs(stuff.materials) do | 
| yellowfive@139 | 311 						incrementTableItem(allStuff.materials, itemId, count) | 
| yellowfive@139 | 312 					end | 
| yellowfive@139 | 313 				end | 
| yellowfive@139 | 314 | 
| yellowfive@139 | 315 				-- make sure not to count the same physical item twice | 
| yellowfive@139 | 316 				if inventoryId ~= -1 then | 
| yellowfive@139 | 317 					visited[inventoryId] = true | 
| yellowfive@139 | 318 				end | 
| yellowfive@89 | 319 			end | 
| yellowfive@89 | 320 		end | 
| yellowfive@89 | 321 | 
| yellowfive@89 | 322 		if hasStuff then | 
| yellowfive@89 | 323 			-- remove what we already own | 
| yellowfive@89 | 324 			local owned = { counts = {}, loaded = {} } | 
| yellowfive@89 | 325 			removeOwned(allStuff.gems, owned) | 
| yellowfive@89 | 326 			removeOwned(allStuff.enchants, owned) | 
| yellowfive@89 | 327 			removeOwned(allStuff.materials, owned) | 
| yellowfive@89 | 328 | 
| yellowfive@89 | 329 			_panelContent:SetLayout("Fill") | 
| yellowfive@89 | 330 | 
| yellowfive@89 | 331 			local scroll = AceGUI:Create("AmrUiScrollFrame") | 
| yellowfive@89 | 332 			scroll:SetLayout("List") | 
| yellowfive@89 | 333 			_panelContent:AddChild(scroll) | 
| yellowfive@89 | 334 | 
| yellowfive@89 | 335 			renderShopSection(allStuff.gems, scroll, L.ShopHeaderGems) | 
| yellowfive@89 | 336 			renderShopSection(allStuff.enchants, scroll, L.ShopHeaderEnchants) | 
| yellowfive@89 | 337 			renderShopSection(allStuff.materials, scroll, L.ShopHeaderMaterials) | 
| yellowfive@89 | 338 		end | 
| yellowfive@89 | 339 	end | 
| yellowfive@89 | 340 | 
| yellowfive@89 | 341 end | 
| yellowfive@89 | 342 | 
| yellowfive@124 | 343 -- compare gear to everything the player owns, and return the minimum gems/enchants/materials needed to optimize, | 
| yellowfive@124 | 344 -- grouped by inventory ID so that we can combine multiple specs without double-counting | 
| yellowfive@131 | 345 local function getShoppingData(player, gear) | 
| yellowfive@89 | 346 | 
| yellowfive@89 | 347 	local ret = {} | 
| yellowfive@89 | 348 | 
| yellowfive@89 | 349 	-- used to prevent considering the same item twice | 
| yellowfive@89 | 350 	local usedItems = {} | 
| yellowfive@89 | 351 | 
| yellowfive@89 | 352 	for slotId, optimalItem in pairs(gear) do | 
| yellowfive@124 | 353 		local matchItem = Amr:FindMatchingItem(optimalItem, player, usedItems) | 
| yellowfive@89 | 354 		local inventoryId = optimalItem.inventoryId or -1 | 
| yellowfive@89 | 355 | 
| yellowfive@89 | 356 		-- find gem/enchant differences on the best-matching item | 
| yellowfive@89 | 357 | 
| yellowfive@124 | 358 		-- gems | 
| yellowfive@124 | 359 		if not optimalItem.relicBonusIds and (not matchItem or not matchItem.relicBonusIds) then | 
| yellowfive@124 | 360 			for i = 1, 3 do | 
| yellowfive@89 | 361 				local g = optimalItem.gemIds[i] | 
| yellowfive@131 | 362 				local isGemEquipped = g == 0 or (matchItem and matchItem.gemIds and matchItem.gemIds[i] == g) | 
| yellowfive@89 | 363 				if not isGemEquipped then | 
| yellowfive@89 | 364 					if not ret[inventoryId] then | 
| yellowfive@89 | 365 						ret[inventoryId] = { gems = {}, enchants = {}, materials = {} } | 
| yellowfive@89 | 366 					end | 
| yellowfive@89 | 367 					incrementTableItem(ret[inventoryId].gems, g, 1) | 
| yellowfive@89 | 368 				end | 
| yellowfive@89 | 369 			end | 
| yellowfive@89 | 370 		end | 
| yellowfive@89 | 371 | 
| yellowfive@89 | 372 		-- enchant | 
| yellowfive@89 | 373 		if optimalItem.enchantId and optimalItem.enchantId ~= 0 then | 
| yellowfive@89 | 374 			local e = optimalItem.enchantId | 
| yellowfive@89 | 375 			local isEnchantEquipped = matchItem and matchItem.enchantId and matchItem.enchantId == e | 
| yellowfive@89 | 376 | 
| yellowfive@89 | 377 			if not isEnchantEquipped then | 
| yellowfive@124 | 378 				-- enchant info | 
| yellowfive@124 | 379 				local enchInfo = Amr.db.char.ExtraEnchantData[e] | 
| yellowfive@89 | 380 				if enchInfo then | 
| yellowfive@89 | 381 					if not ret[inventoryId] then | 
| yellowfive@89 | 382 						ret[inventoryId] = { gems = {}, enchants = {}, materials = {} } | 
| yellowfive@89 | 383 					end | 
| yellowfive@89 | 384 					incrementTableItem(ret[inventoryId].enchants, enchInfo.itemId, 1) | 
| yellowfive@89 | 385 | 
| yellowfive@89 | 386 					if enchInfo.materials then | 
| yellowfive@89 | 387 						for k, v in pairs(enchInfo.materials) do | 
| yellowfive@89 | 388 							incrementTableItem(ret[inventoryId].materials, k, v) | 
| yellowfive@89 | 389 						end | 
| yellowfive@89 | 390 					end | 
| yellowfive@89 | 391 				end | 
| yellowfive@89 | 392 			end | 
| yellowfive@89 | 393 		end | 
| yellowfive@89 | 394 	end | 
| yellowfive@89 | 395 | 
| yellowfive@89 | 396 	return ret | 
| yellowfive@89 | 397 end | 
| yellowfive@89 | 398 | 
| yellowfive@139 | 399 -- look at all gear sets and find stuff that a player needs to acquire to gem/enchant their gear for each setup | 
| yellowfive@57 | 400 function Amr:UpdateShoppingData(player) | 
| yellowfive@57 | 401 | 
| yellowfive@57 | 402 	local required = { | 
| yellowfive@139 | 403 		setups = {} | 
| yellowfive@57 | 404 	} | 
| yellowfive@139 | 405 | 
| yellowfive@139 | 406 	for i, setup in ipairs(Amr.db.char.GearSetups) do | 
| yellowfive@139 | 407 		local gear = setup.Gear | 
| yellowfive@124 | 408 		if gear then | 
| yellowfive@139 | 409 			required.setups[setup.Label] = getShoppingData(player, gear) | 
| yellowfive@124 | 410 		end | 
| yellowfive@57 | 411 	end | 
| yellowfive@139 | 412 | 
| yellowfive@139 | 413 	Amr.db.global.Shopping2[player.Name .. "-" .. player.Realm] = required | 
| yellowfive@57 | 414 end | 
| yellowfive@57 | 415 | 
| yellowfive@57 | 416 Amr:AddEventHandler("AUCTION_HOUSE_SHOW", function() | 
| yellowfive@57 | 417 	_isAhOpen = true | 
| yellowfive@57 | 418 	if Amr.db.profile.options.shopAh then | 
| yellowfive@57 | 419 		Amr:ShowShopWindow() | 
| yellowfive@57 | 420 	end | 
| yellowfive@57 | 421 end) | 
| yellowfive@57 | 422 | 
| yellowfive@57 | 423 Amr:AddEventHandler("AUCTION_HOUSE_CLOSED", function() | 
| yellowfive@57 | 424 	_isAhOpen = false | 
| yellowfive@57 | 425 	if Amr.db.profile.options.shopAh then | 
| yellowfive@57 | 426 		Amr:HideShopWindow() | 
| yellowfive@57 | 427 	end | 
| yellowfive@122 | 428 end) |