local DWChat = LibStub('AceAddon-3.0'):GetAddon('DuowanChat')

local L = LibStub("AceLocale-3.0"):GetLocale("DuowanChat")
local MODNAME = "ICONFRAME"
local DWChatIconFrame = DWChat:NewModule(MODNAME)
DWChatIconFrame.callbacks = LibStub("CallbackHandler-1.0"):New(DWChatIconFrame)
local DWC_NUM_TAB=60 
local DWC_ICON_SIZE_X=25
local DWC_ICON_SIZE_Y=25
local DWC_ICON_NUMBER_X=10 
local DWC_ICON_NUMBER_Y=6 
local chaticonbuttonlist={}
local buttonTemplate 
DWC_IconTable={ 
	{"{rt1}","Interface\\TargetingFrame\\UI-RaidTargetingIcon_1"}, 
	{"{rt2}","Interface\\TargetingFrame\\UI-RaidTargetingIcon_2"}, 
	{"{rt3}","Interface\\TargetingFrame\\UI-RaidTargetingIcon_3"}, 
	{"{rt4}","Interface\\TargetingFrame\\UI-RaidTargetingIcon_4"}, 
	{"{rt5}","Interface\\TargetingFrame\\UI-RaidTargetingIcon_5"}, 
	{"{rt6}","Interface\\TargetingFrame\\UI-RaidTargetingIcon_6"}, 
	{"{rt7}","Interface\\TargetingFrame\\UI-RaidTargetingIcon_7"},
	{"{rt8}","Interface\\TargetingFrame\\UI-RaidTargetingIcon_8"}, 
	{"{"..L.Angel.."}","Interface\\AddOns\\DuowanChat\\icon\\angel.tga"},
	{"{"..L.Angry.."}","Interface\\AddOns\\DuowanChat\\icon\\angry.tga"}, 
	{"{"..L.Biglaugh.."}","Interface\\AddOns\\DuowanChat\\icon\\biglaugh.tga"}, 
	{"{"..L.Clap.."}","Interface\\AddOns\\DuowanChat\\icon\\clap.tga"}, 
	{"{"..L.Cool.."}","Interface\\AddOns\\DuowanChat\\icon\\cool.tga"}, 
	{"{"..L.Cry.."}","Interface\\AddOns\\DuowanChat\\icon\\cry.tga"}, 
	{"{"..L.Cute.."}","Interface\\AddOns\\DuowanChat\\icon\\cutie.tga"},
	{"{"..L.Despise.."}","Interface\\AddOns\\DuowanChat\\icon\\despise.tga"},
	{"{"..L.Dreamsmile.."}","Interface\\AddOns\\DuowanChat\\icon\\dreamsmile.tga"}, 
	{"{"..L.Embarras.."}","Interface\\AddOns\\DuowanChat\\icon\\embarrass.tga"},
	{"{"..L.Evil.."}","Interface\\AddOns\\DuowanChat\\icon\\evil.tga"},
	{"{"..L.Excited.."}","Interface\\AddOns\\DuowanChat\\icon\\excited.tga"}, 
	{"{"..L.Faint.."}","Interface\\AddOns\\DuowanChat\\icon\\faint.tga"}, 
	{"{"..L.Fight.."}","Interface\\AddOns\\DuowanChat\\icon\\fight.tga"},
	{"{"..L.Flu.."}","Interface\\AddOns\\DuowanChat\\icon\\flu.tga"}, 
	{"{"..L.Freeze.."}","Interface\\AddOns\\DuowanChat\\icon\\freeze.tga"},
	{"{"..L.Frown.."}","Interface\\AddOns\\DuowanChat\\icon\\frown.tga"},
	{"{"..L.Greet.."}","Interface\\AddOns\\DuowanChat\\icon\\greet.tga"},
	{"{"..L.Grimace.."}","Interface\\AddOns\\DuowanChat\\icon\\grimace.tga"},
	{"{"..L.Growl.."}","Interface\\AddOns\\DuowanChat\\icon\\growl.tga"},
	{"{"..L.Happy.."}","Interface\\AddOns\\DuowanChat\\icon\\happy.tga"},
	{"{"..L.Heart.."}","Interface\\AddOns\\DuowanChat\\icon\\heart.tga"}, 
	{"{"..L.Horror.."}","Interface\\AddOns\\DuowanChat\\icon\\horror.tga"}, 
	{"{"..L.Ill.."}","Interface\\AddOns\\DuowanChat\\icon\\ill.tga"},
	{"{"..L.Innocent.."}","Interface\\AddOns\\DuowanChat\\icon\\innocent.tga"},
	{"{"..L.Kongfu.."}","Interface\\AddOns\\DuowanChat\\icon\\kongfu.tga"}, 
	{"{"..L.Love.."}","Interface\\AddOns\\DuowanChat\\icon\\love.tga"},
	{"{"..L.Mail.."}","Interface\\AddOns\\DuowanChat\\icon\\mail.tga"}, 
	{"{"..L.Makeup.."}","Interface\\AddOns\\DuowanChat\\icon\\makeup.tga"},
	{"{"..L.Mario.."}","Interface\\AddOns\\DuowanChat\\icon\\mario.tga"}, 
	{"{"..L.Meditate.."}","Interface\\AddOns\\DuowanChat\\icon\\meditate.tga"}, 
	{"{"..L.Miserable.."}","Interface\\AddOns\\DuowanChat\\icon\\miserable.tga"}, 
	{"{"..L.Okay.."}","Interface\\AddOns\\DuowanChat\\icon\\okay.tga"}, 
	{"{"..L.Pretty.."}","Interface\\AddOns\\DuowanChat\\icon\\pretty.tga"}, 
	{"{"..L.Puke.."}","Interface\\AddOns\\DuowanChat\\icon\\puke.tga"}, 
	{"{"..L.Shake.."}","Interface\\AddOns\\DuowanChat\\icon\\shake.tga"}, 
	{"{"..L.Shout.."}","Interface\\AddOns\\DuowanChat\\icon\\shout.tga"}, 
	{"{"..L.Silent.."}","Interface\\AddOns\\DuowanChat\\icon\\shuuuu.tga"}, 
	{"{"..L.Shy.."}","Interface\\AddOns\\DuowanChat\\icon\\shy.tga"}, 
	{"{"..L.Sleep.."}","Interface\\AddOns\\DuowanChat\\icon\\sleep.tga"}, 
	{"{"..L.Smile.."}","Interface\\AddOns\\DuowanChat\\icon\\smile.tga"}, 
	{"{"..L.Suprise.."}","Interface\\AddOns\\DuowanChat\\icon\\suprise.tga"}, 
	{"{"..L.Surrender.."}","Interface\\AddOns\\DuowanChat\\icon\\surrender.tga"},
	{"{"..L.Sweat.."}","Interface\\AddOns\\DuowanChat\\icon\\sweat.tga"},
	{"{"..L.Tear.."}","Interface\\AddOns\\DuowanChat\\icon\\tear.tga"},
	{"{"..L.Tears.."}","Interface\\AddOns\\DuowanChat\\icon\\tears.tga"},
	{"{"..L.Think.."}","Interface\\AddOns\\DuowanChat\\icon\\think.tga"},
	{"{"..L.Titter.."}","Interface\\AddOns\\DuowanChat\\icon\\titter.tga"}, 
	{"{"..L.Ugly.."}","Interface\\AddOns\\DuowanChat\\icon\\ugly.tga"},
	{"{"..L.Victory.."}","Interface\\AddOns\\DuowanChat\\icon\\victory.tga"}, 
	{"{"..L.Volunteer.."}","Interface\\AddOns\\DuowanChat\\icon\\volunteer.tga"}, 
	{"{"..L.Wronged.."}","Interface\\AddOns\\DuowanChat\\icon\\wronged.tga"},
} 

local db 
local defaults = {
	profile = {
		enablechaticon=false
	}
} 

local optGetter, optSetter 
do
	local mod = DWChatIconFrame
	function optGetter(info)
		local key = info[#info] 
		return DWChat.db.profile[key] 
	end 
	
	function optSetter(info, value) 
		local key = info[#info]
		DWChat.db.profile[key] = value
		mod:Refresh() 
	end
end 

local options 
local getOptions=function()
	if not options then
		options={
			type = "group",
			name = L["IconFrame"], 
			arg = MODNAME, 
			get = optGetter,
			set = optSetter, 
			args={
				intro = { 
					order = 1,
					type = "description", 
					name = L["this function allows you to use emtion icons in your chat, and others who has this addon enabled can see your emtion icons"], 
				}, 
				enablechaticon = { 
					order = 2, 
					type = "toggle",
					name = L["Enable emotion icons"], 
					get = function()
						return DWChat:GetModuleEnabled(MODNAME) 
					end, 
					set = function(info, value) 
						DWChat:SetModuleEnabled(MODNAME, value) 
					end, 
				},
			},
		}
	end
	return options
end 

function DWCIconButton_OnClick(self, button)
	local editBox = --[[DEFAULT_CHAT_FRAME.editBox or ]]ChatFrame1EditBox or SELECTED_CHAT_FRAME.editBox
	if (not editBox:IsShown()) then
		editBox:Show();
	end
	editBox:SetFocus();
	local _,font=SELECTED_CHAT_FRAME:GetFont()
	font=floor(font)
	editBox:Insert("|T"..self.texture..":"..font.."|t")
	DWCIconFrame:Hide()
end

local function createIconButton(text,texture,i)
	local chatTab=_G["DWCChatIconButton"..i] or CreateFrame("Button","DWCChatIconButton"..i,DWCIconFrame,"DWCIconButtonTemplate") 
	chatTab.id= i 
	chatTab.text=text
	chatTab.texture=texture
	chatTab:SetNormalTexture(texture) 
	return chatTab 
end 

local function setIconPosition(frame,icon,ix,iy)
	icon:SetPoint("TOPLEFT",frame,"TOPLEFT",(ix-1)*DWC_ICON_SIZE_X+5,-1*(iy-1)*DWC_ICON_SIZE_Y-5) 
end

local function arrangeIcons(frame,icons)
	local px=1
	local py=1 
	for i=1,DWC_NUM_TAB,1 do
		setIconPosition(frame,icons[i],px,py)
		px=px+1
		if px==DWC_ICON_NUMBER_X+1 then 
			px=1 
			py=py+1 
		end
	end 
end

local function createIconFrame()
	local callOutButton=_G.DWCIconFrameCalloutButton 
	local iconFrame=_G.DWCIconFrame 
	callOutButton:SetScript("OnClick",function() 
		if not iconFrame then 
			return
		end
		if iconFrame:IsShown() then
			iconFrame:Hide() 
		else
			iconFrame:Show() 
		end 
	end) 
	callOutButton:SetScript("OnEnter",function()end) 
	callOutButton:SetScript("OnLeave",function()end) 
	callOutButton:SetAlpha(0.8) 
	callOutButton:SetPoint("TOPLEFT",DWCChatFrame,"TOPLEFT",2,-3) 
	callOutButton:Show() 
	local i=0
	for k, v in pairs(DWC_IconTable) do
		i=i+1 
		chaticonbuttonlist[i]=createIconButton( v[1], v[2],k)
	end 
	
	DWC_NUM_TAB=i arrangeIcons(iconFrame,chaticonbuttonlist)
	iconFrame.iconButtonList=chaticonbuttonlist 
	iconFrame:SetScript("OnShow",function(self) 
		local i=1
		while(self.iconButtonList[i]) do 
			self.iconButtonList[i]:Show()
			i=i+1
		end
	end)
	iconFrame:SetScript("OnHide",function(self) 
		local i=1 
		while(self.iconButtonList[i]) do
			self.iconButtonList[i]:Hide()
			i=i+1 
		end 
	end)
end 

function DWChatIconFrame:OnInitialize() 
	self.db = DWChat.db:RegisterNamespace(MODNAME, defaults) 
	db = self.db.profile 
	self:SetEnabledState(DWChat:GetModuleEnabled(MODNAME)) 
	DWChat:RegisterModuleOptions(MODNAME, getOptions, L["IconFrame"])
	local worldFrame_MouseUp=WorldFrame:GetScript("OnMouseUp")
	if worldFrame_MouseUp then
		WorldFrame:HookScript("OnMouseUp",function() 
			if DWCIconFrame then
				DWCIconFrame:Hide() 
			end 
		end) 
	else 
		WorldFrame:SetScript("OnMouseUp",function() 
			if DWCIconFrame then 
				DWCIconFrame:Hide() 
			end
		end)
	end
end 

function DWChatIconFrame:Refresh() 
end

function DWChatIconFrame:OnEnable()	
	for i=1, 10 do
		_G["ChatFrame" .. i .. "EditBox"]:SetScript("OnTextChanged",function(self) 
			local text,tag=DWChat:ParseLocalText(self:GetText())
			if tag then 
				self:SetText(text)
			end
		end) 
	end
	createIconFrame() 
	self:Refresh() 
end

function DWChatIconFrame:OnDisable()	
	for i=1, 10 do
		_G["ChatFrame" .. i .. "EditBox"]:SetScript("OnTextChanged",function(self) end)
	end
	_G.DWCIconFrameCalloutButton:Hide() 
	_G.DWCIconFrame:Hide()
end 

function DWC_StartCount(frame) 
	if frame:GetParent() ~= UIParent then
		DWC_StartCount(frame:GetParent())
		return
	end 
	frame.showTimer = 1;
	frame.isCounting = 1;
end

function DWC_StopCount(frame) 
	if frame:GetParent()~=UIParent then 
		DWC_StopCount(frame:GetParent())
		return 
	end
	frame.isCounting = nil; 
end 

function DWC_OnUpdate(self,elapsed) 
	if ( not self.showTimer or not self.isCounting ) then 
		return;
	elseif ( self.showTimer < 0 ) then 
		self:Hide();
		self.showTimer = nil; 
		self.isCounting = nil;
	else
		self.showTimer = self.showTimer - elapsed; 
	end 
end

local fmtstring = format("\124T%%s:%d\124t",max(floor(select(2,SELECTED_CHAT_FRAME:GetFont())),16))

local function myChatFilter(self, event, msg, ...)
	for i = 9, #DWC_IconTable do
		if msg:find(DWC_IconTable[i][1]) then
			msg = msg:gsub(DWC_IconTable[i][1],format(fmtstring,DWC_IconTable[i][2]),1)
			break
		end
	end
	return false, msg, ...
end

ChatFrame_AddMessageEventFilter("CHAT_MSG_CHANNEL", myChatFilter)
ChatFrame_AddMessageEventFilter("CHAT_MSG_SAY", myChatFilter)
ChatFrame_AddMessageEventFilter("CHAT_MSG_YELL", myChatFilter)
ChatFrame_AddMessageEventFilter("CHAT_MSG_WHISPER", myChatFilter)
ChatFrame_AddMessageEventFilter("CHAT_MSG_BN_WHISPER", myChatFilter)
ChatFrame_AddMessageEventFilter("CHAT_MSG_WHISPER_INFORM", myChatFilter)
ChatFrame_AddMessageEventFilter("CHAT_MSG_RAID", myChatFilter)
ChatFrame_AddMessageEventFilter("CHAT_MSG_RAID_LEADER", myChatFilter)
ChatFrame_AddMessageEventFilter("CHAT_MSG_PARTY", myChatFilter)
ChatFrame_AddMessageEventFilter("CHAT_MSG_PARTY_LEADER", myChatFilter)
ChatFrame_AddMessageEventFilter("CHAT_MSG_GUILD", myChatFilter)
ChatFrame_AddMessageEventFilter("CHAT_MSG_BATTLEGROUND", myChatFilter)
ChatFrame_AddMessageEventFilter("CHAT_MSG_AFK", myChatFilter)
ChatFrame_AddMessageEventFilter("CHAT_MSG_DND", myChatFilter)

local MaxBubbleWidth = 250

function HandleBubbleEmote(frame, fontstring)
	if not frame:IsShown() then 
		fontstring.cachedText = nil
		return 
	end

	MaxBubbleWidth = math.max(frame:GetWidth(), MaxBubbleWidth)

	local text = fontstring:GetText() or ""

	if text == fontstring.cachedText then return end

	frame:SetBackdropBorderColor(fontstring:GetTextColor())
	--fontstring:SetFont(ChatFrame1:GetFont(),select(2,ChatFrame1:GetFont()))
	local term;
	for tag in string.gmatch(text, "%b{}") do
		term = strlower(string.gsub(tag, "[{}]", ""));
		if ( ICON_TAG_LIST[term] and ICON_LIST[ICON_TAG_LIST[term]] ) then
			text = string.gsub(text, tag, ICON_LIST[ICON_TAG_LIST[term]] .. "0|t");
		end
	end  

	for i = 9, #DWC_IconTable do
		if text:find(DWC_IconTable[i][1]) then
			text = text:gsub(DWC_IconTable[i][1],format(fmtstring,DWC_IconTable[i][2]),1)
			break
		end
	end
	fontstring:SetText(text)    
	fontstring.cachedText = text  
	fontstring:SetWidth(math.min(fontstring:GetStringWidth(), MaxBubbleWidth - 14))
end

local function CheckBubbles()
	for i=1,WorldFrame:GetNumChildren() do
		local v = select(i, WorldFrame:GetChildren())
		local b = v:GetBackdrop()
		if b and b.bgFile == "Interface\\Tooltips\\ChatBubble-Background" then
			for i=1,v:GetNumRegions() do
				local frame = v
				local v = select(i, v:GetRegions())
				if v:GetObjectType() == "FontString" then
					HandleBubbleEmote(frame, v)
				end
			end
		end
	end
end

local BubbleScanInterval = 0.15
local AddonFrame = CreateFrame("Frame")
AddonFrame.interval = BubbleScanInterval
AddonFrame:SetScript("OnUpdate", 
function(frame, elapsed) 
	frame.interval = frame.interval - elapsed
	if frame.interval < 0 then
		frame.interval = BubbleScanInterval
		CheckBubbles()
	end
end)
