Quantcast
-- $Revision: 194 $
-- Cauldron shopping list functions

CauldronShopping = {};

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

--[[
	list = {
		["<requestor>"] = {
			["<item name>"] = <quantity>,
			["<item name>"] = <quantity>,
			...
		},
		["<requestor>"] = {
			...
		},
	};
--]]

function CauldronShopping:NewList()

	local list = {};

	return list;
end

function CauldronShopping:AddToList(list, requestor, itemName, quantity)

	-- sanity checks
	if (not list) and (not requestor) and (not itemName) then
		Cauldron:error("No shopping list available!");
		return;
	end

	quantity = math.max(1, tonumber(quantity) or 1);

	if not list[requestor] then
		-- initialize the list for the requestor
		list[requestor] = {};
	end

	if list[requestor][itemName] then
		list[requestor][itemName] = list[requestor][itemName] + quantity;
	else
		list[requestor][itemName] = quantity;
	end

end

function CauldronShopping:RemoveFromList(list, requestor, itemName, quantity)
	-- sanity checks
	if not list then
		Cauldron:error("No shopping list available!");
		return -1;
	end

	if not list[requestor] then
		-- initialize the list for the requestor
		list[requestor] = {};
	end

	local numRemoved = 0;

	if list[requestor][itemName] then
		if quantity then
			local origQty = list[requestor][itemName];
			list[requestor][itemName] = list[requestor][itemName] - quantity;
			numRemoved = quantity;
			if list[requestor][itemName] < 1 then
				numRemoved = origQty;
				list[requestor][itemName] = nil;
			end
		else
			numRemoved = list[requestor][itemName];
			list[requestor][itemName] = nil;
		end
	end

	return numRemoved;
end

function CauldronShopping:GetRequestors(list)

	if not list then
		Cauldron:error("No shopping list available!");
		return;
	end

	local requestors = {};

	for name, _ in pairs(list) do
		table.insert(requestors, name);
	end

	return requestors;
end

function CauldronShopping:ContainsItems(list)

	if not list then
		Cauldron:warn("CauldronShopping:ContainsItems: missing list!");
		return false;
	end

	for _, items in pairs(list) do
		for _, amount in pairs(items) do
			if amount > 0 then
				return true;
			end
		end
	end

	return false;
end

function CauldronShopping:HasItems(list, requestor)

	if not list then
		Cauldron:warn("CauldronShopping:HasItems: missing list!");
		return false;
	end

	if list[requestor] then
		for _, amount in pairs(list[requestor]) do
			if amount > 0 then
				return true;
			end
		end
	end

	return false;
end

function CauldronShopping:GetRequestedItems(list, requestor)

	if not list then
		Cauldron:warn("CauldronShopping:HasItems: missing list!");
		return false;
	end

	if list[requestor] then
	    return list[requestor];
	end

	return {};
end

function CauldronShopping:EmptyShoppingList(list, requestor)

	if not list then
		Cauldron:warn("CauldronShopping:EmptyShoppingList: missing list!");
		return;
	end

	for r, _ in pairs(list) do
		if requestor then
			if requestor == r then
				list[r] = nil;
			end
		else
			list[r] = nil;
		end
	end

end

function CauldronShopping:AutoBuyShoppingItems(list, requestor)

	if not list then
		Cauldron:warn("CauldronShopping:AutoBuyShoppingItems: missing list!");
		return;
	end

	local merchant = Cauldron:GetMerchantItems();

	--[[
	-- TODO: remove
	-- store merchant items in the DB
	if not Cauldron.db.realm.userdata[Cauldron.vars.playername].merchant then
		Cauldron.db.realm.userdata[Cauldron.vars.playername].merchant = {};
	end
	for item, info in pairs(merchant) do
		Cauldron.db.realm.userdata[Cauldron.vars.playername].merchant[item] = info;
	end
	--]]

	-- iterate over shopping list
	if list[requestor] then
		for item, amount in pairs(list[requestor]) do
			-- check if the merchant has the item and it can be purchased
			if merchant[item] then
				-- check if the toon has enough of the item already
				-- local counts = Cauldron:ReagentCount(item);
				-- if counts.total < amount then
					CauldronShopping:BuyItem(item, merchant[item], amount); -- amount - counts.total
				-- end
			end
		end
	end

end

function CauldronShopping:BuyItem(item, merchInfo, amount)

	if (not merchInfo) or (not amount) then
		Cauldron:warn("CauldronShopping:BuyItem: missing merchant item info or invalid amount!");
		return;
	end
	if amount < 1 then
		-- just return with an error
		return;
	end

	-- figure out how many to purchase, accounting for stacks
	local stacks = 1;
	local purchases = 1;
	local tempAmount = amount;
	Cauldron:debug("tempAmount="..tostring(tempAmount));
	local maxStack = 1;

	if amount > 1 then
		Cauldron:debug("item="..tostring(item));
		_,_,_,_,_,_,_,maxStack = GetItemInfo(item);
		Cauldron:debug("maxStack="..tostring(maxStack));

		if maxStack then
			purchases = ceil((amount / maxStack) / merchInfo.quantity);
			Cauldron:debug("purchases="..tostring(purchases));
		else
			maxStack = 1;
			Cauldron:debug("setting maxStack to 1");
		end
		--[[
i="Arcane Powder"
o=40-GetItemCount(i)
b=o
_,_,_,_,_,_,_,s=GetItemInfo(i)
for c=1,GetMerchantNumItems() do
n,_,_,q=GetMerchantItemInfo(c)
if n==i then
for r=1,ceil((o/s)/q) do
BuyMerchantItem(c,b>=s and s/q or ceil(b/q))
b=b-s
end
end
end
		--]]
	end

	local total = purchases * merchInfo.quantity;
	Cauldron:debug("total="..tostring(total));

	local qtyInfo = string.format(L["(%1$d total)"], total);
	Cauldron:debug("qtyInfo="..tostring(qtyInfo));
	if purchases > 1 then
		qtyInfo = string.format(L["(%1$d stacks, %2$d total)"], purchases, total);
		Cauldron:debug("qtyInfo="..tostring(qtyInfo));
	end

	-- tell the user, because that's the right thing to do
	Cauldron:Print(string.format(L["Purchasing %1$s from merchant %2$s..."], item, qtyInfo));

	-- buy the items
	for i=1,purchases do
		stacks = tempAmount >= maxStack and maxStack / merchInfo.quantity or ceil(tempAmount / merchInfo.quantity);
		Cauldron:debug("stacks="..tostring(stacks));

		BuyMerchantItem(merchInfo.index, stacks);

		tempAmount = tempAmount - maxStack;
		Cauldron:debug("tempAmount="..tostring(tempAmount));
	end

end