vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
GMail = AceLibrary("AceAddon-2.0"):new("AceEvent-2.0", "AceHook-2.0")

function GMail:OnInitialize()

tinsert(UISpecialFrames, "GMailInboxOpenAll")

-- Allows the mail frame to be pushed
if ( UIPanelWindows["MailFrame"] ) then
        UIPanelWindows["MailFrame"].pushable = 1
else
        UIPanelWindows["MailFrame"] = { area = "left", pushable = 1 }
end

-- Close FriendsFrame will close if you try to open a mail with mailframe+friendsframe open
if ( UIPanelWindows["FriendsFrame"] ) then
        UIPanelWindows["FriendsFrame"].pushable = 2
else
        UIPanelWindows["FriendsFrame"] = { area = "left", pushable = 2 }
end

MailItem1:SetPoint("TOPLEFT", "InboxFrame", "TOPLEFT", 48, -80)
for i = 1, 7, 1 do
        getglobal("MailItem" .. i .. "ExpireTime"):SetPoint("TOPRIGHT", "MailItem" .. i, "TOPRIGHT", 10, -4)
        getglobal("MailItem" .. i):SetWidth(280)
end

GMAIL_NUMITEMBUTTONS = 21
GMail_BagLinks = { }
GMail_ScheduledStack = { }
GMail_SelectedItems = { }
GMail_DELETEDELAY = 1
GMail_DELETEEVENTDELAY = 1

GMailFrame.num = 0
PanelTemplates_SetNumTabs(MailFrame, 3)

GMailForwardFrame.pickItem = { }
GMailForwardFrame.process = 0

GMailGlobalFrame.queue = { }
GMailGlobalFrame.update = 0
GMailGlobalFrame.total = 0
GMailGlobalFrame.sendmail = 0
GMailGlobalFrame.latency = 2.25

GMailTooltip:SetOwner(WorldFrame, "ANCHOR_NONE")

GMailInboxFrame.eventFunc = { }

end

function GMail:OnEnable()

self:RegisterEvent("MAIL_INBOX_UPDATE")
self:RegisterEvent("UI_ERROR_MESSAGE")
self:RegisterEvent("MAIL_SEND_SUCCESS")
self:RegisterEvent("MAIL_SEND_INFO_UPDATE")
self:RegisterEvent("MAIL_CLOSED")
self:RegisterEvent("BAG_UPDATE")

self:Hook("ContainerFrameItemButton_OnClick")
self:Hook("PickupContainerItem")
self:Hook("ContainerFrame_Update")
self:Hook("ClickSendMailItemButton")
self:HookScript(TradeFrame, "OnShow", "TF_Show")
self:Hook("InboxFrameItem_OnEnter")
self:Hook("MailFrameTab_OnClick")
self:Hook("InboxFrame_OnClick")
self:Hook("InboxFrame_Update")
self:Hook("CloseMail")
self:Hook("TakeInboxItem")
self:Hook("OpenMail_Reply")
oldTakeInboxMoney = OpenMailMoneyButton:GetScript("OnClick")

end

function GMail:MAIL_CLOSED()
        GMail:ClearItems()
        GMailGlobalFrame.total = 0
        GMailGlobalFrame.queue = { }
end

function GMail:MAIL_SEND_SUCCESS() 
        GMAIL_CANSENDNEXT = 1 
end

function GMail:ContainerFrameItemButton_OnClick(btn, ignore)
        if ( self:GetItemFrame(this:GetParent():GetID(), this:GetID()) ) then
                return
        end
        self.hooks["ContainerFrameItemButton_OnClick"].orig(btn, ignore)
        self:UpdateItemButtons()
end

function GMail:PickupContainerItem(bag, item, special)
        if ( ( self:GetItemFrame(bag, item) or ( GMail_addItem and GMail_addItem[1] == bag and GMail_addItem[2] == item ) ) and not special ) then
                return
        end
        if ( not CursorHasItem() ) then
                GMailFrame.bag = bag
                GMailFrame.item = item
        end
        if ( IsAltKeyDown() and GMailFrame:IsVisible() and not CursorHasItem() ) then
                local i
                for i = 1, GMAIL_NUMITEMBUTTONS, 1 do
                        if ( not getglobal("GMailButton" .. i).item ) then

                                if ( self:ItemIsMailable(bag, item) ) then
                                        GMail:Print("GMail: Cannot attach item.", 1, 0.5, 0)
                                        return
                                end

                                self.hooks["PickupContainerItem"].orig(bag, item)
                                self:MailButton_OnClick(getglobal("GMailButton" .. i))
                                self:UpdateItemButtons()
                                return
                        end
                end
        elseif ( IsAltKeyDown() and SendMailFrame:IsVisible() and not CursorHasItem() ) then
                self.hooks["PickupContainerItem"].orig(bag, item)
                ClickSendMailItemButton()
                return
        elseif ( IsAltKeyDown() and TradeFrame:IsVisible() and not CursorHasItem() ) then
                for i = 1, 6, 1 do
                        if ( not GetTradePlayerItemLink(i) ) then
                                self.hooks["PickupContainerItem"].orig(bag, item)
                                ClickTradeButton(i)
                                return
                        end
                end
        elseif ( IsAltKeyDown() and not CursorHasItem() and ( not TradeFrame or not TradeFrame:IsVisible() ) and ( not AuctionFrame or not AuctionFrame:IsVisible() ) and UnitExists("target") and CheckInteractDistance("target", 2) and UnitIsFriend("player", "target") and UnitIsPlayer("target") ) then
                InitiateTrade("target")
                GMail_addItem = { bag, item, UnitName("target"), 2 }
                for i = 1, NUM_CONTAINER_FRAMES, 1 do
                        if ( getglobal("ContainerFrame" .. i):IsVisible() ) then
                                ContainerFrame_Update(getglobal("ContainerFrame" .. i))
                        end
                end
                return
        end
        self.hooks["PickupContainerItem"].orig(bag, item)
        self:UpdateItemButtons()
end

function GMail:MailFrameTab_OnClick(tab)
        if ( not tab ) then 
                tab = this:GetID()
        end

        if ( tab == 3 ) then
                PanelTemplates_SetTab(MailFrame, 3)
                InboxFrame:Hide()
                SendMailFrame:Hide()
                GMailFrame:Show()
                SendMailFrame.sendMode = "massmail"
                MailFrameTopLeft:SetTexture("Interface\\ClassTrainerFrame\\UI-ClassTrainer-TopLeft")
                MailFrameTopRight:SetTexture("Interface\\ClassTrainerFrame\\UI-ClassTrainer-TopRight")
                MailFrameBotLeft:SetTexture("Interface\\ClassTrainerFrame\\UI-ClassTrainer-BotLeft")
                MailFrameBotRight:SetTexture("Interface\\ClassTrainerFrame\\UI-ClassTrainer-BotRight")
                MailFrameTopLeft:SetPoint("TOPLEFT", "MailFrame", "TOPLEFT", 2, -1)
                return
        else
                GMailFrame:Hide()
        end
        self.hooks["MailFrameTab_OnClick"].orig(tab)
        self:Forward_EnableForward()
end

function GMail:ClickSendMailItemButton()
        if ( not GetSendMailItem() ) then
                GMailFrame.mailbag = GMailFrame.bag
                GMailFrame.mailitem = GMailFrame.item
        end
        self.hooks["ClickSendMailItemButton"].orig()
end

-- Handle the dragging of items
function GMail:MailButton_OnClick(button)
        if ( not button ) then button = this end
        if ( CursorHasItem() ) then
                local bag = GMailFrame.bag
                local item = GMailFrame.item
                if ( not bag or not item ) then return end
                if ( self:ItemIsMailable(bag, item) ) then
                        GMail:Print("GMail: Cannot attach item.", 1, 0.5, 0)
                        self.hooks["PickupContainerItem"].orig(bag, item)
                        return
                end
                self.hooks["PickupContainerItem"].orig(bag, item)
                if ( this.bag and this.item ) then
                        -- There's already an item there
                        -- Pickup that item to replicate Send Mail's behaviour
                        self.hooks["PickupContainerItem"].orig(button.bag, button.item)
                        GMailFrame.bag = button.bag
                        GMailFrame.item = button.item
                else
                        GMailFrame.bag = nil
                        GMailFrame.item = nil
                end
                local texture, count = GetContainerItemInfo(bag, item)
                getglobal(button:GetName() .. "IconTexture"):Show()
                getglobal(button:GetName() .. "IconTexture"):SetTexture(texture)
                if ( count > 1 ) then
                        getglobal(button:GetName() .. "Count"):SetText(count)
                        getglobal(button:GetName() .. "Count"):Show()
                else
                        getglobal(button:GetName() .. "Count"):Hide()
                end
                button.bag = bag
                button.item = item
                button.texture = texture
                button.count = count
        elseif ( button.item and button.bag ) then
                self.hooks["PickupContainerItem"].orig(button.bag, button.item)
                getglobal(button:GetName() .. "IconTexture"):Hide()
                getglobal(button:GetName() .. "Count"):Hide()
                GMailFrame.bag = button.bag
                GMailFrame.item = button.item
                button.item = nil
                button.bag = nil
                button.count = nil
                button.texture = nil

        end
        local num = self:GetNumMails()
        GMailFrame.num = num
        self:CanSend(GMailNameEditBox)
        if ( num == 0 ) then num = 1 end
        MoneyFrame_Update("GMailCostMoneyFrame", GetSendMailPrice()*num)
        for i = 1, NUM_CONTAINER_FRAMES, 1 do
                if ( getglobal("ContainerFrame" .. i):IsVisible() ) then
                        ContainerFrame_Update(getglobal("ContainerFrame" .. i))
                end
        end
end

function GMail:ItemIsMailable(bag, item)

        -- Make sure tooltip is cleared
        for i = 1, 29, 1 do
                getglobal("GMailTooltipTextLeft" .. i):SetText("")
        end

        GMailTooltip:SetBagItem(bag, item)
        for i = 1, GMailTooltip:NumLines(), 1 do
                local text = getglobal("GMailTooltipTextLeft" .. i):GetText()
                if ( text == ITEM_SOULBOUND or text == ITEM_BIND_QUEST or text == ITEM_CONJURED or text == ITEM_BIND_ON_PICKUP ) then
                        return 1
                end
        end
        return nil
end


function GMail:UpdateItemButtons(frame)
        local i
        for i = 1, GMAIL_NUMITEMBUTTONS, 1 do
                local btn = getglobal("GMailButton" .. i)
                if ( not frame or btn ~= frame ) then
                        local texture, count
                        if ( btn.item and btn.bag ) then
                                texture, count = GetContainerItemInfo(btn.bag, btn.item)
                        end
                        if ( not texture ) then
                                getglobal(btn:GetName() .. "IconTexture"):Hide()
                                getglobal(btn:GetName() .. "Count"):Hide()
                                btn.item = nil
                                btn.bag = nil
                                btn.count = nil
                                btn.texture = nil
                        else
                                btn.count = count
                                btn.texture = texture
                                getglobal(btn:GetName() .. "IconTexture"):Show()
                                getglobal(btn:GetName() .. "IconTexture"):SetTexture(texture)
                                if ( count > 1 ) then
                                        getglobal(btn:GetName() .. "Count"):Show()
                                        getglobal(btn:GetName() .. "Count"):SetText(count)
                                else
                                        getglobal(btn:GetName() .. "Count"):Hide()
                                end
                        end
                end
        end
end

function GMail:GetItemFrame(bag, item)
        local i
        for i = 1, GMAIL_NUMITEMBUTTONS, 1 do
                local btn = getglobal("GMailButton" .. i)
                if ( btn.item == item and btn.bag == bag ) then
                        return btn
                end
        end
        return nil
end

function GMail:GetNumMails()
        local i
        local num = 0
        for i = 1, GMAIL_NUMITEMBUTTONS, 1 do
                local btn = getglobal("GMailButton" .. i)
                if ( btn.item and btn.bag ) then
                        num = num + 1
                end
        end
        return num
end

function GMail:ClearItems()
        local i
        local num = 0
        for i = 1, GMAIL_NUMITEMBUTTONS, 1 do
                local btn = getglobal("GMailButton" .. i)
                btn.item = nil
                btn.count = nil
                btn.bag = nil
                btn.texture = nil
        end
        self:UpdateItemButtons()
        GMailMailButton:Disable()
        GMailNameEditBox:SetText("")
        GMailSubjectEditBox:SetText("")
        GMailStatusText:SetText("")
        GMailAbortButton:Hide()
        GMailAcceptSendFrame:Hide()
end

function GMail:CanSend(eb)
        if ( not eb ) then eb = this end
        if ( strlen(eb:GetText()) > 0 and GMailFrame.num > 0 and GetSendMailPrice()*GMailFrame.num <= GetMoney() ) then
                GMailMailButton:Enable()
        else
                GMailMailButton:Disable()
        end
end

function GMail:SendMail()
        for key, val in this.queue do
                GMailStatusText:SetText(format(GMAIL_SENDING, key, this.total))
                GMailAbortButton:Show()

                if ( GetSendMailItem() and GMailFrame.mailbag and GMailFrame.mailitem ) then
                        -- There's already an item in the slot
                        ClickSendMailItemButton()
                        self.hooks["PickupContainerItem"].orig(GMailFrame.mailbag, GMailFrame.mailitem)
                        GMailFrame.mailbag = nil
                        GMailFrame.mailitem = nil
                elseif ( CursorHasItem() and GMailFrame.bag and GMailFrame.item ) then
                        PickupContainerItem(GMailFrame.bag, GMailFrame.item)
                        GMailFrame.bag = nil
                        GMailFrame.item = nil
                end

                self.hooks["PickupContainerItem"].orig(val.bag, val.item)

                ClickSendMailItemButton()

                local name, useless, count = GetSendMailItem()

                if ( not name ) then 
                        GMail:Print("GMail: " .. GMAIL_ERROR, 1, 0, 0)
                else

                        local subjectstr = GMailSubjectEditBox:GetText()
                        if ( strlen(subjectstr) > 0 ) then
                                subjectstr = subjectstr .. " "
                        end

                        if ( count > 1 ) then
                                subjectstr = subjectstr .. "[" .. name .. " x" .. count .. "]"
                        else
                                subjectstr = subjectstr .. "[" .. name .. "]"
                        end

                        SendMail(val.to, subjectstr, format(GMAIL_ITEMNUM, key, this.total))
                end

                GMailGlobalFrame.queue[key] = nil
                return
        end
        GMailStatusText:SetText(format(GMAIL_DONESENDING, this.total))
        GMailAbortButton:Hide()
        GMailGlobalFrame:Hide()

        GMailGlobalFrame.total = 0
        GMailGlobalFrame.queue = { }
end

function GMail:FillItemTable()
        local arr = { }
        for i = 1, GMAIL_NUMITEMBUTTONS, 1 do
                local btn = getglobal("GMailButton" .. i)
                if ( btn.item and btn.bag ) then
                        tinsert(arr, { ["item"] = btn.item, ["bag"] = btn.bag, ["to"] = GMailNameEditBox:GetText() })
                end
        end
        return arr
end

function GMail:ProcessQueue(elapsed)
        if ( not GMAIL_CANSENDNEXT ) then
                return
        end
        this.sendmail = this.sendmail + elapsed
        if ( this.sendmail > 0.5 ) then
                this.sendmail = 0
                if ( this.total > 0 ) then
                        self:SendMail()
                        GMAIL_CANSENDNEXT = nil
                end
        end
end

function GMail:ContainerFrame_Update(frame)
        self.hooks["ContainerFrame_Update"].orig(frame)
        local id = frame:GetID()
        if ( GMailFrame:IsVisible() ) then
                local i
                for i = 1, GMAIL_NUMITEMBUTTONS, 1 do
                        local btn = getglobal("GMailButton" .. i)
                        if ( btn.item and btn.bag ) then
                                if ( btn.bag == frame:GetID() ) then
                                        SetItemButtonDesaturated(getglobal(frame:GetName() .. "Item" .. (frame.size-btn.item)+1), 1, 0.5, 0.5, 0.5)
                                end
                        end
                end
        end
        if ( GMail_addItem and GMail_addItem[1] == frame:GetID() ) then
                SetItemButtonDesaturated(getglobal(frame:GetName() .. "Item" .. (frame.size-GMail_addItem[2])+1), 1, 0.5, 0.5, 0.5)
        end
end

function GMail:MAIL_SEND_INFO_UPDATE()
        if ( not SendMailFrame:IsVisible() ) then return end
        local name, useless, count = GetSendMailItem()

        if ( name and strlen(SendMailSubjectEditBox:GetText()) == 0 ) then
                if ( count > 1 ) then
                        name = name .. " x" .. count
                end
                SendMailSubjectEditBox:SetText(name)
        end
end

function GMail:InboxFrameItem_OnEnter()
        local didSetTooltip
        if ( this.index ) then
                if ( GetInboxItem(this.index) ) then
                        GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
                        GameTooltip:SetInboxItem(this.index)
                        didSetTooltip = 1
                end
        end
        if ( not didSetTooltip ) then
                GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
        end
        if (this.money) then
                GameTooltip:AddLine(ENCLOSED_MONEY, "", 1, 1, 1)
                SetTooltipMoney(GameTooltip, this.money)
                SetMoneyFrameColor("GameTooltipMoneyFrame", HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b)
        elseif (this.cod) then
                GameTooltip:AddLine(COD_AMOUNT, "", 1, 1, 1)
                SetTooltipMoney(GameTooltip, this.cod)
                if ( this.cod > GetMoney() ) then
                        SetMoneyFrameColor("GameTooltipMoneyFrame", RED_FONT_COLOR.r, RED_FONT_COLOR.g, RED_FONT_COLOR.b)
                else
                        SetMoneyFrameColor("GameTooltipMoneyFrame", HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b)
                end
        end
        if ( didSetTooltip and ( this.money or this.cod ) ) then
                GameTooltip:SetHeight(GameTooltip:GetHeight()+getglobal("GameTooltipTextLeft" .. GameTooltip:NumLines()):GetHeight())
                if ( GameTooltipMoneyFrame:IsVisible() ) then
                        GameTooltip:SetHeight(GameTooltip:GetHeight()+GameTooltipMoneyFrame:GetHeight())
                end
        end
        GameTooltip:Show()
end

function GMail:TF_Show()
        self.hooks[TradeFrame].OnShow.orig()
        if ( GMail_addItem and not CursorHasItem() and UnitName("NPC") == GMail_addItem[3] ) then
                self.hooks["PickupContainerItem"].orig(GMail_addItem[1], GMail_addItem[2])
                
                ClickTradeButton(1)
        end
        GMail_addItem = nil
end

function GMail:Inbox_OnUpdate(elapsed)
        if ( GMail_addItem ) then
                GMail_addItem[4] = GMail_addItem[4] - elapsed
                if ( GMail_addItem[4] <= 0 ) then
                        GMail_addItem = nil
                        for i = 1, NUM_CONTAINER_FRAMES, 1 do
                                if ( getglobal("ContainerFrame" .. i):IsVisible() ) then
                                        ContainerFrame_Update(getglobal("ContainerFrame" .. i))
                                end
                        end
                end
        end
        if ( this.num and this.elapsed ) then
                this.elapsed = this.elapsed - elapsed
                if ( this.elapsed <= 0 ) then
                        this.elapsed = nil
                        if ( this.id[1] ) then
                                local val = this.id[1]
                                local success = GMail:PickMail(val, this.openSelected)
                                if ( success ~= 2 ) then
                                        tremove(this.id, 1)
                                        this.num = this.num - 1
                                end
                                if ( success == 1 ) then
                                        for key, va in this.id do
                                                if ( va > val ) then
                                                        this.id[key] = va-1
                                                end
                                        end
                                        this.lastVal = val
                                        InboxFrame_Update()
                                else
                                        this.elapsed = 1+GMail_DELETEDELAY
                                        this.lastVal = nil
                                end
                                if ( this.num == 0 ) then
                                        this.num = nil
                                        GMail:Inbox_DisableClicks(nil)
                                end
                        end
                end
        end
        if ( this.delete ) then
                this.delete[1] = this.delete[1] - elapsed
                if ( this.delete[1] <= 0 ) then
                        local packageIcon, stationeryIcon, sender, subject, money, CODAmount, daysLeft, itemID, wasRead, wasReturned, textCreated  = GetInboxHeaderInfo(this.delete[2])
                        if ( money == 0 and not itemID ) then
                                GetInboxText(this.delete[2])
                                DeleteInboxItem(this.delete[2])
                        end
                        this.delete = nil
                        this.elapsed = 0.5+GMail_DELETEDELAY
                end
        end
end

function GMail:MAIL_INBOX_UPDATE()
        if ( GMailInboxFrame.eventDelete ) then
                GMailInboxFrame.delete = { GMail_DELETEEVENTDELAY, GMailInboxFrame.eventDelete }
                GMailInboxFrame.eventDelete = nil
        end
end
function GMail:UI_ERROR_MESSAGE()
        if ( event == "UI_ERROR_MESSAGE" and ( arg1 == ERR_INV_FULL or arg1 == ERR_ITEM_MAX_COUNT ) ) then
                if ( this.num ) then
                        if ( arg1 == ERR_INV_FULL ) then
                                GMail:Inbox_Abort()
                                GMail:Print("GMail: Inventory full. Aborting.", 1, 0, 0)
                        elseif ( arg1 == ERR_ITEM_MAX_COUNT ) then
                                GMail:Print("GMail: You already have the maximum amount of that item. Skipping.", 1, 0, 0)
                                this.elapsed = GMail_DELETEDELAY
                                if ( this.lastVal ) then
                                        for key, va in this.id do
                                                if ( va >= this.lastVal ) then
                                                        this.id[key] = va+1
                                                end
                                        end
                                end
                        end
                end
end
end

function GMail:Print(msg, r, g, b)
        DEFAULT_CHAT_FRAME:AddMessage(msg, r, g, b);
end

function GMail:PickMail(id, openSelected)
        if ( not id ) then
                return 0
        end
        local packageIcon, stationeryIcon, sender, subject, money, CODAmount, daysLeft, hasItem, wasRead, wasReturned, textCreated, canReply = GetInboxHeaderInfo(id)
        if ( CODAmount > 0 ) then
                GMail:Print("GMail: Mail |c00FFFFFF" .. this.numMails-(this.num-1) .. "|r/|c00FFFFFF" .. this.numMails .. "|r is Cash on Delivery, skipping.", 1, 0, 0)
                return 0
        elseif ( not hasItem and money == 0 and not openSelected ) then
                GMail:Print("GMail: Mail |c00FFFFFF" .. this.numMails-(this.num-1) .. "|r/|c00FFFFFF" .. this.numMails .. "|r has no money or items, skipping.", 1, 1, 0)
                return 0
        end
        GMail:Print("GMail: Opening mail |c00FFFFFF" .. this.numMails-(this.num-1) .. "|r/|c00FFFFFF" .. this.numMails .. "|r: \"|c00FFFFFF" .. ( subject or "<No Subject>" ) .. "|r\" from |c00FFFFFF" .. ( sender or "<Unknown Sender>" ) .. "|r.", 1, 1, 0)
        local eventDelete
        if ( hasItem ) then
                self.hooks["TakeInboxItem"].orig(id)
                eventDelete = 1
                if ( money > 0 ) then
                        return 2
                end
        end
        if ( money > 0 ) then
                TakeInboxMoney(id)
                eventDelete = 1
        end
        if ( eventDelete ) then
                GMailInboxFrame.eventDelete = id
        else
                GMailInboxFrame.delete = { GMail_DELETEDELAY, id }
        end
        return 1
end

function GMail_Inbox_SetSelected()
        local id = this:GetID() + (InboxFrame.pageNum-1)*7
        if ( not this:GetChecked() ) then
                for k, v in GMail_SelectedItems do
                        if ( v == id ) then
                                tremove(GMail_SelectedItems, k)
                                break
                        end
                end
        else
                tinsert(GMail_SelectedItems, id)
        end
end

function GMail_Inbox_OpenSelected(openAll)
        GMail:Inbox_DisableClicks(1)
        GMailInboxFrame.num = 0
        GMailInboxFrame.elapsed = GMail_DELETEDELAY
        GMailInboxFrame.id = { }
        GMailInboxFrame.openSelected = not openAll
        if ( openAll ) then
                for i = 1, GetInboxNumItems(), 1 do
                        GMailInboxFrame.num = GMailInboxFrame.num + 1
                        tinsert(GMailInboxFrame.id, i)
                end
        else
                for k, v in GMail_SelectedItems do
                        GMailInboxFrame.num = GMailInboxFrame.num + 1
                        tinsert(GMailInboxFrame.id, v)
                end
        end
        GMailInboxFrame.numMails = GMailInboxFrame.num
        GMail_SelectedItems = { }
end

function GMail:InboxFrame_Update()
        self.hooks["InboxFrame_Update"].orig()
        for i = 1, 7, 1 do
                local index = (i + (InboxFrame.pageNum-1)*7)
                if ( index > GetInboxNumItems() ) then
                        getglobal("GMailBoxItem" .. i .. "CB"):Hide()
                else
                        getglobal("GMailBoxItem" .. i .. "CB"):Show()
                        getglobal("GMailBoxItem" .. i .. "CB"):SetChecked(nil)
                        for k, v in GMail_SelectedItems do
                                if ( v == index ) then
                                        getglobal("GMailBoxItem" .. i .. "CB"):SetChecked(1)
                                        break
                                end
                        end
                end
        end
        if ( GMailInboxFrame.num ) then
                GMail:Inbox_DisableClicks(1, 1)
        end
end

function GMail:Inbox_DisableClicks(disable, loopPrevention)
        if ( disable ) then
                for i = 1, 7, 1 do
                        getglobal("MailItem" .. i .. "ButtonIcon"):SetDesaturated(1)
                end
                if not self:IsHooked("InboxFrame_OnClick") then self:Hook("InboxFrame_OnClick", "DummyFunction") end
        else
                for i = 1, 7, 1 do
                        getglobal("MailItem" .. i .. "ButtonIcon"):SetDesaturated(nil)
                end
                if ( not loopPrevention ) then
                        InboxFrame_Update()
                end
                if self:IsHooked("InboxFrame_OnClick") then self:Unhook("InboxFrame_OnClick") end
        end
end

function GMail:InboxFrame_OnClick()
        this:SetChecked(nil)
end

function GMail:Inbox_Abort()
        GMailInboxFrame.num = nil
        GMailInboxFrame.elapsed = nil
        GMailInboxFrame.id = { }
        GMail_SelectedItems = { }
        GMail:Inbox_DisableClicks()
        HideUIPanel(GMailInboxOpenAll)
end

function GMail:CloseMail()
        self.hooks["CloseMail"].orig()
        GMail:Inbox_Abort()
end

function GMail:TakeInboxItem(id)
        self.hooks["TakeInboxItem"].orig(id)
        local name, itemTexture, count, quality, canUse = GetInboxItem(id)
        tinsert(GMailForwardFrame.pickItem, name)
end

-- Mail Forwarding
function GMail:DisableAttachments(disable)
        if ( disable ) then
                OpenMailMoneyButtonIconTexture:SetDesaturated(1)
                OpenMailPackageButtonIconTexture:SetDesaturated(1)
                if not self:IsHooked(OpenMailMoneyButton, "OnClick") then self:HookScript(OpenMailMoneyButton, "OnClick", "DummyFunction") end
                if not self:IsHooked(OpenMailPackageButton, "OnClick") then self:HookScript(OpenMailPackageButton, "OnClick", "DummyFunction") end
        else
                OpenMailMoneyButtonIconTexture:SetDesaturated(nil)
                OpenMailPackageButtonIconTexture:SetDesaturated(nil)
                if self:IsHooked(OpenMailMoneyButton, "OnClick") then self:Unhook(OpenMailMoneyButton, "OnClick") end
                if self:IsHooked(OpenMailPackageButton, "OnClick") then self:Unhook(OpenMailPackageButton, "OnClick") end
        end
end

function GMail:DummyFunction()
end

function GMail:OpenMail_Reply()
        self.hooks["OpenMail_Reply"].orig()
        SendMailMoneyCopper:SetText("")
        SendMailMoneySilver:SetText("")
        SendMailMoneyGold:SetText("")
end


function GMail:OpenReply()
        OpenMail_Reply()
        local packageIcon, stationeryIcon, sender, subject, money, CODAmount, daysLeft, hasItem, wasRead, wasReturned, textCreated, canReply = GetInboxHeaderInfo(InboxFrame.openMailID)
        
        -- Money
        local gold, silver, copper = "", "", ""
        if ( money and money > 0 ) then
                gold = floor(money / (COPPER_PER_SILVER * SILVER_PER_GOLD))
                silver = floor((money - (gold * COPPER_PER_SILVER * SILVER_PER_GOLD)) / COPPER_PER_SILVER)
                copper = mod(money, COPPER_PER_SILVER)
        end
        SendMailMoneyCopper:SetText(copper)
        SendMailMoneySilver:SetText(silver)
        SendMailMoneyGold:SetText(gold)
        
        -- Items
        local name, itemTexture, count, quality, canUse = GetInboxItem(InboxFrame.openMailID)
        SendMailPackageButton:SetNormalTexture(itemTexture)
        if ( count > 1 ) then
                SendMailPackageButtonCount:SetText(count)
        else
                SendMailPackageButtonCount:SetText("")
        end
        
        -- Text fields
        SendMailNameEditBox:SetText("")
        local subject = OpenMailSubject:GetText()
        local prefix = "FW:".." "
        if ( strsub(subject, 1, strlen(prefix)) ~= prefix ) then
                subject = prefix..subject
        end
        SendMailSubjectEditBox:SetText(subject or "")
        SendMailBodyEditBox:SetText(string.gsub(OpenMailBodyText:GetText() or "", "\n", "\n>"))
        SendMailNameEditBox:SetFocus()

        -- Set the send mode so the work flow can change accordingly
        SendMailFrame.sendMode = "reply"
        
        self:Forward_EnableForward(1)
end

function GMail:SendMailMailButton_OnClick()
        local name, itemTexture, count, quality, canUse = GetInboxItem(InboxFrame.openMailID)
        local packageIcon, stationeryIcon, sender, subject, money, CODAmount, daysLeft, hasItem, wasRead, wasReturned, textCreated, canReply = GetInboxHeaderInfo(InboxFrame.openMailID)
        if ( name ) then
                GMailForwardFrame.searchItem = name
                GMailForwardFrame.forwardStep = 1
                self.hooks["TakeInboxItem"].orig(InboxFrame.openMailID)
        else
                GMailForwardFrame.forwardStep = 2
                if ( money and money > 0 ) then
                        SetSendMailMoney(money)
                        GMailForwardFrame.countDown = 2
                        oldTakeInboxMoney(InboxFrame.openMailID)
                else
                        GMailForwardFrame.countDown = 0.5
                end
        end
        SendMailMailButton:Disable()
end

function GMail:Forward_OnUpdate(elapsed)
        if ( this.forwardStep and this.forwardStep > 1 ) then
                if ( this.countDown ) then
                        this.countDown = this.countDown - elapsed
                        if ( this.countDown <= 0 ) then
                                if ( this.forwardStep == 2 ) then
                                        this.countDown = 0.5
                                        this.forwardStep = 3
                                        -- Send the mail
                                        SendMail(SendMailNameEditBox:GetText(), SendMailSubjectEditBox:GetText(), SendMailBodyEditBox:GetText())
                                        SendMailMailButton:Disable()
                                elseif ( this.forwardStep == 3 ) then
                                        -- Delete the old one
                                        local packageIcon, stationeryIcon, sender, subject, money, CODAmount, daysLeft, itemID, wasRead, wasReturned, textCreated  = GetInboxHeaderInfo(InboxFrame.openMailID)
                                        if ( money == 0 and not itemID ) then
                                                DeleteInboxItem(InboxFrame.openMailID)
                                        end
                                        self:MailFrameTab_OnClick(1)
                                        HideUIPanel(OpenMailFrame)
                                        this.countDown = nil
                                        this.forwardStep = nil
                                end
                        end
                end
        end
        this.process = this.process - elapsed
        if ( this.process <= 0 ) then
                this.process = 3
                if ( getn(GMail_ScheduledStack) > 0 ) then
                        self:ProcessStack()
                end
        end
end

function GMail:InboxFrame_OnClick(id)
        self.hooks["InboxFrame_OnClick"].orig(id)
        local packageIcon, stationeryIcon, sender, subject, money, CODAmount, daysLeft, itemID, wasRead, wasReturned, textCreated  = GetInboxHeaderInfo(id)
        if ( CODAmount and CODAmount > 0 ) then
                OpenMailForwardButton:Disable()
        else
                OpenMailForwardButton:Enable()
        end
end

function GMail:Forward_EnableForward(enable)
        if ( enable ) then
                OpenMailForwardButton:Disable()
                if not self:IsHooked(SendMailPackageButton, "OnEnter") then self:HookScript(SendMailPackageButton, "OnEnter", "SMPBOE") end
                SendMailCODButton:Disable()
                self:DisableAttachments(1)
                if not self:IsHooked("SendMailMailButton_OnClick") then self:Hook("SendMailMailButton_OnClick") end
                if not self:IsHooked("SendMailPackageButton_OnClick") then self:Hook("SendMailPackageButton_OnClick") end
        else
                OpenMailForwardButton:Enable()
                if self:IsHooked(SendMailPackageButton, "OnEnter") then self:Unhook(SendMailPackageButton, "OnEnter") end
                SendMailCODButton:Enable()
                self:DisableAttachments(nil)
                if self:IsHooked("SendMailMailButton_OnClick") then self:Unhook("SendMailMailButton_OnClick") end
                if self:IsHooked("SendMailPackageButton_OnClick") then self:Unhook("SendMailPackageButton_OnClick") end
        end
end

function GMail:SMPBOE()
        GameTooltip:SetOwner(SendMailPackageButton, "ANCHOR_RIGHT")
        GameTooltip:SetInboxItem(InboxFrame.openMailID) 
end
function GMail:SendMailPackageButton_OnClick()
end

function GMail:Forward_AttachSlot(container, item)
        PickupContainerItem(container, item)
        ClickSendMailItemButton()
        GMailForwardFrame.searchItem = nil
        GMailForwardFrame.forwardStep = 2
        GMailForwardFrame.countDown = 1.5
end

function GMail:BAG_UPDATE()
        local old = { }
        for k, v in GMail_BagLinks do
                if ( type(v) == "table" ) then
                        old[k] = { }
                        for key, val in v do
                                old[k][key] = val
                        end
                end
        end
        GMail_BagLinks = { }
        for i = 0, 4, 1 do
                GMail_BagLinks[i] = { }
                for y = 1, GetContainerNumSlots(i), 1 do
                        local curr = GetContainerItemLink(i, y)
                        local _, _, name = string.find(( curr or "" ), "%[(.+)%]")
                        if ( name ) then
                                if ( GMailForwardFrame.searchItem ) then
                                        if ( name and name == GMailForwardFrame.searchItem and not old[i][y] ) then
                                                self:Forward_AttachSlot(i, y)
                                        end
                                else
                                        local _, _, name = string.find(( curr or "" ), "%[(.+)%]")
                                        if ( name and name == GMailForwardFrame.pickItem[1] and not old[i][y] ) then
                                                tremove(GMailForwardFrame.pickItem, 1)
                                                for k, v in old do
                                                        local hasFound
                                                        for key, val in v do
                                                                if ( val == name and ( k ~= i or key ~= y ) ) then
                                                                        local _,_, link = string.find((GetContainerItemLink(k, key) or ""), "(item:[%d:]+)")
                                                                        if ( link ) then
                                                                                local texture, itemCount = GetContainerItemInfo(k,key)
                                                                                local tex, iC = GetContainerItemInfo(i, y)
                                                                                local sName, sLink, iQuality, iLevel, sType, sSubType, iCount = GetItemInfo(link)
                                                                                if ( sName and itemCount and iCount and iC ) then
                                                                                        if ( iCount >= (itemCount+iC) ) then
                                                                                                if ( getn(GMail_ScheduledStack) == 0 ) then
                                                                                                        GMailForwardFrame.process = 2
                                                                                                end
                                                                                                tinsert(GMail_ScheduledStack, { i, y, k, key })
                                                                                                hasFound = 1
                                                                                                break
                                                                                        end
                                                                                end
                                                                        end
                                                                end
                                                        end
                                                        if ( hasFound ) then
                                                                break
                                                        end
                                                end
                                        end
                                end
                                GMail_BagLinks[i][y] = name
                        end
                end
        end
end


function GMail:ProcessStack()
        local val = tremove(GMail_ScheduledStack, 1)
        PickupContainerItem(val[1], val[2])
        PickupContainerItem(val[3], val[4])
end

local oldSMMFfunc = SendMailMoneyFrame.onvalueChangedFunc
SendMailMoneyFrame.onvalueChangedFunc = function()
        if ( oldSMMFfunc ) then
                oldSMMFfunc()
        end
        local subject = SendMailSubjectEditBox:GetText()
        if ( subject == "" or string.find(subject, "%[%d+G, %d+S, %d+C%]") ) then
                local copper, silver, gold = SendMailMoneyFrameCopper:GetText(), SendMailMoneyFrameSilver:GetText(), SendMailMoneyFrameGold:GetText()
                if ( not tonumber(copper) ) then
                        copper = 0
                end
                if ( not tonumber(silver) ) then
                        silver = 0
                end
                if ( not tonumber(gold) ) then
                        gold = 0
                end
                SendMailSubjectEditBox:SetText(format("[%sG, %sS, %sC]", gold, silver, copper))
        end
end