Quantcast
--[[
Jamba - Jafula's Awesome Multi-Boxer Assistant
Copyright 2008 - 2017 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(
	"JambaItemUse",
	"JambaModule-1.0",
	"AceConsole-3.0",
	"AceEvent-3.0",
	"AceTimer-3.0"
)

-- Get the Jamba Utilities Library.
local JambaUtilities = LibStub:GetLibrary( "JambaUtilities-1.0" )
local JambaHelperSettings = LibStub:GetLibrary( "JambaHelperSettings-1.0" )
--local LibBagUtils = LibStub:GetLibrary( "LibBagUtils-1.0" )
--local LibGratuity = LibStub( "LibGratuity-3.0" )
local LibActionButton = LibStub( "LibActionButtonJamba-1.0" )
local tooltipName = "AJMScanner"
local tooltipScanner = CreateFrame("GameTooltip", tooltipName, nil, "GameTooltipTemplate")
AJM.SharedMedia = LibStub( "LibSharedMedia-3.0" )

--  Constants and Locale for this module.
AJM.moduleName = "Jamba-ItemUse"
AJM.settingsDatabaseName = "JambaItemUseProfileDB"
AJM.chatCommand = "jamba-item-use"
local L = LibStub( "AceLocale-3.0" ):GetLocale( AJM.moduleName )
AJM.parentDisplayName = L["Interaction"]
AJM.moduleDisplayName = L["Item Use"]

-- Jamba key bindings.
BINDING_HEADER_JAMBAITEMUSE = L["Jamba-Item-Use"]
BINDING_NAME_JAMBAITEMUSE1 = L["Item 1"]
BINDING_NAME_JAMBAITEMUSE2 = L["Item 2"]
BINDING_NAME_JAMBAITEMUSE3 = L["Item 3"]
BINDING_NAME_JAMBAITEMUSE4 = L["Item 4"]
BINDING_NAME_JAMBAITEMUSE5 = L["Item 5"]
BINDING_NAME_JAMBAITEMUSE6 = L["Item 6"]
BINDING_NAME_JAMBAITEMUSE7 = L["Item 7"]
BINDING_NAME_JAMBAITEMUSE8 = L["Item 8"]
BINDING_NAME_JAMBAITEMUSE9 = L["Item 9"]
BINDING_NAME_JAMBAITEMUSE10 = L["Item 10"]
BINDING_NAME_JAMBAITEMUSE11 = L["Item 11"]
BINDING_NAME_JAMBAITEMUSE12 = L["Item 12"]
BINDING_NAME_JAMBAITEMUSE13 = L["Item 13"]
BINDING_NAME_JAMBAITEMUSE14 = L["Item 14"]
BINDING_NAME_JAMBAITEMUSE15 = L["Item 15"]
BINDING_NAME_JAMBAITEMUSE16 = L["Item 16"]
BINDING_NAME_JAMBAITEMUSE17 = L["Item 17"]
BINDING_NAME_JAMBAITEMUSE18 = L["Item 18"]
BINDING_NAME_JAMBAITEMUSE19 = L["Item 19"]
BINDING_NAME_JAMBAITEMUSE20 = L["Item 20"]

-- Settings - the values to store and their defaults for the settings database.
AJM.settings = {
	profile = {
		showItemUse = true,
		showItemUseOnMasterOnly = true,
		hideItemUseInCombat = false,
		borderStyle = L["Blizzard Tooltip"],
		backgroundStyle = L["Blizzard Dialog Background"],
		itemUseScale = 1,
		itemUseTitleHeight = 3,
		itemUseVerticalSpacing = 3,
		itemUseHorizontalSpacing = 2,
		autoAddQuestItemsToBar = true,
		autoAddArtifactItemsToBar = true,
		autoAddSatchelsItemsToBar = true,
		hideClearButton = false,
		itemBarsSynchronized = true,
		numberOfItems = 10,
		numberOfRows = 2,
		messageArea = JambaApi.DefaultWarningArea(),
		itemsAdvanced = {},
		framePoint = "BOTTOMRIGHT",
		frameRelativePoint = "BOTTOMRIGHT",
		frameXOffset = 0,
		frameYOffset = 0,
		frameAlpha = 1.0,
		frameBackgroundColourR = 1.0,
		frameBackgroundColourG = 1.0,
		frameBackgroundColourB = 1.0,
		frameBackgroundColourA = 1.0,
		frameBorderColourR = 1.0,
		frameBorderColourG = 1.0,
		frameBorderColourB = 1.0,
		frameBorderColourA = 1.0,
	},
}

-- Configuration.
function AJM:GetConfiguration()
	local configuration = {
		name = AJM.moduleDisplayName,
		handler = AJM,
		type = 'group',
		args = {
			push = {
				type = "input",
				name = L["Push Settings"],
				desc = L["Push the item use settings to all characters in the team."],
				usage = "/jamba-item-use push",
				get = false,
				set = "JambaSendSettings",
			},
			hide = {
				type = "input",
				name = L["Hide Item Bar"],
				desc = L["Hide the item bar panel."],
				usage = "/jamba-item-use hide",
				get = false,
				set = "HideItemUseCommand",
			},
			show = {
				type = "input",
				name = L["Show Item Bar"],
				desc = L["Show the item bar panel."],
				usage = "/jamba-item-use show",
				get = false,
				set = "ShowItemUseCommand",
			},
			clear = {
				type = "input",
				name = L["Clear Item Bar"],
				desc = L["Clear the item bar (remove all items)."],
				usage = "/jamba-item-use clear",
				get = false,
				set = "ClearItemUseCommand",
			},
		},
	}
	return configuration
end

local function DebugMessage( ... )
	--AJM:Print( ... )
end

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

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

-------------------------------------------------------------------------------------------------------------
-- Variables used by module.
-------------------------------------------------------------------------------------------------------------

AJM.globalFramePrefix = "JambaItemUse"
AJM.itemContainer = {}
AJM.itemUseCreated = false
AJM.itemSize = 40
AJM.refreshItemUseControlsPending = false
AJM.refreshUpdateItemsInBarPending = false
AJM.refreshUpdateBindingsPending = false
AJM.updateSettingsAfterCombat = false
AJM.maximumNumberOfItems = 20
AJM.maximumNumberOfRows = 20

-------------------------------------------------------------------------------------------------------------
-- Item Bar.
-------------------------------------------------------------------------------------------------------------

local function CanDisplayItemUse()
	local canShow = false
	if AJM.db.showItemUse == true then
		if AJM.db.showItemUseOnMasterOnly == true then
			if JambaApi.IsCharacterTheMaster( AJM.characterName ) == true then
				canShow = true
			end
		else
			canShow = true
		end
	end
	return canShow
end

local function CreateJambaItemUseFrame()
	-- The frame.
	local frame = CreateFrame( "Frame", "JambaItemUseWindowFrame", UIParent, "SecureHandlerStateTemplate" )
	RegisterStateDriver(JambaItemUseWindowFrame, "page", "[mod:alt]0;0")
	JambaItemUseWindowFrame:SetAttribute("_onstate-page", [[
		self:SetAttribute("state", newstate)
		control:ChildUpdate("state", newstate)
	]])
	frame.parentObject = AJM
	frame:SetFrameStrata( "LOW" )
	frame:SetToplevel( true )
	frame:SetClampedToScreen( true )
	frame:EnableMouse( true )
	frame:SetMovable( true )
	frame:RegisterForDrag( "LeftButton" )
	frame:SetScript( "OnDragStart",
		function( this )
			if IsAltKeyDown() then
				this:StartMoving()
			end
		end )
	frame:SetScript( "OnDragStop",
		function( this )
			this:StopMovingOrSizing()
			local point, relativeTo, relativePoint, xOffset, yOffset = this:GetPoint()
			AJM.db.framePoint = point
			AJM.db.frameRelativePoint = relativePoint
			AJM.db.frameXOffset = xOffset
			AJM.db.frameYOffset = yOffset
		end	)
	-- Artifact Remove Buttion
		local updateButton = CreateFrame( "Button", "ButtonUpdate", frame, "UIPanelButtonTemplate" )
		updateButton:SetScript( "OnClick", function() AJM:ClearButton() end )
		updateButton:SetPoint( "TOPRIGHT", frame, "TOPRIGHT", -4, -3 )
		updateButton:SetHeight( 20 )
		updateButton:SetWidth( 70 )
		updateButton:SetText( L["Clear"] )
		updateButton:SetScript("OnEnter", function(self) AJM:ShowTooltip(updateButton, true) end)
		updateButton:SetScript("OnLeave", function(self) GameTooltip:Hide() end)
		ArtifactUpdateButton = updateButton
		frame:ClearAllPoints()
	frame:SetPoint( AJM.db.framePoint, UIParent, AJM.db.frameRelativePoint, AJM.db.frameXOffset, AJM.db.frameYOffset )
	frame:SetBackdrop( {
		bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
		edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
		tile = true, tileSize = 10, edgeSize = 10,
		insets = { left = 3, right = 3, top = 3, bottom = 3 }
	} )
	-- Set transparency of the the frame (and all its children).
	frame:SetAlpha(AJM.db.frameAlpha)
	-- Set the global frame reference for this frame.
	JambaItemUseFrame = frame
	-- Remove unsued items --test
	AJM:SettingsUpdateBorderStyle()
	AJM.itemUseCreated = true
	AJM.UpdateHeight()
end

function AJM:ShowTooltip(frame, show)
	if show then
		GameTooltip:SetOwner(frame, "ANCHOR_TOP")
		GameTooltip:SetPoint("TOPLEFT", frame, "TOPRIGHT", 16, 0)
		GameTooltip:ClearLines()
		GameTooltip:AddLine(L["Clears items no longer in your bags "], 1, 0.82, 0, 1)
		GameTooltip:Show()
	else
	GameTooltip:Hide()
	end
end


function AJM:UpdateHeight()
	if AJM.db.hideClearButton == false then
		AJM.db.itemUseTitleHeight = 2
		local newHeight = AJM.db.itemUseTitleHeight + 20
		ArtifactUpdateButton:Show()
		return newHeight
	else
		AJM.db.itemUseTitleHeight = 2
		oldHeight = AJM.db.itemUseTitleHeight
		ArtifactUpdateButton:Hide()
		return oldHeight
	end
end


function AJM:ShowItemUseCommand()
	AJM.db.showItemUse = true
	AJM:SetItemUseVisibility()
	AJM:SettingsRefresh()
end

function AJM:HideItemUseCommand()
	AJM.db.showItemUse = false
	AJM:SetItemUseVisibility()
	AJM:SettingsRefresh()
end

function AJM:ClearItemUseCommand()
	JambaUtilities:ClearTable(AJM.db.itemsAdvanced)
	AJM:SettingsRefresh()
	AJM:Print(L["Item Bar Cleared"])
end

function AJM:SetItemUseVisibility()
	if CanDisplayItemUse() == true then
		JambaItemUseFrame:ClearAllPoints()
		JambaItemUseFrame:SetPoint( AJM.db.framePoint, UIParent, AJM.db.frameRelativePoint, AJM.db.frameXOffset, AJM.db.frameYOffset )
		JambaItemUseFrame:SetAlpha( AJM.db.frameAlpha )
		JambaItemUseFrame:Show()
	else
		JambaItemUseFrame:Hide()
	end
end

function AJM:SettingsUpdateBorderStyle()
	local borderStyle = AJM.SharedMedia:Fetch( "border", AJM.db.borderStyle )
	local backgroundStyle = AJM.SharedMedia:Fetch( "background", AJM.db.backgroundStyle )
	local frame = JambaItemUseFrame
	frame:SetBackdrop( {
		bgFile = backgroundStyle,
		edgeFile = borderStyle,
		tile = true, tileSize = frame:GetWidth(), edgeSize = 10,
		insets = { left = 3, right = 3, top = 3, bottom = 3 }
	} )
	frame:SetBackdropColor( AJM.db.frameBackgroundColourR, AJM.db.frameBackgroundColourG, AJM.db.frameBackgroundColourB, AJM.db.frameBackgroundColourA )
	frame:SetBackdropBorderColor( AJM.db.frameBorderColourR, AJM.db.frameBorderColourG, AJM.db.frameBorderColourB, AJM.db.frameBorderColourA )
end

-- updates after the quest has been handed in,
function AJM:UpdateQuestItemsInBar()
	local state = "0"
	for iterateItems = 1, AJM.maximumNumberOfItems, 1 do
		local itemContainer = AJM.itemContainer[iterateItems]
		if itemContainer == nil then
			AJM:CreateJambaItemUseItemContainer( iterateItems, parentFrame )
			itemContainer = AJM.itemContainer[iterateItems]
		end
		local containerButton = itemContainer["container"]
		local itemInfo = AJM:GetItemFromItemDatabase( iterateItems )
		local kind = itemInfo.kind
		local action = itemInfo.action
		if kind == "item" then
			local itemLink,_,_,_,_,questItem = GetItemInfo( action )
			--AJM:Print("Checking Item...", itemLink, action)
			if questItem == "Quest" then
				if JambaApi.IsCharacterTheMaster( AJM.characterName ) == true then
					if AJM:IsInInventory( itemLink ) == false then
					--AJM:Print("NOT IN BAGS", itemLink)
						AJM.db.itemsAdvanced[iterateItems] = nil
						AJM:JambaSendSettings()
					end
				end
			end
		end
	end
end

function AJM:UpdateItemsInBar()
	local state = "0"
    local parentFrame = JambaItemUseFrame
	for iterateItems = 1, AJM.maximumNumberOfItems, 1 do
		local itemContainer = AJM.itemContainer[iterateItems]
		if itemContainer == nil then
			AJM:CreateJambaItemUseItemContainer( iterateItems, parentFrame )
			itemContainer = AJM.itemContainer[iterateItems]
		end
		local containerButton = itemContainer["container"]
		local itemInfo = AJM:GetItemFromItemDatabase( iterateItems )
		local kind = itemInfo.kind
		local action = itemInfo.action
		if kind == "item" and not tonumber( action ) then
			action = action:sub(6)
		end
        --AJM:Print(state, kind, action)
		if kind == "mount" or kind == "battlepet" then
            containerButton:ClearStates()
		else
		containerButton:SetState(state, kind, action)
        end
	end
end

function AJM:AddItemToItemDatabase( itemNumber, kind, action )
    if kind == "mount" or kind == "battlepet" then
        return
    end
	if AJM.db.itemsAdvanced[itemNumber] == nil then
		AJM.db.itemsAdvanced[itemNumber] = {}
	end
	AJM.db.itemsAdvanced[itemNumber].kind = kind
	AJM.db.itemsAdvanced[itemNumber].action = action
end

function AJM:GetItemFromItemDatabase( itemNumber )
	if AJM.db.itemsAdvanced[itemNumber] == nil then
		AJM.db.itemsAdvanced[itemNumber] = {}
		AJM.db.itemsAdvanced[itemNumber].kind = "empty"
		AJM.db.itemsAdvanced[itemNumber].action = "empty"
	end
	return AJM.db.itemsAdvanced[itemNumber]
end

function AJM:OnButtonContentsChanged( event, button, state, type, value, ... )
    if type == "mount" or type == "battlepet" then
		return
    end
    AJM:AddItemToItemDatabase( button.itemNumber, type, value )
    AJM:JambaSendSettings()
    AJM:SettingsRefresh()
end

function AJM:OnButtonUpdate( event, button, ... )
	--AJM:Print( event, button, ...)
end

function AJM:OnButtonState( event, button, ... )
	--AJM:Print( event, button, ...)
end

function AJM:OnButtonUsable( event, button, ... )
	--AJM:Print( event, button, ...)
end

function AJM:CreateJambaItemUseItemContainer( itemNumber, parentFrame )
	AJM.itemContainer[itemNumber] = {}
	local itemContainer = AJM.itemContainer[itemNumber]
	local containerButtonName = AJM.globalFramePrefix.."ContainerButton"..itemNumber
    local buttonConfig = {
        outOfRangeColoring = "button",
        tooltip = "enabled",
        showGrid = true,
        colors = {
            range = { 0.8, 0.1, 0.1 },
            mana = { 0.5, 0.5, 1.0 }
        },
        hideElements = {
            macro = false,
            hotkey = false,
            equipped = false,
        },
        keyBoundTarget = false,
        clickOnDown = false,
        flyoutDirection = "UP",
    }
	local containerButton = LibActionButton:CreateButton( itemNumber, containerButtonName, JambaItemUseWindowFrame, buttonConfig )
	containerButton:SetState( "0", "empty", nil)
	containerButton.itemNumber = itemNumber
	itemContainer["container"] = containerButton
end

--ebony test Using the wowapi and not the scanning of tooltips
function AJM:CheckForQuestItemAndAddToBar()
	--[[
	for bag = 0,4,1 do
		for slot = 1,GetContainerNumSlots(bag),1 do
			local IsQuestItem,StartsQuest,_ = GetContainerItemQuestInfo(bag,slot)
			local _,_,_,_,readable,_,itemLink = GetContainerItemInfo(bag,slot) -- readable???
				-- Quests now auto get started since 7.1 kinda making this usless.
				--if not IsQuestItem and StartsQuest then
					--local itemString = GetItemInfo(itemLink)
					--AJM:AddAnItemToTheBarIfNotExists( itemLink, true)
				--end
			end
		end
	]]
	for iterateQuests=1,GetNumQuestLogEntries() do
	local questLogTitleText,_,_,_,isHeader = GetQuestLogTitle(iterateQuests)
		if not isHeader then
			local questItemLink, questItemIcon, questItemCharges = GetQuestLogSpecialItemInfo( iterateQuests )
			if questItemLink  then
				local itemName = GetItemInfo(questItemLink)
				local questname,rank = GetItemSpell(questItemLink) -- Only means to detect if the item is usable
				if questname then
					if JambaUtilities:DoItemLinksContainTheSameItem( questItemLink, questItemLink ) == true then
						--AJM:Print("addItem", questItemLink )
						AJM:AddAnItemToTheBarIfNotExists( questItemLink, false)
					end
				end
			end
		end
	end
end

-- Add satchels to item bar.
function AJM:CheckForSatchelsItemAndAddToBar()
	for bag = 0, NUM_BAG_SLOTS do
		for slot = 1, GetContainerNumSlots(bag) do
		local texture, count, locked, quality, readable, lootable, link, isFiltered, hasNoValue, itemID = GetContainerItemInfo(bag, slot)
		--AJM:Print("test", link, lootable)
			if link and lootable then
				--AJM:Print("satchelsFound", link)
				AJM:AddAnItemToTheBarIfNotExists( link, false )
			end
		end
	end
end

-- Removes unused items.

function AJM:ClearButton()
	local state = "0"
	for iterateItems = 1, AJM.maximumNumberOfItems, 1 do
		local itemContainer = AJM.itemContainer[iterateItems]
		if itemContainer == nil then
			AJM:CreateJambaItemUseItemContainer( iterateItems, parentFrame )
			itemContainer = AJM.itemContainer[iterateItems]
		end
		local containerButton = itemContainer["container"]
		local itemInfo = AJM:GetItemFromItemDatabase( iterateItems )
		local kind = itemInfo.kind
		local action = itemInfo.action
		if kind == "item" then
			local name, itemLink,_,_,_,itemType,questItem = GetItemInfo( action )
			if itemLink and itemLink:match("item:%d") then
				tooltipScanner:SetOwner(UIParent, "ANCHOR_NONE")
				tooltipScanner:SetHyperlink(itemLink)
				--AJM:Print("scanTooltip", itemLink)
				local tooltipText = _G[tooltipName.."TextLeft3"]:GetText()
				--AJM:Print("tooltiptest", tooltipText, tooltipTextTwo)
				if tooltipText == nil or tooltipText ~= "Unique" then
					--AJM:Print("testWorks!", itemLink)
					if AJM:IsInInventory( name ) == false then
						--AJM:Print("NOT IN BAGS", itemLink)
						AJM.db.itemsAdvanced[iterateItems] = nil
						AJM:SettingsRefresh()
						AJM:JambaSendSettings()
					end
				end
			end
		end
	end
end

-- Adds artifact power items to item bar.
function AJM:CheckForArtifactItemAndAddToBar()
	for bag = 0, NUM_BAG_SLOTS do
		for slot = 1, GetContainerNumSlots(bag) do
			local itemLink = GetContainerItemLink(bag, slot)
			--AJM:Print("bagcheck", itemLink)
			if itemLink and itemLink:match("item:%d") then
				tooltipScanner:SetOwner(UIParent, "ANCHOR_NONE")
				tooltipScanner:SetHyperlink(itemLink)
				--AJM:Print("scanTooltip", itemLink)
				local tooltipText = _G[tooltipName.."TextLeft2"]:GetText()
				if tooltipText and tooltipText:match(ARTIFACT_POWER) then
					--AJM:Print("artifactPowerFound", itemLink)
					AJM:AddAnItemToTheBarIfNotExists( itemLink, false )
				end
			end
		end
	end
end

--Removes artifact power after used.
--[[
function AJM:UpdateArtifactItemsInBar()
	local state = "0"
	for iterateItems = 1, AJM.maximumNumberOfItems, 1 do
		local itemContainer = AJM.itemContainer[iterateItems]
		if itemContainer == nil then
			AJM:CreateJambaItemUseItemContainer( iterateItems, parentFrame )
			itemContainer = AJM.itemContainer[iterateItems]
		end
		local containerButton = itemContainer["container"]
		local itemInfo = AJM:GetItemFromItemDatabase( iterateItems )
		local kind = itemInfo.kind
		local action = itemInfo.action
		if kind == "item" then
			local name, itemLink,_,_,_,_,questItem = GetItemInfo( action )
			if itemLink and itemLink:match("item:%d") then
				tooltipScanner:SetOwner(UIParent, "ANCHOR_NONE")
				tooltipScanner:SetHyperlink(itemLink)
				--AJM:Print("scanTooltip", name, itemLink)
				local tooltipText = _G[tooltipName.."TextLeft2"]:GetText()
				if tooltipText and tooltipText:match(ARTIFACT_POWER) then
					if AJM:IsInInventory( name ) == false then
						--AJM:Print("NOT IN BAGS", itemLink)
						AJM.db.itemsAdvanced[iterateItems] = nil
						AJM:SettingsRefresh()
						AJM:JambaSendSettings()
					end
				end
			end
		end
	end
end
--]]

--Checks the item is in the player players bag
function AJM:IsInInventory(itemLink)
	for bag = 0,4,1 do
		for slot = 1,GetContainerNumSlots(bag),1 do
			--AJM:Debug( "Bags OK. checking", itemLink )
			local _,_,_,_,_,_,_,_,_,Link = GetContainerItemInfo(bag,slot)
			if Link then
				--AJM:Debug( "Bags OK. checking", itemLink, Link )
				local itemString = GetItemInfo( Link )
				--AJM:Debug( "Bags OK. checking", itemLink, itemString )
				if itemLink == itemString then
					--AJM:Print( "True" )
					return true
				end
			end
		end
	end
	return false
end


function AJM:AddAnItemToTheBarIfNotExists( itemLink, startsQuest)
	local itemInfo
	local barItemId
	local iterateItems
	local alreadyExists = false
	local itemId = JambaUtilities:GetItemIdFromItemLink( itemLink )
	for iterateItems = 1, AJM.db.numberOfItems, 1 do
		itemInfo = AJM:GetItemFromItemDatabase( iterateItems )
			--AJM:Print("check", itemLink, itemInfo.action)
		if itemInfo.kind == "item" and itemInfo.action == itemId then
			alreadyExists = true
		--	AJM:Print("test", itemLink )
			return
		end
	end
	if alreadyExists == false then
		--AJM:Print("test2", itemLink )
		for iterateItems = 1, AJM.db.numberOfItems, 1 do
			itemInfo = AJM:GetItemFromItemDatabase( iterateItems )
			--Checks the items we talking about is in the bags of the player.
			if itemInfo.kind == "empty" then
				AJM:AddItemToItemDatabase( iterateItems, "item", itemId )
				AJM:JambaSendSettings()
				AJM:SettingsRefresh()
					if startsQuest then
						AJM:JambaSendMessageToTeam( AJM.db.messageArea, L["New item that starts a quest found!"], false )
					end
				return
			end
		end
	end
end

function AJM:RefreshItemUseControls()
	if InCombatLockdown() then
		AJM.refreshItemUseControlsPending = true
		return
	end
	local parentFrame = JambaItemUseFrame
	local positionLeft
	local positionTop
	local itemsPerRow = AJM.db.numberOfItems / AJM.db.numberOfRows
	local row
	local rowLeftModifier
	for iterateItems = 1, AJM.maximumNumberOfItems, 1 do
		local itemContainer = AJM.itemContainer[iterateItems]
		if itemContainer ~= nil then
			local containerButton = itemContainer["container"]
			containerButton:Hide()
		end
	end
	for iterateItems = 1, AJM.db.numberOfItems, 1 do
		local itemContainer = AJM.itemContainer[iterateItems]
		if itemContainer == nil then
			AJM:CreateJambaItemUseItemContainer( iterateItems, parentFrame )
			itemContainer = AJM.itemContainer[iterateItems]
		end
		local containerButton = itemContainer["container"]
		row = math.floor((iterateItems - 1) / itemsPerRow)
		rowLeftModifier = math.floor((iterateItems-1) % itemsPerRow)
		positionLeft = 6 + (AJM.itemSize * rowLeftModifier) + (AJM.db.itemUseHorizontalSpacing * rowLeftModifier)
		local getHeight = AJM.UpdateHeight()
		positionTop = -getHeight - (AJM.db.itemUseVerticalSpacing * 2) - (row * AJM.itemSize) - (row * AJM.db.itemUseVerticalSpacing)
		containerButton:SetWidth( AJM.itemSize )
		containerButton:SetHeight( AJM.itemSize )
		containerButton:SetPoint( "TOPLEFT", parentFrame, "TOPLEFT", positionLeft, positionTop )
		containerButton:Show()
	end
	AJM:UpdateJambaItemUseDimensions()
end

function AJM:UpdateJambaItemUseDimensions()
	local frame = JambaItemUseFrame
	local itemsPerRow = AJM.db.numberOfItems / AJM.db.numberOfRows
	frame:SetWidth( 5 + (AJM.db.itemUseHorizontalSpacing * (3 + itemsPerRow-1)) + (AJM.itemSize * itemsPerRow) )
	local getHeight = AJM.UpdateHeight()
	frame:SetHeight( getHeight + (AJM.itemSize * AJM.db.numberOfRows) + (AJM.db.itemUseVerticalSpacing * AJM.db.numberOfRows) + (AJM.db.itemUseVerticalSpacing * 3))
	frame:SetScale( AJM.db.itemUseScale )
end

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

local function SettingsCreateOptions( top )
	-- Get positions.
    local buttonHeight = JambaHelperSettings:GetButtonHeight()
	local checkBoxHeight = JambaHelperSettings:GetCheckBoxHeight()
	local editBoxHeight = JambaHelperSettings:GetEditBoxHeight()
	local dropdownHeight = JambaHelperSettings:GetDropdownHeight()
	local labelHeight = JambaHelperSettings:GetLabelHeight()
	local mediaHeight = JambaHelperSettings:GetMediaHeight()
	local sliderHeight = JambaHelperSettings:GetSliderHeight()
	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 thirdWidth = (headingWidth - (horizontalSpacing * 2)) / 3
	local column2left = left + halfWidth
	local left2 = left + thirdWidth
	local left3 = left + (thirdWidth * 2)
	local movingTop = top
	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Item Use Options"], movingTop, false )
	movingTop = movingTop - headingHeight
	AJM.settingsControl.displayOptionsCheckBoxShowItemUse = JambaHelperSettings:CreateCheckBox(
		AJM.settingsControl,
		headingWidth,
		left,
		movingTop,
		L["Show Item Bar"],
		AJM.SettingsToggleShowItemUse
	)
	movingTop = movingTop - checkBoxHeight - verticalSpacing
	AJM.settingsControl.displayOptionsCheckBoxShowItemUseOnlyOnMaster = JambaHelperSettings:CreateCheckBox(
		AJM.settingsControl,
		headingWidth,
		left,
		movingTop,
		L["Only On Master"],
		AJM.SettingsToggleShowItemUseOnlyOnMaster
	)
	movingTop = movingTop - checkBoxHeight - verticalSpacing
	AJM.settingsControl.displayOptionsCheckBoxItemBarsSynchronized = JambaHelperSettings:CreateCheckBox(
		AJM.settingsControl,
		headingWidth,
		left,
		movingTop,
		L["Keep Item Bars On Minions Synchronized"],
		AJM.SettingsToggleItemBarsSynchronized
	)
	movingTop = movingTop - checkBoxHeight - verticalSpacing
	AJM.settingsControl.displayOptionsCheckBoxAutoAddQuestItem = JambaHelperSettings:CreateCheckBox(
		AJM.settingsControl,
		headingWidth,
		left,
		movingTop,
		L["Automatically Add Quest Items To Bar"],
		AJM.SettingsToggleAutoAddQuestItem
	)
	movingTop = movingTop - checkBoxHeight - verticalSpacing
	AJM.settingsControl.displayOptionsCheckBoxAutoAddArtifactItem = JambaHelperSettings:CreateCheckBox(
		AJM.settingsControl,
		headingWidth,
		left,
		movingTop,
		L["Automatically Add Artifact Power Items To Bar"],
		AJM.SettingsToggleAutoAddArtifactItem
	)
	movingTop = movingTop - checkBoxHeight - verticalSpacing
	AJM.settingsControl.displayOptionsCheckBoxAutoAddSatchelsItem = JambaHelperSettings:CreateCheckBox(
		AJM.settingsControl,
		headingWidth,
		left,
		movingTop,
		L["Automatically Add Satchel Items To Bar"],
		AJM.SettingsToggleAutoAddSatchelsItem
	)
	movingTop = movingTop - checkBoxHeight - verticalSpacing
	AJM.settingsControl.displayOptionsCheckBoxHideClearButton = JambaHelperSettings:CreateCheckBox(
		AJM.settingsControl,
		headingWidth,
		left,
		movingTop,
		L["Hides the clear Button"],
		AJM.SettingsToggleHideClearButton
	)
	movingTop = movingTop - checkBoxHeight - verticalSpacing
	AJM.settingsControl.displayOptionsCheckBoxHideItemUseInCombat = JambaHelperSettings:CreateCheckBox(
		AJM.settingsControl,
		headingWidth,
		left,
		movingTop,
		L["Hide Item Bar In Combat"],
		AJM.SettingsToggleHideItemUseInCombat
	)
	movingTop = movingTop - checkBoxHeight - verticalSpacing
	AJM.settingsControl.displayOptionsItemUseNumberOfItems = JambaHelperSettings:CreateSlider(
		AJM.settingsControl,
		headingWidth,
		left,
		movingTop,
		L["Number Of Items"]
	)
	AJM.settingsControl.displayOptionsItemUseNumberOfItems:SetSliderValues( 1, AJM.maximumNumberOfItems, 1 )
	AJM.settingsControl.displayOptionsItemUseNumberOfItems:SetCallback( "OnValueChanged", AJM.SettingsChangeNumberOfItems )
	movingTop = movingTop - sliderHeight - verticalSpacing
	AJM.settingsControl.displayOptionsItemUseNumberOfRows = JambaHelperSettings:CreateSlider(
		AJM.settingsControl,
		headingWidth,
		left,
		movingTop,
		L["Number Of Rows"]
	)
	AJM.settingsControl.displayOptionsItemUseNumberOfRows:SetSliderValues( 1, AJM.maximumNumberOfRows, 1 )
	AJM.settingsControl.displayOptionsItemUseNumberOfRows:SetCallback( "OnValueChanged", AJM.SettingsChangeNumberOfRows )
	movingTop = movingTop - sliderHeight - verticalSpacing
	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Appearance & Layout"], movingTop, false )
	movingTop = movingTop - headingHeight
	AJM.settingsControl.displayOptionsItemUseScaleSlider = JambaHelperSettings:CreateSlider(
		AJM.settingsControl,
		headingWidth,
		left,
		movingTop,
		L["Scale"]
	)
	AJM.settingsControl.displayOptionsItemUseScaleSlider:SetSliderValues( 0.5, 2, 0.01 )
	AJM.settingsControl.displayOptionsItemUseScaleSlider:SetCallback( "OnValueChanged", AJM.SettingsChangeScale )
	movingTop = movingTop - sliderHeight - verticalSpacing
	AJM.settingsControl.displayOptionsItemUseTransparencySlider = JambaHelperSettings:CreateSlider(
		AJM.settingsControl,
		headingWidth,
		left,
		movingTop,
		L["Transparency"]
	)
	AJM.settingsControl.displayOptionsItemUseTransparencySlider:SetSliderValues( 0, 1, 0.01 )
	AJM.settingsControl.displayOptionsItemUseTransparencySlider:SetCallback( "OnValueChanged", AJM.SettingsChangeTransparency )
	movingTop = movingTop - sliderHeight - verticalSpacing
	AJM.settingsControl.displayOptionsItemUseMediaBorder = JambaHelperSettings:CreateMediaBorder(
		AJM.settingsControl,
		halfWidth,
		left,
		movingTop,
		L["Border Style"]
	)
	AJM.settingsControl.displayOptionsItemUseMediaBorder:SetCallback( "OnValueChanged", AJM.SettingsChangeBorderStyle )
	AJM.settingsControl.displayOptionsBorderColourPicker = JambaHelperSettings:CreateColourPicker(
		AJM.settingsControl,
		halfWidth,
		column2left + 15,
		movingTop - 15,
		L["Border Colour"]
	)
	AJM.settingsControl.displayOptionsBorderColourPicker:SetHasAlpha( true )
	AJM.settingsControl.displayOptionsBorderColourPicker:SetCallback( "OnValueConfirmed", AJM.SettingsBorderColourPickerChanged )
	movingTop = movingTop - mediaHeight - verticalSpacing
	AJM.settingsControl.displayOptionsItemUseMediaBackground = JambaHelperSettings:CreateMediaBackground(
		AJM.settingsControl,
		halfWidth,
		left,
		movingTop,
		L["Background"]
	)
	AJM.settingsControl.displayOptionsItemUseMediaBackground:SetCallback( "OnValueChanged", AJM.SettingsChangeBackgroundStyle )
	AJM.settingsControl.displayOptionsBackgroundColourPicker = JambaHelperSettings:CreateColourPicker(
		AJM.settingsControl,
		halfWidth,
		column2left + 15,
		movingTop - 15,
		L["Background Colour"]
	)
	AJM.settingsControl.displayOptionsBackgroundColourPicker:SetHasAlpha( true )
	AJM.settingsControl.displayOptionsBackgroundColourPicker:SetCallback( "OnValueConfirmed", AJM.SettingsBackgroundColourPickerChanged )
	movingTop = movingTop - mediaHeight - verticalSpacing
	JambaHelperSettings:CreateHeading( AJM.settingsControl, L["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
    JambaHelperSettings:CreateHeading( AJM.settingsControl, L["Clear Item Bar"], movingTop, false )
    movingTop = movingTop - headingHeight
    AJM.settingsControl.buttonClearItemBar = JambaHelperSettings:CreateButton(
        AJM.settingsControl,
        headingWidth,
        left,
        movingTop,
        L["Clear Item Bar"],
        AJM.ClearItemUseCommand
    )
    movingTop = movingTop - buttonHeight - 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 bottomOfOptions = SettingsCreateOptions( JambaHelperSettings:TopOfSettings() )
	AJM.settingsControl.widgetSettings.content:SetHeight( -bottomOfOptions )
	-- Help
	local helpTable = {}
	JambaHelperSettings:CreateHelp( AJM.settingsControl, helpTable, AJM:GetConfiguration() )
end

-------------------------------------------------------------------------------------------------------------
-- Settings Populate.
-------------------------------------------------------------------------------------------------------------

function AJM:BeforeJambaProfileChanged()
end

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

function AJM:SettingsRefresh()
	-- Values.
	AJM.settingsControl.displayOptionsCheckBoxShowItemUse:SetValue( AJM.db.showItemUse )
	AJM.settingsControl.displayOptionsCheckBoxShowItemUseOnlyOnMaster:SetValue( AJM.db.showItemUseOnMasterOnly )
	AJM.settingsControl.displayOptionsCheckBoxHideItemUseInCombat:SetValue( AJM.db.hideItemUseInCombat )
	AJM.settingsControl.displayOptionsItemUseNumberOfItems:SetValue( AJM.db.numberOfItems )
	AJM.settingsControl.displayOptionsItemUseNumberOfRows:SetValue( AJM.db.numberOfRows )
	AJM.settingsControl.displayOptionsCheckBoxAutoAddQuestItem:SetValue( AJM.db.autoAddQuestItemsToBar )
	AJM.settingsControl.displayOptionsCheckBoxAutoAddArtifactItem:SetValue( AJM.db.autoAddArtifactItemsToBar )
	AJM.settingsControl.displayOptionsCheckBoxAutoAddSatchelsItem:SetValue( AJM.db.autoAddSatchelsItemsToBar )
	AJM.settingsControl.displayOptionsCheckBoxHideClearButton:SetValue( AJM.db.hideClearButton )
	AJM.settingsControl.displayOptionsCheckBoxItemBarsSynchronized:SetValue( AJM.db.itemBarsSynchronized )
	AJM.settingsControl.displayOptionsItemUseScaleSlider:SetValue( AJM.db.itemUseScale )
	AJM.settingsControl.displayOptionsItemUseTransparencySlider:SetValue( AJM.db.frameAlpha )
	AJM.settingsControl.displayOptionsItemUseMediaBorder:SetValue( AJM.db.borderStyle )
	AJM.settingsControl.displayOptionsItemUseMediaBackground:SetValue( AJM.db.backgroundStyle )
	AJM.settingsControl.dropdownMessageArea:SetValue( AJM.db.messageArea )
	AJM.settingsControl.displayOptionsBackgroundColourPicker:SetColor( AJM.db.frameBackgroundColourR, AJM.db.frameBackgroundColourG, AJM.db.frameBackgroundColourB, AJM.db.frameBackgroundColourA )
	AJM.settingsControl.displayOptionsBorderColourPicker:SetColor( AJM.db.frameBorderColourR, AJM.db.frameBorderColourG, AJM.db.frameBorderColourB, AJM.db.frameBorderColourA )
	-- State.
	-- Trying to change state in combat lockdown causes taint. Let's not do that. Eventually it would be nice to have a "proper state driven item list",
	-- but this workaround is enough for now.
	if not InCombatLockdown() then
		AJM.settingsControl.displayOptionsCheckBoxShowItemUseOnlyOnMaster:SetDisabled( not AJM.db.showItemUse )
		AJM.settingsControl.displayOptionsCheckBoxHideItemUseInCombat:SetDisabled( not AJM.db.showItemUse )
		AJM.settingsControl.displayOptionsItemUseNumberOfItems:SetDisabled( not AJM.db.showItemUse )
		AJM.settingsControl.displayOptionsItemUseNumberOfRows:SetDisabled( not AJM.db.showItemUse )
		AJM.settingsControl.displayOptionsCheckBoxAutoAddQuestItem:SetDisabled( not AJM.db.showItemUse )
		AJM.settingsControl.displayOptionsCheckBoxAutoAddArtifactItem:SetDisabled( not AJM.db.showItemUse )
		AJM.settingsControl.displayOptionsCheckBoxAutoAddSatchelsItem:SetDisabled( not AJM.db.showItemUse )
		AJM.settingsControl.displayOptionsCheckBoxHideClearButton:SetDisabled( not AJM.db.showItemUse )
		AJM.settingsControl.displayOptionsCheckBoxItemBarsSynchronized:SetDisabled( not AJM.db.showItemUse )
		AJM.settingsControl.displayOptionsItemUseScaleSlider:SetDisabled( not AJM.db.showItemUse )
		AJM.settingsControl.displayOptionsItemUseTransparencySlider:SetDisabled( not AJM.db.showItemUse )
		AJM.settingsControl.displayOptionsItemUseMediaBorder:SetDisabled( not AJM.db.showItemUse )
		AJM.settingsControl.displayOptionsItemUseMediaBackground:SetDisabled( not AJM.db.showItemUse )
		AJM.settingsControl.dropdownMessageArea:SetDisabled( not AJM.db.showItemUse )
		AJM.settingsControl.displayOptionsBackgroundColourPicker:SetDisabled( not AJM.db.showItemUse )
		AJM.settingsControl.displayOptionsBorderColourPicker:SetDisabled( not AJM.db.showItemUse )
		if AJM.itemUseCreated == true then
			AJM:RefreshItemUseControls()
			AJM:SettingsUpdateBorderStyle()
			AJM:SetItemUseVisibility()
			AJM:UpdateItemsInBar()
			AJM:UpdateHeight()
		end
	else
		AJM.updateSettingsAfterCombat = true
	end
end

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

function AJM:SettingsToggleShowItemUse( event, checked )
	AJM.db.showItemUse = checked
	AJM:SettingsRefresh()
end

function AJM:SettingsToggleHideItemUseInCombat( event, checked )
	AJM.db.hideItemUseInCombat = checked
	AJM:SettingsRefresh()
end

function AJM:SettingsToggleShowItemUseOnlyOnMaster( event, checked )
	AJM.db.showItemUseOnMasterOnly = checked
	AJM:SettingsRefresh()
end

function AJM:SettingsToggleAutoAddQuestItem( event, checked )
	AJM.db.autoAddQuestItemsToBar = checked
	AJM:SettingsRefresh()
end

function AJM:SettingsToggleAutoAddArtifactItem( event, checked )
	AJM.db.autoAddArtifactItemsToBar = checked
	AJM:SettingsRefresh()
end

function AJM:SettingsToggleAutoAddSatchelsItem( event, checked )
	AJM.db.autoAddSatchelsItemsToBar = checked
	AJM:SettingsRefresh()
end

function AJM:SettingsToggleHideClearButton(event, checked )
	AJM.db.hideClearButton = checked
	AJM:SettingsRefresh()
end

function AJM:SettingsToggleItemBarsSynchronized( event, checked )
	AJM.db.itemBarsSynchronized = checked
	AJM:SettingsRefresh()
end

function AJM:SettingsChangeNumberOfItems( event, value )
	AJM.db.numberOfItems = tonumber( value )
	AJM:SettingsRefresh()
end

function AJM:SettingsChangeNumberOfRows( event, value )
	AJM.db.numberOfRows= tonumber( value )
	AJM:SettingsRefresh()
end

function AJM:SettingsChangeScale( event, value )
	AJM.db.itemUseScale = tonumber( value )
	AJM:SettingsRefresh()
end

function AJM:SettingsChangeTransparency( event, value )
	AJM.db.frameAlpha = tonumber( value )
	AJM:SettingsRefresh()
end

function AJM:SettingsChangeBorderStyle( event, value )
	AJM.db.borderStyle = value
	AJM:SettingsRefresh()
end

function AJM:SettingsChangeBackgroundStyle( event, value )
	AJM.db.backgroundStyle = value
	AJM:SettingsRefresh()
end

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

function AJM:OnMasterChanged( message, characterName )
	AJM:SettingsRefresh()
end

function AJM:SettingsBackgroundColourPickerChanged( event, r, g, b, a )
	AJM.db.frameBackgroundColourR = r
	AJM.db.frameBackgroundColourG = g
	AJM.db.frameBackgroundColourB = b
	AJM.db.frameBackgroundColourA = a
	AJM:SettingsRefresh()
end

function AJM:SettingsBorderColourPickerChanged( event, r, g, b, a )
	AJM.db.frameBorderColourR = r
	AJM.db.frameBorderColourG = g
	AJM.db.frameBorderColourB = b
	AJM.db.frameBorderColourA = a
	AJM:SettingsRefresh()
end

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

-- Initialise the module.
function AJM:OnInitialize()
	-- Create the settings control.
	SettingsCreate()
	-- Initialise the JambaModule part of this module.
	AJM:JambaModuleInitialize( AJM.settingsControl.widgetSettings.frame )
	-- Populate the settings.
	AJM:SettingsRefresh()
	-- Create the item use frame.
	CreateJambaItemUseFrame()
	AJM:RefreshItemUseControls()
	AJM:SettingsUpdateBorderStyle()
	AJM:SetItemUseVisibility()
	AJM:UpdateItemsInBar()
end

-- Called when the addon is enabled.
function AJM:OnEnable()
	AJM:RegisterEvent( "PLAYER_REGEN_ENABLED" )
	AJM:RegisterEvent( "PLAYER_REGEN_DISABLED" )
	AJM:RegisterEvent( "BAG_UPDATE" )
	AJM:RegisterEvent( "ITEM_PUSH" )
	AJM:RegisterEvent( "UNIT_QUEST_LOG_CHANGED", "QUEST_UPDATE" )
	AJM.SharedMedia.RegisterCallback( AJM, "LibSharedMedia_Registered" )
    AJM.SharedMedia.RegisterCallback( AJM, "LibSharedMedia_SetGlobal" )
	AJM:RegisterMessage( JambaApi.MESSAGE_TEAM_MASTER_CHANGED, "OnMasterChanged" )
	AJM:RegisterMessage( JambaApi.MESSAGE_MESSAGE_AREAS_CHANGED, "OnMessageAreasChanged" )
	AJM:RefreshItemUseControls()
	AJM:UpdateItemsInBar()
	AJM.keyBindingFrame = CreateFrame( "Frame", nil, UIParent )
	AJM:RegisterEvent( "UPDATE_BINDINGS" )
	AJM:UPDATE_BINDINGS()
	LibActionButton.RegisterCallback( AJM, "OnButtonContentsChanged", "OnButtonContentsChanged" )
	LibActionButton.RegisterCallback( AJM, "OnButtonUpdate", "OnButtonUpdate" )
	LibActionButton.RegisterCallback( AJM, "OnButtonState", "OnButtonState" )
	LibActionButton.RegisterCallback( AJM, "OnButtonUsable", "OnButtonUsable" )
end

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

-- Settings received.
function AJM:JambaOnSettingsReceived( characterName, settings )
	if characterName ~= AJM.characterName then
		-- Update the settings.
		AJM.db.showItemUse = settings.showItemUse
		AJM.db.showItemUseOnMasterOnly = settings.showItemUseOnMasterOnly
		AJM.db.hideItemUseInCombat = settings.hideItemUseInCombat
		AJM.db.borderStyle = settings.borderStyle
		AJM.db.backgroundStyle = settings.backgroundStyle
		AJM.db.itemUseScale = settings.itemUseScale
		AJM.db.itemUseTitleHeight = settings.itemUseTitleHeight
		AJM.db.itemUseVerticalSpacing = settings.itemUseVerticalSpacing
		AJM.db.itemUseHorizontalSpacing = settings.itemUseHorizontalSpacing
		AJM.db.autoAddQuestItemsToBar = settings.autoAddQuestItemsToBar
		AJM.db.autoAddArtifactItemsToBar = settings.autoAddArtifactItemsToBar
		AJM.db.autoAddSatchelsItemsToBar = settings.autoAddSatchelsItemsToBar
		AJM.db.hideClearButton = settings.hideClearButton
		AJM.db.itemBarsSynchronized = settings.itemBarsSynchronized
		AJM.db.numberOfItems = settings.numberOfItems
		AJM.db.numberOfRows = settings.numberOfRows
		AJM.db.messageArea = settings.messageArea
		if AJM.db.itemBarsSynchronized == true then
		 AJM.db.itemsAdvanced = JambaUtilities:CopyTable( settings.itemsAdvanced )
		end
		AJM.db.frameAlpha = settings.frameAlpha
		AJM.db.framePoint = settings.framePoint
		AJM.db.frameRelativePoint = settings.frameRelativePoint
		AJM.db.frameXOffset = settings.frameXOffset
		AJM.db.frameYOffset = settings.frameYOffset
		AJM.db.frameBackgroundColourR = settings.frameBackgroundColourR
		AJM.db.frameBackgroundColourG = settings.frameBackgroundColourG
		AJM.db.frameBackgroundColourB = settings.frameBackgroundColourB
		AJM.db.frameBackgroundColourA = settings.frameBackgroundColourA
		AJM.db.frameBorderColourR = settings.frameBorderColourR
		AJM.db.frameBorderColourG = settings.frameBorderColourG
		AJM.db.frameBorderColourB = settings.frameBorderColourB
		AJM.db.frameBorderColourA = settings.frameBorderColourA
		-- 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

function AJM:PLAYER_REGEN_ENABLED()
	if AJM.db.hideItemUseInCombat == true then
		AJM:SetItemUseVisibility()
	end
	if AJM.refreshItemUseControlsPending == true then
		AJM:RefreshItemUseControls()
		AJM.refreshItemUseControlsPending = false
	end
	if AJM.refreshUpdateItemsInBarPending == true then
		AJM:UpdateItemsInBar()
		AJM.refreshUpdateItemsInBarPending = false
	end
	if AJM.refreshUpdateBindingsPending == true then
		AJM:UPDATE_BINDINGS()
		AJM.refreshUpdateBindingsPending = false
	end
	if AJM.updateSettingsAfterCombat == true then
		AJM:SettingsRefresh()
		AJM.updateSettingsAfterCombat = false
	end
end

function AJM:PLAYER_REGEN_DISABLED()
	if AJM.db.hideItemUseInCombat == true then
		JambaItemUseFrame:Hide()
	end
end

function AJM:BAG_UPDATE()
	if not InCombatLockdown() then
		AJM:UpdateItemsInBar()
		AJM:UpdateQuestItemsInBar()
		--AJM:ScheduleTimer( "UpdateArtifactItemsInBar", 1 )
	end
end

function AJM:QUEST_UPDATE()
	if not InCombatLockdown() then
		AJM:UpdateQuestItemsInBar()
	end
end


function AJM:ITEM_PUSH()
	if AJM.db.showItemUse == false then
		return
	end
	if AJM.db.autoAddQuestItemsToBar == true then
		AJM:ScheduleTimer( "CheckForQuestItemAndAddToBar", 1 )
	end
	if AJM.db.autoAddArtifactItemsToBar == true then
		AJM:ScheduleTimer( "CheckForArtifactItemAndAddToBar", 1 )
	end
	if AJM.db.autoAddSatchelsItemsToBar == true then
		AJM:ScheduleTimer( "CheckForSatchelsItemAndAddToBar", 1 )
	end
end

function AJM:UPDATE_BINDINGS()
	if InCombatLockdown() then
		AJM.refreshUpdateBindingsPending = true
		return
    end
	ClearOverrideBindings( AJM.keyBindingFrame )
	for iterateItems = 1, AJM.maximumNumberOfItems, 1 do
		local containerButtonName = AJM.globalFramePrefix.."ContainerButton"..iterateItems
		local key1, key2 = GetBindingKey( "JAMBAITEMUSE"..iterateItems )
		if key1 then
			SetOverrideBindingClick( AJM.keyBindingFrame, false, key1, containerButtonName )
		end
		if key2 then
			SetOverrideBindingClick( AJM.keyBindingFrame, false, key2, containerButtonName )
		end
	end
end

function AJM:LibSharedMedia_Registered()
end

function AJM:LibSharedMedia_SetGlobal()
end

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