---------------------------------------------------------------------------------
--
-- Prat - A framework for World of Warcraft chat mods
--
-- Copyright (C) 2006-2007  Prat Development Team
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; either version 2
-- of the License, or (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to:
--
-- Free Software Foundation, Inc., 
-- 51 Franklin Street, Fifth Floor, 
-- Boston, MA  02110-1301, USA.
--
--
-------------------------------------------------------------------------------



--[[
Name: PratPlayerNames
Revision: $Revision: 29578 $
Author(s): Curney (asml8ed@gmail.com)
           Krtek (krtek4@gmail.com)
Inspired by: idChat2_PlayerNames by Industrial
Website: http://www.wowace.com/files/index.php?path=Prat/
Documentation: http://www.wowace.com/wiki/Prat/Integrated_Modules#PlayerNames
SVN: http://svn.wowace.com/wowace/trunk/Prat/
Description: Module for Prat that adds player name options.
Dependencies: Prat
]]

local PRAT_MODULE = Prat:RequestModuleName("PlayerNames")
local L = AceLibrary("AceLocale-2.2"):new(PRAT_MODULE)

L:RegisterTranslations("enUS", function() return {
    ["PlayerNames"] = true,
    ["Player name formating options."] = true,
    ["Brackets"] = true,
    ["Square"] = true,
    ["Angled"] = true,
    ["None"] = true,
    ["Class"] = true,
    ["Random"] = true,
	["Reset settings"] = true,
	["Restore default settings, and delete stored character data."] = true,
    ["Sets style of brackets to use around player names."] = true,
    ["Use common color"] = true,
    ["Toggle useing common color for unknown player names."] = true,
    ["Set common color"] = true,
    ["Change the common color of PlayerNames"] = true,
    ["Use TabComplete"] = true,
    ["Toggle tab completion of player names."] = true,
	["Show Level"] = true,
    ["Toggle level showing."] = true,
	["Show Group"] = true,
    ["Toggle raid group showing."] = true,
    ["Keep Info"] = true,
    ["Keep Lots Of Info"] = true,
    ["Keep player information between session for all players except cross-server players"] = true,
    ["Keep player information between session. But limit it to friends and guild memebers."] = true,
    ["Color Mode"] = true,
    ["How to color Players name."] = true,
	["Common Color From TasteTheNaimbow"] = true,
    ["Let TasteTheNaimbow set the color for unknown players."] = true,   
	["Enable Alt-Invite"] = true,
    ["Invite the player by alt clicking on his name in the chat"] = true,
    ["Enable Invite Links"] = true,
	["Invite the player by alt clicking hyperlinked keywords like 'invite'"] = true,
    ["Brackets Color"] = true,
    ["Sets color of brackets to use around player names."] = true,
    ["Brackets Use Common Color"] = true,
    ["Sets if a common color should be used for the brackets around player names."] = true,
} end)

L:RegisterTranslations("zhCN", function() return {
	["PlayerNames"] = "玩家姓名",
	["Player name formating options."] = "玩家姓名格式选项。",
	["Brackets"] = "圆弧",
	["Square"] = "方形",
	["Angled"] = "折角",
	["None"] = "无",
    ["Class"] = "职业",
    ["Random"] = "随机",
	["Sets style of brackets to use around player names."] = "设置玩家姓名的括号。",
	["Use common color"] = "使用特殊颜色",
    ["Toggle useing common color for unknown player names."] = "未知玩家姓名是否使用特殊颜色",
    ["Set common color"] = "设置特殊颜色",
    ["Change the common color of PlayerNames"] = "改变玩家姓名的特殊颜色",
	["Use TabComplete"] = "标签",
	["Toggle tab completion of player names."] = "为玩家姓名作标签。",
	["Show Level"] = "显示等级",
	["Toggle level showing."] = "人物等级显示。",
	["Show Group"] = "显示小组",
	["Toggle raid group showing."] = "团队小组显示。",
    ["Keep Info"] = true,
    ["Keep Lots Of Info"] = true,
    ["Keep player information between session for all players except cross-server players"] = true,
    ["Keep player information between session. But limit it to friends and guild memebers."] = true,
	["Color Mode"] = "颜色模块",
	["How to color Players name."] = "玩家姓名颜色。",
} end)

L:RegisterTranslations("koKR", function() return {
    ["PlayerNames"] = "플레이어명",
    ["Player name formating options."] = "플레이어명 형식을 설정합니다.",
    ["Brackets"] = "괄호",
    ["Square"] = "사각형",
    ["Angled"] = "각진형",
    ["None"] = "없음",
    ["Class"] = "직업",
    ["Random"] = "무작위",
    ["Reset settings"] = "설정 초기화",
    ["Restore default settings, and delete stored character data."] = "기본 설정을 복원하고 저장된 케릭터 데이터를 삭제합니다.",
    ["Sets style of brackets to use around player names."] = "플레이어명 주위 괄호의 스타일을 설정합니다.",
    ["Use common color"] = "공통 색상 사용",
    ["Toggle useing common color for unknown player names."] = "알려지지 않은 플레이어명에 대해 공통 색상을 사용합니다.",
    ["Set common color"] = "공통 색상 설정",
    ["Change the common color of PlayerNames"] = "플레이어명의 공통 색상을 설정합니다.",
    ["Use TabComplete"] = "탭완성 사용",
    ["Toggle tab completion of player names."] = "플레이어명의 탭 완성기능을 사용합니다.",
    ["Show Level"] = "레벨 표시",
    ["Toggle level showing."] = "레벨을 표시합니다.",
    ["Show Group"] = "파티 표시",
    ["Toggle raid group showing."] = "공격대 내의 파티 번호를 표시합니다.",
    ["Keep Info"] = "정보 유지",
    ["Keep Lots Of Info"] = "각종 정보 유지",
    ["Keep player information between session for all players except cross-server players"] = "서버가 다른 플레이어를 제외하고 모든 플레이어에 대해 접속간 플레이어 정보를 유지합니다.",
    ["Keep player information between session. But limit it to friends and guild memebers."] = "접속간 플레이어 정보를 유지합니다. 친구와 길드원에 한함.",
    ["Color Mode"] = "색상 모드",
    ["How to color Players name."] = "플레이어명 색상을 변경합니다.",
    ["Common Color From TasteTheNaimbow"] = "TasteTheNaimbow의 공통 색상을 사용합니다.",
    ["Let TasteTheNaimbow set the color for unknown players."] = "알려지지 않은 플레이어에 대한 색상설정을 TasteTheNaimbow가 하도록 합니다.",    
    ["Enable Alt-Invite"] = "ALT-초대 사용",
    ["Invite the player by alt clicking on his name in the chat"] = "대화창에 이름을 ALT-클릭하여 초대합니다.",
    ["Enable Invite Links"] = "링크 초대 사용",
    ["Invite the player by alt clicking hyperlinked keywords like 'invite'"] = "'초대'같은 키워드로된 링크를 ALT-클릭으로 초대합니다.",
    ["Brackets Color"] = "괄호 색상",
    ["Sets color of brackets to use around player names."] = "플레이어 이름 주변에 사용할 괄호의 색상을 설정합니다.",
    ["Brackets Use Common Color"] = "괄호 공통 색상 사용",
    ["Sets if a common color should be used for the brackets around player names."] = "플레이어 이름 주변에 사용되는 괄호에 공통 색상을 사용합니다.",
} end)

L:RegisterTranslations("zhTW", function() return {
    ["PlayerNames"] = "玩家姓名",
    ["Player name formating options."] = "玩家姓名格式選項。",
    ["Brackets"] = "圓弧",
    ["Square"] = "方形",
    ["Angled"] = "折角",
    ["None"] = "無",
    ["Class"] = "職業",
    ["Random"] = "隨機",
    ["Sets style of brackets to use around player names."] = "設定玩家姓名的括號。",
    ["Use common color"] = "使用共同顏色",
    ["Toggle useing common color for unknown player names."] = "未知玩家姓名是否使用共同顏色",
    ["Set common color"] = "設定共同顏色",
    ["Change the common color of PlayerNames"] = "改變玩家姓名的共同顏色",
    ["Use TabComplete"] = "補齊",
    ["Toggle tab completion of player names."] = "切換是否開啟Tab鍵補齊功能，為玩家姓名作補齊。",
    ["Show Level"] = "顯示等級",
    ["Toggle level showing."] = "人物等級顯示。",
    ["Show Group"] = "顯示小組",
    ["Toggle raid group showing."] = "團隊小組顯示。",
    ["Keep Info"] = true,
    ["Keep Lots Of Info"] = true,
    ["Keep player information between session for all players except cross-server players"] = true,
    ["Keep player information between session. But limit it to friends and guild memebers."] = true,
    ["Color Mode"] = "顏色模組",
    ["How to color Players name."] = "如何顯示玩家姓名顏色。",
} end)

L:RegisterTranslations("esES", function() return {
    ["PlayerNames"] = "Nombres de Jugador",
    ["Player name formating options."] = "Opciones de formateado de nombres de jugador",
    ["Brackets"] = "Par\195\169ntesis",
    ["Square"] = "Corchetes",
    ["Angled"] = "Llaves",
    ["None"] = "Ninguno",
    ["Class"] = "Clase",
    ["Random"] = "Aleatorio",
    ["Sets style of brackets to use around player names."] = "Establece el estilo de los par\195\169ntesis a usar alrededor de los nombres de jugador",
    ["Use common color"] = "Usar color com\195\186n",
    ["Toggle useing common color for unknown player names."] = "Determina si se usa el color com\195\186n para los nombres de jugadores desconocidos",
    ["Set common color"] = "Establecer color com\195\186n",
    ["Change the common color of PlayerNames"] = "Cambia el color com\195\186n de los nombres de jugador",
    ["Use TabComplete"] = "Usar Tab para Completar",
    ["Toggle tab completion of player names."] = "Determina si se usa Tab para completar nombres de jugadores",
	["Show Level"] = "Mostrar Nivel",
    ["Toggle level showing."] = "Determina si se muestra el nivel",
	["Show Group"] = "Mostrar Grupo",
    ["Toggle raid group showing."] = "Determina si se muestra el grupo en banda",
    ["Keep Info"] = "Guardar Info",
    ["Keep Lots Of Info"] = "Guardar Montones de Info",
    ["Keep player information between session for all players except cross-server players"] = "Guarda la informaci\195\179n sobre jugadores entre sesiones para todos los jugadores excepto los de otros servidores",
    ["Keep player information between session. But limit it to friends and guild memebers."] = "Guarda la informaci\195\179n sobre jugadores entre sesiones, pero lo limita a los amigos y miembros de hermandad",
    ["Color Mode"] = "Modo de Color",
    ["How to color Players name."] = "C\195\179mo se colorean los nombres de jugador",
	["Common Color From TasteTheNaimbow"] = "Color Com\195\186n de TasteTheNaimbow",
    ["Let TasteTheNaimbow set the color for unknown players."] = "Permite a TasteTheNaimbow establecer el color de los jugadores desconocidos",
	["Enable Alt-Invite"] = "Activar Alt-Invitar",
    ["Invite the player by alt clicking on his name in the chat"] = "Invita a jugadores hacienco Clic+Alt en su nombre en la ventana de chat",
    ["Enable Invite Links"] = "Activar Enlaces de Invitaci\195\179n",
	["Invite the player by alt clicking hyperlinked keywords like 'invite'"] = "Invita a los jugadores haciendo Clic+Alt en palabras clave enlazadas como 'invitar'",
    ["Brackets Color"] = "Color de Par\195\169ntesis",
    ["Sets color of brackets to use around player names."] = "Establece el color del par\195\169ntesis de los nombres de jugador",
    ["Brackets Use Common Color"] = "Par\195\169ntesis usan color com\195\186n",
    ["Sets if a common color should be used for the brackets around player names."] = "Determina si se usa un color com\195\186n para los par\195\169ntesis de los nombres de jugador",
} end)

L:RegisterTranslations("deDE", function() return {
    ["PlayerNames"] = "Spielernamen",
    ["Player name formating options."] = "Spielernamen Formatierungs Optionen.",
    ["Brackets"] = "Winkel",
    ["Square"] = "Quadrat",
    ["Angled"] = "Spitzwinkel",
    ["None"] = "Kein",
    ["Class"] = "Klasse",
    ["Random"] = "Zufall",
    ["Sets style of brackets to use around player names."] = "Setze Typ der Klammern die Spieler Namen umranden.",
    ["Use common color"] = "Nutze allgemeine Farbe",
    ["Toggle useing common color for unknown player names."] = "Aktiviert das benutzen der allgemeinen Farbe f\195\188r Unbekannte Spieler.",
    ["Set common color"] = "Setze allgemeine Farbe",
    ["Change the common color of PlayerNames"] = "Allgemeine Farbe der Spielernamen \195\164ndern.",
    ["Use TabComplete"] = "Benutze Tab Verfolst\195\164ndigen",
    ["Toggle tab completion of player names."] = "Aktiviere Tab Verfolst\195\164ndigen der Spielernamen.",
	["Show Level"] = "Zeige Level",
    ["Toggle level showing."] = "Aktiviere das Anzeigen des Levels.",
	["Show Group"] = "Zeige Gruppe",
    ["Toggle raid group showing."] = "Aktiviere das Anzeigen der Schlachtgruppe.",
    ["Keep Info"] = "Behalte Infos",
    ["Keep Lots Of Info"] = "Behalte viele Infos",
    ["Keep player information between session for all players except cross-server players"] = "Behalte Spieler Informationen zwischen Spielsessions für alle Spieler außer Serverübergreifende Namen.",
    ["Keep player information between session. But limit it to friends and guild memebers."] = "Behalte Spielernamen zwischen Spielesessions. Limitiere sie jedoch auf Freunde und Gildenmitglieder.",
    ["Color Mode"] = "Farben Modus",
    ["How to color Players name."] = "Wie Spielernamen einzuf\195\164rben sind.",
	["Common Color From TasteTheNaimbow"] = "Allgemeine Farben von TasteTheNaimbow",
    ["Let TasteTheNaimbow set the color for unknown players."] = "Lass TasteTheNaimbow die Farbe f\195\188r Unbekannte Spieler festlegen.",
	["Enable Alt-Invite"] = "Aktiviere Alt-Einladen",
    ["Invite the player by alt clicking on his name in the chat"] = "Lade Spieler durch Alt-Klicken ihrer Namen im Chat.",
    ["Enable Invite Links"] = "Aktivieren Einladen Links",
	["Invite the player by alt clicking hyperlinked keywords like 'invite'"] = "Lade Spieler ein durch Alt-Klicken hypergelinkter Passw\195\182rter wie 'Einladen'.",
    ["Brackets Color"] = "Klammern Farbe",
    ["Sets color of brackets to use around player names."] = "Stellt die Farbe der Klammern ein welche um die Spielernamen angezeigt werden.",
    ["Brackets Use Common Color"] = "Klammern benutzen allgemeine Farbe",
    ["Sets if a common color should be used for the brackets around player names."] = "Bestimmt ob die allgemeine Farbe f\195\188r die Klammern um Spielernamen verwendet wird.",
} end)

L:RegisterTranslations("frFR", function() return {
    ["PlayerNames"] = "Nom des joueurs",
    ["Player name formating options."] = "Options d'affichage des noms des joueurs",
    ["Brackets"] = "Parentese",
    ["Square"] = "Crochets",
    ["Angled"] = "truc",
    ["None"] = "Aucun",
    ["Class"] = "Classe",
    ["Random"] = "Al\195\169atoire",
    ["Sets style of brackets to use around player names."] = "S\195\169lectionne le style de crochets \195\160 utiliser pour encadrer les noms de joueurs",
    ["Use common color"] = "Utiliser une couleur par d\195\169faut",
    ["Toggle useing common color for unknown player names."] = "Active/d\195\169sactive l'utilisation d'une couleur par d\195\169faut quand la classe du joueur est inconnue",
    ["Set common color"] = "Couleur par d\195\169faut",
    ["Change the common color of PlayerNames"] = "Change la couleur par d\195\169faut",
    ["Use TabComplete"] = "Compl\195\169tion avec Tab",
    ["Toggle tab completion of player names."] = "Compl\195\169ter le nom des joueurs avec Tab",
	["Show Level"] = "Afficher le level",
    ["Toggle level showing."] = "Active/d\195\169sactive l'affichage du niveau",
	["Show Group"] = "Afficher le groupe",
    ["Toggle raid group showing."] = "Affiche le groupe du joueur en raid",
    ["Keep Info"] = "Garder Info",
    ["Keep Lots Of Info"] = "Garder toute les Info",
    ["Keep player information between session for all players except cross-server players"] = "Garder les informations des joueurs entre les sessions pour tous les joueurs excepté les joueurs des autres serveurs",
    ["Keep player information between session. But limit it to friends and guild memebers."] = "Garde les informacions des joueurs entre sessions, seulement pour les amis et les guildeux",
    ["Color Mode"] = "Mode de Coloration",
    ["How to color Players name."] = "Choisit comment coloriser les noms des joueurs",
	["Common Color From TasteTheNaimbow"] = "Couleur par d\195\169faut tir\195\169e de TasteTheNaimbow",
    ["Let TasteTheNaimbow set the color for unknown players."] = "Laisser TasteTheNaimbow choisir la couleur pour les joueurs inconnus",
	["Enable Alt-Invite"] = "Invitation sur Alt-Clic",
    ["Invite the player by alt clicking on his name in the chat"] = "Invite le joueur en faisant Alt-Clic sur son nom dans le chat",
    ["Enable Invite Links"] = "Mot invite cliquable",
	["Invite the player by alt clicking hyperlinked keywords like 'invite'"] = "Inviter le joueur en faisant Alt-Clic sur le mot 'invite'",
    ["Brackets Color"] = "Couleur des crochets",
    ["Sets color of brackets to use around player names."] = "Choisit la couleur des crochets autour du nom des joueurs",
    ["Brackets Use Common Color"] = "Couleur par d\195\169faut pour les crochets",
    ["Sets if a common color should be used for the brackets around player names."] = "Choisit une couleur par d\195\169faut pour les crochets autour du nom des joueurs",
} end)


local BC = AceLibrary("Babble-Class-2.2")

Prat_PlayerNames = Prat:NewModule(PRAT_MODULE)

Prat_PlayerNames.Classes = {}
Prat_PlayerNames.Levels = {}
Prat_PlayerNames.Subgroups = {}

Prat_PlayerNames.revision = tonumber(string.sub("$Revision: 29578 $", 12, -3))

-- Prat categories relevant to this module. list at: http://groups.google.com/group/wow-prat/web/prat-categories
local cat = Prat.Categories
Prat_PlayerNames.Categories	= { cat.NAME, cat.FORMATTING, cat.TEXT, cat.INFO, cat.LINK }	-- eg { cat.TEXT, cat.INFO }

Prat_PlayerNames.defaultDB = {
    on = true,
    brackets = "Angled",
    tabcomplete = true,
    tabcompletelimit = 20,
    level = true,
    subgroup = true,
    keep = true,
    keeplots = false,
    colormode = "CLASS",
    usecommoncolor = true,
    altinvite = false,
    linkinvite = false,
    bracketscommoncolor = false,
    bracketscolor = {
        r = 0.85,
        g = 0.85,
        b = 0.85,
    },
    useTTN = true,
    color = {
        r = 0.65,
        g = 0.65,
        b = 0.65,
    },
}

Prat_PlayerNames.moduleOptions = {}
Prat_PlayerNames.toggleOptions = { reset_sep=214 }

-- Set this to true to use Prat Event Support
Prat_PlayerNames.supportsPratEvents = true

function Prat_PlayerNames:GetModuleOptions()
    self.moduleOptions = {
        name = L["PlayerNames"],
        desc = L["Player name formating options."],
        type = "group",
        args = {
            brackets = {
                name = L["Brackets"],
                desc = L["Sets style of brackets to use around player names."],
                type = "text",
                order = 140,
                get = function() return Prat_PlayerNames.db.profile.brackets end,
                set = function(v) Prat_PlayerNames.db.profile.brackets = v end,
                validate = {["Square"] = L["Square"], ["Angled"] = L["Angled"], ["None"] = L["None"]}
            },
            bracketscommoncolor = {
                name = L["Brackets Use Common Color"],
                desc = L["Sets if a common color should be used for the brackets around player names."],
                type = "toggle",
                order = 141,
                get = function() return Prat_PlayerNames.db.profile.bracketscommoncolor end,
                set = function(v) Prat_PlayerNames.db.profile.bracketscommoncolor = v end,
            },
            bracketscolor = {
                name = L["Brackets Color"],
                desc = L["Sets color of brackets to use around player names."],
                type = "color",
                order = 142,
                get = function() local c = Prat_PlayerNames.db.profile.bracketscolor 
                        return c.r, c.g, c.b end,
                set = function(r, g, b, a) 
                	Prat_PlayerNames.db.profile.bracketscolor.r, 
                	Prat_PlayerNames.db.profile.bracketscolor.g, 
                	Prat_PlayerNames.db.profile.bracketscolor.b = r,g,b end,
                disabled = function() return not Prat_PlayerNames.db.profile.bracketscommoncolor end,
            },
            colormode = {
                name = L["Color Mode"],
                desc = L["How to color Players name."],
                type = "text",
                order = 150,
                get = function() return Prat_PlayerNames.db.profile.colormode end,
                set = function(v) Prat_PlayerNames.db.profile.colormode = v end,
                validate = {["RANDOM"] = L["Random"], ["CLASS"] = L["Class"], ["NONE"] = L["None"]}
            },
            level = {
                name = L["Show Level"],
                desc = L["Toggle level showing."],
                type = "toggle",
                order = 160,
                get = function() return Prat_PlayerNames.db.profile.level end,
                set = function(v) Prat_PlayerNames.db.profile.level = v end
            },
            subgroup = {
                name = L["Show Group"],
                desc = L["Toggle raid group showing."],
                type = "toggle",
                order = 170,
                get = function() return Prat_PlayerNames.db.profile.subgroup end,
                set = function(v) Prat_PlayerNames.db.profile.subgroup = v end
            },
            keep = {
                name = L["Keep Info"],
                desc = L["Keep player information between session. But limit it to friends and guild memebers."],
                type = "toggle",
                order = 180,
                get = function() return Prat_PlayerNames.db.profile.keep end,
                set = function(v) Prat_PlayerNames.db.profile.keep = v end
            },
            keeplots = {
                name = L["Keep Lots Of Info"],
                desc = L["Keep player information between session for all players except cross-server players"],
                type = "toggle",
                order = 185,
                get = function() return Prat_PlayerNames.db.profile.keeplots end,
                set = function(v) Prat_PlayerNames.db.profile.keeplots = v end,
                disabled = function() return not Prat_PlayerNames.db.profile.keep end,
            },
            tabcomplete = {
                name = L["Use TabComplete"],
                desc = L["Toggle tab completion of player names."],
                type = "toggle",
                order = 190,
                get = function() return Prat_PlayerNames.db.profile.tabcomplete end,
                set = function(v) Prat_PlayerNames.db.profile.tabcomplete = v; self:TabComplete(v) end
            },
            usecommoncolor = {
                name = L["Use common color"],
                desc = L["Toggle useing common color for unknown player names."],
                type = "toggle",
                order = 200,
                get = function() return Prat_PlayerNames.db.profile.usecommoncolor end,
                set = function(v) Prat_PlayerNames.db.profile.usecommoncolor = v end
            },
            commoncolorTTN = {
                name = L["Common Color From TasteTheNaimbow"],
                desc = L["Let TasteTheNaimbow set the color for unknown players."],
                type = "color",
                order = 210,
                get = function() return Prat_PlayerNames.db.profile.useTTN end,
                set = function(v) Prat_PlayerNames.db.profile.useTTN = v end,
                hidden = function() if TasteTheNaimbow_Loaded then return false else return true end end,
                disabled = function() if not Prat_PlayerNames.db.profile.usecommoncolor then return true else return false end end,
            },
            setcolor = {
                name = L["Set common color"],
                desc = L["Change the common color of PlayerNames"],
                type = "color",
                order = 211,
                get = function() return Prat_PlayerNames.db.profile.color.r, Prat_PlayerNames.db.profile.color.g, Prat_PlayerNames.db.profile.color.b end,
                set = function(r, g, b, a) Prat_PlayerNames.db.profile.color.r, Prat_PlayerNames.db.profile.color.g, Prat_PlayerNames.db.profile.color.b = r, g, b end,
                disabled = function() if not Prat_PlayerNames.db.profile.usecommoncolor then return true else return false end end,
            },
            altinvite = {
                name = L["Enable Alt-Invite"],
                desc = L["Invite the player by alt clicking on his name in the chat"],
                type = "toggle",
                order = 212,
                get = function() return Prat_PlayerNames.db.profile.altinvite end,
                set = function(v) Prat_PlayerNames.db.profile.altinvite = v self:SetAltInvite() end,
            },            
            linkinvite = {
                name = L["Enable Invite Links"],
                desc = L["Invite the player by alt clicking hyperlinked keywords like 'invite'"],
                type = "toggle",
                order = 212,
                get = function() return Prat_PlayerNames.db.profile.linkinvite end,
                set = function(v) Prat_PlayerNames.db.profile.linkinvite = v self:SetAltInvite() end,
            },             
			reset = {
				type = "execute",
				name = L["Reset settings"],
				desc = L["Restore default settings, and delete stored character data."],
				func = function() Prat_PlayerNames:resetStoredData() end,
				order = 215,
			},              
        }
    }
    
    return self.moduleOptions
end

    
function Prat_PlayerNames:OnModuleInit() 
    self:Debug("OnModuleInit")
    Prat:RegisterDefaults("PlayerNames", "realm", {
        classes = {},
        levels = {}
    })
    
    -- Added by Eternally777; 22/12/2006 @ 9:30 GMT-5
    -- After switching from db.profile to db.realm, transfer the player's
    -- names over and then nil them out in the old table.
    local tbl = { "classes", "levels" }
    for i in ipairs(tbl) do
        if ( Prat_PlayerNames.db.profile[ tbl[i] ] ) then
            for k in next, Prat_PlayerNames.db.profile[ tbl[i] ] do
                if (( Prat_PlayerNames.db.realm[ tbl[i] ] ) and ( not Prat_PlayerNames.db.realm[ tbl[i] ][k] )) then
                    Prat_PlayerNames.db.realm[ tbl[i] ][k] = Prat_PlayerNames.db.profile[ tbl[i] ][k]
                    Prat_PlayerNames.db.profile[ tbl[i] ][k] = nil
                end
            end
            Prat_PlayerNames.db.profile[ tbl[i] ] = nil
        end
    end
    tbl = nil
end

function Prat_PlayerNames:OnModuleEnable()
    self:Debug("OnModuleEnable")

	self:RegisterEvent("Prat_FrameMessage")

	self:SetAltInvite()

    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("UPDATE_MOUSEOVER_UNIT", "updateMouseOver")
    self:RegisterEvent("WHO_LIST_UPDATE", "updateWho")
	self:RegisterEvent("CHAT_MSG_SYSTEM", "updateWho") -- for short /who command

    -- Load stored name info
    for name, color in pairs(Prat_PlayerNames.db.realm.classes) do Prat_PlayerNames.Classes[name] = color end
    for name, level in pairs(Prat_PlayerNames.db.realm.levels) do	Prat_PlayerNames.Levels[name] = level end

    self:updateAll()

    self:TabComplete(Prat_PlayerNames.db.profile.tabcomplete)
end

function Prat_PlayerNames:OnModuleDisable()
    self:TabComplete(false)
end

function Prat_PlayerNames:GetModulePatterns()
end

--[[------------------------------------------------
	Core Functions
------------------------------------------------]]--
function Prat_PlayerNames:updateAll()
 	local PlayerClass
    _, PlayerClass = UnitClass("player")
    local  Name, Server = UnitName("player")
    self:addName(Name, Server, PlayerClass, UnitLevel("player"), nil, "PLAYER")

	self:updateParty()
	self:updateRaid()
	self:updateFriends()
	self:updateGuild(Prat_PlayerNames.db.profile.keeplots)
end

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

function Prat_PlayerNames:updateGuild(lots)
    if IsInGuild() then
        local Name, Class, Level
        for i = 1, GetNumGuildMembers(lots) do
            Name, _, _, Level, Class = GetGuildRosterInfo(i)
            self:addName(Name, nil, Class, Level, nil,"GUILD")
        end
    end
end

function Prat_PlayerNames:updateRaid()
    local Name, Class, SubGroup, Level, Server
	Prat_PlayerNames.Subgroups = {}
    for i = 1, GetNumRaidMembers() do
        _, _, SubGroup, Level, Class = GetRaidRosterInfo(i)
        Name, Server = UnitName("raid" .. i)
        self:addName(Name, Server, Class, Level, SubGroup, "RAID")
    end
end

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

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

function Prat_PlayerNames:updateMouseOver()
    local Class, Name, Server
    if not UnitIsPlayer("mouseover") or not UnitIsFriend("player", "mouseover") then
        return
    end
    _, Class = UnitClass("mouseover")
    Name, Server = UnitName("mouseover")
    self:addName(Name, Server, Class, UnitLevel("mouseover"), nil,  "MOUSE")
end

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


function Prat_PlayerNames:resetStoredData()
   -- Prat_PlayerNames:ResetDB()

    Prat_PlayerNames.db.realm.classes = {}
    Prat_PlayerNames.db.realm.levels = {}

    Prat_PlayerNames.Levels = {}
    Prat_PlayerNames.Classes = {}
    Prat_PlayerNames.Subgroups = {}


--    Prat_PlayerNames:UpdateAll()
    Prat:Print("Prat_PlayerNames: Stored Player Data Cleared")
end

--
-- Coloring Functions
--
function CLR:Bracket(text) return self:Colorize(Prat_PlayerNames:GetBracketCLR(), text) end
function CLR:Common(text) return self:Colorize(Prat_PlayerNames:GetCommonCLR(), text) end
function CLR:Random(text, seed) return self:Colorize(Prat_PlayerNames:GetRandomCLR(seed), text) end
function CLR:Class(text, class) return self:Colorize(BC:GetHexColor(class), text) end




function Prat_PlayerNames:addName(Name, Server, Class, Level, SubGroup, Source)
  if Name then
    local nosave

    -- Messy negations, but this says dont save data from 
    -- sources other than guild or friends unless you enable
    -- the keeplots option
    if Source ~= "GUILD" and Source ~= "FRIEND" and Source ~= "PLAYER" then
        nosave = not Prat_PlayerNames.db.profile.keeplots
    end

    if Server then 
        nosave = true
        Server = string.gsub(Server, " ", "")
    end
   
    Name = Name..(Server and ("-"..Server) or "")
	if Level and Level ~= 0 and ( not ( Prat_PlayerNames.Levels[Name] and Prat_PlayerNames.Levels[Name] > Level ) ) then
		Prat_PlayerNames.Levels[Name] = Level
        if ((not nosave) and  Prat_PlayerNames.db.profile.keep) then	Prat_PlayerNames.db.realm.levels[Name] = Level end
	end
    if Class then
        Prat_PlayerNames.Classes[Name] = Class
        if ((not nosave) and   Prat_PlayerNames.db.profile.keep ) then Prat_PlayerNames.db.realm.classes[Name] = Class end
    end
	if SubGroup then
		Prat_PlayerNames.Subgroups[Name] = SubGroup
	end
  end
end



function Prat_PlayerNames:addInfo(Name)
	if Name then
        local returnName = Name

        if Prat_PlayerNames.Levels[Name] and Prat_PlayerNames.db.profile.level then
			returnName = string.format("%s:%s", Prat_PlayerNames.Levels[Name], returnName)
        end
        if Prat_PlayerNames.Subgroups[Name] and Prat_PlayerNames.db.profile.subgroup then
			returnName = string.format("%s:%s", returnName, Prat_PlayerNames.Subgroups[Name])
        end
		if Prat_PlayerNames.Classes[Name] then
		        if Prat_PlayerNames.db.profile.colormode == "CLASS" then
				returnName =  string.format("|cff%s%s|r", BC:GetHexColor(Prat_PlayerNames.Classes[Name]), returnName)
			elseif Prat_PlayerNames.db.profile.colormode == "RANDOM" then
				returnName =  string.format("|cff%s%s|r", self:randomColor(Name), returnName)
		        end
		else
			if Prat_PlayerNames.db.profile.usecommoncolor then
				local color
				if Prat_PlayerNames.db.profile.useTTN and TasteTheNaimbow_Loaded then
					color = TasteTheNaimbowExternalColor(name)
				else
					color = string.format("%02x%02x%02x", Prat_PlayerNames.db.profile.color.r*255, Prat_PlayerNames.db.profile.color.g*255, Prat_PlayerNames.db.profile.color.b*255)
				end
				if strlen(returnName) > 0 then
					returnName = string.format("|cff%s%s|r", color, returnName)
				end
			end
		end

		return returnName
	else
		return ""
	end
end





--
-- Prat Event Implementation
--
local EVENTS_FOR_RECHECK = {
 ["CHAT_MSG_GUILD"] = updateGuild,
 ["CHAT_MSG_OFFICER"] = updateGuild,
 ["CHAT_MSG_PARTY"] = updateParty,
 ["CHAT_MSG_RAID"] = updateRaid,
 ["CHAT_MSG_RAID_LEADER"] = updateRaid,
 ["CHAT_MSG_RAID_WARNING"] = updateRaid,
 ["CHAT_MSG_BATTLEGROUND"] = updateRaid,
 ["CHAT_MSG_BATTLEGROUND_LEADER"] = updateRaid,
}

function Prat_PlayerNames:Prat_FrameMessage(message, frame)
    self:Debug("Prat_FrameMessage", message, frame)
	local Name = message.PLAYERLINK
	message.Pp = ""
	message.pP = ""
	if strlen(Name) == 0 then
	    return
	end

    local level = Prat_PlayerNames.Levels[Name]
    local class = Prat_PlayerNames.Classes[Name]
    local subgroup = Prat_PlayerNames.Subgroups[Name]

    local prof_colormode = Prat_PlayerNames.db.profile.colormode

    -- Add level information if needed
    if level and Prat_PlayerNames.db.profile.level then
    	message.pP = message.pP..level..":"
    end

    -- Add raid subgroup information if needed
    if subgroup and Prat_PlayerNames.db.profile.subgroup then
		message.Pp  = ":"..subgroup..message.Pp
    end

    -- Add the player name in the proper color
	if class then
        if prof_colormode == "CLASS" then
           message.PLAYER =  CLR:Class(message.PLAYER, class)
        elseif prof_colormode == "RANDOM" then
            message.PLAYER =  CLR:Random(message.PLAYER, Name)
        end
	else
		message.PLAYER = CLR:Common(message.PLAYER)
	end

    -- Add the correct bracket style and color
    local prof_brackets = Prat_PlayerNames.db.profile.brackets
    if prof_brackets == "Angled" then
        message.pP = CLR:Bracket("<")..message.pP
        message.Pp  = message.Pp..CLR:Bracket(">")
    elseif prof_brackets == "None" then
    else
        message.pP = CLR:Bracket("[")..message.pP
        message.Pp  = message.Pp..CLR:Bracket("]")
    end
end

function Prat_PlayerNames:GetBracketCLR()
	if not self.db.profile.bracketscommoncolor then
		return CLR.COLOR_NONE
	else
		local color = self.db.profile.bracketscolor
		return CLR:GetHexColor(color)
	end
end
function Prat_PlayerNames:GetCommonCLR()
	local color = CLR.COLOR_NONE
    if Prat_PlayerNames.db.profile.usecommoncolor then
    	if Prat_PlayerNames.db.profile.useTTN and TasteTheNaimbow_Loaded then
    		color = TasteTheNaimbowExternalColor(name)
    	else
    		color = CLR:GetHexColor(Prat_PlayerNames.db.profile.color)
    	end
    end
    return color
end
function Prat_PlayerNames:GetRandomCLR(Name)
	local hash = 17
	for i=1,string.len(Name) do
		hash = hash * 37 * string.byte(Name, i);
	end

	local r = math.floor(math.fmod(hash / 97, 255));
	local g = math.floor(math.fmod(hash / 17, 255));
	local b = math.floor(math.fmod(hash / 227, 255));

    if ((r * 299 + g * 587 + b * 114) / 1000) < 105 then
    	r = math.abs(r - 255);
        g = math.abs(g - 255);
        b = math.abs(b - 255);
    end

	return string.format("%02x%02x%02x", r, g, b)
end


function Prat_PlayerNames:TabComplete(enabled)
    if enabled then
        if not AceLibrary("AceTab-2.0"):IsTabCompletionRegistered("Prat_PlayerNames") then
            AceLibrary("AceTab-2.0"):RegisterTabCompletion("Prat_PlayerNames", "",
                function(t, text, pos)
                    for name in pairs(Prat_PlayerNames.Classes) do
                        table.insert(t, pos == 0 and name..":" or name)
                    end
                end,
                function(u, cands)
                	local candcount = #cands
                	if candcount <= self.db.profile.tabcompletelimit then
						local text = ""
	                    for _, cand in ipairs(cands) do
							cand = string.gsub(cand, ":", "")
							cand = self:addInfo(cand)
							text = text .. " " .. cand
	                    end
	                    Prat:Print("Tab completion : " .. text)
	                else
	                	Prat:Print("Tab completion : Too many matches (".. candcount.." possible)")
	                end
                end
            )
        end
    else
        if AceLibrary("AceTab-2.0"):IsTabCompletionRegistered("Prat_PlayerNames") then
            AceLibrary("AceTab-2.0"):UnregisterTabCompletion("Prat_PlayerNames")
        end
    end
end

function Prat_PlayerNames:SetAltInvite()
	local enabled = self.db.profile.linkinvite or self.db.profile.altinvite

	if enabled then
		if not self:IsHooked("SetItemRef") then
			self:Hook("SetItemRef", true);
		end
        for _,v in pairs(Prat_PlayerNames.modulePatterns) do
            Prat:RegisterPattern(v, self.name)
        end
	else
	    if self:IsHooked("SetItemRef") then
	    	self:Unhook("SetItemRef")
	    end
        Prat:UnregisterAllPatterns(self.name)
	end
end


function Prat_PlayerNames:SetItemRef(link, text, button)
	if ( strsub(link, 1, 6) == "player" ) and  Prat_PlayerNames.db.profile.altinvite then
		local name = strsub(link, 8);
		if ( name and (strlen(name) > 0) ) then
			local begin = string.find(name, "%s[^%s]+$");
			if ( begin ) then
				name = strsub(name, begin+1);
			end
			if ( IsAltKeyDown() ) then
				InviteUnit(name);
				ChatEdit_OnEscapePressed(SELECTED_CHAT_FRAME.editBox)
				return false;
			end
		end
	elseif ( strsub(link, 1, 6) == "invplr" ) and Prat_PlayerNames.db.profile.linkinvite then
			local name = strsub(link, 8);
			if ( name and (strlen(name) > 0) ) then
				local begin = string.find(name, "%s[^%s]+$");
				if ( begin ) then
					name = strsub(name, begin+1);
				end
				if ( button == "LeftButton" ) then
					InviteUnit(name);

				end
			end

			return false;
	end

	 self.hooks.SetItemRef(link, text, button);
	return true;
end

--{ "invite $w" }

local EVENTS_FOR_INVITE = {
 ["CHAT_MSG_GUILD"] = true,
 ["CHAT_MSG_OFFICER"] = true,
 ["CHAT_MSG_PARTY"] = true,
 ["CHAT_MSG_RAID"] = true,
 ["CHAT_MSG_RAID_LEADER"] = true,
 ["CHAT_MSG_RAID_WARNING"] = true,
 ["CHAT_MSG_SAY"] = true,
 ["CHAT_MSG_YELL"] = true,
 ["CHAT_MSG_WHISPER_INFORM"] = true,
 ["CHAT_MSG_CHANNEL"] = true,
}

local function Invite(text, ...)
    return Prat_PlayerNames:ScanForLinks(text, Prat.SplitMessage.PLAYERLINK)
end

local INVALID_NAMES = {
    ["me"] = true,
    ["meh"] = true,
    ["now"] = true,
    ["plz"] = true,
    ["please"] = true,
    ["when"] = true,
}

local function InviteSomone(text, name)
    if name and not INVALID_NAMES[string.lower(name)] then 
        return Prat_PlayerNames:ScanForLinks(text, name)
    end
end
Prat_PlayerNames.modulePatterns = { 
    { pattern = "(invite%s+(%w+))", matchfunc=InviteSomone },
    { pattern = "(invites?%??)", matchfunc=Invite },
}

function Prat_PlayerNames:ScanForLinks(text, name)
    if text == nil then 
        return ""
    end

	local enabled = Prat_PlayerNames.db.profile.linkinvite

    	if enabled and CanGroupInvite() then

		if EVENTS_FOR_INVITE[event] then
       			return  Prat_PlayerNames:InviteLink(text, name)
    		end
	end

	return text
end

function Prat_PlayerNames:InviteLink(link, name)
    local returnedLink = ""

	returnedLink = "|cffffff00"

    returnedLink = returnedLink .. "|Hinvplr:" .. name .. "|h"

    returnedLink = returnedLink .. "[" .. link .. "]"

    returnedLink = returnedLink .. "|h|r"

    return Prat:RegisterMatch(returnedLink)
end

