WindChatTimeConfig = {}
WindChat_Names = {}
WindChat_Date = ""

local SemEvents = {}

local ClassRevs = {
	["마법사"] = "MAGE",
	["흑마법사"] = "WARLOCK",
	["사제"] = "PRIEST",
	["드루이드"] = "DRUID",
	["주술사"] = "SHAMAN",
	["전사"] = "WARRIOR",
	["성기사"] = "PALADIN",
	["도적"] = "ROGUE",
	["사냥꾼"] = "HUNTER"
}

local ClassColors = {}

for k,v in pairs(_G.RAID_CLASS_COLORS) do
	ClassColors[k] = string.format("|cff%2x%2x%2x", v.r*255, v.g*255, v.b*255)
end

local WindCommon_ColorBorder = {
	bgFile = "Interface/Tooltips/UI-Tooltip-Background",
	edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
	tile = true,
	tileSize = 20,
	edgeSize = 20,
	insets = { left = 5, right = 5, top = 5, bottom = 5 }
}

local function WindCommon_setPoint(frame, point, relative, relativePoint, xOfs, yOfs)
	frame:ClearAllPoints()
	frame:SetPoint(point, relative, relativePoint, xOfs, yOfs)
end

local function WindCommon_setSize(frame, width, height)
	frame:SetWidth(width)
	frame:SetHeight(height)
end

local function WindCommon_setHide(object)
	object:SetAlpha(0.0)
	WindCommon_setSize(object, 1, 1)
end

local function WindCommon_setBackgroundPoint(bg, context, inset)
	local minset = inset * (-1)
	bg:ClearAllPoints()
	bg:SetPoint("BOTTOMLEFT", context, "BOTTOMLEFT", minset, minset)
	bg:SetPoint("TOPLEFT", context, "TOPLEFT", minset, inset)
	bg:SetPoint("TOPRIGHT", context, "TOPRIGHT", inset, inset)
	bg:SetPoint("BOTTOMRIGHT", context, "BOTTOMRIGHT", inset, minset)
end

local function WindCommon_setBackgroundLevel(bg, context)
	local level = context:GetFrameLevel()
	bg:SetFrameLevel(level)
	context:SetFrameLevel(level+1)
end

local function WindCommon_setBackground(bg, frame, inset)
	WindCommon_setBackgroundPoint(bg, frame, inset)
	WindCommon_setBackgroundLevel(bg, frame)
end

function WindChat_OnLoad(self)
	local name = WindChat_getBlzFrame(self:GetName())
	local frame = getglobal(name)

	WindChat_setBackground(self, frame, 6)
	WindCommon_setHide(getglobal(name.."UpButton"))
	WindCommon_setHide(getglobal(name.."DownButton"))

	local bottom = getglobal(name.."BottomButton")
	WindCommon_setSize(bottom, 24, 24)
	WindCommon_setPoint(bottom, "BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0, 0)
	WindCommon_setHide(bottom)

	self:RegisterEvent("VARIABLES_LOADED")
	self:RegisterEvent("GUILD_ROSTER_UPDATE")
	self:RegisterEvent("PARTY_MEMBERS_CHANGED")
	self:RegisterEvent("RAID_ROSTER_UPDATE")
end

function WindChat_OnEvent(self)
	SemEvents[event] = true
end

local updateTime = 0

function WindChat_OnUpdate(self, elapsed)
	updateTime = updateTime + elapsed

	if (updateTime >= 0.2) then
		updateTime = updateTime - 0.2

		local name = WindChat_getBlzFrame(self:GetName())
		local frame = getglobal(name)

		if (frame:AtBottom()) then
			WindCommon_setHide(getglobal(name.."BottomButton"))
		else
			WindChat_viewBottomButton(getglobal(name.."BottomButton"), frame)
		end

		local ev, v

		for ev,v in pairs(SemEvents) do
			if (v) then
				SemEvents[ev] = false

				if (ev == "VARIABLES_LOADED") then
					if (WindChat_Date ~= date("%m") and WindChat_Names) then
						DEFAULT_CHAT_FRAME:AddMessage("이월됨에 따라서 |cffffffffWindChat|r 클래스 정보를 초기화 합니다.")

						WindChat_Names = {}
						WindChat_Date = date("%m")
					end

					WindChat_BuildFriendsInfo()
				else
					-- 클래스 정보 수집
					if (WindChatConfigAll[16]) then
						if (ev == "GUILD_ROSTER_UPDATE") then
							local i

							for i=1, GetNumGuildMembers(), 1 do
								local name, _, _, _, class =  GetGuildRosterInfo(i)
								WindChat_setClassData(name, ClassRevs[class])
							end
						elseif (ev == "PARTY_MEMBER_CHANGED" or ev == "RAID_ROSTER_UPDATE") then
							local i

							if GetNumRaidMembers() > 0 then
								for i=1, GetNumRaidMembers(), 1 do
									local raidname, _, _, _, class = GetRaidRosterInfo(i)
									WindChat_setClassData(raidname, ClassRevs[class])
								end
							else
								for i=1, GetNumPartyMembers(), 1 do
									local _, class = UnitClass("party"..i)
									WindChat_setClassData(UnitName("party"..i), class)
								end
							end
						end
					end
				end
			end
		end
	end
end

function WindChat_setBackground(bg, frame, inset)
	local minset = inset * (-1)
	bg:ClearAllPoints()
	bg:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", minset-4, minset-4)
	bg:SetPoint("TOPLEFT", frame, "TOPLEFT", minset-4, inset-2)
	bg:SetPoint("TOPRIGHT", frame, "TOPRIGHT", inset, inset-2)
	bg:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", inset, minset-4)
	WindCommon_setBackgroundLevel(bg, frame)
end

function WindChat_getBlzFrame(name)
	return string.sub(name, 5)
end

function WindChat_OnMouseWheel(self, value)
	local name = WindChat_getBlzFrame(self:GetName())
	local frame = getglobal(name)

	if (value < 0) then
		if IsShiftKeyDown() then
			frame:ScrollToBottom()
		elseif IsControlKeyDown() then
			frame:ScrollDown()
			frame:ScrollDown()
			frame:ScrollDown()
		else
			frame:ScrollDown()
		end
	elseif (value > 0) then
		if IsShiftKeyDown() then
			frame:ScrollToTop()
		elseif IsControlKeyDown() then
			frame:ScrollUp()
			frame:ScrollUp()
			frame:ScrollUp()
		else
			frame:ScrollUp()
		end
	end
end

function WindChat_viewBottomButton(bottom, frame)
	WindCommon_setPoint(bottom, "BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0, 0)
	WindCommon_setSize(bottom, 24, 24)
	bottom:SetAlpha(1.0)
end

function WindChatEditBox_OnLoad(self)
	WindChat_setChatFrameMenuButton()

	ChatFrameEditBoxLeft:ClearAllPoints()
	ChatFrameEditBoxLeft:SetPoint("LEFT", "ChatFrame1", "LEFT", 0, 0)
	ChatFrameEditBoxLeft:SetPoint("RIGHT", "ChatFrame1", "RIGHT", 0, 0)
	ChatFrameEditBoxLeft:Hide()
	ChatFrameEditBoxRight:Hide()

	WindCommon_setBackground(self, ChatFrameEditBox, 1)
	WindCommon_setBackgroundPoint(WindChatEditBoxBG, WindChatEditBox, -4)
	WindCommon_setPoint(ChatFrameEditBoxLanguage, "LEFT", "ChatFrameEditBox", "RIGHT", -6, 0)

	SetItemRef = WindChat_SetItemRef

	ChatFrameEditBox:SetAltArrowKeyMode(false)
	ChatFrameEditBox:SetBackdrop(WindCommon_ColorBorder)
	ChatFrameEditBox:SetBackdropColor(0.0, 0.0, 0.0, 1.0)
	ChatFrameEditBox:SetHeight(30)
	ChatFrameEditBox:SetFrameStrata("TOOLTIP")

	WindChatEditBox:RegisterEvent("VARIABLES_LOADED")
end

function WindChat_setChatFrameMenuButton()
	WindCommon_setSize(ChatFrameMenuButton, 20, 20)
	WindCommon_setPoint(ChatFrameMenuButton, "TOPRIGHT", "ChatFrame1", "TOPRIGHT", 0, 0)
	ChatFrameMenuButton:SetAlpha(0.4)
end

function WindChat_SetItemRef(link, text, button)
	if (strsub(link, 1, 6) == "player") then
		WindChat_SetItemRefPlayer(link, button)
		return
	end

	if (strsub(link, 1, 3) == "url") then
		link = strsub(link, 5)

		if (not ChatFrameEditBox:IsShown()) then
			ChatFrame_OpenChat(link, DEFAULT_CHAT_FRAME)
		else
			ChatFrameEditBox:Insert(link)
		end
		return
	end

	if (IsControlKeyDown()) then
		DressUpItemLink(text)
	elseif (IsShiftKeyDown()) then
		if (ChatFrameEditBox:IsVisible()) then
			ChatFrameEditBox:Insert(text) 
		elseif (WIM_EditBoxInFocus) then 
			WIM_EditBoxInFocus:Insert(text)
		end
	else
		ShowUIPanel(ItemRefTooltip)
		if (not ItemRefTooltip:IsVisible()) then ItemRefTooltip:SetOwner(UIParent, "ANCHOR_PRESERVE") end
		ItemRefTooltip:SetHyperlink(link)
	end
end

function WindChat_SetItemRefPlayer(link, button)
	local name = strsub(link, 8)

	if (name and (strlen(name) > 0)) then
		name = gsub(name, "([^%s]*)%s+([^%s]*)%s+([^%s]*)", "%3")
		name = gsub(name, "([^%s]*)%s+([^%s]*)", "%2")
		name = gsub(name, "([^%s]*):%d*", "%1")

		if (IsShiftKeyDown()) then 
			local staticPopup
			staticPopup = StaticPopup_Visible("ADD_IGNORE")
			if (staticPopup) then getglobal(staticPopup.."EditBox"):SetText(name) return end
			staticPopup = StaticPopup_Visible("ADD_FRIEND")
			if (staticPopup) then getglobal(staticPopup.."EditBox"):SetText(name) return end
			staticPopup = StaticPopup_Visible("ADD_GUILDMEMBER")
			if (staticPopup) then getglobal(staticPopup.."EditBox"):SetText(name) return end
			staticPopup = StaticPopup_Visible("ADD_RAIDMEMBER")
			if (staticPopup) then getglobal(staticPopup.."EditBox"):SetText(name) return end
			if (ChatFrameEditBox:IsVisible()) then ChatFrameEditBox:Insert(name)
			else SendWho("n-"..name) end		
		elseif (button == "RightButton") then FriendsFrame_ShowDropdown(name, 1)
		elseif (IsAltKeyDown()) then InviteUnit(name)
		elseif (IsControlKeyDown()) then AddFriend(name)
		elseif (StaticPopup_Visible("ADD_IGNORE")) then getglobal(staticPopup.."EditBox"):SetText(name)
		else ChatFrame_SendTell(name) end
	end
end

function WindChatEditBox_OnEvent(self)
	if (event == "VARIABLES_LOADED") then
		local i

		WindChat_initConfig()
		WindChatEditBox_setLocation()

		for i=1,7 do
			WindChat_setScale(i)
			WindChat_setBorder(i)
		end

		WindChat_setColor()
		WindChat_setTime()
		WindChat_setSticky()
		WindChat_setStrings()
	end
end

function WindChat_initConfig()
	local i

	if (not WindChatConfigAll) then
		WindChatConfigAll = {}
	end

	for i=1,7 do
		if (WindChatConfigAll[i] == nil) then
			WindChatConfigAll[i] = {}
		end

		if (WindChatConfigAll[i][3] == nil) then
			WindChatConfigAll[i][3] = false
		end

		if (WindChatConfigAll[i][1] == nil) then
			WindChatConfigAll[i][1] = 1
		end

		if (WindChatConfigAll[i][4] == nil) then
			WindChatConfigAll[i][4] = { {r=0,g=0,b=0,a=0}, {r=0,g=0,b=0,a=0} }
		end
	end

	WindChat_initTimeColor()
end

function WindChat_initTimeColor()
	if (IsAddOnLoaded("WindConfig")) then
		WindChatConfig_OnShow()
	end
end

function WindChat_setScale(index)
	getglobal("ChatFrame"..index):SetScale(WindChatConfigAll[index][1])

	if (index == 1) then
		ChatFrameEditBox:SetScale(WindChatConfigAll[1][1])
	end
end

function WindChat_setBorder(index)
	if (WindChatConfigAll[index][2]) then
		getglobal("WindChatFrame"..index):SetBackdrop(WindCommon_ColorBorder)
		WindChat_setColor()
	else
		getglobal("WindChatFrame"..index):SetBackdrop(nil)
	end
end

function WindChat_setColor()
	local i

	for i=1,7 do
		getglobal("WindChatFrame"..i):SetBackdropBorderColor(WindChatConfigAll[i][4][1].r, WindChatConfigAll[i][4][1].g, WindChatConfigAll[i][4][1].b, WindChatConfigAll[i][4][1].a)
		getglobal("WindChatFrame"..i):SetBackdropColor(WindChatConfigAll[i][4][2].r, WindChatConfigAll[i][4][2].g, WindChatConfigAll[i][4][2].b, WindChatConfigAll[i][4][2].a)
	end

	ChatFrameEditBox:SetBackdropBorderColor(WindChatConfigAll[1][4][1].r, WindChatConfigAll[1][4][1].g, WindChatConfigAll[1][4][1].b, WindChatConfigAll[1][4][1].a)
end

function WindChatEditBox_setLocation()
	if (WindChatConfigAll[8]) then
		ChatFrameEditBox:ClearAllPoints()
		ChatFrameEditBox:SetPoint("BOTTOMLEFT", "ChatFrame1", "TOPLEFT", -10, 0)
		ChatFrameEditBox:SetPoint("BOTTOMRIGHT", "ChatFrame1", "TOPRIGHT", 6, 0)
	else
		ChatFrameEditBox:ClearAllPoints()
		ChatFrameEditBox:SetPoint("TOPLEFT", "ChatFrame1", "BOTTOMLEFT", -10, -7)
		ChatFrameEditBox:SetPoint("TOPRIGHT", "ChatFrame1", "BOTTOMRIGHT", 6, -7)
	end
end

function WindChat_setSticky()
	--[[
	if (WindChatConfigAll[13]) then
		]]
		ChatTypeInfo["CHANNEL"].sticky = 1
		ChatTypeInfo["OFFICER"].sticky = 1
		ChatTypeInfo["RAID_WARNING"].sticky = 1
		ChatTypeInfo["BATTLEGROUND_LEADER"].sticky = 1
	--[[
	else
		ChatTypeInfo["CHANNEL"].sticky = 0
		ChatTypeInfo["OFFICER"].sticky = 0
		ChatTypeInfo["RAID_WARNING"].sticky = 0
		ChatTypeInfo["BATTLEGROUND_LEADER"].sticky = 0
	end]]
end

function WindChat_setStrings()
	if (WindChatConfigAll[14]) then
		CHAT_FLAG_GM = "<GM>"
		CHAT_FLAG_AFK = "<비움> "
		CHAT_FLAG_DND = "<용무중> "
		CHAT_WHISPER_GET = "%s▶:\32"
		CHAT_WHISPER_INFORM_GET = "%s◀:\32"
		CHAT_MONSTER_YELL_GET = "[Y] %s:\32"
		CHAT_GUILD_GET = "[G] %s:\32"
		CHAT_RAID_GET = "[R] %s:\32"
		CHAT_RAID_LEADER_GET = "[RL] %s:\32"
		CHAT_RAID_WARNING_GET = "[RW] %s:\32"
		CHAT_BATTLEGROUND_GET = "[BP] %s:\32"
		CHAT_BATTLEGROUND_LEADER_GET = "[BFL] %s:\32"
		CHAT_PARTY_GET = "[P] %s:\32"
		CHAT_OFFICER_GET = "[GM] %s:\32"
		CHAT_YELL_GET = "[Y] %s:\32"
	else
		CHAT_FLAG_GM = "<GM>"
		CHAT_FLAG_AFK = "<자리비움> "
		CHAT_FLAG_DND = "<다른용무중> "
		CHAT_WHISPER_GET = "%s님의 귓속말:\32"
		CHAT_WHISPER_INFORM_GET = "%s님에게 귓속말:\32"
		CHAT_MONSTER_YELL_GET = "%s의 외침:\32"
		CHAT_GUILD_GET = "[길드] %s:\32"
		CHAT_RAID_GET = "[레이드] %s:\32"
		CHAT_RAID_LEADER_GET = "[공격대장] %s:\32"
		CHAT_RAID_WARNING_GET = "[공격대경보] %s:\32"
		CHAT_BATTLEGROUND_GET = "[전장] %s:\32"
		CHAT_BATTLEGROUND_LEADER_GET = "[전장지휘관] %s:\32"
		CHAT_PARTY_GET = "[파티] %s:\32"
		CHAT_OFFICER_GET = "[GM] %s:\32"
		CHAT_YELL_GET = "%s님의 외침:\32"
	end
end

local Original_ChatFrame_OnEvent

function WindChatTime_OnLoad(self)
	Original_ChatFrame_OnEvent = ChatFrame_OnEvent
	ChatFrame_OnEvent = WindChat_ChatFrame_OnEvent
end

function WindChat_ChatFrame_OnEvent(self, event, ...)
	if (not self.Original_AddMessage) then
		self.Original_AddMessage = self.AddMessage
		self.AddMessage = WindChat_AddMessage
	end

	Original_ChatFrame_OnEvent(self, event, ...)
end

function WindChat_setTime()
	local i

	for i=1, 7 do
		if (WindChatConfigAll[i][3]) then
			WindChatTimeConfig["WindChatFrame"..i] = true
		else
			WindChatTimeConfig["WindChatFrame"..i] = false
		end
	end
end
--[[
function WindChat_setNameColor(event, name)
	if (event) then
		if (event == "CHAT_MSG_PARTY") then
			local class, i

			for i=1,GetNumPartyMembers(),1 do
				if (UnitName("party"..i) == name) then
					_, class = UnitClass("party"..i)
					WindChat_setClassData(name, class)
				elseif (UnitName("player") == name) then
					_, class = UnitClass("player")
					WindChat_setClassData(name, class)
				end
			end
		end

		if (event == "CHAT_MSG_RAID" or event == "CHAT_MSG_RAID_LEADER" ) then
			for i=1,GetNumRaidMembers(),1 do
				local raidname, _, _, _, class = GetRaidRosterInfo(i)

				if (raidname and raidname == name) then
					WindChat_setClassData(name, ClassRevs[class])
				end
			end
		end
	end
end
]]
function WindChat_getNameColor(name)
	if WindChat_Names[name] then
		return WindChat_Names[name]
	else
		return ""
	end
end

function WindChat_setClassData(name, class)
	if (not WindChat_Names[name]) then
		local color = ClassColors[class]

		if color then
			WindChat_Names[name] = color
		end
	end
end

function WindChat_BuildFriendsInfo()
	local i

	for i=1,GetNumFriends(),1 do
		local name, _, class, _, con = GetFriendInfo(i)

		if not name then
			break
		elseif con then
			WindChat_setClassData(name, ClassRevs[class])
		end
	end
end

-- for URL copy -Isidur
WindChat_UrlPatterns = {
	-- www.X.Y url
	"((%a+)://(%S+))",
	"(www%.[_A-Za-z0-9-]+%.%S+)",
	-- X@X.Y url (---> email)
	"([_A-Za-z0-9-%.]+@[_A-Za-z0-9-]+%.[_A-Za-z0-9-%.]+)",
	-- XXX.YYY.ZZZ.WWW:VVVV url (IP of ts server for example)
	"(%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?:%d%d?%d?%d?%d?)",
	-- XXX.YYY.ZZZ.WWW url (---> IP)
	"(%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?)",
	-- X.Y.Z url
	"([_A-Za-z0-9-]+%.[_A-Za-z0-9-]+%.%S+)",
	-- X.Y.Z:WWWW url  (ts server for example)
	"([_A-Za-z0-9-]+%.[_A-Za-z0-9-]+%.%S+%:[_0-9-]+)",
}

function WindChat_AddMessage(self, msg, r, g, b, id)
	if (not msg) then
		return
	end

	local _, _, _, name = string.find(msg, "(|Hplayer:.-|h%[)([^%]]+)(.+)")

	if name then
		if (WindChatConfigAll[16]) then
			PreFix = WindChat_getNameColor(name)
			LocalEnd = "|r"
		else
			PreFix = ""
			LocalEnd = ""
		end

		if (WindChatConfigAll[15] and strsub(event, 1, 13) == "CHAT_MSG_RAID") then
			local i

			for i=1, GetNumRaidMembers(), 1 do
				local raidname, _, subgroup, _, class = GetRaidRosterInfo(i)

				if (name == raidname) then
					local strClass = ""

					if (class == "사냥꾼") then
						strClass = strClass..subgroup.."냥"
					else
						strClass = strClass..subgroup..strsub(class, 1, 3)
					end

					msg = string.gsub(msg, "(|Hplayer:.-|h)(%[)([^%]]+)(%])(.+)", "%1["..PreFix.."%3"..LocalEnd.."]["..strClass.."]%5")
					break
				end
			end
		else
			msg = string.gsub(msg, "(|Hplayer:.-|h)(%[)([^%]]+)(%])(.+)", "%1["..PreFix.."%3"..LocalEnd.."]%5")
		end
	end

	-- for URL copy -Isidur
	for k,v in pairs(WindChat_UrlPatterns) do
		if string.find(msg, v) then
			msg = string.gsub(msg, v, "|cffffffff|Hurl:".."%1".."|h".."%1".."|h|r")
			break
		end
	end

	if (WindChatTimeConfig["Wind"..self:GetName()]) then
		local new_msg = date("%M")
		local hour = date("%H")
		local second = date("%S")
		local ampm = "오전"

		if (WindChatConfigAll[9]) then
			new_msg = new_msg..":"..second
		end

		if (WindChatConfigAll[10]) then
			hour = hour + 0
			if (hour > 12) then
				hour = hour - 12
				ampm = "오후"
			else
				if (hour == 12) then
					ampm = "오후"
				else
					ampm = "오전"
				end
			end
			new_msg = ampm.." "..hour..":"..new_msg
		else
			new_msg = hour..":"..new_msg
		end

		if (WindChatConfigAll[11]) then
			new_msg = "|cFF"..WindChatConfigAll[12].."["..new_msg.."]".."|r".." "..msg
		else
			new_msg = "["..new_msg.."]".." "..msg
		end

		self:Original_AddMessage(new_msg, r, g, b, id)
	else
		self:Original_AddMessage(msg, r, g, b, id)
	end
end
