Quantcast
--[[
Jamba - Jafula's Awesome Multi-Boxer Assistant
Copyright 2008 - 2018 Michael "Jafula" Miller
License: The MIT License
]]--

-- Create the addon using AceAddon-3.0 and embed some libraries.
local AJM = LibStub( "AceAddon-3.0" ):NewAddon(
	"JambaPurchase",
	"JambaModule-1.0",
	"AceConsole-3.0",
	"AceEvent-3.0"
)

-- Load libraries.
local JambaUtilities = LibStub:GetLibrary( "JambaUtilities-1.0" )
local JambaHelperSettings = LibStub:GetLibrary( "JambaHelperSettings-1.0" )
local LibBagUtils = LibStub:GetLibrary( "LibBagUtils-1.0" )
local AceGUI = LibStub:GetLibrary( "AceGUI-3.0" )

--  Constants and Locale for this module.
AJM.moduleName = "Jamba-Purchase"
AJM.settingsDatabaseName = "JambaPurchaseProfileDB"
AJM.chatCommand = "jamba-purchase"
local L = LibStub( "AceLocale-3.0" ):GetLocale( AJM.moduleName )
AJM.parentDisplayName = L["Merchant"]
AJM.moduleDisplayName = L["Purchase"]

-- Settings - the values to store and their defaults for the settings database.
AJM.settings = {
	profile = {
		autoBuy = false,
		autoBuyOverflow = true,
		messageArea = JambaApi.DefaultMessageArea(),
		autoBuyItems = {}
	},
}

-- Configuration.
function AJM:GetConfiguration()
	local configuration = {
		name = AJM.moduleDisplayName,
		handler = AJM,
		type = 'group',
		childGroups  = "tab",
		get = "JambaConfigurationGetSetting",
		set = "JambaConfigurationSetSetting",
		args = {
			--[[
			popout = {
				type = "input",
				name = L["PopOut"],
				desc = L["Show the purchase settings in their own window."],
				usage = "/jamba-purchase popout",
				get = false,
				set = "ShowPopOutWindow",
			},
			]]--
			push = {
				type = "input",
				name = L["Push Settings"],
				desc = L["Push the purchase settings to all characters in the team."],
				usage = "/jamba-purchase push",
				get = false,
				set = "JambaSendSettings",
			},
		},
	}
	return configuration
end

-------------------------------------------------------------------------------------------------------------
-- Command this module sends.
-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------
-- Messages module sends.
-------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------
-- Purchase Management.
-------------------------------------------------------------------------------------------------------------

function AJM:BeforeJambaProfileChanged()
end

function AJM:OnJambaProfileChanged()
	AJM:SettingsRefresh()
end

function AJM:SettingsRefresh()
	AJM.settingsControl.checkBoxAutoBuy:SetValue( AJM.db.autoBuy )
	AJM.settingsControl.checkBoxAutoBuyOverflow:SetValue( AJM.db.autoBuyOverflow )
	AJM.settingsControl.editBoxTag:SetText( AJM.autoBuyItemTag )
	AJM.settingsControl.editBoxAmount:SetText( AJM.autoBuyAmount )
	AJM.settingsControl.dropdownMessageArea:SetValue( AJM.db.messageArea )
	AJM.settingsControl.checkBoxAutoBuyOverflow:SetDisabled( not AJM.db.autoBuy )
	AJM.settingsControl.editBoxItem:SetDisabled( not AJM.db.autoBuy )
	AJM.settingsControl.editBoxTag:SetDisabled( not AJM.db.autoBuy )
	AJM.settingsControl.editBoxAmount:SetDisabled( not AJM.db.autoBuy )
	AJM.settingsControl.buttonRemove:SetDisabled( not AJM.db.autoBuy )
	AJM.settingsControl.buttonAdd:SetDisabled( not AJM.db.autoBuy )
	AJM:SettingsScrollRefresh()
end

-- Settings received.
function AJM:JambaOnSettingsReceived( characterName, settings )
	if characterName ~= AJM.characterName then
		-- Update the settings.
		AJM.db.autoBuy = settings.autoBuy
		AJM.db.autoBuyOverflow = settings.autoBuyOverflow
		AJM.db.messageArea = settings.messageArea
		AJM.db.autoBuyItems = JambaUtilities:CopyTable( settings.autoBuyItems )
		-- Refresh the settings.
		AJM:SettingsRefresh()
		-- Tell the player.
		AJM:Print( L["Settings received from A."]( characterName ) )
		-- Tell the team?
		--AJM:JambaSendMessageToTeam( AJM.db.messageArea,  L["Settings received from A."]( characterName ), false )
	end
end

-------------------------------------------------------------------------------------------------------------
-- Settings Dialogs.
-------------------------------------------------------------------------------------------------------------

local function SettingsCreateOptions( top )
	-- Position and size constants.
	local buttonControlWidth = 105
	local checkBoxHeight = JambaHelperSettings:GetCheckBoxHeight()
	local buttonHeight = JambaHelperSettings:GetButtonHeight()
	local editBoxHeight = JambaHelperSettings:GetEditBoxHeight()
	local dropdownHeight = JambaHelperSettings:GetDropdownHeight()
	local left = JambaHelperSettings:LeftOfSettings()
	local headingHeight = JambaHelperSettings:HeadingHeight()
	local headingWidth = JambaHelperSettings:HeadingWidth( false )
	local horizontalSpacing = JambaHelperSettings:GetHorizontalSpacing()
	local verticalSpacing = JambaHelperSettings:GetVerticalSpacing()
	local halfWidth = (headingWidth - horizontalSpacing) / 2
	local left2 = left + halfWidth + horizontalSpacing
	local movingTop = top
	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Purchase Items"], movingTop, false )
	movingTop = movingTop - headingHeight
	AJM.settingsControl.checkBoxAutoBuy = JambaHelperSettings:CreateCheckBox(
		AJM.settingsControl,
		halfWidth,
		left,
		movingTop,
		L["Auto Buy Items"],
		AJM.SettingsToggleAutoBuyItems
	)
	AJM.settingsControl.checkBoxAutoBuyOverflow = JambaHelperSettings:CreateCheckBox(
		AJM.settingsControl,
		halfWidth,
		left2,
		movingTop,
		L["Overflow"],
		AJM.SettingsToggleAutoBuyItemsOverflow
	)
	movingTop = movingTop - checkBoxHeight
	AJM.settingsControl.highlightRow = 1
	AJM.settingsControl.offset = 1
	local list = {}
	list.listFrameName = "JambaPurchaseSettingsFrame"
	list.parentFrame = AJM.settingsControl.widgetSettings.content
	list.listTop = movingTop
	list.listLeft = left
	list.listWidth = headingWidth
	list.rowHeight = 20
	list.rowsToDisplay = 8
	list.columnsToDisplay = 3
	list.columnInformation = {}
	list.columnInformation[1] = {}
	list.columnInformation[1].width = 60
	list.columnInformation[1].alignment = "LEFT"
	list.columnInformation[2] = {}
	list.columnInformation[2].width = 10
	list.columnInformation[2].alignment = "RIGHT"
	list.columnInformation[3] = {}
	list.columnInformation[3].width = 30
	list.columnInformation[3].alignment = "LEFT"
	list.scrollRefreshCallback = AJM.SettingsScrollRefresh
	list.rowClickCallback = AJM.SettingsRowClick
	AJM.settingsControl.list = list
	JambaHelperSettings:CreateScrollList( AJM.settingsControl.list )
	movingTop = movingTop - list.listHeight - verticalSpacing
	AJM.settingsControl.buttonRemove = JambaHelperSettings:CreateButton(
		AJM.settingsControl,
		buttonControlWidth,
		left,
		movingTop,
		L["Remove"],
		AJM.SettingsRemoveClick
	)
	movingTop = movingTop -	buttonHeight - verticalSpacing
	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Add Item"], movingTop, false )
	movingTop = movingTop - headingHeight
	AJM.settingsControl.editBoxItem = JambaHelperSettings:CreateEditBox(
		AJM.settingsControl,
		headingWidth,
		left,
		movingTop,
		L["Item (drag item to box from your bags)"]
	)
	AJM.settingsControl.editBoxItem:SetCallback( "OnEnterPressed", AJM.SettingsEditBoxChangedItem )
	movingTop = movingTop - editBoxHeight
	AJM.settingsControl.editBoxTag = JambaHelperSettings:CreateEditBox(
		AJM.settingsControl,
		halfWidth,
		left,
		movingTop,
		L["Tag"]
	)
	AJM.settingsControl.editBoxTag:SetCallback( "OnEnterPressed", AJM.SettingsEditBoxChangedTag )
	AJM.settingsControl.editBoxAmount = JambaHelperSettings:CreateEditBox(
		AJM.settingsControl,
		halfWidth,
		left2,
		movingTop,
		L["Amount"]
	)
	AJM.settingsControl.editBoxAmount:SetCallback( "OnEnterPressed", AJM.SettingsEditBoxChangedAmount )
	movingTop = movingTop - editBoxHeight
	AJM.settingsControl.buttonAdd = JambaHelperSettings:CreateButton(
		AJM.settingsControl,
		buttonControlWidth,
		left,
		movingTop,
		L["Add"],
		AJM.SettingsAddClick
	)
	movingTop = movingTop -	buttonHeight
	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Purchase Messages"], movingTop, false )
	movingTop = movingTop - headingHeight
	AJM.settingsControl.dropdownMessageArea = JambaHelperSettings:CreateDropdown(
		AJM.settingsControl,
		headingWidth,
		left,
		movingTop,
		L["Message Area"]
	)
	AJM.settingsControl.dropdownMessageArea:SetList( JambaApi.MessageAreaList() )
	AJM.settingsControl.dropdownMessageArea:SetCallback( "OnValueChanged", AJM.SettingsSetMessageArea )
	movingTop = movingTop - dropdownHeight - verticalSpacing
	return movingTop
end

function AJM:OnMessageAreasChanged( message )
	AJM.settingsControl.dropdownMessageArea:SetList( JambaApi.MessageAreaList() )
end

local function SettingsCreate()
	AJM.settingsControl = {}
	JambaHelperSettings:CreateSettings(
		AJM.settingsControl,
		AJM.moduleDisplayName,
		AJM.parentDisplayName,
		AJM.SettingsPushSettingsClick
	)
	local bottomOfSettings = SettingsCreateOptions( JambaHelperSettings:TopOfSettings() )
	AJM.settingsControl.widgetSettings.content:SetHeight( -bottomOfSettings )
	-- Help
	local helpTable = {}
	JambaHelperSettings:CreateHelp( AJM.settingsControl, helpTable, AJM:GetConfiguration() )
end

-------------------------------------------------------------------------------------------------------------
-- Settings Callbacks.
-------------------------------------------------------------------------------------------------------------

function AJM:SettingsScrollRefresh()
	FauxScrollFrame_Update(
		AJM.settingsControl.list.listScrollFrame,
		AJM:GetItemsMaxPosition(),
		AJM.settingsControl.list.rowsToDisplay,
		AJM.settingsControl.list.rowHeight
	)
	AJM.settingsControl.offset = FauxScrollFrame_GetOffset( AJM.settingsControl.list.listScrollFrame )
	for iterateDisplayRows = 1, AJM.settingsControl.list.rowsToDisplay do
		-- Reset.
		AJM.settingsControl.list.rows[iterateDisplayRows].columns[1].textString:SetText( "" )
		AJM.settingsControl.list.rows[iterateDisplayRows].columns[1].textString:SetTextColor( 1.0, 1.0, 1.0, 1.0 )
		AJM.settingsControl.list.rows[iterateDisplayRows].columns[2].textString:SetText( "" )
		AJM.settingsControl.list.rows[iterateDisplayRows].columns[2].textString:SetTextColor( 1.0, 1.0, 1.0, 1.0 )
		AJM.settingsControl.list.rows[iterateDisplayRows].columns[3].textString:SetText( "" )
		AJM.settingsControl.list.rows[iterateDisplayRows].columns[3].textString:SetTextColor( 1.0, 1.0, 1.0, 1.0 )
		AJM.settingsControl.list.rows[iterateDisplayRows].highlight:SetColorTexture( 0.0, 0.0, 0.0, 0.0 )
		-- Get data.
		local dataRowNumber = iterateDisplayRows + AJM.settingsControl.offset
		if dataRowNumber <= AJM:GetItemsMaxPosition() then
			-- Put data information into columns.
			local itemInformation = AJM:GetItemAtPosition( dataRowNumber )
			AJM.settingsControl.list.rows[iterateDisplayRows].columns[1].textString:SetText( itemInformation.name )
			AJM.settingsControl.list.rows[iterateDisplayRows].columns[2].textString:SetText( itemInformation.amount )
			AJM.settingsControl.list.rows[iterateDisplayRows].columns[3].textString:SetText( itemInformation.tag )
			-- Highlight the selected row.
			if dataRowNumber == AJM.settingsControl.highlightRow then
				AJM.settingsControl.list.rows[iterateDisplayRows].highlight:SetColorTexture( 1.0, 1.0, 0.0, 0.5 )
			end
		end
	end
end

function AJM:SettingsRowClick( rowNumber, columnNumber )
	if AJM.settingsControl.offset + rowNumber <= AJM:GetItemsMaxPosition() then
		AJM.settingsControl.highlightRow = AJM.settingsControl.offset + rowNumber
		AJM:SettingsScrollRefresh()
	end
end

function AJM:SettingsPushSettingsClick( event )
	AJM:JambaSendSettings()
end

function AJM:SettingsSetMessageArea( event, value )
	AJM.db.messageArea = value
	AJM:SettingsRefresh()
end

function AJM:SettingsToggleAutoBuyItems( event, checked )
	AJM.db.autoBuy = checked
	AJM:SettingsRefresh()
end

function AJM:SettingsToggleAutoBuyItemsOverflow( event, checked )
	AJM.db.autoBuyOverflow = checked
	AJM:SettingsRefresh()
end

function AJM:SettingsRemoveClick( event )
	StaticPopup_Show( "JAMBAPURCHASE_CONFIRM_REMOVE_AUTO_BUY_ITEM" )
end

function AJM:SettingsEditBoxChangedItem( event, text )
	AJM.autoBuyItemLink = text
	AJM:SettingsRefresh()
end

function AJM:SettingsEditBoxChangedTag( event, text )
	if not text or text:trim() == "" or text:find( "%W" ) ~= nil then
		AJM:Print( L["Item tags must only be made up of letters and numbers."] )
		return
	end
	AJM.autoBuyItemTag = text
	AJM:SettingsRefresh()
end

function AJM:SettingsEditBoxChangedAmount( event, text )
	if not text or text:trim() == "" or text:find( "^(%d+)$" ) == nil then
		AJM:Print( L["Amount to buy must be a number."] )
		return
	end
	AJM.autoBuyAmount = text
	AJM:SettingsRefresh()
end

function AJM:SettingsAddClick( event )
	if AJM.autoBuyItemLink ~= nil and AJM.autoBuyItemTag ~= nil then
		AJM:AddItem( AJM.autoBuyItemLink, AJM.autoBuyItemTag, AJM.autoBuyAmount )
		AJM.autoBuyItemLink = nil
		AJM.settingsControl.editBoxItem:SetText( "" )
		AJM:SettingsRefresh()
	end
end

-------------------------------------------------------------------------------------------------------------
-- Popup Dialogs.
-------------------------------------------------------------------------------------------------------------

-- Initialize Popup Dialogs.
local function InitializePopupDialogs()
	StaticPopupDialogs["JAMBAPURCHASE_CONFIRM_REMOVE_AUTO_BUY_ITEM"] = {
        text = L["Are you sure you wish to remove the selected item from the auto buy items list?"],
        button1 = YES,
        button2 = NO,
        timeout = 0,
		whileDead = 1,
		hideOnEscape = 1,
        OnAccept = function()
			AJM:RemoveItem()
		end,
    }
end

-------------------------------------------------------------------------------------------------------------
-- Addon initialization, enabling and disabling.
-------------------------------------------------------------------------------------------------------------

-- Initialise the module.
function AJM:OnInitialize()
	AJM.autoBuyItemTag = JambaApi.AllTag()
	AJM.autoBuyItemLink = nil
	AJM.autoBuyAmount = 20
	-- Create the settings control.
	SettingsCreate()
	-- Initialise the JambaModule part of this module.
	AJM:JambaModuleInitialize( AJM.settingsControl.widgetSettings.frame )
	-- Initialise the popup dialogs.
	InitializePopupDialogs()
	-- Populate the settings.
	AJM:SettingsRefresh()
	-- Create a standalone window for the purchase.
	--[[
	AJM.standaloneWindow = AceGUI:Create( "Window" )
	AJM.standaloneWindow:Hide()
	AJM.standaloneWindow:SetTitle( "Jamba-Purchase" )
	AJM.standaloneWindow:SetLayout( "Fill" )
	AJM.standaloneWindow:AddChild( AJM.settingsControl.widgetSettings )
	AJM.standaloneWindow:SetHeight( 410 )
	AJM.standaloneWindow:SetWidth( 410 )
	AJM.standaloneWindow.frame:SetFrameStrata( "HIGH" )
	]]--
end

-- Called when the addon is enabled.
function AJM:OnEnable()
	AJM:RegisterEvent( "MERCHANT_SHOW" )
	AJM:RegisterMessage( JambaApi.MESSAGE_MESSAGE_AREAS_CHANGED, "OnMessageAreasChanged" )
end

-- Called when the addon is disabled.
function AJM:OnDisable()
end

-------------------------------------------------------------------------------------------------------------
-- JambaPurchase functionality.
-------------------------------------------------------------------------------------------------------------

function AJM:ShowPopOutWindow()
	--AJM.standaloneWindow:Show()
end

function AJM:GetItemsMaxPosition()
	return #AJM.db.autoBuyItems
end

function AJM:GetItemAtPosition( position )
	return AJM.db.autoBuyItems[position]
end

function AJM:AddItem( itemLink, itemTag, amountToBuy )
	-- Get some more information about the item.
	local name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice = GetItemInfo( itemLink )
	-- If the item could be found.
	if name ~= nil then
		local itemInformation = {}
		itemInformation.link = itemLink
		itemInformation.name = name
		itemInformation.tag = itemTag
		itemInformation.amount = amountToBuy
		table.insert( AJM.db.autoBuyItems, itemInformation )
		AJM:SettingsRefresh()
		AJM:SettingsRowClick( 1, 1 )
	end
end

function AJM:RemoveItem()
	table.remove( AJM.db.autoBuyItems, AJM.settingsControl.highlightRow )
	AJM:SettingsRefresh()
	AJM:SettingsRowClick( 1, 1 )
end

function AJM:MERCHANT_SHOW()
	if AJM.db.autoBuy == true then
		AJM:DoMerchantAutoBuy()
	end
end

-- A Jamba command has been recieved.
function AJM:JambaOnCommandReceived( characterName, commandName, ... )
end

function AJM:DoMerchantAutoBuy()
	-- Flags will be set if the character does not have enough bag space or money.
	local outOfBagSpace = false
	local outOfMoney = false
	local outOfOtherCurrency = false
	-- Iterate all the wanted items...
	for position, itemInfoTable in pairs( AJM.db.autoBuyItems ) do
		local maxItemAmount = tonumber( itemInfoTable.amount )
		local itemTag = itemInfoTable.tag
		local itemLink = itemInfoTable.link
		-- Does this character have the item tag?  No, don't buy.
		if JambaApi.DoesCharacterHaveTag( AJM.characterName, itemTag ) then
			-- Does the merchant have the item in stock?
			local itemIndexMerchant = AJM:DoesMerchantHaveItemInStock( itemLink )
			if itemIndexMerchant ~= nil then
				-- Yes, item is in stock, how many does the character need?
				local amountNeeded = AJM:GetAmountNeededForItemTopUp( itemLink, maxItemAmount )
				-- Need more than 0 items, buy them.
				if amountNeeded > 0 then
					-- Attempt to buy the items.
					local noFreeBagSpace, notEnoughMoney, notEnoughOtherCurrency = AJM:BuyItemFromMerchant( itemIndexMerchant, amountNeeded )
					-- Set flags if problems occurred.
					if noFreeBagSpace then
						outOfBagSpace = true
					end
					if notEnoughMoney then
						outOfMoney = true
					end
					if notEnoughOtherCurrency then
						outOfOtherCurrency = true
					end
				end
			end
		end
	end
	-- If there was a problem, tell the master.
	if outOfBagSpace then
		AJM:JambaSendMessageToTeam( AJM.db.messageArea, L["I do not have enough space in my bags to complete my purchases."], false )
	end
	if outOfMoney then
		AJM:JambaSendMessageToTeam( AJM.db.messageArea, L["I do not have enough money to complete my purchases."], false )
	end
	if outOfOtherCurrency then
		AJM:JambaSendMessageToTeam( AJM.db.messageArea, L["I do not have enough other currency to complete my purchases."], false )
	end
end

function AJM:DoesMerchantHaveItemInStock( itemLink )
	-- The index of the item to be found in the merchants inventory; initially nil, not found.
	local indexOfItemToFind = nil
	-- Get the name of the item to find from the item link.
	local itemNameToFind = GetItemInfo( itemLink )
	-- How many items does the merchant have?
	local numberMerchantItems = GetMerchantNumItems()
	-- Iterate all the merchants items...
	for merchantIndex = 1, numberMerchantItems do
		-- Is there an item link for this item.
		local merchantItemLink = GetMerchantItemLink( merchantIndex )
		if merchantItemLink then
			-- Yes, get the item name.
			local itemNameMerchant = GetItemInfo( merchantItemLink )
			if itemNameMerchant == itemNameToFind then
				indexOfItemToFind = merchantIndex
				break
			end
		end
	end
	-- Return the index into the merchants inventory of the item.
	return indexOfItemToFind
end

function AJM:GetAmountNeededForItemTopUp( itemLink, maxItemAmount )
	-- The amount of the item needed to top up the item.
	local amountNeeded = 0
	-- How much of this item does the character have in it's bags?
	local amountInBags = GetItemCount( itemLink )
	-- Does the character need more?
	if amountInBags < maxItemAmount then
		-- Yes, how much more?
		amountNeeded = maxItemAmount - amountInBags
	end
	-- Return the amount needed.
	return amountNeeded
end

function AJM:BuyItemFromMerchant( itemIndexMerchant, amountToBuy )
	-- Flags will be set if the character does not have enough bag space or money.
	local noFreeBagSpace = false
	local notEnoughMoney = false
	local notEnoughOtherCurrency = false
	-- Processing variables.
	local buyThisAmount = 0
	local amountLeftToBuy = amountToBuy
	local actualAmountToBuy = 0
	local costToBuy = 0
	local moneyAvailable = 0
	-- Get information about the item from the merchant.
	local name, texture, price, itemsPerStack, numberAvailable, isUsable, extendedCost = GetMerchantItemInfo( itemIndexMerchant )
	local maximumCanBuyAtATime = GetMerchantItemMaxStack( itemIndexMerchant )
	-- Loop buying stacks from the merchant until the required number has been purchased.
	repeat
		-- Still need to buy more than the maximum?
		if amountLeftToBuy >= maximumCanBuyAtATime then
			-- Yes, buy the maximum amount.
			buyThisAmount = maximumCanBuyAtATime
		else
			-- No, just buy the amount left.
			buyThisAmount = amountLeftToBuy
		end
		-- Attempt to buy this amount from the merchant; although actual amount bought may differ,
		-- depending on merchant stock and over buy flag.
		-- How many does the merchant have left?
		numberAvailable = select( 5, GetMerchantItemInfo( itemIndexMerchant ) )
		-- Calculate how many to buy depending on the stacksize and whether over buying is allowed.
		actualAmountToBuy = buyThisAmount
		if AJM.db.autoBuyOverflow == true then
			actualAmountToBuy = ceil(actualAmountToBuy)
		else
			actualAmountToBuy = floor(actualAmountToBuy)
		end
		-- If requesting more than the number available, then just buy as much as possible.
		-- If numberAvailable is -1 then there is unlimited stock available.
		if numberAvailable ~= -1 then
			if actualAmountToBuy > numberAvailable then
				actualAmountToBuy = numberAvailable
			end
		end
		-- Does the character have enough money?
		costToBuy = actualAmountToBuy * price
		moneyAvailable = GetMoney()
		if moneyAvailable < costToBuy then
			notEnoughMoney = true
		end
		-- Is there enough free space for this item in the characters bags?
		--TODO - need to find items family type and compare to each container.
		local numFreeSlots, numTotalSlots = LibBagUtils:CountSlots("BAGS", 0)
        if numFreeSlots == 0 then
            noFreeBagSpace = true
        end
		-- Buy from the merchant, if there is a valid amount to buy and the character has enough money.
		if (actualAmountToBuy > 0) and (not notEnoughMoney) then
			BuyMerchantItem( itemIndexMerchant, actualAmountToBuy )
		end
		-- How much left to buy?
		amountLeftToBuy = amountLeftToBuy - buyThisAmount
	until (amountLeftToBuy == 0 or noFreeBagSpace == true)
	-- TODO
	-- Return the success flags.
	return noFreeBagSpace, notEnoughMoney, notEnoughOtherCurrency
end