vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
-- -----------------------------------------------------------------
-- File: AllInOneBank.lua
--
-- Purpose: Functions for AIOB WoW Window.
-- 
-- Author: Ramble 
-- 
-- Credits: 
--   Starven, for MyInventory
--   Kaitlin, for BankItems
--   Sarf, for the original concept of AllInOneInventory
-- -----------------------------------------------------------------
-----------------------
-- Saved Configuration
-----------------------
AIOBProfile = {}
AIOB_VERSION           =  "1.5.2";

local PlayerName = nil; -- Logged in player name
local bankPlayer     = nil; -- viewing player pointer
local bankPlayerName = nil; -- Viewing player name

------------------------
-- Saved Function Calls
------------------------
local BankFrame_Saved = nil;
local PurchaseSlot_Saved = nil;
-----------------------
-- Local Configuration
-----------------------
local AIOB_Loaded = nil;
local AtBank = false;

AIOB_MAX_ID              = 132; -- 6 * 18 slot bags, 24 Bankslots
AIOB_COLUMNS_MIN         =   6; -- 6 Bags, so it has to be at least 6 wide
AIOB_COLUMNS_MAX         =  18; -- Same as MI
AIOB_BASE_HEIGHT         = 153; -- Height of Borders + Title + Bottom
AIOB_ROW_HEIGHT          =  40; -- One Row
AIOB_BASE_WIDTH          =  12; -- Width of the borders
AIOB_COL_WIDTH           =  39; -- One Column
AIOB_FIRST_ITEM_OFFSET_X =   7; -- Leave room for the border
AIOB_FIRST_ITEM_OFFSET_Y = -28 - 39; -- Leave room for the title.
AIOB_ITEM_OFFSET_X       =  39; -- Each is 39 apart
AIOB_ITEM_OFFSET_Y       = -39; -- Each is 39 apart

AIOBDEBUG                = 0;
-- Not Saved between Sessions
AIOBAllRealms                           = 0;
-- Saved Between Sessions
AIOBReplaceBank          = 1;
AIOBColumns              = 10;
AIOBFreeze                                       = 0;
AIOBHighlightItems               = 1;
AIOBHighlightBags                        = 1;
AIOBBagView              = 0;
AIOBGraphics             = 1;
AIOBBackground           = 1;
AIOBShowPlayers          = 1;

--InitializeProfile: Initializes a players profile {{{
--  If Player's profile is not found, it makes a new one from defaults
--  If Player's profile is found, it loads the values from AIOBProfile
function AIOB_InitializeProfile()
        if ( UnitName("player") ) then
                PlayerName = UnitName('player').."|"..AIOB_Trim(GetCVar("realmName"));
                AIOB_LoadSettings();

                AIOB_DEBUG("AIOB: Profile for "..PlayerName.." Initilized.");
                AIOBFrame_PopulateFrame();
                -- TODO: why is this here?
                -- AIOB_UpdateBagCost(AIOBProfile[PlayerName].Bags);
        end
end

function AIOB_LoadSettings()
        if ( AIOBProfile[PlayerName] == nil ) then
                AIOBProfile[PlayerName] = {};
                AIOB_Print("Creating new Profile for "..PlayerName);
        end
        AIOBReplaceBank    = AIOB_SavedOrDefault("ReplaceBank");
        AIOBColumns        = AIOB_SavedOrDefault("Columns");
        AIOBFreeze         = AIOB_SavedOrDefault("Freeze");
        AIOBHighlightItems = AIOB_SavedOrDefault("HighlightItems");
        AIOBHighlightBags  = AIOB_SavedOrDefault("HighlightBags");
        AIOBBagView        = AIOB_SavedOrDefault("BagView");
        AIOBGraphics       = AIOB_SavedOrDefault("Graphics");
        AIOBBackground     = AIOB_SavedOrDefault("Background");
        AIOBShowPlayers    = AIOB_SavedOrDefault("ShowPlayers");

        AIOB_SetGraphics();
        AIOB_SetReplaceBank();
        AIOB_SetFreeze();
end
function AIOB_SavedOrDefault(varname)
        if PlayerName == nil or varname == nil then
                AIOB_DEBUG("ERR: nil value");
                return nil;
        end
        if AIOBProfile[PlayerName][varname] == nil then -- Setting not set
                AIOBProfile[PlayerName][varname] = getglobal("AIOB"..varname); -- Load Default
        end
        return AIOBProfile[PlayerName][varname];  -- Return Setting.
end
-- END  Initialization }}}
function AIOB_GetPlayer(playerName)
        if ( not AIOBProfile[playerName] ) then
                AIOB_InitializeProfile();
        end
        bankPlayerName = playerName;
        UIDropDownMenu_SetSelectedValue(AIOBDropDown, bankPlayerName);
        return AIOBProfile[playerName];
end

function AIOB_GetBag(bagIndex)
        local curBag
        if bagIndex == BANK_CONTAINER then
                curBag = bankPlayer["Bank"];
        else
                curBag = bankPlayer["Bag"..bagIndex];
        end
        return curBag;
end

function AIOB_GetBagsTotalSlots()
        local slots = 24;
        if bankPlayer == nil then
                return slots;
        end 
        for bag = 5, 10 do
                local curBag = bankPlayer["Bag"..bag];
                if (curBag ~= nil) then
                        if curBag["s"] ~=nil then
                                slots = slots + curBag["s"];
                        end
                end
        end
        return slots;
end

-- == Event Handling == 
-- OnLoad {{{
function AIOBFrame_OnLoad()
        AIOB_Register(); -- Slash Commands
        this:RegisterEvent("PLAYER_ENTERING_WORLD");
        this:RegisterEvent("BAG_UPDATE");
        this:RegisterEvent("ITEM_LOCK_CHANGED");
        this:RegisterEvent("UPDATE_INVENTORY_ALERTS");
        this:RegisterEvent("BANKFRAME_OPENED");
        this:RegisterEvent("BANKFRAME_CLOSED");
        this:RegisterEvent("PLAYERBANKSLOTS_CHANGED");
        this:RegisterEvent("PLAYERBANKBAGSLOTS_CHANGED");
        this:RegisterEvent("PLAYER_MONEY");
        tinsert(UISpecialFrames, "AIOBFrame"); -- Esc Closes AIOB
end

function AIOB_Register()
        SlashCmdList["AIOBSLASHMAIN"] = AIOB_ChatCommandHandler;
        SLASH_AIOBSLASHMAIN1 = "/AIOB";
        this:RegisterEvent("VARIABLES_LOADED");
end
-- End Load }}}
-- Confirm Dialog for buying bag slot {{{
function AIOB_RegisterConfirm() 
        PurchaseSlot_Saved = PurchaseSlot;
        PurchaseSlot = AIOB_PurchaseSlot;
        StaticPopupDialogs["PURCHASE_BANKBAG"] = {
                text = TEXT(AIOB_PURCHASE_CONFIRM_S),
                button1 = TEXT(ACCEPT),
                button2 = TEXT(CANCEL),
                OnAccept = function()
                        PurchaseSlot_Saved();
                end,
                showAlert = 1,
                timeout = 0,
        };
end

function AIOB_PurchaseSlot()
        if not StaticPopupDialogs["PURCHASE_BANKBAG"] then
                return;
        end
        local cost = GetBankSlotCost();
        if cost < 10000 then
                StaticPopupDialogs["PURCHASE_BANKBAG"]["text"] = format(AIOB_PURCHASE_CONFIRM_S,(cost/100)); 
        else
                StaticPopupDialogs["PURCHASE_BANKBAG"]["text"] = format(AIOB_PURCHASE_CONFIRM_G,(cost/10000)); 
        end
        StaticPopup_Show("PURCHASE_BANKBAG");
end
-- End buy bag slot config }}}
-- Register with MyAddons
function AIOB_MyAddonsRegister()
        if (myAddOnsFrame) then
                myAddOnsList.AIOB = {
                        name = AIOB_MYADDON_NAME,
                        description = AIOB_MYADDON_DESCRIPTION,
                        version = AIOB_VERSION,
                        category = MYADDONS_CATEGORY_INVENTORY,
                        frame = "AIOBFrame",
                        optionsframe = "AIOBConfigFrame"
                };
        end
end

function AIOBFrame_OnEvent(event)
        if ( event == "VARIABLES_LOADED" ) then
                AIOB_Loaded = 1;
                AIOB_MyAddonsRegister();
                AIOB_InitializeProfile();
                if not BankBuyFrame then
                        AIOB_RegisterConfirm();
                end
        end
        if (not AIOB_Loaded) then
                return;
        end
        
        if ( event == "PLAYER_ENTERING_WORLD" and bankPlayer == nil ) then
                PlayerName = UnitName("player").."|"..AIOB_Trim(GetCVar("realmName"));
                bankPlayer = AIOB_GetPlayer(PlayerName);
                AIOB_InitializeProfile();
                AIOB_SaveMoney();
        elseif ( event == "BAG_UPDATE" ) then
                if AtBank and arg1 >=5 and arg1 <=10 then
                        AIOBFrame_SaveItems();
                end
        elseif (event == "PLAYERBANKSLOTS_CHANGED" or event=="PLAYERBANKBAGSLOTS_CHANGED") then
                AIOBFrame_SaveItems();
        elseif ( event == "ITEM_LOCK_CHANGED" or  event == "UPDATE_INVENTORY_ALERTS" ) then
                if ( AtBank ) then
                        AIOBFrame_PopulateFrame();
                end
        end
        if (event == "BANKFRAME_OPENED") then
                AtBank = true;
                SetPortraitTexture(AIOBFramePortrait, "npc");
                AIOBFrameAtBankText:Show();
                OpenBackpack(); -- Open Backpack at Bank
                bankPlayer = AIOB_GetPlayer(PlayerName);
                AIOBFrame_SaveItems();
                AIOBFramePurchaseButton:Enable();
                if AIOBReplaceBank == 1 then
                        OpenAIOBFrame();
                end
        elseif (event == "BANKFRAME_CLOSED") then
                AtBank = false;
                AIOBFramePortrait:SetTexture("Interface\\Addons\\AllInOneInventory\\Skin\\AIOBPortait");
                AIOBFrameAtBankText:Hide();
                AIOBFramePurchaseButton:Disable();
                CloseBackpack(); -- Close Backpack when leaving
                if AIOBReplaceBank == 1 then
                        if AIOBFreeze == 0 then
                                CloseAIOBFrame();
                        end
                end
                if StackSplitFrame:IsVisible() then
                        StackSplitFrame:Hide();
                end
        elseif (event == "PLAYER_MONEY" ) then
                AIOB_SaveMoney();
                return;
        end
end

function AIOB_HighlightBag(bagID, bagName, isItem)
        if AIOBHighlightBags == 0 and isItem then 
                return;
        end
        if AIOBHighlightItems == 0 and (not isItem) then
                return;
        end
        if isItem then
                if bagID > -1 then
                        getglobal("AIOBFrameBag"..bagID):LockHighlight();
                end
        end
        if(bankPlayer[bagName])then
                local i, found;
                for i=1, AIOB_MAX_ID do
                        local itemButton = getglobal("AIOBFrameItem"..i);
                        if not itemButton:IsVisible() then
                                break;
                        end
                        if itemButton.bagIndex == bagID then
                                found = true;
                                itemButton:LockHighlight();
                        else
                                if found then
                                        break;
                                end
                        end
                end
        end
end

function AIOB_GetCooldown(item)
        if item["d"] then
                local cooldownInfo = item["d"];
                local CoolDownRemaining;
                if cooldownInfo and cooldownInfo["d"] and cooldownInfo["s"] then
                        CoolDownRemaining = cooldownInfo["d"] - (GetTime() - cooldownInfo["s"]);
                else
                        CoolDownRemaining = 0;
                end
                if CoolDownRemaining <= 0 then
                        item["d"] = nil;
                else
                        return cooldownInfo;
                end
        end
        return nil;
end

function AIOB_GetCooldownString(cooldownInfo)
        local CoolDownRemaining = cooldownInfo["d"] - (GetTime() - cooldownInfo["s"]);
        -- 60 secs in a min
        -- 3600 secs in an hour
        -- 86400 secs in a day
        local days, hours, minutes, seconds;
        days = math.floor(CoolDownRemaining / 86400);
        CoolDownRemaining = CoolDownRemaining - 86400 * days;
        hours = math.floor(CoolDownRemaining / 3600);
        CoolDownRemaining = CoolDownRemaining - 3600 * hours;
        minutes = math.floor(CoolDownRemaining / 60);
        seconds = math.floor(CoolDownRemaining - 60 * minutes);
        if days > 0 then
                return format(ITEM_COOLDOWN_TIME_DAYS_P1, days+1);
        elseif hours > 0 then
                return format(ITEM_COOLDOWN_TIME_HOURS_P1, hours+1);
        elseif minutes > 0 then
                return format(ITEM_COOLDOWN_TIME_MIN, minutes+1);
        else
                return format(ITEM_COOLDOWN_TIME_SEC, seconds);
        end
end

function AIOB_MakeLink(item)
        if item and item["l"] then
                local name;
                _,_,_, name = strfind(item["l"],"|H(item:%d+:%d+:%d+:%d+)|h%[(.-)%]|h|r");
                item["name"] = name;
                item["l"] = nil;
        end
        if item and item["name"] then
                local myHyperlink;
                if ItemsMatrix_GetHyperlink then
                        myHyperlink = ItemsMatrix_GetHyperlink(item["name"]);
                elseif LootLink_GetHyperlink then
                        myHyperlink = LootLink_GetHyperlink(item["name"]);
                else
                        myHyperlink = AIOB_GetHyperlink(item);
                end
                if myHyperlink then
                        GameTooltip:Hide();
                        GameTooltip:SetOwner(this,"ANCHOR_RIGHT");
                        GameTooltip:SetHyperlink(myHyperlink);
                        if item["sb"] then
                                GameTooltipTextLeft2:SetText(ITEM_SOULBOUND);
                        end
                        if item["m"] then
                                GameTooltip:AddLine(format(ITEM_CREATED_BY, item["m"]));
                        end
                        local cooldownInfo = item["d"];
                        if cooldownInfo and cooldownInfo["e"] and cooldownInfo["e"] > 0 and cooldownInfo["d"] > 0 then
                                CoolDownString = AIOB_GetCooldownString(cooldownInfo);
                                GameTooltip:AddLine(CoolDownString, 1.0, 1.0, 1.0);
                        end
                        GameTooltip:Show();
                end
        end
end

function AIOBFrame_Button_OnEnter()
        --show tooltip
        local myLink, MadeBy, Soulbound, count;
        local bagName = strsub(this:GetName(), 10, 13);
        local curBag;
        local cooldownInfo;
        if AtBank then
                local hasCooldown, repairCost;
                GameTooltip:SetOwner(this,"ANCHOR_RIGHT");
                if (this.isBag) then
                        AIOB_HighlightBag(this:GetID(), bagName);
                        local inventoryID = BankButtonIDToInvSlotID(this:GetID(), 1);
                        hasCooldown, repairCost = GameTooltip:SetInventoryItem("player", inventoryID);
                else
                        AIOB_HighlightBag(this.bagIndex, bagName, 1);
                        if this.bagIndex < 0 then
                                local newIndex =BankFrameItem1:GetInventorySlot(); 
                                hasCooldown, repairCost = GameTooltip:SetInventoryItem("player", newIndex);
                        else
                                hasCooldown, repairCost = GameTooltip:SetBagItem(this.bagIndex, this.itemIndex);
                        end
                end

        else
                if LootLink_AutoInfoOff then
                        LootLink_AutoInfoOff();
                end
                if (this.isBag) then
                        AIOB_MakeLink(bankPlayer[bagName]);
                        AIOB_HighlightBag(this:GetID(), bagName);
                else
                        AIOB_HighlightBag(this.bagIndex, bagName, 1);
                        curBag = AIOB_GetBag(this.bagIndex);
                        if curBag and curBag[this.itemIndex] then
                                AIOB_MakeLink(curBag[this.itemIndex]);
                        end

                end
                if LootLink_AutoInfoOn then
                        LootLink_AutoInfoOn();
                end
        end
end
function AIOBFrame_Button_OnLeave()
        if this.isBag then
                local bagName= strsub(this:GetName(), 10, 13);
                local i, found;
                for i=1, AIOB_MAX_ID do
                        local itemButton = getglobal("AIOBFrameItem"..i);
                        if itemButton.bagIndex == this:GetID() then
                                found = true;
                                itemButton:UnlockHighlight();
                        else
                                if found then
                                        break;
                                end
                        end
                end
        else
                if this.bagIndex > -1 then
                        getglobal("AIOBFrameBag"..(this.bagIndex)):UnlockHighlight();
                end

        end
        GameTooltip:Hide();
end

function AIOBFrame_UpdateCooldown(button)
        if (not button.bagIndex) or (not button.itemIndex) then
                return;
        end
  local cooldown = getglobal(button:GetName().."Cooldown");
  local start, duration, enable = GetContainerItemCooldown(button.bagIndex, button.itemIndex);
  CooldownFrame_SetTimer(cooldown, start, duration, enable);
  if ( duration > 0 and enable == 0 ) then
    SetItemButtonTextureVertexColor(button, 0.4, 0.4, 0.4);
  end
end

function AIOBFrame_OnHide()
        if AtBank then
                CloseBankFrame();
        end
        PlaySound("igBackPackClose");
end

function AIOBFrame_OnShow()
        if AtBank then
                AIOBFramePurchaseButton:Enable();
        else
                AIOBFramePurchaseButton:Disable();
        end
        AIOB_UpdateTotalMoney();
        AIOBFrame_UpdateLookIfNeeded();
        PlaySound("igBackPackOpen");
end

function AIOBFrameItemButton_OnLoad()
        this:RegisterForClicks("LeftButtonUp", "RightButtonUp");
        this:RegisterForDrag("LeftButton");

        this.SplitStack = function(button, split)
                SplitContainerItem(button:GetParent():GetID(), button:GetID(), split);
        end
end

function AIOBFrameItemButton_OnClick(button, ignoreShift)
        local myLink;
        local item = AIOB_GetBag(this.bagIndex)[this.itemIndex];
        if (button == "LeftButton" ) then
                if (IsShiftKeyDown() and (not ignoreShift)) then
                        if ChatFrameEditBox:IsVisible() or ( MacroFrameText and MacroFrameText:IsVisible() ) then
                                -- Insert Link
                                if ItemsMatrix_GetLink then
                                        myLink = ItemsMatrix_GetLink(item["name"]);
                                elseif LootLink_GetLink then
                                        myLink = LootLink_GetLink(item["name"]);
                                else
                                        myLink = AIOB_GetLink(item);
                                end
                                if myLink then
                                   if ChatFrameEditBox:IsVisible() then
                                           ChatFrameEditBox:Insert(myLink);
                                        elseif ( MacroFrameText and MacroFrameText:IsVisible() ) then
                            MacroFrameText:Insert(myLink);
                         end
                                end
                        else
                                if AtBank then
                                        --Shift key down, left mouse button
                                        local texture, itemCount, locked = GetContainerItemInfo(this.bagIndex, this.itemIndex);
                                        if ( not locked ) then
                                                this.SplitStack = function(button, split)
                                                        SplitContainerItem(button.bagIndex, button.itemIndex, split);
                                                end
                                                OpenStackSplitFrame(this.count, this, "BOTTOMRIGHT", "TOPRIGHT");
                                        end
                                end
                        end
                else
                        -- no shift, left mouse button
                        if AtBank==true then
                                PickupContainerItem(this.bagIndex, this.itemIndex);
                        end
                end
        elseif (button == "RightButton") then
                if AtBank==true then
                        UseContainerItem(this.bagIndex, this.itemIndex);
                end
        end
end
                          
function AIOBFrameItemButtonBag_OnShiftClick(button, ignoreShift) 
        local bankBag = getglobal("BankFrameBag"..(tonumber(strsub(this:GetName(), 13, 15))-4));
        local inventoryID = BankButtonIDToInvSlotID(bankBag:GetID(), 1);
        if ( ChatFrameEditBox:IsVisible() ) then
                local bagName= strsub(this:GetName(), 10, 13);
                local myLink;
                if ItemsMatrix_GetLink then
                        myLink = ItemsMatrix_GetLink(bankPlayer[bagName]["name"]);
                elseif LootLink_GetLink then
                        myLink = LootLink_GetLink(bankPlayer[bagName]["name"]);
                else
                        myLink = AIOB_GetLink(bankPlayer[bagName]);
                end
                if myLink then
                        if ChatFrameEditBox:IsVisible() then
                           ChatFrameEditBox:Insert(myLink);
                        elseif ( MacroFrameText and MacroFrameText:IsVisible() ) then
            MacroFrameText:Insert(myLink);
         end
                end
        else
                 -- Shift key, no chat box
                if AtBank then
                        PickupBagFromSlot(inventoryID);
                        PlaySound("BAGMENUBUTTONPRESS");
                end
        end
end
function AIOBFrameItemButtonBag_OnClick(button, ignoreShift) 
        local bankBag = getglobal("BankFrameBag"..(tonumber(strsub(this:GetName(), 13, 15))-4));
        local inventoryID = BankButtonIDToInvSlotID(bankBag:GetID(), 1);
        AIOB_DEBUG(bankBag:GetName().." "..inventoryID);
                 -- No ShiftKey
        if AtBank then
                local hadItem = PutItemInBag(inventoryID);
                local id = this:GetID();
        end
end
-- == End Event Handling == 

function AIOBFrame_SetColumns(col)
        if ( type(col) ~= "number" ) then
                col = tonumber(col);
        end
        if ( ( col >= AIOB_COLUMNS_MIN ) and ( col <= AIOB_COLUMNS_MAX ) ) then
                AIOBColumns = col;
                bankPlayer.Columns = AIOBColumns;
                AIOBFrame_UpdateLook(getglobal("AIOBFrame"), AIOB_GetBagsTotalSlots());
        end
end

function AIOBFrame_GetAppropriateHeight(rows)
        local height = AIOB_BASE_HEIGHT + ( AIOB_ROW_HEIGHT * (AIOBBagView - 1 + rows ));
        if AIOBShowPlayers == 0 and AIOBGraphics == 0 then
                height = height - AIOB_ROW_HEIGHT;
        end
        return height;
end

function AIOBFrame_GetAppropriateWidth(cols)
        return AIOB_BASE_WIDTH + ( AIOB_COL_WIDTH * cols );
end

function AIOBTitle_Update()
        local i, j, totalSlots, takenSlots = 0, 0, 0, 0;
        totalSlots = AIOB_GetBagsTotalSlots();
        -- Need to calculate Free slots.
        if bankPlayer and bankPlayer["Bank"] then
                for i = 1, 24 do
                        if bankPlayer["Bank"][i] then
                                takenSlots = takenSlots + 1;
                        end
                end
                for i = 5, 10 do
                        if bankPlayer["Bag"..i] and bankPlayer["Bag"..i]["s"] then
                                for j = 1, bankPlayer["Bag"..i]["s"] do
                                        if bankPlayer["Bag"..i][j] then
                                                takenSlots = takenSlots + 1;
                                        end
                                end
                        end
                end
        end

        if ( bankPlayerName ) then
                local playername = AIOB_Split(bankPlayerName, "|");
                if ( AIOBColumns >= 9 ) then
                        AIOBFrameName:SetText(format(AIOB_FRAME_PLAYERANDREGION, playername[1], playername[2]));
                else
                        AIOBFrameName:SetText(format(AIOB_FRAME_PLAYERONLY, playername[1]));
                end
                AIOBFrameName:SetTextColor(1.0, 1.0, 1.0);
        end
        AIOBFrameSlots:SetText(format(AIOB_FRAME_SLOTS, (totalSlots-takenSlots), (totalSlots)));
end

function AIOB_UpdateTotalMoney()
        local totalMoney = 0;
        for key, value in AIOBProfile do
                local thisRealmPlayers = AIOB_Split(key, "|")[2];
                if AIOBAllRealms == 1 or thisRealmPlayers == AIOB_Trim(GetCVar("realmName")) then
                        if ( AIOBProfile[key].money ) then
                                totalMoney = totalMoney + AIOBProfile[key].money;
                        end
                end
        end
        if AIOBColumns < 8 then
                totalMoney = math.floor(totalMoney / 10000) * 10000;
        end
        MoneyFrame_Update("AIOB_MoneyFrameTotal", totalMoney);
end

function AIOB_UpdateBagCost(bags) 
        if not bags then
                bags=0;
        end
        if bags < 6 then
                AIOBFramePurchaseInfo:Show();
                local cost = AIOB_GetBankSlotCost(bags);
                MoneyFrame_Update("AIOBFrameDetailMoneyFrame", cost);
                if ( bankPlayer and bankPlayer["money"] and bankPlayer["money"] >= cost ) then
                        SetMoneyFrameColor("AIOBFrameDetailMoneyFrame", 1.0, 1.0, 1.0);
                else
                        SetMoneyFrameColor("AIOBFrameDetailMoneyFrame", 1.0, 0.1, 0.1)
                end
        else
                -- Hide frame
                AIOBFramePurchaseInfo:Hide();
        end
end

function AIOBFrame_UpdateLookIfNeeded()
        local slots = AIOB_GetBagsTotalSlots();
        if ( ( not AIOBFrame.size ) or ( slots ~= AIOBFrame.size ) ) then
                AIOBFrame_UpdateLook(getglobal("AIOBFrame"), slots);
        end
end

function AIOBFrame_UpdateLook(frame, frameSize)
        frame.size = frameSize;
        local name = frame:GetName();
        local columns = AIOBColumns;
        
        local rows = ceil(frame.size / columns);
        local height = AIOBFrame_GetAppropriateHeight(rows);
        frame:SetHeight(height);
        
        local width = AIOBFrame_GetAppropriateWidth(columns);
        frame:SetWidth(width);
        
        AIOBTitle_Update();     
        if AIOBShowPlayers ==1 then
                AIOBDropDown:Show();
                AIOB_AllRealms_Check:Show();
                --MYINVENTORY_BASE_HEIGHT = MYINVENTORY_BASE_HEIGHT - MYINVENTORY_ITEM_OFFSET_Y;
        else
                AIOBDropDown:Hide();
                AIOB_AllRealms_Check:Hide();
        end
        for j=5,10 do
                local bagButton=getglobal("AIOBFrameBag"..j);
                bagButton:ClearAllPoints();
                if j == 5 then
                        bagButton:SetPoint("TOPLEFT", "AIOBBagButtonsBar", "TOPLEFT", 0, 0);
                else
                        bagButton:SetPoint("TOPLEFT", "AIOBFrameBag"..(j-1), "TOPLEFT", AIOB_ITEM_OFFSET_X, 0);
                end
                bagButton:Show();
        end
        local First_Y;
                First_Y = AIOB_FIRST_ITEM_OFFSET_Y;
        if AIOBBagView == 1 then
                First_Y = AIOB_FIRST_ITEM_OFFSET_Y + AIOB_ITEM_OFFSET_Y;
                AIOBBagButtonsBar:Show();
        else
                First_Y = AIOB_FIRST_ITEM_OFFSET_Y;
                AIOBBagButtonsBar:Hide();
        end
        if (AIOBShowPlayers == 0 and AIOBGraphics == 0 ) then
                AIOB_DEBUG("move up");
                First_Y = First_Y - AIOB_ITEM_OFFSET_Y;
                AIOBBagButtonsBar:ClearAllPoints();
                AIOBBagButtonsBar:SetPoint("TOP", "AIOBFrame", "TOP", 0, -28);
        else
                AIOBBagButtonsBar:ClearAllPoints();
                AIOBBagButtonsBar:SetPoint("TOP", "AIOBFrame", "TOP", 0, -28-39);
                
        end
        for j=1, frame.size, 1 do
                local itemButton = getglobal(name.."Item"..j);
                -- Set first button
                itemButton:ClearAllPoints();
                if ( j == 1 ) then
                        itemButton:SetPoint("TOPLEFT", name, "TOPLEFT", AIOB_FIRST_ITEM_OFFSET_X, First_Y);
                else
                        if ( mod((j-1), columns) == 0 ) then
                                itemButton:SetPoint("TOPLEFT", name.."Item"..(j - columns), "TOPLEFT", 0, AIOB_ITEM_OFFSET_Y);  
                        else
                                itemButton:SetPoint("TOPLEFT", name.."Item"..(j - 1), "TOPLEFT", AIOB_ITEM_OFFSET_X, 0);  
                        end
                end
                
                itemButton.readable = readable;
                itemButton:Show();
        end
        local button = nil;
        for i = frame.size+1, AIOB_MAX_ID do
                button = getglobal("AIOBFrameItem"..i);
                if ( button ) then
                        button:Hide();
                end
        end
        AIOBFrame_PopulateFrame();
end


function AIOB_GetTooltipData()
        local soulbound = nil;
        local madeBy = nil;
        local field;
        local left, right;

        for index = 1, 15, 1 do
                field = getglobal("AIOBHiddenTooltipTextLeft"..index);
                if( field and field:IsVisible() ) then
                        left = field:GetText();
                else
                        left = "";
                end
                field = getglobal("AIOBHiddenTooltipTextRight"..index);
                if( field and field:IsVisible() ) then
                        right = field:GetText();
                else
                        right = "";
                end
                if ( string.find(left, ITEM_SOULBOUND) ) then
                        soulbound = 1;
                end
                local iStart, iEnd, val1 = string.find(left, "<Made by (.+)>");
                if (val1) then
                        madeBy = val1;
                end
        end
        return soulbound, madeBy;
end

function AIOBFrame_SaveBagInfo(currPlayer, bagIndex, bagName)
        if bagName=="Bank" then
                return 24;
        end
        local bagNum_Slots = GetContainerNumSlots(bagIndex);
        local bagNum_ID    = BankButtonIDToInvSlotID(bagIndex, 1);
        local itemLink     = GetInventoryItemLink("player", bagNum_ID);
        local texture      = GetInventoryItemTexture("player", bagNum_ID);
        local hasCooldown, repairCost = AIOBHiddenTooltip:SetInventoryItem("player", bagNum_ID);
        local soulbound, madeBy = AIOB_GetTooltipData();
        if (itemLink) then
                currPlayer[bagName]= {};
                AIOB_SaveItemData(currPlayer[bagName], itemLink, strsub(texture,17), bagNum_Slots, _ , _ , soulbound, madeBy, _); 
                return bagNum_Slots;
        else
                currPlayer[bagName] = nil;
                return 0;
        end
end
function        AIOBSaveBagItem(currPlayer, bagNewIndex, itemIndex, bagName)
        local itemLink = GetContainerItemLink(bagNewIndex, itemIndex);
        local texture, itemCount, _, itemQuality = GetContainerItemInfo(bagNewIndex, itemIndex);
        local hasCooldown, repairCost;
        if bagNewIndex == BANK_CONTAINER then
                local newIndex = 39 + itemIndex; 
                hasCooldown, repairCost = AIOBHiddenTooltip:SetInventoryItem("player", newIndex);
        else
                hasCooldown, repairCost = AIOBHiddenTooltip:SetBagItem(bagNewIndex, itemIndex);
        end
        local start, duration, enable = GetContainerItemCooldown(bagNewIndex, itemIndex);
        local soulbound, madeBy = AIOB_GetTooltipData();
        local cooldown;
        if hasCooldown and enable > 0 then
                cooldown = {
                        ["s"] = start,
                        ["d"] = duration,
                        ["e"] = enable
                };
        end
        if (itemLink) then
                currPlayer[bagName][itemIndex] = {};
                AIOB_SaveItemData(currPlayer[bagName][itemIndex], itemLink, strsub(texture,17), _, itemCount, itemQuality, soulbound, madeBy, cooldown); 
        else
                currPlayer[bagName][itemIndex] = nil;
        end
end
function AIOB_SaveItemData(AIOBItem, itemLink, texture, Slots, Count, Quality, soulbound, madeBy, Cooldown)
        local myColor, myLink, name;
        local _,_, myColor, myLink, name = strfind(itemLink, "|c(%x+)|Hitem:(%d+:%d+:%d+:%d+)|h%[(.-)%]|h|r");
        AIOBItem["name"] = name;
        AIOBItem["i"] = texture;
        AIOBItem["s"] = Slots;
        AIOBItem["c"] = Count;
   AIOBItem["q"] = Quality;
        if (ItemsMatrix_GetLink or LootLink_GetLink) then
                AIOBItem["color"] = nil;
                AIOBItem["item"] = nil;
        else
                AIOBItem["color"] = myColor;
                AIOBItem["item"] = myLink;
        end
        AIOBItem["sb"] = soulbound;
        AIOBItem["m"] = madeBy;
        AIOBItem["d"] = Cooldown;
end

function AIOB_SaveMoney()
        if ( PlayerName ) then
                if ( AIOBProfile[PlayerName] ) then
                        AIOBProfile[PlayerName]["money"] = GetMoney();
                end
                if ( AIOB_MoneyFrame:IsVisible() ) then
                        MoneyFrame_Update("AIOB_MoneyFrame", bankPlayer.money);
                        AIOB_UpdateTotalMoney();
                end
        end
end

function AIOBFrame_SaveItems()
        local currPlayer=AIOBProfile[PlayerName];
        if currPlayer == nil then
                return;
        end
        if not AtBank then
                return;
        end
        AIOB_DEBUG("SaveItems");
        currPlayer.Bags, _ = GetNumBankSlots();
        local bagName, bagMaxIndex, bagNewIndex;
        for bagNum = 0, currPlayer.Bags do
                if bagNum == 0 then -- Is it the bank?
                        bagName = "Bank";
                        bagNewIndex = BANK_CONTAINER;
                else    -- It's in a bag slot
                        bagName = "Bag"..(4+bagNum);
                        bagNewIndex = (4+bagNum);
                end
                if (not currPlayer[bagName]) then
                        AIOB_DEBUG("Clearing "..bagName);
                        currPlayer[bagName] = {} ;
                end
                bagMaxIndex = AIOBFrame_SaveBagInfo(currPlayer, bagNewIndex, bagName);
                for itemIndex = 1, bagMaxIndex do
                        AIOBSaveBagItem(currPlayer, bagNewIndex, itemIndex, bagName);
                end
        end
        for bagNum = 5+currPlayer.Bags, 10 do
                currPlayer["Bag"..bagNum] = nil;
        end
        AIOB_SaveMoney();
        AIOBFrame_PopulateFrame();
end


function AIOBFrame_PopulateFrame()
        local texture, itemButton, itemCount, itemQuality;
        local bagName, bagMaxIndex, bagNewIndex;
        local buttonIndex = 1;
        local BlankTexture;
        local maxBags;
        if not bankPlayer then 
                return;
        end
        if bankPlayer.Bags then
                maxBags = bankPlayer.Bags;
        else
                maxBags = 0;
        end
        AIOB_UpdateBagCost(maxBags);
        _, BlankTexture = GetInventorySlotInfo("Bag0Slot");
        for bagNum = 0, maxBags do
                if bagNum == 0 then -- Is it the bank?
                        bagName = "Bank";
                        bagNewIndex = BANK_CONTAINER;
                        bagMaxIndex = 24;
                else
                        bagName = "Bag"..(4+bagNum);
                        bagNewIndex = (4+bagNum);
                        local bagButton = getglobal("AIOBFrameBag"..(bagNewIndex));
                        SetItemButtonNormalTextureVertexColor(bagButton, 1.0,1.0,1.0);
                        SetItemButtonTextureVertexColor(bagButton, 1.0,1.0,1.0);
                        if bankPlayer[bagName] and bankPlayer[bagName]["s"] then
                                bagMaxIndex = bankPlayer[bagName]["s"];
                                SetItemButtonTexture(bagButton, "Interface\\Icons\\"..bankPlayer[bagName]["i"]);
                        else
                                bagMaxIndex = 0;
                                SetItemButtonTexture(bagButton, BlankTexture);
                        end
                end
                for itemIndex = 1,bagMaxIndex do
                        itemButton = getglobal("AIOBFrameItem"..buttonIndex);
                        buttonIndex = buttonIndex + 1;
                        if(bankPlayer and bankPlayer[bagName] and bankPlayer[bagName][itemIndex]) then
                                texture = "Interface\\Icons\\"..bankPlayer[bagName][itemIndex]["i"];
                                itemCount = bankPlayer[bagName][itemIndex]["c"];        
                        else
                                texture = nil;
                                itemCount = 0;
                        end
                        if(itemButton) then
                                local locked;
                                if AtBank then
                                        texture, itemCount, locked, itemQuality, itemReadable = GetContainerItemInfo(bagNewIndex, itemIndex);
                                        AIOBFrame_UpdateCooldown(itemButton);
                                else
                                        locked = nil;
                                end
                                if bankPlayer[bagName] and bankPlayer[bagName][itemIndex] and bankPlayer[bagName][itemIndex]["d"] then
                                        local cooldown = getglobal(itemButton:GetName().."Cooldown");
                                        local cooldownInfo = bankPlayer[bagName][itemIndex]["d"];
                                        if cooldownInfo and cooldownInfo["e"] then
                                                local start, duration, enable = cooldownInfo["s"], cooldownInfo["d"], cooldownInfo["e"];
                                                if duration > 0 then
                                                        CooldownFrame_SetTimer(cooldown, start, duration, enable);
                                                else
                                                        cooldown:Hide();
                                                end
                                        else
                                                cooldown:Hide();
                                        end
                                end
                                if bankPlayer[bagName] and bankPlayer[bagName][itemIndex] and bankPlayer[bagName][itemIndex]["q"] then
                                   AIOB_UpdateBorder(itemButton, bankPlayer[bagName][itemIndex]["q"]);
                                else
                                   AIOB_UpdateBorder(itemButton, itemQuality);
                                end
                                SetItemButtonTexture(itemButton, texture);
                                SetItemButtonCount(itemButton, itemCount);
                                SetItemButtonDesaturated(itemButton, locked, 0.5, 0.5, 0.5);
                                itemButton.bagIndex = bagNewIndex;
                                itemButton.itemIndex= itemIndex;
                        end
                end
        end
        for bagNum = 5+maxBags, 10 do
                local bagButton = getglobal("AIOBFrameBag"..(bagNum));
                SetItemButtonNormalTextureVertexColor(bagButton, 1.0,0.1,0.1);
                SetItemButtonTextureVertexColor(bagButton, 1.0,0.1,0.1);
                SetItemButtonTexture(bagButton, BlankTexture);
        end
        if ( bankPlayer and  bankPlayer["money"] ) then
                MoneyFrame_Update("AIOB_MoneyFrame", bankPlayer["money"]);
                AIOB_MoneyFrame:Show();
        else
                AIOB_MoneyFrame:Hide();
        end
        AIOB_UpdateTotalMoney();
        AIOBFrame_UpdateLookIfNeeded();
end




function AIOB_UpdateBorder(itemButton, itemQuality)
   local color = {
      ["r"]=0.5,
      ["g"]=0.5,
      ["b"]=0.5 };
   
   if ( itemQuality ) then
      if itemQuality == -1 then
         color = {
            ["r"]=1,
            ["g"]=1,
            ["b"]=1 } -- white
      elseif itemQuality == 1 then
         color = {
            ["r"]=0.5,
            ["g"]=0.5,
            ["b"]=0.5 } -- grey
      elseif itemQuality == 2 then
         color = {
            ["r"]=0.0,
            ["g"]=1.0,
            ["b"]=0.0 } -- green
      elseif itemQuality == 3 then
         color = {
            ["r"]=0.5,
            ["g"]=0.5,
            ["b"]=1.0 } --  blue
   
      elseif itemQuality == 4 then
         color = {
            ["r"]=0.7,
            ["g"]=0.1,
            ["b"]=1.0 } -- purple
      else
         color = {
            ["r"]=0.0,
            ["g"]=0.0,
            ["b"]=0.0 }  -- black
      end
   end
   SetItemButtonNormalTextureVertexColor(itemButton, color.r, color.g, color.b);
end




-- == Viewing other peoples banks ==
function AIOB_UserDropDown_GetValue()
        if ( bankPlayerName ) then
                return bankPlayerName;
        else
                return (UnitName("player").."|"..AIOB_Trim(GetCVar("realmName")));
        end
end
function AIOB_UserDropDown_OnLoad()
        UIDropDownMenu_Initialize(this, AIOB_UserDropDown_Initialize);
        UIDropDownMenu_SetSelectedValue(this, AIOB_UserDropDown_GetValue());
        AIOBDropDown.tooltip = "You are viewing this player's bank contents.";
        UIDropDownMenu_SetWidth(140, AIOBDropDown);
        OptionsFrame_EnableDropDown(AIOBDropDown);
end

function AIOB_UserDropDown_OnClick()
        if ( not bankPlayer ) then
                return;
        end
        if AtBank then
                CloseBankFrame();
                OpenAIOBFrame();
        end
        -- UIDropDownMenu_SetSelectedValue(AIOBDropDown, this.value);
        if ( this.value ) then
                bankPlayer = AIOB_GetPlayer(this.value);
        end
        AIOBFrame_PopulateFrame();
end

function AIOB_UserDropDown_Initialize()
        local selectedValue = UIDropDownMenu_GetSelectedValue(AIOBDropDown);
        local info;
        for key, value in AIOBProfile do
                local thisRealmPlayers = AIOB_Split(key, "|")[2];
                if ( table.getn(AIOBProfile[key]) > 0 or AIOBProfile[key].money ) then
                        if (AIOBAllRealms == 1 or thisRealmPlayers == AIOB_Trim(GetCVar("realmName")) ) then
                                info = {};
                                info.text = AIOB_Split(key,"|")[1].." of "..AIOB_Split(key,"|")[2];
                                info.value = key;
                                info.func = AIOB_UserDropDown_OnClick;
                                if ( selectedValue == info.value ) then
                                        info.checked = 1;
                                else
                                        info.checked = nil;
                                end
                                UIDropDownMenu_AddButton(info);
                        end
                end
        end
end

function AIOB_ShowAllRealms_Check_OnClick()
                if ( AIOBAllRealms == 0 ) then
                        AIOBAllRealms = 1;
                else
                        AIOBAllRealms = 0;
                end
                AIOB_UpdateTotalMoney();
end

function AIOB_ShowAllRealms_Check_OnShow()
        if ( AIOBAllRealms == 1 ) then
                this.checked = 1;
        else
                this.checked = nil;
        end
        OptionsFrame_EnableCheckBox(this);
        this:SetChecked(this.checked);
        this.tooltipText = "Check to show all saved characters, regardless of realm.";
end


-- === Toggle Functions ===
-- All toggling of options
function ToggleAIOBFrame()
        if ( AIOBFrame:IsVisible() ) then
                CloseAIOBFrame();
        else
                OpenAIOBFrame();
        end
end
function CloseAIOBFrame()
        if AtBank then
                CloseBankFrame();
        end
        if ( AIOBFrame:IsVisible() ) then
                HideUIPanel(AIOBFrame);
        end
end
function OpenAIOBFrame()
        AIOBFrame_UpdateLookIfNeeded();
        ShowUIPanel(AIOBFrame, 1);
end

function AIOB_Toggle_Option(option, value, quiet)
        if value == nil then
                if getglobal("AIOB"..option) == 1 then
                        value = 0;
                else
                        value = 1;
                end
        end
        setglobal("AIOB"..option, value);
        AIOBProfile[PlayerName][option] = value;
        if not quiet then
                local chat_message;
                local globalName = "AIOB_CHAT_"..string.upper(option);
                if value == 0 then
                        globalName = globalName.."OFF";
                else
                        globalName = globalName.."ON";
                end
                chat_message = getglobal(globalName);
                if ( chat_message ) then
                        AIOB_Print(chat_message);
                else
                        AIOB_DEBUG("ERROR: No global "..globalName);
                end
        end
        if option == "ReplaceBank" then
                AIOB_SetReplaceBank();
        elseif option == "ShowPlayers" or option == "BagView" then
                AIOBFrame_UpdateLook(getglobal("AIOBFrame"),AIOB_GetBagsTotalSlots());
        elseif option == "Graphics" or option == "Background" then
                AIOB_SetGraphics();
                AIOBFrame_UpdateLook(getglobal("AIOBFrame"),AIOB_GetBagsTotalSlots());
        elseif option == "Freeze" then
                AIOB_SetFreeze();
        end
end
function AIOB_SetGraphics()
        if AIOBGraphics == 1 then
                AIOBFrame:SetBackdropColor(0,0,0,0);
                AIOBFrame:SetBackdropBorderColor(0,0,0,0);
                
                AIOBFramePortrait:Show();
                AIOBFrameTextureTopLeft:Show();
                AIOBFrameTextureTopCenter:Show();
                AIOBFrameTextureTopRight:Show();
                AIOBFrameTextureLeft:Show();
                AIOBFrameTextureCenter:Show();
                AIOBFrameTextureRight:Show();
                AIOBFrameTextureBottomLeft:Show();
                AIOBFrameTextureBottomCenter:Show();
                AIOBFrameTextureBottomRight:Show();
                AIOBFrameName:ClearAllPoints();
                AIOBFrameName:SetPoint("TOPLEFT", "AIOBFrame", "TOPLEFT", 70, -8);
                AIOBFrameCloseButton:ClearAllPoints();
                AIOBFrameCloseButton:SetPoint("TOPRIGHT", "AIOBFrame", "TOPRIGHT", 10, 0);
        else
                if AIOBBackground==1 then
                        AIOBFrame:SetBackdropColor(0,0,0,0.7);
                        AIOBFrame:SetBackdropBorderColor(1,1,1,0.7);
                else
                        AIOBFrame:SetBackdropColor(0,0,0,0);
                        AIOBFrame:SetBackdropBorderColor(1,1,1,0);
                end
                        
                AIOBFramePortrait:Hide();
                AIOBFrameTextureTopLeft:Hide();
                AIOBFrameTextureTopCenter:Hide();
                AIOBFrameTextureTopRight:Hide();
                AIOBFrameTextureLeft:Hide();
                AIOBFrameTextureCenter:Hide();
                AIOBFrameTextureRight:Hide();
                AIOBFrameTextureBottomLeft:Hide();
                AIOBFrameTextureBottomCenter:Hide();
                AIOBFrameTextureBottomRight:Hide();
                AIOBFrameName:ClearAllPoints();
                AIOBFrameName:SetPoint("TOPLEFT", "AIOBFrame", "TOPLEFT", 5, -6);
                AIOBFrameCloseButton:ClearAllPoints();
                AIOBFrameCloseButton:SetPoint("TOPRIGHT", "AIOBFrame", "TOPRIGHT", 2, 2);
        end
end
function AIOB_SetFreeze()
        if AIOBFreeze == 1 then
                AIOBFreezeNormalTexture:SetTexture("Interface\\AddOns\\AllInOneInventory\\Skin\\LockButton-Locked-Up");
        else
                AIOBFreezeNormalTexture:SetTexture("Interface\\AddOns\\AllInOneInventory\\Skin\\LockButton-Unlocked-Up");
        end
end

-- SetReplaceBank: Sets if AIOB replaces the official Bank frame
-- Unhooks the Official blizzard frome from the opened and closed events
function AIOB_SetReplaceBank()
        if BankFrame_Saved == nil then
                BankFrame_Saved = getglobal("BankFrame");
        end
        if ( AIOBReplaceBank == 0 ) then
                BankFrame_Saved:RegisterEvent("BANKFRAME_OPENED");
                BankFrame_Saved:RegisterEvent("BANKFRAME_CLOSED");
                setglobal("BankFrame", BankFrame_Saved);
                BankFrame_Saved = nil;
        else
                if BankFrame_Saved:IsVisible() then
                        BankFrame_Saved:Hide();
                end
                BankFrame_Saved:UnregisterEvent("BANKFRAME_OPENED");
                BankFrame_Saved:UnregisterEvent("BANKFRAME_CLOSED");
                setglobal("BankFrame", AIOBFrameAtBankText);
        end
end
-- == End Toggle Functions ==

-- Get Link and Get Hyperlink - maintain independance.
function AIOB_GetLink(item)
        if item and item.color and item.item and item.name then
                local link = "|c"..item.color.."|H"..AIOB_GetHyperlink(item).."|h["..item.name.."]|h|r";
                return link;
        end
        return nil;
end

function AIOB_GetHyperlink(item)
        if item and item.item then
                local link = string.gsub(item.item, "(%d+):(%d+):(%d+):(%d+)", "%1:0:%3:%4");
                return "item:"..link;
        end
        return nil;
end