local MS = LibStub('AceAddon-3.0'):GetAddon('MessageShare')
local KEYWROD = "PlayerList"
local mod = MS:Module(KEYWROD,"AceEvent-3.0")
local module = mod.func
local classColor={}
local offline = {_time=0}
local order = "down"
local NUM_FILTERS_TO_DISPLAY = 12
local BROWSE_FILTER_HEIGHT = 25
local catch = {}
local function getcolor(t)
	if not (t.r and t.g and t.b) then
		t.r,t.g,t.b = 1,1,1
	end
	return ("|cff%.2x%.2x%.2x"):format(t.r*255,t.g*255,t.b*255)
end
local classindex = { -- key 为 UnitClass 返回的第三个值
	"WARRIOR",--1
	"PALADIN",--2
	"HUNTER",--3
	"ROGUE",--4
	"PRIEST",--5
	"DEATHKNIGHT",--6
	"SHAMAN",--7
	"MAGE",--8
	"WARLOCK",--9
	"MONK",--10
	"DRUID",--11
}
for k, v in pairs(LOCALIZED_CLASS_NAMES_MALE) do
    classColor[v] = getcolor(RAID_CLASS_COLORS[k])
    classColor[k] = getcolor(RAID_CLASS_COLORS[k])
end
for i,j in pairs(classindex) do
	classColor[i] = getcolor(RAID_CLASS_COLORS[j])
end
local diffColor = setmetatable({}, {
	__index = function(t,i)
		local c = i and GetQuestDifficultyColor(i)
        t[i] = c and getcolor(c) or "|cffffffff"
        return t[i]
	end
})
do
	local chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+="
	local len = string.len(chars)
	function sublink(link)-- 物品链接进行压缩
		local id,enchant,gem1,gem2,gem3,level = link:match("item:(%d+):(%d+):(%d+):(%d+):(%d+).-(%d+)\124h%[")
		if id then
		--print(link,level)
			link = "%.6d%.4d%.4d%.4d%.4d%.4d" --26位数
			link = link:format(id,enchant,gem1,gem2,gem3,level)
			local link1 = tonumber(link:sub(1,13))
			local link2 = tonumber(link:sub(14)) or 0
			local text1,text2 = "",""
			while link1>0 do
				text1 = text1..chars:sub(link1%len+1,link1%len+1)
				link1 = floor(link1/len)
			end
			while link2>0 do
				text2 = text2..chars:sub(link2%len+1,link2%len+1)
				link2 = floor(link2/len)
			end
			if text2=="" then return text1 end
			link = text1.." "..text2
		end
		return link
	end
	function unsublink(link)
		local num1,num2 = 0,0
		local numbers = 11
		local link1,link2 = string.split(" ",link)
		for i=1,string.len(link1) do
			num1 = num1 + (string.find(chars,link1:sub(i,i),1,true)-1)*math.pow(len,i-1)
		end
		if link2 then
			for i=1,string.len(link2) do
				num2 = num2 + (string.find(chars,link2:sub(i,i),1,true)-1)*math.pow(len,i-1)
			end
		end
		if string.len(num1)>10 then
			numbers=13
		end
		link = string.rep("0",numbers-string.len(num1))..num1..string.rep("0",numbers-string.len(num2))..num2
		local id,enchant,gem1,gem2,gem3,level = link:match("(%d%d%d%d%d%d)(%d%d%d%d)(%d%d%d%d)(%d%d%d%d)(%d%d%d%d)(%d%d%d%d)")
		if not id then
			id,enchant,gem1,gem2,gem3= link:match("(%d%d%d%d%d%d)(%d%d%d%d)(%d%d%d%d)(%d%d%d%d)(%d%d%d%d)")
		end
		id = tonumber(id)
		enchant = tonumber(enchant)
		gem1 = tonumber(gem1)
		gem2 = tonumber(gem2)
		gem3 = tonumber(gem3)
		level = tonumber(level) or 0
		link = id and select(2,GetItemInfo(id))
		link = link and link:gsub("item:%d+:%d+:%d+:%d+:%d+(.-)%d+\124h%[","item:"..id..":"..enchant..":"..gem1..":"..gem2..":"..gem3.."%1"..level.."\124h[")
		return link
	end
end
function mod:OnInitialize()
	self:RegisterEvent("INSPECT_READY");
end
function mod:OnReceiveMessage(key,sender,msg)
	if type(msg)=="table" then
		self:CheckUnitInfo(msg,self.db,true)
	end
end
local function checkdate(msg)
	--	print("GetAllDate")
	for i,j in pairs(mod.db) do
		if type(j)=="table" then
			if mod:CheckUnitInfo(j,msg)==true then
				mod:SendUnitInfo(j)
			end
		end
	end
	MS:CopyTable(mod.db,msg)
	mod.db.time = time()
	--self:UpdateList(order)
	collectgarbage()
end
function mod:OnReceiveWhisper(key,sender,msg)
--print("OnReceiveWhisper2",sender,msg)
	if type(msg)=="table" then
		catch[sender] = msg
		MS:CancelTimer(mod.timer,true)
		mod.timer = MS:ScheduleTimer(function()
			local alldate = {}
			for i,j in pairs(catch)do
				if type(j)=="table" then
					for _,date in pairs(j) do
						tinsert(alldate,date)
					end
				end
			end
			checkdate(alldate)
			wipe(catch)
		end,
		5)
	elseif (msg=="CallAllDate") then
	--print("SendAllDate",sender)
		self:SendAllDate(sender)
	elseif msg:find("CallDate") then
		local part,all = msg:match("CallDate:(%d+)@(%d+)")
		self:SendPartDate(part,all,sender)
	end
end
function mod:SendAllDate(sender)
	if sender then
		MS:SendWisper(KEYWROD,self.db,sender)
	end
end
function mod:SendPartDate(part,all,sender)
	if sender then
		self:Srotdb("down")
		local t = {}
		local start,ends = (#self.db/all)*(part-1),(#self.db/all)*(part)
		for i,j in pairs(self.db) do
			if type(j)=="table" then
				if i>=start or i<ends then
					tinsert(t,j)
				end
			end
		end
		MS:SendWisper(KEYWROD,t,sender)
		mod:UpdateList(order) 
	end
end
function mod:CallAllDate()
--print("call",MS:GetChannelMaster())
	if mod.db.time and (time() - mod.db.time < 3600) then
		return
	end
	MS:ScheduleTimer(function()
		local userlist = {}
		for user in pairs(module.UserList) do
			tinsert(userlist,user)
		end
		if #userlist>1 then
			for i,j in pairs(userlist) do
				catch[j] = "CallDate:"..i.."@"..#userlist
				MS:SendWisper(KEYWROD,"CallDate:"..i.."@"..#userlist,j)
			end
			return
		end
		local name = module:GetModuleUser()--上次为什么获取不到,重载才获取到
		if name then
			MS:SendWisper(KEYWROD,"CallAllDate",name)
		end
	end,
	2)
end
function mod:OnModuleReady()
	module:RegisterChatType(KEYWROD)
	self:CallAllDate()
end
local function FindUnit(guid)
	assert(guid, "Here guid should not be nil.")
	if InspectFrame and InspectFrame:IsVisible() and InspectFrame.unit and UnitGUID(InspectFrame.unit)==guid then
		return InspectFrame.unit
	else
		if GetNumGroupMembers() then
			for i=1, GetNumGroupMembers() do
				if UnitGUID("raid"..i)==guid then
					return "raid"..i
				end
			end
		end
		if GetNumSubgroupMembers() then
			for i=1, GetNumSubgroupMembers() do
				if UnitGUID("party"..i)==guid then
					return "party"..i
				end
			end
		end
		if UnitGUID("player")==guid then return "player" end
		if UnitGUID("target")==guid then return "target" end
		if UnitGUID("focus")==guid then return "focus" end
		if UnitGUID("mouseover")==guid then return "mouseover" end
	end
end
local levelstab = {
	["446"]=4,--pve
	["447"]=8,
	["452"]=8,
	["459"]=4,--25 pve
	["460"]=8,
	["461"]=12,
	["462"]=16,

	["454"]=4,--pvp
	["455"]=8,
	["457"]=8,
}
local function GetItemLevelfromlink(link)
	local level = select(4,GetItemInfo(link))
	local extra = link:match(":(%d+)\124h")
	extra = levelstab[extra] or 0
	return level+extra
end
local function GetItemLevel(t)
	local link = t[17]
	local totlelevel = 0
	local equiped = 15
	if link then
		equiped = 16
	end
	for i=1,17 do
		link = t[i] and unsublink(t[i])
		if i~=4 and link then
			totlelevel = totlelevel + GetItemLevelfromlink(link)--select(4,GetItemInfo(link))
		end
	end
	return string.format("%.2f",totlelevel/equiped)
end
function mod:GetUnitInfo(unit,guid)
	if not unit then return end
	local t = {}
	local link,realm
	t.n,realm = UnitName(unit)
	if realm then
		return
	end
	t.items = {}
	for i = 1, 17 do
		link = GetInventoryItemLink(unit,i)
		if  not link and GetInventoryItemTexture(unit,i) then--延迟循环处理,避免明明有装备,观察到是却是空的.
			MS:ScheduleTimer(function()
				self:INSPECT_READY(nil,guid)
			end,
			.2)
			return
		end 
		t.items[i] = link and sublink(link)
	end
	--t.time = time()
	t.level = UnitLevel(unit)
	t.c = select(3,UnitClass(unit))
	t.il = GetItemLevel(t.items)
	return t
end
function mod:SendUnitInfo(t)
	MS:SendMessage(KEYWROD,t)
end
function mod:CheckUnitInfo(t,parent,update)
	if not t.il or t.il=="0" or t.level>90 then
		return false
	end
	for i,j in pairs(parent) do
		if type(j)=="table" and j.n==t.n then
			if not (j.il==t.il and j.level==t.level) then
				--[[ if j.il>t.il then
					return j
				else ]]
				if update then
					parent[i] = t
					return true
				end
				--end
			end
			return
		end
	end
	tinsert(parent,t)
	return true
end

function mod:INSPECT_READY(event,guid)
	if InCombatLockdown() then return end
	local unit = FindUnit(guid)
	local t = self:GetUnitInfo(unit,guid)
	if t then
		if self:CheckUnitInfo(t,mod.db,true)==true then
			self:SendUnitInfo(t)
		end
	end
end


local slottexture = {
    "HeadSlot",--1
    "NeckSlot",--2
    "ShoulderSlot",--3
	"ShirtSlot",--4
    "ChestSlot",--5
    "WaistSlot",--6
    "LegsSlot",--7
    "FeetSlot",--8
    "WristSlot",--9
    "HandsSlot",--10
    "Finger0Slot",--11
    "Finger1Slot",--12
    "Trinket0Slot",--13
    "Trinket1Slot",--14
    "BackSlot",--15
    "MainHandSlot",--16
    "SecondaryHandSlot"--17
}
local function PlayerListMenu_Initialize(frame, level, name)	
	local info = UIDropDownMenu_CreateInfo();	
	info.text = name;
	info.level = 1;
	info.isTitle = 1;
	info.notCheckable = 1;
	UIDropDownMenu_AddButton(info, level);
	
	info = UIDropDownMenu_CreateInfo();	
	info.text = WHISPER;
	info.level = 1;
	info.notCheckable = 1;
	info.func = function() ChatFrame_SendTell(name) end;
	UIDropDownMenu_AddButton(info, level);
	
	local isFriend
	for i = 1, GetNumFriends() do
		if(name == GetFriendInfo(i)) then
			isFriend = true
			break;
		end
	end
	if isFriend then
		info = UIDropDownMenu_CreateInfo();	
		info.text = REMOVE_FRIEND;
		info.level = 1;
		info.notCheckable = 1;
		info.func = function() RemoveFriend(name) end;
		UIDropDownMenu_AddButton(info, level);
	else
		info = UIDropDownMenu_CreateInfo();	
		info.text = ADD_FRIEND;
		info.level = 1;
		info.notCheckable = 1;
		info.func = function() AddFriend(name) end;
		UIDropDownMenu_AddButton(info, level);
	end
	info = UIDropDownMenu_CreateInfo();	
	info.text = PARTY_INVITE;
	info.level = 1;
	info.notCheckable = 1;
	info.func = function() InviteUnit(name) end;
	UIDropDownMenu_AddButton(info, level);
	
	info = UIDropDownMenu_CreateInfo();	
	info.text = MESSAGESHARE_PLAYERLIST_SENDWHO;
	info.level = 1;
	info.notCheckable = 1;
	info.func = function() SendWho(WHO_TAG_NAME..name) end;
	UIDropDownMenu_AddButton(info, level);
	
	info = UIDropDownMenu_CreateInfo();	
	info.text = CANCEL;
	info.level = 1;
	info.notCheckable = 1;
	info.func = function() frame:Hide() end;
	UIDropDownMenu_AddButton(info, level);
end
local function GetDiffColor(level,averagelevel)
	level,averagelevel = tonumber(level),tonumber(averagelevel)
	local playerlevel = UnitLevel("Player")
	level = floor(playerlevel+(level-averagelevel)/2)
	return diffColor[level]
end
local function SetItem(f,link,index,averagelevel)
	local itemLink = link and unsublink(link)
	if not itemLink then
		f.border:SetVertexColor(0, 0, 0);
		f.texture:SetTexture(select(2,GetInventorySlotInfo(slottexture[index])))
		f.itemlevel:SetText("")
		f:SetScript("OnEnter",nil)
		f.link = nil
		if link then
			MS:ScheduleTimer(function()
				if unsublink(link) then
					SetItem(f,link,index,averagelevel)
				end
			end,
			.2)
		end
	else
		local itemName, _, itemQuality, itemlevel, _, _, _, _, _, texture = GetItemInfo(itemLink);
		itemlevel = GetItemLevelfromlink(itemLink)
		if itemName and texture then
			f.link = itemLink
			f.texture:SetTexture(texture)
			f.itemlevel:SetText(GetDiffColor(itemlevel,averagelevel)..itemlevel)
			if IsDressableItem(itemLink) then
				MSItemFrame.model:TryOn(itemLink)
			end
			if (type(itemQuality) == "number" and itemQuality > 0) then
				local r, g, b = GetItemQualityColor(itemQuality)
				f.border:SetVertexColor(r, g, b);
			else
				f.border:SetVertexColor(0, 0, 0);
			end
			f:SetScript("OnEnter",function(self)
				GameTooltip:SetOwner(self,"ANCHOR_RIGHT",50)
				GameTooltip:SetHyperlink(itemLink)
				GameTooltip:Show()
			end)
		end
		if index==16 then
			local f = MSItemFrame.f
			local info = f.info
			MS:ScheduleTimer(function()
				if f and f.info==info then
					if info.il~= GetItemLevel(info.items) then
						info.il = GetItemLevel(info.items)
						f.itemlevel:SetText(info.il)
						mod:SendUnitInfo(info)
					end
				end
			end,
			2)
		end
	end
end
local function CreateItemFrame()
	local f = CreateFrame("Frame","MSItemFrame",MSPlayerList,"ButtonFrameTemplate")
	f:Hide()
	f.model = CreateFrame("DressUpModel",nil,f,"ModelWithControlsTemplate")
	f.model:SetSize(145,290)
	f.model:SetPoint("CENTER")
	--f.model:SetFrameStrata("HIGH")
	f:SetPoint("TOPLEFT",MSPlayerList,"TOPRIGHT",10,0)
	f:SetSize(230,350)
	local font, _, flags = NumberFontNormal:GetFont()
	for i=1,17 do
		f["item"..i] = CreateFrame("Button",nil,f)
		--f["item"..i]:SetFrameStrata("DIALOG")
		f["item"..i]:SetFrameLevel(f.model:GetFrameLevel()+1)
		f["item"..i].itemlevel = f["item"..i]:CreateFontString(nil,"OVERLAY")
		f["item"..i].itemlevel:SetFont(font, 10, flags)
		f["item"..i].itemlevel:SetPoint("BOTTOM",f["item"..i],"BOTTOM",0,3)
		f["item"..i]:SetScript("OnClick",function(self,button) 
			if self.link then
				HandleModifiedItemClick(self.link)
			end 
		end)
		f["item"..i]:EnableMouse(1)
		f["item"..i]:SetScript("OnLeave",function() GameTooltip:Hide() end)
		f["item"..i]:SetSize(31,31)
		f["item"..i].texture = f["item"..i]:CreateTexture(nil,"BACKGROUND")
		f["item"..i].texture:SetAllPoints(f["item"..i])
		f["item"..i].texture:SetTexture(select(2,GetInventorySlotInfo(slottexture[i])))
		f["item"..i].border = f["item"..i]:CreateTexture(nil, "BORDER");
		f["item"..i].border:SetAllPoints(f["item"..i])
		f["item"..i].border:SetTexture("Interface\\Buttons\\UI-Debuff-Overlays")
		f["item"..i].border:SetTexCoord(0.296875,0.5703125,0,0.515625)
	end
	f.item1:SetPoint("TOPLEFT",f,"TOPLEFT",10,-65)
	f.item2:SetPoint("TOP",f.item1,"BOTTOM")
	f.item3:SetPoint("TOP",f.item2,"BOTTOM")
	f.item15:SetPoint("TOP",f.item3,"BOTTOM")
	f.item5:SetPoint("TOP",f.item15,"BOTTOM")
	f.item4:SetPoint("TOP",f.item5,"BOTTOM")
	f.item9:SetPoint("TOP",f.item4,"BOTTOM",0,-31)
	f.item16:SetPoint("LEFT",f.item9,"RIGHT",20,-10)
	f.item17:SetPoint("LEFT",f.item16,"RIGHT")

	f.item10:SetPoint("TOPRIGHT",f,"TOPRIGHT",-10,-65)
	f.item6:SetPoint("TOP",f.item10,"BOTTOM")
	f.item7:SetPoint("TOP",f.item6,"BOTTOM")
	f.item8:SetPoint("TOP",f.item7,"BOTTOM")
	f.item11:SetPoint("TOP",f.item8,"BOTTOM")
	f.item12:SetPoint("TOP",f.item11,"BOTTOM")
	f.item13:SetPoint("TOP",f.item12,"BOTTOM")
	f.item14:SetPoint("TOP",f.item13,"BOTTOM")
end
local function UpdateItemFrame(f)
	if not f.info then
		return
	end
	local info = f.info
	local color = classColor[info.c]
	local class = classindex[info.c];
	local name = info.n
	if MSItemFrame.f then
		MSItemFrame.f:SetBackdropColor(0, 0, 0)
	end
	f:SetBackdropColor(.5, .5, .5)
	MSItemFrame.f = f
	MSItemFrame:Show()
	MSItemFrameTitleText:SetText(color..name)
	MSItemFramePortrait:SetTexture("Interface\\TargetingFrame\\UI-Classes-Circles");
	MSItemFramePortrait:SetTexCoord(unpack(CLASS_ICON_TCOORDS[class]));
	MSItemFrame.model:SetUnit("player")
	MSItemFrame.model:Undress()
	for index = 1,17 do
		SetItem(MSItemFrame["item"..index],info.items[index],index,info.il)
	end
end
local function CreateList()
	for index = 1,NUM_FILTERS_TO_DISPLAY do
		local f = CreateFrame("Button",nil,MSPlayerList)
		f:SetBackdrop({
			bgFile="Interface\\Tooltips\\UI-Tooltip-Background",
			edgeFile="Interface\\Tooltips\\UI-Tooltip-Border",
			edgeSize = 8,
			TileSize=16,
			insets = { 
				left = 2, 
				right = 2, 
				top = 2, 
				bottom = 2
			} 
		})
		f:SetBackdropColor(0, 0, 0)
		f:RegisterForClicks("AnyUp")
		f:SetScript("OnEnter",function(self) self:SetBackdropColor(.5, .5, .5) end)
		f:SetScript("OnLeave",function(self)
			if not(MSItemFrame and MSItemFrame.f==self) then
				self:SetBackdropColor(0, 0, 0)
			end		
		end)
		f:SetScript("OnClick",function(self,button)
			local name = self.info and self.info.n
			if name then
				if button=="RightButton" then
					CloseDropDownMenus()
					ToggleDropDownMenu(nil, nil, PlayerListMenuFrame, "cursor", 20, -2,name );
				else
					CloseDropDownMenus()
					UpdateItemFrame(f)
				end
			end
		end)
		f:SetBackdropBorderColor(.5, .5, .5)
		f:SetSize(577,25)
		f.index = f:CreateFontString(nil,"OVERLAY","GameFontHighLight")
		f.name = f:CreateFontString(nil,"OVERLAY","GameFontHighLight")
		f.level = f:CreateFontString(nil,"OVERLAY","GameFontHighLight")
		f.class = f:CreateTexture(nil,"OVERLAY")
		f.class:SetTexture("Interface\\Glues\\CharacterCreate\\UI-CharacterCreate-Classes");
		f.class:SetSize(18,18)
		f.itemlevel = f:CreateFontString(nil,"OVERLAY","GameFontHighLight")
		f.index:SetPoint("LEFT",f,"LEFT",5,0)
		f.level:SetPoint("LEFT",f,"LEFT",20,0)
		f.class:SetPoint("LEFT",f,"LEFT",45,0)
		f.name:SetPoint("LEFT",f,"LEFT",85,0)
		f.itemlevel:SetPoint("LEFT",f,"LEFT",200,0)
		MSPlayerList.scroll["list"..index] = f
		
		f:SetPoint("TOPLEFT",MSPlayerList.scroll,"TOPLEFT",0,-25*(index-1))
		--f:SetPoint("TOPRIGHT",MSPlayerList.scroll,"TOPRIGHT",0,-25*(index-1))
	end
end
ChatFrame_AddMessageEventFilter("CHAT_MSG_SYSTEM", function(_,_,msg)
	if not (MSPlayerList and MSPlayerList.scroll)then return end
	local name = msg and msg:match(ERR_CHAT_PLAYER_NOT_FOUND_S:gsub("%%s","(.+)"))
	if name then
		local i = 1
		local color = "|cff666666"
		while MSPlayerList.scroll["list"..i] do
			if MSPlayerList.scroll["list"..i].info then
				if name==MSPlayerList.scroll["list"..i].info.n then
					MSPlayerList.scroll["list"..i].name:SetText(color..name)
					offline[name] = "offline"
					return true
				end
			end
			i = i + 1
		end
		if offline[name] then
			offline[name] = "offline"
			return true
		end
	end
end)
function mod:Srotdb(order)
	table.sort(mod.db,function(t1,t2)
		if type(t1)=="table" and type(t2)=="table" and t1.il and t2.il then
			if order=="up" then
				return tonumber(t1.il)<tonumber(t2.il)
			elseif order=="down" then
				return tonumber(t1.il)>tonumber(t2.il)
			elseif order=="nup" then
				return t1.n<=t2.n
			elseif order=="ndown" then
				return t1.n>t2.n
			elseif order=="cup" then
				if t1.c==t2.c then
					return tonumber(t1.il)>tonumber(t2.il)
				else
					return t1.c<t2.c
				end
			elseif order=="cdown" then
				if t1.c==t2.c then
					return tonumber(t1.il)>tonumber(t2.il)
				else
					return t1.c>t2.c
				end
			end
		end
	end)
	if MSPlayerList and MSPlayerList.myplace:IsShown() then
		for i=1,#mod.db do
			if mod.db[i].n==UnitName("player") then
				MSPlayerList.myplace:SetText(MESSAGESHARE_PLAYERLIST_MYPLACE..i.."/"..#mod.db)
			end
		end
	end
end
function mod:UpdateList(order)
	if not (MSPlayerList and MSPlayerList:IsShown()) then
		return
	end
	if MSItemFrame.f then
		MSItemFrame.f:SetBackdropColor(0, 0, 0)
		MSItemFrame.f = nil
	end
	local now,sended = time()
	for i=#mod.db,1,-1 do
		if mod.db[i]==nil or (type(mod.db[i])=="table" and (mod.db[i].il==nil or not next(mod.db[i].items))) then
			tremove(mod.db,i)
		else
			if mod.db[i].n==UnitName("Player") then
				--MSPlayerList.myplace:SetText(MESSAGESHARE_PLAYERLIST_MYPLACE..i.."/"..#mod.db)
			elseif now - offline._time > 60 then
				sended = true
				offline[mod.db[i].n] = offline[mod.db[i].n] or "online"
				MS:SendAddonMessage("1","","WHISPER",mod.db[i].n)--确定是否在线
			end
		end
	end
	if sended then
		offline._time = now
	end
	self:Srotdb(order)
	PlayerListFrame_Update()
end
function PlayerListFrame_Update()
	PlayerList_UpdateListButton();
	-- Update scrollFrame
	FauxScrollFrame_Update(MSPlayerListScroll, getn(mod.db), NUM_FILTERS_TO_DISPLAY, BROWSE_FILTER_HEIGHT);
end
function PlayerList_UpdateListButton()
	
	local button, index, info,color,class;
	local offlinecolor =  "|cff666666"
	local offset = FauxScrollFrame_GetOffset(MSPlayerListScroll);
	index = offset;
	for i=1, NUM_FILTERS_TO_DISPLAY do
		button = MSPlayerList.scroll["list"..i]
		if ( getn(mod.db) > NUM_FILTERS_TO_DISPLAY ) then
			button:SetWidth(260);
		else
			button:SetWidth(278);
		end
		index = index + 1;
		if ( index <= getn(mod.db) ) then
			info = mod.db[index];
			color = classColor[info.c]
			class = classindex[info.c];
			button.info = info
			if index<100 then
				button.level:SetText(diffColor[info.level]..info.level)
			else
				button.level:SetText("")
			end
			button.class:SetTexCoord(unpack(CLASS_ICON_TCOORDS[class]));
			if offline[info.n]=="offline" then
				button.name:SetText(offlinecolor..info.n)
			else
				button.name:SetText(color..info.n)
			end
			button.index:SetText(index)
			button.itemlevel:SetText(info.il)
			button:Show();
		else
			button:Hide();
		end
	end
end

local function CreatePlayerList()
	local f = CreateFrame("Frame","MSPlayerList",UIParent,"ButtonFrameTemplate")
	f:SetFrameStrata("HIGH")
	_G[f:GetName().."TitleText"]:SetText(MESSAGESHARE_PLAYERLIST_TITLE)
	SetPortraitToTexture(MSPlayerListPortrait, "Interface\\Icons\\INV_Arcane_Orb");
	f.myplace = f:CreateFontString(nil,"OVERLAY","GameFontHighLight")
	f.myplace:SetPoint("BOTTOMRIGHT",f,"BOTTOMRIGHT",-20,8)
	f.class = CreateFrame("Button","MSPlayerListClass",f,"WhoFrameColumnHeaderTemplate")
	f.class:SetPoint("TOPLEFT",f,"TOPLEFT",47,-37)
	f.class:SetText(CLASS)
	WhoFrameColumn_SetWidth(f.class,40)
	f.class:SetScript("OnClick",function() 
		if order == "cdown" then
			order = "cup"
		elseif order=="cup" then
			order = "cdown"
		else
			order = "cup"
		end
		mod:UpdateList(order) 
	end)
	f.name = CreateFrame("Button","MSPlayerListIndex",f,"WhoFrameColumnHeaderTemplate")
	f.name:SetPoint("TOPLEFT",f,"TOPLEFT",87,-37)
	f.name:SetText(NAME)
	WhoFrameColumn_SetWidth(f.name,120)
	f.name:SetScript("OnClick",function() 
		if order == "ndown" then
			order = "nup"
		elseif order=="nup" then
			order = "ndown"
		else
			order = "nup"
		end
		mod:UpdateList(order) 
	end)

	f.level = CreateFrame("Button","MSPlayerListLevel",f,"WhoFrameColumnHeaderTemplate")
	f.level:SetPoint("TOPLEFT",f,"TOPLEFT",205,-37)
	f.level:SetText(MESSAGESHARE_PLAYERLIST_ITEMLEVEL)
	WhoFrameColumn_SetWidth(f.level,63)
	f.level:SetScript("OnClick",function() 
		if order == "down" then
			order = "up"
		elseif order=="up" then
			order = "down"
		else
			order = "down"
		end
		mod:UpdateList(order) 
	end)
	f:SetMovable(1)
	f:SetScript("OnMouseDown",function(self) self:StartMoving() end)
	f:SetScript("OnMouseUp",function(self) self:StopMovingOrSizing() end)
	f:SetPoint("CENTER")
	f:SetSize(300,400)
	f.scroll = CreateFrame("ScrollFrame","MSPlayerListScroll",f,"FauxScrollFrameTemplate")
	f.scroll:SetPoint("TOPLEFT",f,"TOPLEFT",10,-65)
	f.scroll:SetPoint("TOPRIGHT",f,"TOPRIGHT",-32,-65)
	f.scroll:SetHeight(305)
	f.scroll:SetScript("OnVerticalScroll",function(self,offset)
		FauxScrollFrame_OnVerticalScroll(self, offset, BROWSE_FILTER_HEIGHT, PlayerListFrame_Update)
	end)
	CreateList()
	CreateItemFrame()
	f.menuFrame = CreateFrame("Frame", "PlayerListMenuFrame", f, "UIDropDownMenuTemplate");
	f.menuFrame:Hide()
	UIDropDownMenu_Initialize(f.menuFrame, PlayerListMenu_Initialize, "MENU")
	
	f.search = f.search or CreateFrame("EditBox","MSPlayerListEearch",f,"SearchBoxTemplate")
	f.search:SetSize(130,20)
	f.search:SetPoint("BOTTOMLEFT",f,"BOTTOMLEFT",20,5)
	f.search:SetScript("OnEnterPressed",function(self)
		local name = self:GetText()
		for i,j in pairs(mod.db) do
			if type(j)=="table" and j.n==name then
				_G[MSPlayerList.scroll:GetName().."ScrollBar"]:SetValue((i-1)*25)
				return
			end
		end
		for i,j in pairs(mod.db) do
			if type(j)=="table" and j.n:find(name) then
				_G[MSPlayerList.scroll:GetName().."ScrollBar"]:SetValue((i-1)*25)
				return
			end
		end
		print(string.format(MESSAGESHARE_PLAYERLIST_NOPLAYER,name))
	end)
end
function ShowPlayerList()
	mod:INSPECT_READY(nil,UnitGUID("Player"))
	if not MSPlayerList then
		CreatePlayerList()
	end
	MSPlayerList:Show()
	MSPlayerList.myplace:SetText("")
	mod:UpdateList(order)
end
