Prat_PlayerNames = Prat:NewModule('playernames')
Prat_PlayerNames.Colors = {
    DRUID   = "ff7c0a",
    HUNTER  = "aad372",
    MAGE    = "68ccef",
    PALADIN = "f48cba",
    PRIEST  = "ffffff",
    ROGUE   = "fff468",
    SHAMAN  = "f48cba",
    WARLOCK = "9382c9",
    WARRIOR = "c69b6d"
}
Prat_PlayerNames.Names = {}

function Prat_PlayerNames:OnInitialize()
    self.db = Prat:AcquireDBNamespace('PlayerNames')

    Prat:RegisterDefaults('PlayerNames', 'profile', {
        on = true,
        Brackets = 'Angled'
    })

    Prat.Options.args.playernames = {
        name = 'PlayerNames',
        desc = 'PlayerNames',
        type = 'group',
        args = {
            toggle = {
                name = 'Toggle',
                desc = 'Toggle the module on and off',
                type = 'toggle',
                get = function() return self.db.profile.on end,
                set = function(v)
                    if v then
                        self:OnEnable()
                    else
                        self:OnDisable()
                    end
                    self.db.profile.on = v
                end
            },
            brackets = {
                name = 'Brackets',
                desc = 'Different bracket styles',
                type = 'group',
                args = {
                    square = {
                        name = 'Square',
                        desc = 'Use square brackets: [Name].',
                        type = 'execute',
                        func = function()
                            self.db.profile.Brackets = 'Square'
                        end
                    },
                    angled = {
                        name = 'Angled',
                        desc = 'Use Angled brackets: <Name>.',
                        type = 'execute',
                        func = function()
                            self.db.profile.Brackets = 'Angled'
                        end
                    },
                    none = {
                        name = 'None',
                        desc = 'Use no brackets: Name.',
                        type = 'execute',
                        func = function()
                            self.db.profile.Brackets = 'None'
                        end
                    },
                }
            }
        }
    }
end

function Prat_PlayerNames:OnEnable()
    local Playerclass

    for i=1,7 do
        self:Hook(getglobal('ChatFrame'..i), 'AddMessage')
    end

    self:RegisterEvent('FRIENDLIST_UPDATE', 'updateFriends')
    self:RegisterEvent('GUILD_ROSTER_UPDATE', 'updateGuild')
    self:RegisterEvent('RAID_ROSTER_UPDATE', 'updateRaid')
    self:RegisterEvent('PARTY_MEMBERS_CHANGED', 'updateParty')
    self:RegisterEvent('PLAYER_TARGET_CHANGED', 'updateTarget')
    self:RegisterEvent('WHO_LIST_UPDATE', 'updateWho')

    _, Playerclass = UnitClass('player')
    self:addName(UnitName('player'), Playerclass)

    if IsInGuild() then
        GuildRoster()
    end
    if GetNumFriends() > 0 then
        ShowFriends()
    end
end

function Prat_PlayerNames:OnDisable()
    for i=1,7 do
        self:Unhook(getglobal('ChatFrame'..i), 'AddMessage')
    end

    self:UnregisterEvent('FRIENDLIST_UPDATE')
    self:UnregisterEvent('GUILD_ROSTER_UPDATE')
    self:UnregisterEvent('RAID_ROSTER_UPDATE')
    self:UnregisterEvent('PARTY_MEMBERS_CHANGED')
    self:UnregisterEvent('PLAYER_TARGET_CHANGED')
    self:UnregisterEvent('WHO_LIST_UPDATE')
end

function Prat_PlayerNames:updateFriends()
    local Name, Class
    for i = 1, GetNumFriends() do
        Name, _, Class = GetFriendInfo(i)
        self:addName(Name, Class)
    end
end

function Prat_PlayerNames:updateGuild()
    local Name, Class
    for i = 1, GetNumGuildMembers() do
        Name, _, _, _, Class = GetGuildRosterInfo(i)
        self:addName(Name, Class)
    end
end

function Prat_PlayerNames:updateRaid()
    local Name, Class
    for i = 1, GetNumRaidMembers() do
        Name, _, _, _, _, Class = GetRaidRosterInfo(i)
        self:addName(Name, Class)
    end
end

function Prat_PlayerNames:updateParty()
    local Unit, Name, Class
    for i = 1, GetNumPartyMembers() do
        Unit = 'party' .. i
        Name = UnitName(Unit)
        _, Class = UnitClass(Unit)
        self:addName(Name, Class)
    end
end

function Prat_PlayerNames:updateTarget()
    local Name, Class
    if not UnitIsPlayer('target') or not UnitIsFriend('player', 'target') then
        return
    end
    Name = UnitName('target')
    _, Class = UnitClass('target')
    self:addName(Name, Class)
end

function Prat_PlayerNames:updateWho()
    local Name, Class
    for i = 1, GetNumWhoResults() do
        Name, _, _, _, Class = GetWhoInfo(i)
        self:addName(Name, Class)
    end
end

function Prat_PlayerNames:addName(Name, Class)
    if not Class then
        return
    end

    Class = string.upper(Class)

    if Class == 'UNKNOWN' or not self.Colors[Class] then
        return
    end

    self.Names[Name] = string.format('|cff%s%s|r', self.Colors[Class], Name)
end

function Prat_PlayerNames:AddMessage(frame, Text, r, g, b, id)
    local Name = string.gsub(Text, '.*|Hplayer:(.-)|h.*', '%1')
    local Brackets

    if self.Names[Name] then
        Name = self.Names[Name]
    end

    if self.db.profile.Brackets == 'Angled' then
        Brackets = '<|Hplayer:%1|h' .. Name .. '|h>'
    elseif self.db.profile.Brackets == 'None' then
        Brackets = '|Hplayer:%1|h' .. Name .. '|h:'
    else
        Brackets = '[|Hplayer:%1|h' .. Name .. '|h]'
    end

    Text = string.gsub(Text, '|Hplayer:(.-)|h%[.-%]|h.-:', Brackets)

    self.hooks[frame].AddMessage.orig(frame, Text, r, g, b, id)
end

