Quantcast
--[[-------------------------------------------------------------------
--  CaptainsLog - Copyright 2010 - James N. Whitehead II
-------------------------------------------------------------------]]--

local addonName, addon = ...
local L = addon.L

addon.ldb = LibStub("LibDataBroker-1.1")

local C = {
    whisper = WHISPER,
    party = PARTY,
    guild = GUILD,
    bnet = L["Battle.net"],
    raid = RAID,
}

local MINUTE = 60
local HOUR = MINUTE * 60

function addon:Initialize()
    self.db = LibStub("AceDB-3.0"):New("CaptainsLogDB", {
        char = {
            messages = {
                ["*"] = {},
            },
        },
        profile = {
            timestamp = true,
            timestamp_format = "%H:%M ",
            msg_life = 6 * HOUR,
            buffersize = {
                ["*"] = 15,
            },
            ignoreself = {
                ["*"] = true,
            },
            showinfeed = {
                whisper = true,
                party = true,
                guild = true,
                bnet = true,
                raid = true,
            },
            showintooltip = {
                whisper = true,
                party = true,
                guild = true,
                bnet = true,
                raid = true,
            },
            log = {
                whisper = true,
                party = true,
                guild = true,
                bnet = true,
                raid = true,
            }
        },
    })

    self.name = UnitName("player")
    self.messages = self.db.char.messages

    self:RegisterEvent("CHAT_MSG_WHISPER")
    self:RegisterEvent("CHAT_MSG_GUILD")
    self:RegisterEvent("CHAT_MSG_PARTY")
    self:RegisterEvent("CHAT_MSG_PARTY_LEADER", "CHAT_MSG_PARTY")
    self:RegisterEvent("CHAT_MSG_BN_WHISPER")
    self:RegisterEvent("CHAT_MSG_BN_CONVERSATION", "CHAT_MSG_BN_WHISPER")
    self:RegisterEvent("CHAT_MSG_RAID")
    self:RegisterEvent("CHAT_MSG_RAID_WARNING", "CHAT_MSG_RAID")
    self:RegisterEvent("CHAT_MSG_RAID_LEADER", "CHAT_MSG_RAID")

    self.feed = addon.ldb:NewDataObject("CaptainsLog", {
        type = "data source",
        icon = "Interface\\Icons\\Ability_Warrior_CommandingShout",
        text = "",
        OnTooltipShow = function(tooltip)
            self:PopulateTooltip(tooltip)
        end,
    })

    local last = self.db.char.last
    if last and last.mtype and last.sender then
        self:UpdateFeedText(last.mtype, last.sender)
    end
end

function addon:PruneMessages()
    for mtype, list in pairs(self.messages) do
        while #list > addon.db.profile.buffersize[mtype] do
            table.remove(list, 1)
        end
    end
end

function addon:Log(mtype, sender, msg)
    table.insert(self.messages[mtype], {time(), sender, msg})

    local bufsize = addon.db.profile.buffersize[mtype]
    while #self.messages[mtype] > bufsize do
        table.remove(self.messages[mtype], 1)
    end

    self.db.char.last = {
        mtype = mtype,
        sender = sender,
        msg = msg,
    }
end

function addon:UpdateFeedText(mtype, sender)
    if addon.db.profile.showinfeed[mtype] then
        self.feed.text = L["%s from %s"]:format(C[mtype] or mtype, sender)
    end
end

local colorMap = {
    party = "PARTY",
    guild = "GUILD",
    whisper = "WHISPER",
    raid = "RAID",
    bnet = "BN_WHISPER",
}

function addon:GetStardate()
    return date("%H%M.%S")
end

function addon:PopulateTooltip(tooltip)
    local stardate
    tooltip:AddLine(L["Captain's Log - Stardate %s"]:format(self:GetStardate()))
    tooltip:AddLine(" ")

    local sort = {}
    for k, v in pairs(self.messages) do
        table.insert(sort, k)
    end
    table.sort(sort)

    local now = time()

    for idx, mtype in ipairs(sort) do
        if addon.db.profile.showintooltip[mtype] then
            local color = ChatTypeInfo[colorMap[mtype]] or {}

            if idx > 1 then
                self:AddSpacerLine(tooltip, 3, 0.6, 0.6, 0.6)
            end

            tooltip:AddLine(C[mtype] or mtype)

            local msgShown = false
            if #self.messages[mtype] > 0 then
                for idx = 1, #self.messages[mtype], 1 do
                    local msg = self.messages[mtype][idx]
                    if now <= msg[1] + addon.db.profile.msg_life then
                        msgShown = true
                        local timestamp = " "
                        if addon.db.profile.timestamp then
                            timestamp = date(addon.db.profile.timestamp_format, msg[1])
                        end

                        tooltip:AddLine(
                        string.format("%s[%s]: %s", timestamp, msg[2], msg[3]),
                        color.r, color.g, color.b
                        )
                    end
                end
            end
            if not msgShown then
                tooltip:AddLine(L["No messages"])
            end
        end
    end

    if #sort <= 0 then
        tooltip:AddLine(L["No messages logged"])
    end
end

function addon:CHAT_MSG_WHISPER(event, msg, sender, ...)
    local mtype = "whisper"
    if not addon.db.profile.log[mtype] then return end
    if sender == self.name and addon.db.profile.ignoreself[mtype] then return end

    local cname = GetColoredName(event, msg, sender, ...)
    self:Log(mtype, cname, msg)
    self:UpdateFeedText(mtype, cname)
end

function addon:CHAT_MSG_GUILD(event, msg, sender, ...)
    local mtype = "guild"
    if not addon.db.profile.log[mtype] then return end
    if sender == self.name and addon.db.profile.ignoreself[mtype] then return end

    local cname = GetColoredName(event, msg, sender, ...)
    self:Log(mtype, cname, msg)
    self:UpdateFeedText(mtype, cname)
end

function addon:CHAT_MSG_PARTY(event, msg, sender, ...)
    local mtype = "party"
    if not addon.db.profile.log[mtype] then return end
    if sender == self.name and addon.db.profile.ignoreself[mtype] then return end

    local cname = GetColoredName(event, msg, sender, ...)
    self:Log(mtype, cname, msg)
    self:UpdateFeedText(mtype, cname)
end

function addon:CHAT_MSG_BN_WHISPER(event, msg, sender, ...)
    local mtype = "bnet"
    if not addon.db.profile.log[mtype] then return end
    if sender == self.name and addon.db.profile.ignoreself[mtype] then return end

    self:Log(mtype, sender, msg)
    self:UpdateFeedText(mtype, sender)
end

function addon:CHAT_MSG_RAID(event, msg, sender, ...)
    local mtype = "raid"
    if not addon.db.profile.log[mtype] then return end
    if sender == self.name and addon.db.profile.ignoreself[mtype] then return end

    local cname = GetColoredName(event, msg, sender, ...)
    self:Log(mtype, cname, msg)
    self:UpdateFeedText(mtype, cname)
end

--[[-------------------------------------------------------------------------
-- Tooltip spacer code, thanks to Mikma and Torhal
-------------------------------------------------------------------------]]--

local tooltipHooked = {}
local tooltipLines = {}
function addon:AddSpacerLine(tooltip, height, r, g, b, a)
    if not tooltipLines[tooltip] then
        tooltipLines[tooltip] = {}
    end

    if not tooltipHooked[tooltip] then
        tooltip:HookScript("OnTooltipCleared", function(self)
            for k, line in pairs(tooltipLines[self]) do
                line:Hide()
            end
        end)
        tooltipHooked[tooltip] = true
    end

    tooltip:AddDoubleLine(" ", " ")
    local num = tooltip:NumLines()
    local line = tooltipLines[tooltip][num]
    if not line then
        line = tooltip:CreateTexture(nil,"ARTWORK")
        line:SetPoint("LEFT", tooltip:GetName().."TextLeft"..num, "LEFT")
        line:SetPoint("RIGHT", tooltip:GetName().."TextRight"..num, "RIGHT")
        tooltipLines[tooltip][num] = line
    end
    line:SetHeight(height or 1)
    line:SetTexture(r or NORMAL_FONT_COLOR.r, g or NORMAL_FONT_COLOR.g, b or NORMAL_FONT_COLOR.b, a or 1)
    line:Show()
end