Quantcast
-- copy from inventory module of tukui
-- all credit goes to tukz
local A, L = ...

local Noop = function() end
local ReplaceBags = 0
local NeedBagRefresh, NeedBankRefresh
local LastButtonBag, LastButtonBank
local Token1, Token2, Token3 = BackpackTokenFrameToken1, BackpackTokenFrameToken2, BackpackTokenFrameToken3
local NUM_CONTAINER_FRAMES = NUM_CONTAINER_FRAMES
local NUM_BAG_FRAMES = NUM_BAG_FRAMES
local ContainerFrame_GetOpenFrame = ContainerFrame_GetOpenFrame
local OriginalToggleBag = ToggleBag
local BankFrame = BankFrame
local BagHelpBox = BagHelpBox
local ButtonSize, ButtonSpacing, ItemsPerRow
local Bags = CreateFrame("Frame")
local QuestColor = {1, 1, 0}
local Bag_Normal = 1
local Bag_SoulShard = 2
local Bag_Profession = 3
local Bag_Quiver = 4
local KEYRING_CONTAINER = KEYRING_CONTAINER
local BAGTYPE_QUIVER = 0x0001 + 0x0002
local BAGTYPE_SOUL = 0x004
local BAGTYPE_PROFESSION = 0x0008 + 0x0010 + 0x0020 + 0x0040 + 0x0080 + 0x0200 + 0x0400
local RAID_CLASS_COLORS = RAID_CLASS_COLORS

local BlizzardBags = {
	CharacterBag0Slot,
	CharacterBag1Slot,
	CharacterBag2Slot,
	CharacterBag3Slot,
}

local BagProfessions = {
	[8] = "Leatherworking",
	[16] = "Inscription",
	[32] = "Herb",
	[64] = "Enchanting",
	[128] = "Engineering",
	[512] = "Gem",
	[1024] = "Mining",
	[32768] = "Fishing",
}

local BagSize = {}

function Bags:SetTokensPosition()
	local Money = ContainerFrame1MoneyFrame

	MAX_WATCHED_TOKENS = 2

	-- Set Position
	Token1:ClearAllPoints()
	Token1:SetPoint("LEFT", Money, "RIGHT", 0, -2)
	Token2:ClearAllPoints()
	Token2:SetPoint("LEFT", Token1, "RIGHT", 0, 0)
	Token3:SetParent(L.Hider)

	-- Skin Icons
	Token1.icon:SetTexCoord(0.1, 0.9, 0.1, 0.9)
	Token2.icon:SetTexCoord(0.1, 0.9, 0.1, 0.9)
end

function Bags:GetBagProfessionType(bag)
	local BagType = select(2, GetContainerNumFreeSlots(bag))

	if BagProfessions[BagType] then
		return BagProfessions[BagType]
	end
end

function Bags:GetBagType(bag)
	local bagType = select(2, GetContainerNumFreeSlots(bag))

	if bit.band(bagType, BAGTYPE_QUIVER) > 0 then
		return Bag_Quiver
	elseif bit.band(bagType, BAGTYPE_SOUL) > 0 then
		return Bag_SoulShard
	elseif bit.band(bagType, BAGTYPE_PROFESSION) > 0 then
		return Bag_Profession
	end

	return Bag_Normal
end

function Bags:HideBlizzard()
	local BankPortraitTexture = _G["BankPortraitTexture"]
	local BankSlotsFrame = _G["BankSlotsFrame"]

	BankPortraitTexture:Hide()

	BankFrame:EnableMouse(false)

	for i = 1, 12 do
		local CloseButton = _G["ContainerFrame"..i.."CloseButton"]
		CloseButton:Hide()

		for k = 1, 7 do
			local Container = _G["ContainerFrame"..i]
			select(k, Container:GetRegions()):SetAlpha(0)
		end
	end

	-- Hide Bank Frame Textures
	for i = 1, BankFrame:GetNumRegions() do
		local Region = select(i, BankFrame:GetRegions())

		Region:SetAlpha(0)
	end

	-- Hide BankSlotsFrame Textures and Fonts
	for i = 1, BankSlotsFrame:GetNumRegions() do
		local Region = select(i, BankSlotsFrame:GetRegions())

		Region:SetAlpha(0)
	end
end

function Bags:CreateContainer(storagetype, ...)
	local Container = CreateFrame("Frame", A .. storagetype, UIParent)
	Container:SetScale(1)
	Container:SetWidth(((ButtonSize + ButtonSpacing) * ItemsPerRow) + 22 - ButtonSpacing)
	Container:SetPoint(...)
	Container:SetFrameStrata("MEDIUM")
	Container:SetFrameLevel(1)
	Container:Hide()
    L.F.CreateBackdrop(Container)
	Container:EnableMouse(true)

	if (storagetype == "Bag") then
		local Sort = CreateFrame("Button", nil, Container)
		local Keys = CreateFrame("Button", nil, Container)

		Sort:SetSize(16, 16)
		Sort:SetPoint("TOPRIGHT", Container, "TOPRIGHT", -8, -8)
		Sort.Text = Sort:CreateFontString(nil, "OVERLAY")
        Sort.Text:SetFont(L.C.font, 12)
		Sort.Text:SetJustifyH("LEFT")
		Sort.Text:SetPoint("CENTER")
		Sort.Text:SetText("S")
		Sort:SetScript("OnEnter", GameTooltip_Hide)
		Sort:SetScript("OnClick", function()
			if InCombatLockdown() then
				print("You cannot sort your bag in combat")
				return
			end
			SortBags()
		end)

        Keys:SetSize(16, 16)
        Keys:SetPoint("RIGHT", Sort, "LEFT", -5, 0)
        Keys.Text = Keys:CreateFontString(nil, "OVERLAY")
        Keys.Text:SetFont(L.C.font, 12)
		Keys.Text:SetJustifyH("LEFT")
		Keys.Text:SetPoint("CENTER")
		Keys.Text:SetText("K")
        Keys:SetScript("OnEnter", GameTooltip_Hide)
        Keys:SetScript("OnClick", function()
            if not IsBagOpen(KEYRING_CONTAINER) then
                ToggleBag(KEYRING_CONTAINER)
            else
                ToggleAllBags()
                ToggleAllBags()
            end
        end)

		Container.SortButton = Sort
		Container.Keys = Keys
	else
		local PurchaseButton = BankFramePurchaseButton
		local CostText = BankFrameSlotCost
		local TotalCost = BankFrameDetailMoneyFrame
		local Purchase = BankFramePurchaseInfo
        local CloseButton = BankCloseButton
		local BankBagsContainer = CreateFrame("Frame", nil, Container)
        local ToggleBags = CreateFrame("Button", nil, Container)

		CostText:ClearAllPoints()
		CostText:SetPoint("BOTTOMLEFT", 60, 10)
		TotalCost:ClearAllPoints()
		TotalCost:SetPoint("LEFT", CostText, "RIGHT", 0, 0)
		PurchaseButton:ClearAllPoints()
		PurchaseButton:SetPoint("BOTTOMRIGHT", -10, 10)

		local SortButton = CreateFrame("Button", nil, Container)
		SortButton:SetSize(16, 16)
		SortButton:SetPoint("TOPRIGHT", Container, "TOPRIGHT", -8, -8)

		SortButton.Text = SortButton:CreateFontString(nil, "OVERLAY")
		SortButton.Text:SetFont(L.C.font, 12)
		SortButton.Text:SetJustifyH("LEFT")
		SortButton.Text:SetPoint("CENTER")
		SortButton.Text:SetText("S")
		SortButton:SetScript("OnClick", BankFrame_AutoSortButtonOnClick)

        ToggleBags:SetSize(16, 16)
		ToggleBags:SetPoint("RIGHT", SortButton, "LEFT", -5, 0)
        ToggleBags.Text = ToggleBags:CreateFontString(nil, "OVERLAY")
        ToggleBags.Text:SetFont(L.C.font, 12)
		ToggleBags.Text:SetJustifyH("LEFT")
		ToggleBags.Text:SetPoint("CENTER")
		ToggleBags.Text:SetText("B")
		ToggleBags:SetScript("OnEnter", GameTooltip_Hide)
		ToggleBags:SetScript("OnClick", function(self)
			local BanksContainer = Bags.Bank.BagsContainer

			if (ReplaceBags == 0) then
				ReplaceBags = 1
				BanksContainer:Show()
			else
				ReplaceBags = 0
				BanksContainer:Hide()
			end
		end)

		Purchase:ClearAllPoints()
		Purchase:SetWidth(Container:GetWidth() + 50)
		Purchase:SetHeight(70)
		Purchase:SetPoint("TOP", UIParent, "TOP", 0, -8)

		BankBagsContainer:SetSize(Container:GetWidth(), BankSlotsFrame.Bag1:GetHeight() + ButtonSpacing + ButtonSpacing)
        L.F.CreateBackdrop(BankBagsContainer)
		BankBagsContainer:SetPoint("BOTTOMLEFT", Container, "TOPLEFT", 0, 3)
		BankBagsContainer:SetFrameLevel(Container:GetFrameLevel())
		BankBagsContainer:SetFrameStrata(Container:GetFrameStrata())

		for i = 1, 7 do
			local Bag = BankSlotsFrame["Bag"..i]

			Bag:SetParent(BankBagsContainer)
			Bag:SetWidth(ButtonSize)
			Bag:SetHeight(ButtonSize)
			Bag:ClearAllPoints()

			if i == 1 then
				Bag:SetPoint("TOPLEFT", BankBagsContainer, "TOPLEFT", ButtonSpacing, -ButtonSpacing)
			else
				Bag:SetPoint("LEFT", BankSlotsFrame["Bag"..i-1], "RIGHT", ButtonSpacing, 0)
			end
		end

		BankBagsContainer:SetWidth((ButtonSize * 7) + (ButtonSpacing * (7 + 1)))
		BankBagsContainer:SetHeight(ButtonSize + (ButtonSpacing * 2))
		BankBagsContainer:Hide()

		BankFrame:EnableMouse(false)

		Container.BagsContainer = BankBagsContainer
		Container.SortButton = SortButton
        Container.ToggleBags = ToggleBags
        CloseButton:Hide()
	end

	self[storagetype] = Container
end

function Bags:SlotUpdate(id, button)
	if not button then
		return
	end

	local _, _, _, Rarity, _, _, ItemLink, _, _, ItemID, IsBound = GetContainerItemInfo(id, button:GetID())
	local QuestItem = false
	local IsNewItem = C_NewItems.IsNewItem(id, button:GetID())

	if (button.ItemID == ItemID) then
		return
	end

	if button.Quest then
		button.Quest:Hide()
	end

	button.ItemID = ItemID

	if ItemLink then
		local itemName, itemString, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemTexture = GetItemInfo(ItemLink)

		if itemString then
			if (itemType == TRANSMOG_SOURCE_2) then
				QuestItem = true
			end
		end
	end

	if L.C.showQuest and QuestItem then
		button.Backdrop:SetBackdropBorderColor(1, 1, 0)
	else
		if Rarity and Rarity > LE_ITEM_QUALITY_COMMON then
			button.Backdrop:SetBackdropBorderColor(GetItemQualityColor(Rarity))
        else
			button.Backdrop:SetBackdropBorderColor(unpack(L.C.button.backdrop.borderColor))
		end
	end

	if L.C.flashNew and IsNewItem then
		if not button.Animation then
			button.Animation = button:CreateAnimationGroup()
			button.Animation:SetLooping("BOUNCE")

			button.Animation.FadeOut = button.Animation:CreateAnimation("Alpha")
			button.Animation.FadeOut:SetFromAlpha(1)
			button.Animation.FadeOut:SetToAlpha(.3)
			button.Animation.FadeOut:SetDuration(.3)
			button.Animation.FadeOut:SetSmoothing("IN_OUT")
			button:HookScript("OnEnter", function(self)
				local ItemID = self.ItemID
				local BagID = self:GetID()

				if ItemID and BagID then
					local IsNewItem = C_NewItems.IsNewItem(self.ItemID, self:GetID())

					if not IsNewItem and button.Animation:IsPlaying() then
						button.Animation:Stop()
					end
				end
			end)
		end

		if not button.Animation:IsPlaying() then
			button.Animation:Play()
		end
	end

	if L.C.showItemLevel then
		if ItemLink then
			local Level = GetDetailedItemLevelInfo(ItemLink)
			local _, _, Rarity, _, _, _, _, _, _, _, _, ClassID = GetItemInfo(ItemLink)

			if (ClassID == LE_ITEM_CLASS_ARMOR or ClassID == LE_ITEM_CLASS_WEAPON) and Level > 1 then
				if not button.ItemLevel then
					button.ItemLevel = button:CreateFontString(nil, "ARTWORK")
					button.ItemLevel:SetPoint("TOPRIGHT", 1, -1)
					button.ItemLevel:SetFont(L.C.font, 12, "OUTLINE")
					button.ItemLevel:SetJustifyH("RIGHT")
				end

				button.ItemLevel:SetText(Level)

				if Rarity then
					button.ItemLevel:SetTextColor(GetItemQualityColor(Rarity))
				else
					button.ItemLevel:SetTextColor(1, 1, 1)
				end
			else
				if button.ItemLevel then
					button.ItemLevel:SetText("")
				end
			end
		else
			if button.ItemLevel then
				button.ItemLevel:SetText("")
			end
		end
	end
end

function Bags:BagUpdate(id)
	local Size = GetContainerNumSlots(id)
	local ContainerNumber = IsBagOpen(KEYRING_CONTAINER) and 1 or id + 1

	for Slot = 1, Size do
		local Button = _G["ContainerFrame"..ContainerNumber.."Item"..Slot]

		if Button then
			if not Button:IsShown() then
				Button:Show()
			end

			local BagType = Bags:GetBagType(id)

			if (BagType ~= 1) and (not Button.IsTypeStatusCreated) then
				Button.TypeStatus = CreateFrame("StatusBar", nil, Button)
				Button.TypeStatus:SetPoint("BOTTOMLEFT", 1, 1)
				Button.TypeStatus:SetPoint("BOTTOMRIGHT", -1, 1)
				Button.TypeStatus:SetHeight(3)
				Button.TypeStatus:SetFrameStrata(Button:GetFrameStrata())
				Button.TypeStatus:SetFrameLevel(Button:GetFrameLevel())
				Button.TypeStatus:SetStatusBarTexture(L.C.backdrop.bgFile)

				Button.IsTypeStatusCreated = true
			end

			if BagType == 2 then
				-- Warlock Soul Shards Slots
                local color = RAID_CLASS_COLORS["WARLOCK"]
				Button.TypeStatus:SetStatusBarColor(color.r, color.g, color.b)
			elseif BagType == 3 then
				local ProfessionType = Bags:GetBagProfessionType(id)

				if ProfessionType == "Leatherworking" then
					Button.TypeStatus:SetStatusBarColor(102/255, 51/255, 0/255)
				elseif ProfessionType == "Inscription" then
					Button.TypeStatus:SetStatusBarColor(204/255, 204/255, 0/255)
				elseif ProfessionType == "Herb" then
					Button.TypeStatus:SetStatusBarColor(0/255, 153/255, 0/255)
				elseif ProfessionType == "Enchanting" then
					Button.TypeStatus:SetStatusBarColor(230/255, 25/255, 128/255)
				elseif ProfessionType == "Engineering" then
					Button.TypeStatus:SetStatusBarColor(25/255, 230/255, 230/255)
				elseif ProfessionType == "Gem" then
					Button.TypeStatus:SetStatusBarColor(232/255, 252/255, 252/255)
				elseif ProfessionType == "Mining" then
					Button.TypeStatus:SetStatusBarColor(138/255, 40/255, 40/255)
				elseif ProfessionType == "Fishing" then
					Button.TypeStatus:SetStatusBarColor(54/255, 54/255, 226/255)
				end
			elseif BagType == 4 then
				-- Hunter Quiver Slots
                local color = RAID_CLASS_COLORS["HUNTER"]
				Button.TypeStatus:SetStatusBarColor(color.r, color.g, color.b)
			end

			self:SlotUpdate(id, Button)
		end
	end
end

function Bags:UpdateAllBags()
	-- check if containers changed
	if not NeedBagRefresh then
		for i = 1, 5 do
			local ContainerSize = _G["ContainerFrame"..i].size

			if ContainerSize ~= BagSize[i] then
				NeedBagRefresh = true

				BagSize[i] = ContainerSize
			end
		end

		if (not NeedBagRefresh) then
			return
		end
	end

	-- Refresh layout if a refresh if found
	local NumRows, LastRowButton, NumButtons, LastButton = 0, ContainerFrame1Item1, 1, ContainerFrame1Item1
	local FirstButton

	for Bag = 1, 5 do
		local ID = Bag - 1

		if IsBagOpen(KEYRING_CONTAINER) then
			ID = -2
		end

		local Slots = GetContainerNumSlots(ID)

		for Item = Slots, 1, -1 do
			local Button = _G["ContainerFrame"..Bag.."Item"..Item]
			local Money = ContainerFrame1MoneyFrame

			if not FirstButton then
				FirstButton = Button
			end

			Button:ClearAllPoints()
			Button:SetWidth(ButtonSize)
			Button:SetHeight(ButtonSize)
			Button:SetScale(1)

			Button.newitemglowAnim:Stop()
			Button.newitemglowAnim.Play = Noop

			Button.flashAnim:Stop()
			Button.flashAnim.Play = Noop

			if (Button == FirstButton) then
				Button:SetPoint("TOPLEFT", Bags.Bag, "TOPLEFT", 10, -30)
				LastRowButton = Button
				LastButton = Button
			elseif (NumButtons == ItemsPerRow) then
				Button:SetPoint("TOPRIGHT", LastRowButton, "TOPRIGHT", 0, -(ButtonSpacing + ButtonSize))
				Button:SetPoint("BOTTOMLEFT", LastRowButton, "BOTTOMLEFT", 0, -(ButtonSpacing + ButtonSize))
				LastRowButton = Button
				NumRows = NumRows + 1
				NumButtons = 1
			else
				Button:SetPoint("TOPRIGHT", LastButton, "TOPRIGHT", (ButtonSpacing + ButtonSize), 0)
				Button:SetPoint("BOTTOMLEFT", LastButton, "BOTTOMLEFT", (ButtonSpacing + ButtonSize), 0)
				NumButtons = NumButtons + 1
			end

			LastButton = Button

            rButtonTemplate:StyleItemButton(Button, L.C.button)
            -- Button:SetFrameLevel(0)
            -- Button.Backdrop:SetFrameLevel(Button:GetFrameLevel())

			if not Money.IsMoved then
				Money:ClearAllPoints()
				Money:Show()
				Money:SetPoint("TOPLEFT", Bags.Bag, "TOPLEFT", 8, -10)
				Money:SetScale(1)
				Money.IsMoved = true
			end
		end

		Bags:BagUpdate(ID)

		if IsBagOpen(KEYRING_CONTAINER) then
			break
		end
	end

	NeedBagRefresh = false

	self.Bag:SetHeight(((ButtonSize + ButtonSpacing) * (NumRows + 1) + L.C.bag.extraHeight + (ButtonSpacing * 4)) - ButtonSpacing)
end

function Bags:UpdateAllBankBags()
	-- check if containers changed
	for i = 6, 13 do
		local ContainerSize = _G["ContainerFrame"..i].size

		if ContainerSize ~= BagSize[i] then
			NeedBankRefresh = true

			BagSize[i] = ContainerSize
		end
	end

	if not NeedBankRefresh then
		return
	end

	local NumRows, LastRowButton, NumButtons, LastButton = 0, ContainerFrame1Item1, 1, ContainerFrame1Item1
	local BankFrameMoneyFrame = BankFrameMoneyFrame

	for Bank = 1, 28 do
		local Button = _G["BankFrameItem"..Bank]
		local Money = ContainerFrame2MoneyFrame

		Button:ClearAllPoints()
		Button:SetWidth(ButtonSize)
		Button:SetHeight(ButtonSize)
		Button:SetScale(1)
		Button.IconBorder:SetAlpha(0)

		if (Bank == 1) then
			Button:SetPoint("TOPLEFT", Bags.Bank, "TOPLEFT", 10, -30)
			LastRowButton = Button
			LastButton = Button
		elseif (NumButtons == ItemsPerRow) then
			Button:SetPoint("TOPRIGHT", LastRowButton, "TOPRIGHT", 0, -(ButtonSpacing + ButtonSize))
			Button:SetPoint("BOTTOMLEFT", LastRowButton, "BOTTOMLEFT", 0, -(ButtonSpacing + ButtonSize))
			LastRowButton = Button
			NumRows = NumRows + 1
			NumButtons = 1
		else
			Button:SetPoint("TOPRIGHT", LastButton, "TOPRIGHT", (ButtonSpacing + ButtonSize), 0)
			Button:SetPoint("BOTTOMLEFT", LastButton, "BOTTOMLEFT", (ButtonSpacing + ButtonSize), 0)
			NumButtons = NumButtons + 1
		end

        rButtonTemplate:StyleItemButton(Button, L.C.button)
        -- Button:SetFrameLevel(0)
        -- Button.Backdrop:SetFrameLevel(Button:GetFrameLevel())
		Bags.SlotUpdate(self, -1, Button)

		LastButton = Button
	end

	BankFrameMoneyFrame:Hide()

	for Bag = 6, 12 do
		local Slots = GetContainerNumSlots(Bag - 1)

		for Item = Slots, 1, -1 do
			local Button = _G["ContainerFrame"..Bag.."Item"..Item]

			Button:ClearAllPoints()
			Button:SetWidth(ButtonSize)
			Button:SetHeight(ButtonSize)
			Button:SetScale(1)
			Button.IconBorder:SetAlpha(0)

			if (NumButtons == ItemsPerRow) then
				Button:SetPoint("TOPRIGHT", LastRowButton, "TOPRIGHT", 0, -(ButtonSpacing + ButtonSize))
				Button:SetPoint("BOTTOMLEFT", LastRowButton, "BOTTOMLEFT", 0, -(ButtonSpacing + ButtonSize))
				LastRowButton = Button
				NumRows = NumRows + 1
				NumButtons = 1
			else
				Button:SetPoint("TOPRIGHT", LastButton, "TOPRIGHT", (ButtonSpacing+ButtonSize), 0)
				Button:SetPoint("BOTTOMLEFT", LastButton, "BOTTOMLEFT", (ButtonSpacing+ButtonSize), 0)
				NumButtons = NumButtons + 1
			end

            rButtonTemplate:StyleItemButton(Button, L.C.button)
            -- Button:SetFrameLevel(0)
            -- Button.Backdrop:SetFrameLevel(Button:GetFrameLevel())
			Bags.SlotUpdate(self, Bag - 1, Button)

			LastButton = Button
		end
	end

	NeedBankRefresh = false

	Bags.Bank:SetHeight(((ButtonSize + ButtonSpacing) * (NumRows + 1) + L.C.bank.extraHeight) - ButtonSpacing)
end

function Bags:OpenBag(id)
	if (not CanOpenPanels()) then
		if (UnitIsDead("player")) then
			NotWhileDeadError()
		end

		return
	end

	local Size = GetContainerNumSlots(id)
	local OpenFrame = ContainerFrame_GetOpenFrame()

	for i = 1, 40 do
		local Index = Size - i + 1
		local Button = _G[OpenFrame:GetName().."Item"..i]

		if Button then
			if (i > Size) then
				Button:Hide()
			else
				Button:SetID(Index)
				Button:Show()
			end
		end
	end

	OpenFrame.size = Size
	OpenFrame:SetID(id)
	OpenFrame:Show()

	if (id == 4) then
		Bags:UpdateAllBags()
	end
end

function Bags:CloseBag(id)
	CloseBag(id)
end

function Bags:OpenAllBags()
	self:OpenBag(0)

	for i = 1, 4 do
		self:OpenBag(i)
	end

	if IsBagOpen(0) then
		self.Bag:Show()

		if not self.Bag.MoverAdded then
            --create drag frame
            rLib:CreateDragFrame(self.Bag, L.dragFrames, -2, true)
			self.Bag.MoverAdded = true
		end
	end
end

function Bags:OpenAllBankBags()
	local Bank = BankFrame

	if Bank:IsShown() then
		self.Bank:Show()

		if not self.Bank.MoverAdded then
			--create drag frame
            rLib:CreateDragFrame(self.Bank, L.dragFrames, -2, true)
			self.Bank.MoverAdded = true
		end

		for i = 5, 11 do
			if (not IsBagOpen(i)) then
				self:OpenBag(i, 1)
			end
		end
	end
end

function Bags:CloseAllBags()
	if MerchantFrame:IsVisible() or InboxFrame:IsVisible() then
		return
	end

	CloseAllBags()

	if IsBagOpen(KEYRING_CONTAINER) then
		CloseBag(KEYRING_CONTAINER)
	end

	PlaySound(SOUNDKIT.IG_BACKPACK_CLOSE)
end

function Bags:CloseAllBankBags()
	local Bank = BankFrame

	if (Bank:IsVisible()) then
		CloseBankBagFrames()
		CloseBankFrame()
	end
end

function Bags:ToggleBags(id, openonly)
	if id == KEYRING_CONTAINER then
		if not IsBagOpen(KEYRING_CONTAINER) then
			CloseAllBags()
			CloseBankBagFrames()
			CloseBankFrame()

			NeedBagRefresh = true

			Bags:OpenBag(id)
			Bags:UpdateAllBags()

			NeedBagRefresh = true
		else
			CloseBag(id)
		end
	else
		if (self.Bag:IsShown() and BankFrame:IsShown()) and (not self.Bank:IsShown()) then
			self:OpenAllBankBags()
			return
		end

		if (not openonly) and (self.Bag:IsShown() or self.Bank:IsShown()) then
			if MerchantFrame:IsVisible() or InboxFrame:IsVisible() then
				return
			end

			self:CloseAllBags()
			self:CloseAllBankBags()

			return
		end

		if not self.Bag:IsShown() then
			self:OpenAllBags()
		end

		if not self.Bank:IsShown() and BankFrame:IsShown() then
			self:OpenAllBankBags()
		end
	end
end

function Bags:OnEvent(event, ...)
	if (event == "BAG_UPDATE") then
		if not IsBagOpen(KEYRING_CONTAINER) then
			self:BagUpdate(...)
		else
			self:BagUpdate(-2)
		end
	elseif (event == "MERCHANT_CLOSED" or event ==  "MAIL_CLOSED") then
		CloseAllBags()
	elseif (event == "CURRENCY_DISPLAY_UPDATE") then
		BackpackTokenFrame_Update()
	elseif (event == "BAG_CLOSED") then
		-- This is usually where the client find a bag swap in character or bank slots.

		local Bag = ... + 1

		-- We need to hide buttons from a bag when closing it because they are not parented to the original frame
		local Container = _G["ContainerFrame"..Bag]
		local Size = Container.size

		if Size then
			for i = 1, Size do
				local Button = _G["ContainerFrame"..Bag.."Item"..i]

				if Button then
					Button:Hide()
				end
			end
		end

		-- We close to refresh the all in one layout.
		self:CloseAllBags()
		self:CloseAllBankBags()
	elseif (event == "PLAYERBANKSLOTS_CHANGED") then
		local ID = ...
		if ID <= 28 then
			local Button = _G["BankFrameItem"..ID]

			if (Button) then
				self:SlotUpdate(-1, Button)
			end
		end
	elseif (event == "PLAYERREAGENTBANKSLOTS_CHANGED") then
		local ID = ...
		local Button = _G["ReagentBankFrameItem"..ID]
		if (Button) then
			self:SlotUpdate(-3, Button)
		end
	elseif (event == "BANKFRAME_CLOSED") then
		local Bank = self.Bank
		self:CloseAllBags()
		self:CloseAllBankBags()
	elseif (event == "BANKFRAME_OPENED") then
		local Bank = self.Bank
		Bank:Show()
		self:UpdateAllBankBags()
	elseif (event == "SOULBIND_FORGE_INTERACTION_STARTED") then
		self:OpenAllBags()
		ItemButtonUtil.OpenAndFilterBags(SoulbindViewer)
	elseif (event == "SOULBIND_FORGE_INTERACTION_ENDED") then
		self:CloseAllBags()
	end
end

function Bags:Enable()
	if L.C.sort.sortToBottom then
		SetSortBagsRightToLeft(false)
	else
		SetSortBagsRightToLeft(true)
	end
	SetInsertItemsLeftToRight(false)

	-- Bug with mouse click
	GroupLootContainer:EnableMouse(false)

	ButtonSize = L.C.icon.size
	ButtonSpacing = L.C.icon.spacing
	ItemsPerRow = L.C.icon.columns

	local Bag = ContainerFrame1
	local BankItem1 = BankFrameItem1

	self:CreateContainer("Bag", unpack(L.C.bag.point))
	self:CreateContainer("Bank", unpack(L.C.bank.point))
	self:HideBlizzard()

	Bag:SetScript("OnHide", function()
		self.Bag:Hide()
	end)

	Bag:HookScript("OnShow", function() -- Cinematic Bug with Bags open.
		self.Bag:Show()
	end)

	BankItem1:SetScript("OnHide", function()
		self.Bank:Hide()
	end)

	-- Rewrite Blizzard Bags Functions
	function UpdateContainerFrameAnchors() end
	function ToggleBag(id) ToggleAllBags(id) end
	function ToggleBackpack() ToggleAllBags() end
	function OpenAllBags() ToggleAllBags(1, true) end
	function OpenBackpack() ToggleAllBags(1, true) end
	function ToggleAllBags(id, openonly) self:ToggleBags(id, openonly) end

	-- Destroy bubbles help boxes
	for i = 1, 13 do
		local HelpBox = _G["ContainerFrame"..i.."ExtraBagSlotsHelpBox"]

		if HelpBox then
            HelpBox:Hide()
			HelpBox:SetParent(L.Hider)
		end
	end

	OpenAllBagsMatchingContext = function() return 4 end

	-- Register Events for Updates
	self:RegisterEvent("BAG_UPDATE")
	self:RegisterEvent("PLAYERBANKSLOTS_CHANGED")
	self:RegisterEvent("BAG_CLOSED")
	self:RegisterEvent("BANKFRAME_CLOSED")
	self:RegisterEvent("BANKFRAME_OPENED")
	self:RegisterEvent("MERCHANT_CLOSED")
	self:RegisterEvent("MAIL_CLOSED")
	self:SetScript("OnEvent", self.OnEvent)

	for i = 1, 13 do
		_G["ContainerFrame"..i]:EnableMouse(false)
	end

	-- fix for wrath
	ContainerFrame1.SetHeight = function() return end

	ToggleAllBags()
	ToggleAllBags()
end

rBag.Bags = Bags