Quantcast
-- $Revision: 206 $
-- Cauldron utility functions

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

function Cauldron:IsVendorItem(item)

	if (not item) or (type(item) ~= "number") then
		return false;
	end

	for _,num in ipairs(Cauldron.vars.vendoritems) do
		if num == item then
			return true;
		end
	end

	self:debug("not found");
	return false;
end

function Cauldron:GetAltReagentCount(reagentInfo)
	self:debug("GetAltReagentCount enter");

	-- TODO

	self:debug("GetAltReagentCount exit");
end

function Cauldron:GetPotentialCraftCount(skillInfo)
	self:debug("GetPotentialCraftCount enter");

	local count = 0;

	-- a place to store count values
	local c = {};

	-- iterate over the reagent list and find out how many can be made for each reagent count;
	-- the lowest value is the potential amount craftable; only count a skill if it has more
	-- than one reagent, and is a key reagent
	if #skillInfo.reagents > 1 then
		for i,rinfo in ipairs(skillInfo.reagents) do
			-- only count "key" reagents
			if rinfo.key then
				local counts = Cauldron:ReagentCount(rinfo.name);
				local makeable = math.floor(counts.has / rinfo.numRequired);

				table.insert(c, makeable);

				--[[
				if (makeable > 0) and (count > 0) and (makeable < count) then
					count = makeable;
				end
				--]]
			end
		end

		-- sort the table
		table.sort(c);

		-- if there are any results, get the first, because it will be the lowest number
		if #c > 0 then
			count = c[1];
		end
	end

	--[[
	if count == 999999 then
		count = 0;
	end
	--]]

	self:debug("GetPotentialCraftCount exit");

	return count;
end

function Cauldron:ReagentCount(reagent)

	local count = {
		has = 0,
		bank = 0,
		guildBank = 0,
		mail = 0,
		altHas = {},
		total = 0,
	};

	-- sanity checks
	if not reagent then
		self:debug("No reagent specified for count!");
		return count;
	end

	count.has = GetItemCount(reagent, false);
	count.bank = GetItemCount(reagent, true) - count.has;

	-- total up
	count.total = count.has + count.bank + count.guildBank + count.mail;
	--[[
	for alt,altCount in pairs(count.altHas) do
		count.total = count.total + altCount;
	end
	--]]

	return count;
end

function Cauldron:SkillContainsText(recipe, text)

	-- sanity checks
	if (not recipe) or (not text) then
		-- TODO: display error
		return false;
	end

	if string.find(recipe.name, text) then
		return true;
	end

	for i, reagent in ipairs(recipe.reagents) do
		if string.find(reagent.name, text) then
			return true;
		end
	end

	-- TODO: check flavor text?

	return false;
end

function Cauldron:GetIdFromLink(link)
  	if not link then return end
--  local _,_,id,name = strfind(link,"|Hitem:(%d+):.+%[(.+)%]");
  	local _,_,id = strfind(link,"item:(%d+):");
  	if not id then
--  	local _,_,id,name = strfind(link,"|Henchant:(%d+)|h%[(.+)%]");
  		local _,_,id = strfind(link,"enchant:(%d+)");
	  	if id then return tonumber(id) end
	else
		return tonumber(id);
	end
end

function Cauldron:GetNameFromLink(link)
	if not link then return end
  	local _,_,name = strfind(link,"|Hitem:.+%[(.+)%]");
  	if not name then
  		_,_,name = strfind(link,"|Henchant:.+%[(.+)%]");
  	end
	return name;
end

function Cauldron:GetSpellNameFromLink(link)
	if not link then return end
  	local _,_,name = strfind(link,"|Henchant:.+%[.+: (.+)%]");
	return name;
end

function Cauldron:ScanBags()

	-- reset inventory
	self.vars.inventory = {};

	-- process keyring and inventory bags
	for _,bagid in ipairs({-2,0,1,2,3,4}) do
		-- iterate over bag
		for i=1,GetContainerNumSlots(bagid) do
			local link = GetContainerItemLink(bagid, i);
			if link then
				local name = Cauldron:GetNameFromLink(link);
				if name then
					local count = GetItemCount(link);

					self.vars.inventory[name] = count;
				end
			end
		end
	end

end

function Cauldron:GetItemDeltas(bagid)

	-- sanity checks
	if not bagid then
		self:error("No bag ID specified!");
		return {};
	end

	local deltas = {};

	if not self.vars.inventory then
		self.vars.inventory = {};
	end
	local inv = self.vars.inventory;

	for i=1,GetContainerNumSlots(bagid) do
		local link = GetContainerItemLink(bagid, i);
		if link then
			local name = Cauldron:GetNameFromLink(link);
			if name then
				local count = GetItemCount(link);
				-- local count = select(2, {GetContainerItemInfo(bagid, i)});

				local delta = count;
				if inv[name] then
					delta = count - inv[name];
				end

				if delta ~= 0 then
					-- save the delta information
					deltas[name] = delta;
				end
			end
		end
	end

	return deltas;
end

function Cauldron:GetMerchantItems()

	local items = {};

	for i=1,GetMerchantNumItems() do
		local name, _, price, quantity, avail, _, extCost = GetMerchantItemInfo(i);
		-- Cauldron:info("MERCHANT: item="..name.."; price="..tostring(price).."; quantity="..tostring(quantity).."; avail="..tostring(avail).."; extCost="..tostring(extCost));
		local maxStack = GetMerchantItemMaxStack(i);

		if (avail ~= 0) and name then
			items[name] = {
				['index'] = i,
				['price'] = price,
				['quantity'] = quantity,
				['available'] = avail,
				['maxStack'] = maxStack,
			};
		end
	end

	return items;
end

function Cauldron:SortTableIndices(t)

	if not t then
		return {};
	end

	local a = {};

	for n in pairs(t) do
		a[#a + 1] = n;
	end

	table.sort(a);

	return a;
end

function Cauldron:CreateAchievementSkillMap()

	Cauldron.vars.achievementMap = {};

	-- TODO: get all achievement categories that have 169 (Professions) as parent
	-- currently: 171 (Fishing), 170 (Cooking), 172 (First Aid)
	local categories = { 170, 171, 172 };

	for _,categoryID in ipairs(categories) do
		-- get the number of achievements in this category
		local numAchievements = GetCategoryNumAchievements(categoryID);
		for i=1,numAchievements do
			-- get the achievements in the category
			local achievementID,_,_,achievementCompleted,_,_,_,_,_,_,_ = GetAchievementInfo(categoryID, i);
			if not achievementCompleted then
				local numCriteria = GetAchievementNumCriteria(achievementID);
				for j=1,numCriteria do
					-- get the criteria of the achievement
					local criteriaString,criteriaType,criteriaCompleted,_,_,_,_,assetID,_,criteriaID = GetAchievementCriteriaInfo(achievementID, j);

					-- check if the achievement has been completed
					if not criteriaCompleted then
						-- check if the criteria is the right type
						if criteriaType == 29 or criteriaType == 112 then
							if not Cauldron.vars.achievementMap[criteriaString] then
								Cauldron.vars.achievementMap[criteriaString] = {};
							end

							table.insert(Cauldron.vars.achievementMap[criteriaString], achievementID);
						end
					end
				end
			end
		end
	end

end

function Cauldron:GetAchievementsForSkill(skillInfo)

	if not skillInfo then
		return nil;
	end

	return Cauldron.vars.achievementMap[skillInfo.name];
end

function Cauldron:GetAutoBuy()
	return Cauldron.db.realm.userdata[Cauldron.vars.playername].options.autoBuy;
end

function Cauldron:MarkRecipeForRescan(skillDB, name)

	if not skillDB then
		return;
	end

	-- store rescan info
	if not skillDB.rescan then
		skillDB.rescan = {
			failedRecipes = {},
		};
	end

	-- record the failed recipe
	skillDB.rescan.failedRecipes[name] = true;
end

function Cauldron:JoinStrings(strings, sep)

	local joinedStr = "";

	for i,str in ipairs(strings) do
		if i > 1 then
			joinedStr = joinedStr..sep;
		end

		joinedStr = joinedStr..str;
	end

	return joinedStr;
end