Quantcast

* Fixed crash with picking up trash equipment

Brandon Talbot [07-04-16 - 19:29]
* Fixed crash with picking up trash equipment
* Fixed search crash
* Added bag bar
* Added bank bag
* Added reagent bag
Filename
.idea/misc.xml
DJBags.toc
src/lua/cache/cache.lua
src/lua/controllers/bag.lua
src/lua/controllers/bank.lua
src/lua/core.lua
src/lua/elements/bagBar.lua
src/lua/elements/bagItem.lua
src/lua/elements/categoryContainer.lua
src/lua/elements/item.lua
src/lua/elements/mainBar.lua
src/lua/event/eventManager.lua
src/lua/settings/defaults/bagItem.lua
src/lua/utils/utils.lua
src/manifest.xml
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 2c9fc54..921071f 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,5 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
+  <component name="EntryPointsManager">
+    <entry_points version="2.0" />
+  </component>
   <component name="MavenImportPreferences">
     <option name="generalSettings">
       <MavenGeneralSettings>
diff --git a/DJBags.toc b/DJBags.toc
index 7fecc7e..e953e0d 100644
--- a/DJBags.toc
+++ b/DJBags.toc
@@ -2,7 +2,7 @@
 ## Title: DJBags
 ## Author: DarkJaguar91
 ## Notes: BagAddon - BETA
-## Version: 0.1.1
+## Version: 0.2.0
 ## SavedVariables: DJBagsConfig

 src/manifest.xml
\ No newline at end of file
diff --git a/src/lua/cache/cache.lua b/src/lua/cache/cache.lua
index 34208bb..20834eb 100644
--- a/src/lua/cache/cache.lua
+++ b/src/lua/cache/cache.lua
@@ -6,6 +6,8 @@ ADDON.cache.__index = ADDON.cache
 local cache = ADDON.cache
 cache.items = {}
 cache.bagContainers = {}
+cache.bankContainers = {}
+cache.reagentContainers = {}

 function cache:GetItem(bag, slot)
     self.items[bag] = self.items[bag] or {}
@@ -18,6 +20,16 @@ function cache:GetBagItemContainer(name)
     return self.bagContainers[name]
 end

+function cache:GetBankItemContainer(name)
+    self.bankContainers[name] = self.bankContainers[name] or ADDON.itemContainer(name, name ~= ADDON.utils.EMPTY_BAG_NAME, nil, name == ADDON.utils.EMPTY_BAG_NAME)
+    return self.bankContainers[name]
+end
+
+function cache:GetReagentItemContainer(name)
+    self.reagentContainers[name] = self.reagentContainers[name] or ADDON.itemContainer(name, name ~= ADDON.utils.EMPTY_BAG_NAME, nil, name == ADDON.utils.EMPTY_BAG_NAME)
+    return self.reagentContainers[name]
+end
+
 function cache:UpdateSettings(arrange)
     for _, slots in pairs(self.items) do
         for _, item in pairs(slots) do
diff --git a/src/lua/controllers/bag.lua b/src/lua/controllers/bag.lua
index 448032a..ce040e7 100644
--- a/src/lua/controllers/bag.lua
+++ b/src/lua/controllers/bag.lua
@@ -13,7 +13,9 @@ function bag:Init()
     self.frame.mainBar = ADDON.mainBar(self.frame)
     self.frame.mainBar:SetPoint('TOPRIGHT', self.frame, 'BOTTOMRIGHT', 0, -2)
     self.frame.mainBar:Show()
-    ADDON.eventManager:AddEvent(self, 'SETTINGS_UPDATE')
+    self.frame.bagBar = ADDON.bagBar(self.frame)
+    self.frame.bagBar:SetPoint('TOPRIGHT', self.frame.mainBar, 'BOTTOMRIGHT', 0, -3)
+    self.frame.mainBar:SetBagFrame(self.frame.bagBar)

     self.frame:HookScript('OnShow', function()
         self:Register()
@@ -26,6 +28,7 @@ end
 function bag:Open()
     self:UpdateAllItems()
     self.frame.mainBar:Update()
+    self.frame.bagBar:Update()
     self.frame:Show()
 end

@@ -41,47 +44,12 @@ function bag:Toggle()
     end
 end

-local function UpdateItemsForBag(self, bag, arrangeList)
-    local count = GetContainerNumSlots(bag)
-    if count == 0 and ADDON.cache.items[bag] then
-        for _, item in pairs(ADDON.cache.items[bag]) do
-            if item:GetParent() and item:GetParent().__class == ADDON.itemContainer.__class then
-                local previousContainer = item:GetParent()
-                previousContainer:RemoveItem(item)
-                arrangeList[previousContainer] = true
-                item:Hide()
-            end
-        end
-    else
-        for slot = 1, count do
-            local item = ADDON.cache:GetItem(bag, slot)
-            local previousContainer
-            if item:GetParent() and item:GetParent().__class == ADDON.itemContainer.__class then
-                previousContainer = item:GetParent()
-            end
-
-            item:Update()
-
-            local newContainer = ADDON.cache:GetBagItemContainer(ADDON.utils:GetItemContainerName(bag, slot))
-            self.frame:AddContainer(newContainer)
-
-            if previousContainer ~= newContainer then
-                if previousContainer then
-                    previousContainer:RemoveItem(item)
-                    arrangeList[previousContainer] = true
-                end
-                newContainer:AddItem(item)
-                arrangeList[newContainer] = true
-            end
-        end
-    end
-end
-
 function bag:UpdateAllItems()
     local arrangeList = {}
     for bag = 0, NUM_BAG_SLOTS do
-        UpdateItemsForBag(self, bag, arrangeList)
+        ADDON.utils:UpdateItemsForBag(self.frame, bag, arrangeList, ADDON.cache.GetBagItemContainer)
     end
+    self:CheckForRemovedItems(arrangeList)
     for container, _ in pairs(arrangeList) do
         container:Arrange()
     end
@@ -90,7 +58,8 @@ end

 function bag:UpdateAllItemsForBag(bag)
     local arrangeList = {}
-    UpdateItemsForBag(self, bag, arrangeList)
+    ADDON.utils:UpdateItemsForBag(self.frame, bag, arrangeList, ADDON.cache.GetBagItemContainer)
+    self:CheckForRemovedItems(arrangeList)
     for container, _ in pairs(arrangeList) do
         container:Arrange()
     end
@@ -103,6 +72,7 @@ function bag:Register()
     ADDON.eventManager:AddEvent(self, 'BAG_UPDATE_COOLDOWN')
     ADDON.eventManager:AddEvent(self, 'ITEM_LOCK_CHANGED')
     ADDON.eventManager:AddEvent(self, 'PLAYER_MONEY')
+    ADDON.eventManager:AddEvent(self, 'BAG_UPDATE_DELAYED')
 end

 function bag:UnRegister()
@@ -111,12 +81,14 @@ function bag:UnRegister()
     ADDON.eventManager:RemoveEvent(self, 'BAG_UPDATE_COOLDOWN')
     ADDON.eventManager:RemoveEvent(self, 'ITEM_LOCK_CHANGED')
     ADDON.eventManager:RemoveEvent(self, 'PLAYER_MONEY')
+    ADDON.eventManager:RemoveEvent(self, 'BAG_UPDATE_DELAYED')
 end

 function bag:UpdateSettings(arrange)
     self.frame:Setup()
     self.frame.mainBar:Setup()
     self.frame.mainBar:Update()
+    self.frame.bagBar:Setup()
     if self.frame:IsVisible() and arrange then
         self:Open()
     end
@@ -134,7 +106,8 @@ end

 function bag:INVENTORY_SEARCH_UPDATE()
     for bag = 0, NUM_BAG_SLOTS do
-        for _, item in pairs(ADDON.cache:GetItemsForBag(bag)) do
+        for slot = 1, GetContainerNumSlots(bag) do
+            local item = ADDON.cache:GetItem(bag, slot)
             item:UpdateSearch()
         end
     end
@@ -153,4 +126,17 @@ function bag:ITEM_LOCK_CHANGED(bag, slot)
     if bag >= 0 and bag <= NUM_BAG_SLOTS then
         ADDON.cache:GetItem(bag, slot):UpdateLock()
     end
+    self.frame.bagBar:UpdateLock(bag)
+end
+
+function bag:BAG_UPDATE_DELAYED()
+    self.frame.bagBar:Update()
+end
+
+function bag:CheckForRemovedItems(arrangeList)
+    for bag = 1, NUM_BAG_SLOTS do
+        if GetContainerNumSlots(bag) == 0 and ADDON.cache.items[bag] then
+            ADDON.utils:UpdateItemsForBag(self.frame, bag, arrangeList, ADDON.cache.GetBagItemContainer)
+        end
+    end
 end
\ No newline at end of file
diff --git a/src/lua/controllers/bank.lua b/src/lua/controllers/bank.lua
new file mode 100644
index 0000000..2299599
--- /dev/null
+++ b/src/lua/controllers/bank.lua
@@ -0,0 +1,326 @@
+local NAME, ADDON = ...
+
+ADDON.bank = {}
+ADDON.bank.__index = ADDON.bank
+
+local bank = ADDON.bank
+
+function bank:Init()
+    self.frame = ADDON.container('DJBagsBankMainBar')
+    self:InitMainBar()
+
+    self.bankContainer = ADDON.categoryContainer('DJBagsBankCategoryContainer', self.frame)
+    self.bankContainer:SetPoint('TOPLEFT', self.frame, 'BOTTOMLEFT', 0, -5)
+    self.bankContainer:SetScript("OnDragStart", function(_, ...)
+        self.frame:StartMoving(...)
+    end)
+    self.bankContainer:SetScript("OnDragStop", function(_, ...)
+        self.frame:StopMovingOrSizing(...)
+    end)
+
+    self.reagentContainer = ADDON.categoryContainer('DJBagsReagentBankCategoryContainer', self.frame)
+    self.reagentContainer:SetSize(10, 10)
+    self.reagentContainer:SetPoint('TOPLEFT', self.frame, 'BOTTOMLEFT', 0, -34)
+    self.reagentContainer:SetScript("OnDragStart", function(_, ...)
+        self.frame:StartMoving(...)
+    end)
+    self.reagentContainer:SetScript("OnDragStop", function(_, ...)
+        self.frame:StopMovingOrSizing(...)
+    end)
+    self.reagentButton = CreateFrame('BUTTON', 'DJBagsBankBarReagentDepositButton', self.reagentContainer, 'UIPanelButtonTemplate')
+    self.reagentButton:SetScript('OnClick', bank.ReagentButtonClick)
+    self.reagentButton:SetHeight(24)
+    self.reagentButton:SetPoint('BOTTOMLEFT', self.reagentContainer, 'TOPLEFT', 0, 5)
+
+    self.frame:HookScript('OnShow', self.OnShow)
+    self.frame:HookScript('OnHide', self.OnHide)
+
+    ADDON.eventManager:AddEvent(self, "BANKFRAME_OPENED")
+    ADDON.eventManager:AddEvent(self, "BANKFRAME_CLOSED")
+    BankFrame:UnregisterAllEvents()
+end
+
+function bank:UpdateSettings(arrange)
+    self.frame:Setup()
+    self.bankContainer:Setup()
+    self.reagentContainer:Setup()
+    if self.frame:IsVisible() and arrange then
+        self:UpdateAllItems()
+    end
+end
+
+function bank:BANKFRAME_OPENED()
+    self.frame:Show()
+end
+
+function bank:BANKFRAME_CLOSED()
+    self.frame:Hide()
+end
+
+function bank:ReagentButtonClick()
+    if IsReagentBankUnlocked() then
+        PlaySound("igMainMenuOption");
+        DepositReagentBank();
+    else
+        PlaySound("igMainMenuOption");
+        StaticPopup_Show("CONFIRM_BUY_REAGENTBANK_TAB");
+    end
+end
+
+function bank:OnShow()
+    PlaySound("igMainMenuOpen")
+    ADDON.bag:Open()
+    bank:Register()
+    bank:UpdateAllItems()
+    bank:UpdateBags()
+    PanelTemplates_SetTab(self, 1)
+    bank.bankContainer:Show()
+    bank.reagentContainer:Hide()
+end
+
+function bank:OnHide()
+    PlaySound("igMainMenuClose")
+    CloseAllBags(self);
+    CloseBankBagFrames();
+    CloseBankFrame();
+    StaticPopup_Hide("CONFIRM_BUY_BANK_SLOT")
+    bank:UnRegister()
+end
+
+function bank:UpdateAllItems()
+    local arrangeList = {}
+    ADDON.utils:UpdateItemsForBag(self.bankContainer, BANK_CONTAINER, arrangeList, ADDON.cache.GetBankItemContainer)
+    for bag = NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + GetNumBankSlots() do
+        ADDON.utils:UpdateItemsForBag(self.bankContainer, bag, arrangeList, ADDON.cache.GetBankItemContainer)
+    end
+    for container, _ in pairs(arrangeList) do
+        container:Arrange()
+    end
+    self.bankContainer:Arrange()
+
+    self:UpdateReagentBank()
+end
+
+function bank:UpdateReagentBank()
+    if IsReagentBankUnlocked() then
+        local arrangeList = {}
+        ADDON.utils:UpdateItemsForBag(self.reagentContainer, REAGENTBANK_CONTAINER, arrangeList, ADDON.cache.GetReagentItemContainer)
+        for container, _ in pairs(arrangeList) do
+            container:Arrange()
+        end
+        self.reagentContainer:Arrange()
+        self.reagentButton:SetText(REAGENTBANK_DEPOSIT)
+        self.reagentButton:SetWidth(self.reagentButton:GetFontString():GetStringWidth() + 31)
+    else
+        self.reagentButton:SetText(BANKSLOTPURCHASE)
+        self.reagentButton:SetWidth(self.reagentButton:GetFontString():GetStringWidth() + 31)
+    end
+end
+
+function bank:UpdateAllItemsForBag(bag)
+    local arrangeList = {}
+    ADDON.utils:UpdateItemsForBag(self.bankContainer, bag, arrangeList, ADDON.cache.GetBankItemContainer)
+    for container, _ in pairs(arrangeList) do
+        container:Arrange()
+    end
+    self.bankContainer:Arrange()
+end
+
+function bank:Register()
+    ADDON.eventManager:AddEvent(self, 'PLAYERBANKSLOTS_CHANGED')
+    ADDON.eventManager:AddEvent(self, 'BAG_UPDATE')
+    ADDON.eventManager:AddEvent(self, 'INVENTORY_SEARCH_UPDATE')
+    ADDON.eventManager:AddEvent(self, 'BAG_UPDATE_COOLDOWN')
+    ADDON.eventManager:AddEvent(self, 'ITEM_LOCK_CHANGED')
+    ADDON.eventManager:AddEvent(self, 'PLAYERREAGENTBANKSLOTS_CHANGED')
+    ADDON.eventManager:AddEvent(self, 'PLAYERBANKBAGSLOTS_CHANGED')
+    ADDON.eventManager:AddEvent(self, 'REAGENTBANK_PURCHASED')
+end
+
+function bank:UnRegister()
+    ADDON.eventManager:RemoveEvent(self, 'PLAYERBANKSLOTS_CHANGED')
+    ADDON.eventManager:RemoveEvent(self, 'BAG_UPDATE')
+    ADDON.eventManager:RemoveEvent(self, 'INVENTORY_SEARCH_UPDATE')
+    ADDON.eventManager:RemoveEvent(self, 'BAG_UPDATE_COOLDOWN')
+    ADDON.eventManager:RemoveEvent(self, 'ITEM_LOCK_CHANGED')
+    ADDON.eventManager:RemoveEvent(self, 'PLAYERREAGENTBANKSLOTS_CHANGED')
+    ADDON.eventManager:RemoveEvent(self, 'PLAYERBANKBAGSLOTS_CHANGED')
+    ADDON.eventManager:RemoveEvent(self, 'REAGENTBANK_PURCHASED')
+end
+
+function bank:PLAYERBANKBAGSLOTS_CHANGED()
+    self:UpdateBags()
+end
+
+function bank:BAG_UPDATE(bag)
+    if bag > NUM_BAG_SLOTS then
+        self:UpdateAllItemsForBag(bag)
+    end
+end
+
+function bank:PLAYERBANKSLOTS_CHANGED(slot)
+    if slot <= NUM_BANKGENERIC_SLOTS then
+        self:UpdateAllItemsForBag(BANK_CONTAINER)
+    else
+        self.bags[slot-NUM_BANKGENERIC_SLOTS]:Update()
+    end
+end
+
+function bank:PLAYERREAGENTBANKSLOTS_CHANGED()
+    self:UpdateReagentBank()
+end
+
+function bank:REAGENTBANK_PURCHASED()
+    self:UpdateReagentBank()
+end
+
+function bank:INVENTORY_SEARCH_UPDATE()
+    for bag = NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + GetNumBankSlots() do
+        for slot = 1, GetContainerNumSlots(bag) do
+            ADDON.cache:GetItem(bag, slot):UpdateSearch()
+        end
+    end
+    for slot = 1, GetContainerNumSlots(BANK_CONTAINER) do
+        ADDON.cache:GetItem(BANK_CONTAINER, slot):UpdateSearch()
+    end
+    if IsReagentBankUnlocked() then
+        for slot = 1, GetContainerNumSlots(REAGENTBANK_CONTAINER) do
+            ADDON.cache:GetItem(REAGENTBANK_CONTAINER, slot):UpdateSearch()
+        end
+    end
+end
+
+function bank:BAG_UPDATE_COOLDOWN()
+    for bag = NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + GetNumBankSlots() do
+        for slot = 1, GetContainerNumSlots(bag) do
+            ADDON.cache:GetItem(bag, slot):UpdateCooldown()
+        end
+    end
+    for slot = 1, GetContainerNumSlots(BANK_CONTAINER) do
+        ADDON.cache:GetItem(BANK_CONTAINER, slot):UpdateCooldown()
+    end
+    if IsReagentBankUnlocked() then
+        for slot = 1, GetContainerNumSlots(REAGENTBANK_CONTAINER) do
+            ADDON.cache:GetItem(REAGENTBANK_CONTAINER, slot):UpdateCooldown()
+        end
+    end
+end
+
+function bank:ITEM_LOCK_CHANGED(bag, slot)
+    if bag ~= BANK_CONTAINER and bag ~= REAGENTBANK_CONTAINER and bag <= NUM_BAG_SLOTS then return end
+
+    if bag == BANK_CONTAINER and slot > NUM_BANKGENERIC_SLOTS then
+        self.bags[slot-NUM_BANKGENERIC_SLOTS]:UpdateLock()
+    elseif slot then
+        ADDON.cache:GetItem(bag, slot):UpdateLock()
+    end
+end
+
+function bank:InitMainBar()
+    table.insert(UISpecialFrames, self.frame:GetName())
+    self.frame:SetMovable(true)
+    self.frame:EnableMouse(true)
+    self.frame:RegisterForDrag("LeftButton")
+    self.frame:SetScript("OnDragStart", self.frame.StartMoving)
+    self.frame:SetScript("OnDragStop", self.frame.StopMovingOrSizing)
+    self.frame:SetPoint('TOPLEFT', 200, -100)
+    self.frame:SetUserPlaced(true)
+    self.frame:Hide()
+    self.bags = {}
+
+    self.emptyBag = CreateFrame('BUTTON', 'DJBagsBankEmptyContainer', self.frame)
+    self.emptyBag:SetBackdrop({
+        bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
+        edgeFile = "Interface\\Buttons\\WHITE8x8",
+        tile = true,
+        tileSize = 16,
+        edgeSize = 1,
+    })
+    self.emptyBag:SetBackdropBorderColor(1, 0, 0, 1)
+    self.emptyBag:SetBackdropColor(0, 0, 0, 0)
+    self.emptyBag.money = CreateFrame('Frame', 'DJBagsBankBagBost', self.emptyBag, 'SmallMoneyFrameTemplate')
+    self.emptyBag.money:SetPoint('CENTER', 6, 0)
+    self.emptyBag:SetPoint("TOPRIGHT", -5, -5)
+    self.emptyBag:SetScript('OnClick', function()
+        PlaySound("igMainMenuOption");
+        StaticPopup_Show("CONFIRM_BUY_BANK_SLOT");
+    end)
+    SmallMoneyFrame_OnLoad(self.emptyBag.money)
+    MoneyFrame_SetType(self.emptyBag.money, "STATIC")
+
+    self.searchBar = CreateFrame('EDITBOX', 'DJBagsBankSearch', self.frame, 'BagSearchBoxTemplate')
+    self.searchBar:SetPoint('BOTTOMLEFT', 10, 5)
+    self.searchBar:SetPoint('BOTTOMRIGHT', -5, 5)
+    self.searchBar:SetHeight(25)
+
+    self.bagBtn = CreateFrame('BUTTON', self.frame:GetName()..'Tab1', self.frame, 'TabButtonTemplate')
+    self.bagBtn.tab = 1
+    self.bagBtn:SetPoint('BOTTOMLEFT', self.frame, 'TOPLEFT')
+    self.bagBtn:SetText(BANK)
+    self.bagBtn:SetScript('OnClick', self.TabClick)
+    PanelTemplates_TabResize(self.bagBtn, 0)
+    _G[self.bagBtn:GetName().."HighlightTexture"]:SetWidth(self.bagBtn:GetTextWidth() + 31)
+
+    self.reagentBtn = CreateFrame('BUTTON', self.frame:GetName()..'Tab2', self.frame, 'TabButtonTemplate')
+    self.reagentBtn.tab = 2
+    self.reagentBtn:SetPoint('BOTTOMLEFT', self.bagBtn, 'BOTTOMRIGHT', 0, 0)
+    self.reagentBtn:SetText(REAGENT_BANK)
+    self.reagentBtn:SetScript('OnClick', self.TabClick)
+    PanelTemplates_TabResize(self.reagentBtn, 0)
+    _G[self.reagentBtn:GetName().."HighlightTexture"]:SetWidth(self.reagentBtn:GetTextWidth() + 31)
+    PanelTemplates_SetNumTabs(self.frame, 2)
+end
+
+function bank:TabClick()
+    PlaySound("igMainMenuOpen")
+    PanelTemplates_SetTab(self:GetParent(), self.tab)
+    if self.tab == 1 then
+        bank.bankContainer:Show()
+        bank.reagentContainer:Hide()
+    else
+        bank.bankContainer:Hide()
+        bank.reagentContainer:Show()
+    end
+end
+
+function bank:UpdateBags()
+    local numBankslots, full = GetNumBankSlots()
+    for bag = #self.bags+1, numBankslots do
+        local item = ADDON.bagItem('DJBagsBankBagItem' .. bag, bag, BankButtonIDToInvSlotID(bag, 1))
+        item:SetParent(self.frame)
+        tinsert(self.bags, item)
+    end
+
+    if not full then
+        self.emptyBag:Show()
+        local cost = GetBankSlotCost(numSlots);
+        BankFrame.nextSlotCost = cost;
+        if( GetMoney() >= cost ) then
+            SetMoneyFrameColor(self.emptyBag.money, "white");
+        else
+            SetMoneyFrameColor(self.emptyBag.money, "red")
+        end
+        MoneyFrame_Update(self.emptyBag.money, cost);
+    else
+        self.emptyBag:Hide()
+    end
+    self:ArrangeBags()
+end
+
+function bank:ArrangeBags()
+    local x = 5
+    local y = ADDON.settings.bagItem.size
+
+    for _, bag in pairs(self.bags) do
+        bag:Update()
+        bag:SetPoint('TOPLEFT', x, -5)
+        x = x + 5 + bag:GetWidth()
+    end
+
+    if self.emptyBag:IsVisible() then
+        self.emptyBag:SetSize(math.max(y, self.emptyBag.money:GetWidth() - 10), y)
+        x = x + 5 + self.emptyBag:GetWidth()
+    end
+
+    self.frame:SetSize(math.max(x, 175), y + 12 + self.searchBar:GetHeight())
+end
\ No newline at end of file
diff --git a/src/lua/core.lua b/src/lua/core.lua
index 94f49fa..33f35bf 100644
--- a/src/lua/core.lua
+++ b/src/lua/core.lua
@@ -12,6 +12,7 @@ function core:ADDON_LOADED(name)
     ADDON.settingsController:Init()

     ADDON.bag:Init()
+    ADDON.bank:Init()

     ADDON.eventManager:AddEvent(self, "SETTINGS_UPDATE")
     ADDON.eventManager:RemoveEvent(self, 'ADDON_LOADED')
@@ -20,6 +21,7 @@ end
 function core:SETTINGS_UPDATE(arrange)
     ADDON.cache:UpdateSettings(arrange)
     ADDON.bag:UpdateSettings(arrange)
+    ADDON.bank:UpdateSettings(arrange)
     ADDON.categoryDialog:Setup()
 end

@@ -31,12 +33,9 @@ ToggleAllBags = function()
     ADDON.bag:Toggle()
 end

-local oldToggleBag = ToggleBag
-ToggleBag = function(id, ...)
+ToggleBag = function(id)
     if id < 5 and id > -1 then
         ADDON.bag:Toggle()
-    else
-        oldToggleBag(id, ...)
     end
 end

diff --git a/src/lua/elements/bagBar.lua b/src/lua/elements/bagBar.lua
index 3d92cfb..b1d0e32 100644
--- a/src/lua/elements/bagBar.lua
+++ b/src/lua/elements/bagBar.lua
@@ -1,6 +1,61 @@
---
--- User: Brandon James Talbot
--- Date: 2016/06/29
--- Time: 6:04 PM
---
+local NAME, ADDON = ...

+ADDON.bagBar = {}
+ADDON.bagBar.__index = ADDON.bagBar
+
+local bar = ADDON.bagBar
+setmetatable(bar, {
+    __call = function(self, parent)
+        local frame = ADDON.container('DJBagsBagBar', parent)
+
+        for k, v in pairs(self) do
+            frame[k] = v
+        end
+
+        frame:Init()
+        frame:Setup()
+
+        return frame
+    end
+})
+
+function bar:Init()
+    self.bag1 = ADDON.bagItem('DJBagsBag0', 1, GetInventorySlotInfo("Bag0Slot"))
+    self.bag1:SetParent(self)
+    self.bag2 = ADDON.bagItem('DJBagsBag1', 2, GetInventorySlotInfo("Bag1Slot"))
+    self.bag2:SetParent(self)
+    self.bag3 = ADDON.bagItem('DJBagsBag2', 3, GetInventorySlotInfo("Bag2Slot"))
+    self.bag3:SetParent(self)
+    self.bag4 = ADDON.bagItem('DJBagsBag3', 4, GetInventorySlotInfo("Bag3Slot"))
+    self.bag4:SetParent(self)
+end
+
+function bar:Setup()
+    ADDON.container.Setup(self)
+
+    self.bag1:SetPoint("TOPRIGHT", -5, -5)
+    self.bag2:SetPoint("TOPRIGHT", self.bag1, 'TOPLEFT', -5, 0)
+    self.bag3:SetPoint("TOPRIGHT", self.bag2, 'TOPLEFT', -5, 0)
+    self.bag4:SetPoint("TOPRIGHT", self.bag3, 'TOPLEFT', -5, 0)
+
+    self:SetSize(self.bag1:GetWidth() * 4 + 25, 10 + self.bag1:GetHeight())
+end
+
+function bar:Update()
+    self.bag1:Update()
+    self.bag2:Update()
+    self.bag3:Update()
+    self.bag4:Update()
+end
+
+function bar:UpdateLock(bag)
+    if bag == self.bag1:GetID() then
+        self.bag1:UpdateLock()
+    elseif bag == self.bag2:GetID() then
+        self.bag2:UpdateLock()
+    elseif bag == self.bag3:GetID() then
+        self.bag3:UpdateLock()
+    elseif bag == self.bag4:GetID() then
+        self.bag4:UpdateLock()
+    end
+end
\ No newline at end of file
diff --git a/src/lua/elements/bagItem.lua b/src/lua/elements/bagItem.lua
new file mode 100644
index 0000000..be8f51e
--- /dev/null
+++ b/src/lua/elements/bagItem.lua
@@ -0,0 +1,94 @@
+local NAME, ADDON = ...
+
+ADDON.bagItem = {}
+ADDON.bagItem.__index = ADDON.bagItem
+
+local item = ADDON.bagItem
+setmetatable(item, {
+    __call = function(tbl, name, slot, id)
+        local frame = CreateFrame('BUTTON', name, nil, 'ItemButtonTemplate')
+        frame:SetID(id)
+        frame.slot = slot
+
+        for k, v in pairs(tbl) do
+            frame[k] = v
+        end
+
+        frame:Init()
+        frame:Setup()
+
+        return frame
+    end
+})
+
+function item:Init()
+    self:SetScript('OnDragStart', self.DragItem)
+    self:SetScript('OnReceiveDrag', self.PlaceOrPickup)
+    self:SetScript('OnClick', self.PlaceOrPickup)
+    self:SetScript('OnEnter', self.OnEnter)
+    self:SetScript('OnLeave', self.OnLeave)
+
+    self.IconBorder:ClearAllPoints()
+    self.IconBorder:SetAllPoints()
+
+    self:SetNormalTexture([[Interface\Common\WhiteIconFrame]])
+    self:GetNormalTexture():ClearAllPoints()
+    self:GetNormalTexture():SetAllPoints()
+end
+
+function item:Setup()
+    local settings = ADDON.settings.bagItem or {size = 26}
+
+    self:SetSize(settings.size, settings.size)
+end
+
+function item:Update()
+    PaperDollItemSlotButton_Update(self)
+end
+
+function item:UpdateLock()
+    PaperDollItemSlotButton_UpdateLock(self)
+end
+
+function item:PlaceOrPickup()
+    local placed = PutItemInBag(self:GetID())
+    if not placed then
+        PickupBagFromSlot(self:GetID())
+    end
+end
+
+function item:DragItem()
+    PickupBagFromSlot(self:GetID())
+end
+
+function item:OnEnter()
+    if self:GetRight() >= (GetScreenWidth() / 2) then
+        GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
+    else
+        GameTooltip:SetOwner(self, 'ANCHOR_RIGHT')
+    end
+
+    local hasItem, hasCooldown, repairCost, speciesID, level, breedQuality, maxHealth, power, speed, name = GameTooltip:SetInventoryItem("player", self:GetID());
+    if(speciesID and speciesID > 0) then
+        BattlePetToolTip_Show(speciesID, level, breedQuality, maxHealth, power, speed, name);
+        CursorUpdate(self);
+        return;
+    end
+
+    if (not IsInventoryItemProfessionBag("player", self:GetID())) then
+        for i = LE_BAG_FILTER_FLAG_EQUIPMENT, NUM_LE_BAG_FILTER_FLAGS do
+            if ( GetBankBagSlotFlag(self:GetID(), i) ) then
+                GameTooltip:AddLine(BAG_FILTER_ASSIGNED_TO:format(BAG_FILTER_LABELS[i]));
+                break;
+            end
+        end
+    end
+
+    GameTooltip:Show();
+    CursorUpdate(self);
+end
+
+function item:OnLeave()
+    GameTooltip_Hide();
+    ResetCursor();
+end
\ No newline at end of file
diff --git a/src/lua/elements/categoryContainer.lua b/src/lua/elements/categoryContainer.lua
index d35d461..42fe9b9 100644
--- a/src/lua/elements/categoryContainer.lua
+++ b/src/lua/elements/categoryContainer.lua
@@ -4,7 +4,6 @@ ADDON.categoryContainer = {}
 ADDON.categoryContainer.__index = ADDON.categoryContainer

 local container = ADDON.categoryContainer
-container.containers = {}
 setmetatable(container, {
     __call = function(tbl, name, parent)
         local frame = ADDON.container(name, parent)
@@ -27,6 +26,7 @@ function container:Init()
     self:RegisterForDrag("LeftButton")
     self:SetScript("OnDragStart", self.StartMoving)
     self:SetScript("OnDragStop", self.StopMovingOrSizing)
+    self.containers = {}
 end

 function container:Setup()
diff --git a/src/lua/elements/item.lua b/src/lua/elements/item.lua
index d5ec641..70d74fd 100644
--- a/src/lua/elements/item.lua
+++ b/src/lua/elements/item.lua
@@ -7,7 +7,9 @@ local item = ADDON.item
 setmetatable(item, {
     __call = function(tbl, bag, slot)
         local parent = CreateFrame('FRAME', string.format('DJBagsItemParent%d_%d', bag, slot))
-        parent.button = CreateFrame('BUTTON', string.format('DJBagsItem%d_%d', bag, slot), parent, 'ContainerFrameItemButtonTemplate')
+        local inherit = bag == BANK_CONTAINER and 'BankItemButtonGenericTemplate' or
+                bag == REAGENTBANK_CONTAINER and 'ReagentBankItemButtonGenericTemplate' or 'ContainerFrameItemButtonTemplate'
+        parent.button = CreateFrame('BUTTON', string.format('DJBagsItem%d_%d', bag, slot), parent, inherit)

         parent:SetID(bag)
         parent.button:SetID(slot)
@@ -34,15 +36,21 @@ function item:Init()
     self.button:GetNormalTexture():ClearAllPoints()
     self.button:GetNormalTexture():SetAllPoints()

-    self.button.NewItemTexture:ClearAllPoints()
-    self.button.NewItemTexture:SetAllPoints()
+    if self.button.NewItemTexture then
+        self.button.NewItemTexture:ClearAllPoints()
+        self.button.NewItemTexture:SetAllPoints()
+    end

-    self.button.flash:ClearAllPoints()
-    self.button.flash:SetAllPoints()
+    if self.button.flash then
+        self.button.flash:ClearAllPoints()
+        self.button.flash:SetAllPoints()
+    end

     self.button.quest = _G[self.button:GetName() .. "IconQuestTexture"]
-    self.button.quest:ClearAllPoints()
-    self.button.quest:SetAllPoints()
+    if self.button.quest then
+        self.button.quest:ClearAllPoints()
+        self.button.quest:SetAllPoints()
+    end

     self.button.cooldown = _G[self.button:GetName() .. "Cooldown"]

@@ -116,7 +124,7 @@ local function UpdateFiltered(self, filtered, shouldDoRelicChecks, itemID)
 end

 local function UpdateCountcolour(self, equipable, quality)
-    if equipable and quality then
+    if equipable and quality and quality >= LE_ITEM_QUALITY_COMMON then
         self.button.Count:SetVertexColor(BAG_ITEM_QUALITY_COLORS[quality].r, BAG_ITEM_QUALITY_COLORS[quality].g, BAG_ITEM_QUALITY_COLORS[quality].b)
     else
         self.button.Count:SetVertexColor(1, 1, 1)
@@ -140,30 +148,40 @@ end

 function item:Update()
     local texture, count, locked, quality, _, _, _, filtered, _, id = GetContainerItemInfo(self:GetID(), self.button:GetID())
-    local isQuestItem, questId, isActive = GetContainerItemQuestInfo(self:GetID(), self.button:GetID())
-    local isNewItem = C_NewItems.IsNewItem(self:GetID(), self.button:GetID())
-    local isBattlePayItem = IsBattlePayItem(self:GetID(), self.button:GetID())
-    local shouldDoRelicChecks = not BagHelpBox:IsShown() and not GetCVarBitfield("closedInfoFrames", LE_FRAME_TUTORIAL_ARTIFACT_RELIC_MATCH)
     local equipable = IsEquippableItem(id)
-
-    if (equipable) then
-        count = count > 1 and count or select(4, GetItemInfo(id))
-    end
-
     self.id = id
     self.name = id and select(1, GetItemInfo(id)) or ''
     self.quality = quality or 0
     self.ilevel = id and select(4, GetItemInfo(id)) or 0

-    SetItemButtonTexture(self.button, texture)
-    SetItemButtonQuality(self.button, quality, id)
-    SetItemButtonCount(self.button, count)
-    SetItemButtonDesaturated(self.button, locked)
-    UpdateQuest(self, isQuestItem, questId, isActive)
-    UpdateNewItemAnimations(self, isNewItem, isBattlePayItem, quality)
-    UpdateFiltered(self, filtered, shouldDoRelicChecks, id)
-    UpdateCountcolour(self, equipable, quality)
-    UpdateCooldown(self)
+
+    if self:GetID() == BANK_CONTAINER or self:GetID() == REAGENTBANK_CONTAINER then
+        BankFrameItemButton_Update(self.button)
+        if (equipable) then
+            count = count > 1 and count or select(4, GetItemInfo(id))
+            SetItemButtonCount(self.button, count)
+            UpdateCountcolour(self, equipable, quality)
+        end
+    else
+        local isQuestItem, questId, isActive = GetContainerItemQuestInfo(self:GetID(), self.button:GetID())
+        local isNewItem = C_NewItems.IsNewItem(self:GetID(), self.button:GetID())
+        local isBattlePayItem = IsBattlePayItem(self:GetID(), self.button:GetID())
+        local shouldDoRelicChecks = not BagHelpBox:IsShown() and not GetCVarBitfield("closedInfoFrames", LE_FRAME_TUTORIAL_ARTIFACT_RELIC_MATCH)
+
+        if (equipable) then
+            count = count > 1 and count or select(4, GetItemInfo(id))
+        end
+
+        SetItemButtonTexture(self.button, texture)
+        SetItemButtonQuality(self.button, quality, id)
+        SetItemButtonCount(self.button, count)
+        SetItemButtonDesaturated(self.button, locked)
+        UpdateQuest(self, isQuestItem, questId, isActive)
+        UpdateNewItemAnimations(self, isNewItem, isBattlePayItem, quality)
+        UpdateFiltered(self, filtered, shouldDoRelicChecks, id)
+        UpdateCountcolour(self, equipable, quality)
+        UpdateCooldown(self)
+    end
 end

 function item:UpdateCooldown()
diff --git a/src/lua/elements/mainBar.lua b/src/lua/elements/mainBar.lua
index 0ea7168..2a6050f 100644
--- a/src/lua/elements/mainBar.lua
+++ b/src/lua/elements/mainBar.lua
@@ -47,6 +47,18 @@ function bar:Init()
     self.slots:SetPoint('TOPLEFT', self.searchBox, 'TOPRIGHT', 5, 0)
     self.slots:SetPoint('BOTTOMLEFT', self.searchBox, 'BOTTOMRIGHT', 5, 0)

+    self.bagBtn = CreateFrame("CheckButton", 'TestBtnThingy', self, 'UIRadioButtonTemplate')
+    self.bagBtn:SetPoint('RIGHT', -5, 0)
+    self.bagBtn:SetScript('OnClick', function()
+        if self.bagFrame then
+            if self.bagBtn:GetChecked() then
+                self.bagFrame:Show()
+            else
+                self.bagFrame:Hide()
+            end
+        end
+    end)
+
     self.currencyBox:SetScript('OnEnter', function()
         local cnt = GetCurrencyListSize()
         GameTooltip:SetOwner(self.currencyBox, "ANCHOR_NONE")
@@ -66,6 +78,15 @@ function bar:Init()
     end)
 end

+function bar:SetBagFrame(frame)
+    self.bagFrame = frame
+    if self.bagBtn:GetChecked() then
+        frame:Show()
+    else
+        frame:Hide()
+    end
+end
+
 function bar:Setup()
     ADDON.container.Setup(self)

diff --git a/src/lua/event/eventManager.lua b/src/lua/event/eventManager.lua
index d527be2..6d4b442 100644
--- a/src/lua/event/eventManager.lua
+++ b/src/lua/event/eventManager.lua
@@ -20,7 +20,7 @@ eventFrame:SetScript("OnEvent", eventFrame.FireEvent)
 function eventFrame:AddEvent(obj, event)
     if not obj[event] then return end

-    if not self.types[event] or next(self.types[event]) == nil then
+    if not self.types[event] then
         self.types[event] = {}
         self:RegisterEvent(event)
     end
@@ -32,10 +32,6 @@ function eventFrame:RemoveEvent(obj, event)
     if not self.types[event] and not self.types[event][obj] then return end

     self.types[event][obj] = nil
-
-    if next(self.types[event]) == nil then
-        self:UnregisterEvent(event)
-    end
 end

 ADDON.eventManager = eventFrame
\ No newline at end of file
diff --git a/src/lua/settings/defaults/bagItem.lua b/src/lua/settings/defaults/bagItem.lua
new file mode 100644
index 0000000..af69a5d
--- /dev/null
+++ b/src/lua/settings/defaults/bagItem.lua
@@ -0,0 +1,7 @@
+local NAME, ADDON = ...
+
+ADDON.settings = ADDON.settings or {}
+
+ADDON.settings.bagItem = {
+    size = 32,
+}
\ No newline at end of file
diff --git a/src/lua/utils/utils.lua b/src/lua/utils/utils.lua
index e46f1b6..bc3c526 100644
--- a/src/lua/utils/utils.lua
+++ b/src/lua/utils/utils.lua
@@ -36,7 +36,7 @@ function utils:GetItemContainerName(bag, slot)
         local isInSet, setName = GetContainerItemEquipmentSetInfo(bag, slot)

         if quality == LE_ITEM_QUALITY_POOR then
-            return subClassName
+            return BAG_FILTER_JUNK
         end

         if isInSet then
@@ -56,4 +56,40 @@ function utils:GetItemContainerName(bag, slot)
         return className
     end
     return self.EMPTY_BAG_NAME
+end
+
+function utils:UpdateItemsForBag(frame, bag, arrangeList, containerFunc)
+    local count = GetContainerNumSlots(bag)
+    if count == 0 and ADDON.cache.items[bag] then
+        for _, item in pairs(ADDON.cache.items[bag]) do
+            if item:GetParent() then
+                local previousContainer = item:GetParent()
+                previousContainer:RemoveItem(item)
+                arrangeList[previousContainer] = true
+                item:Hide()
+            end
+        end
+    else
+        for slot = 1, count do
+            local item = ADDON.cache:GetItem(bag, slot)
+            local previousContainer
+            if item:GetParent() and item:GetParent().__class == ADDON.itemContainer.__class then
+                previousContainer = item:GetParent()
+            end
+
+            item:Update()
+
+            local newContainer = containerFunc(ADDON.cache, ADDON.utils:GetItemContainerName(bag, slot))
+            frame:AddContainer(newContainer)
+            arrangeList[newContainer] = true
+
+            if previousContainer ~= newContainer then
+                if previousContainer then
+                    previousContainer:RemoveItem(item)
+                    arrangeList[previousContainer] = true
+                end
+                newContainer:AddItem(item)
+            end
+        end
+    end
 end
\ No newline at end of file
diff --git a/src/manifest.xml b/src/manifest.xml
index b1160f0..1f0a9d4 100644
--- a/src/manifest.xml
+++ b/src/manifest.xml
@@ -15,6 +15,7 @@
     <Script file="src/lua/settings/defaults/category.lua"/>
     <Script file="src/lua/settings/defaults/categoryContainer.lua"/>
     <Script file="src/lua/settings/defaults/mainBar.lua"/>
+    <Script file="src/lua/settings/defaults/bagItem.lua"/>
     <Script file="src/lua/settings/editor.lua"/>
     <Script file="src/lua/settings/settings.lua"/>

@@ -32,9 +33,12 @@
     <Script file="src/lua/elements/categoryContainer.lua"/>
     <Script file="src/lua/elements/mainBar.lua"/>
     <Script file="src/lua/elements/categoryDialog.lua"/>
+    <Script file="src/lua/elements/bagItem.lua"/>
+    <Script file="src/lua/elements/bagBar.lua"/>

     <!-- Controller -->
     <Script file="src/lua/controllers/bag.lua"/>
+    <Script file="src/lua/controllers/bank.lua"/>

     <!-- Core (Load last) -->
     <Script file="src/lua/core.lua"/>