
local parser = ParserLib:GetInstance('1.1')
local dewdrop = DewdropLib:GetInstance('1.0')
local version = '0.7'


SimpleCombatLog = {}

local self = SimpleCombatLog


-- Unnamed frame for events.
if not self.frame then
	self.frame = CreateFrame('Frame');
	self.frame:RegisterEvent('VARIABLES_LOADED');
	self.frame:SetScript('OnEvent', function() self:OnEvent() end );
end



-- Hook the FCF_Tab_OnClick() to check for alt-rightclick.
SimpleCombatLog.FCF_Tab_OnClick = function(button)
	if IsAltKeyDown() and button == 'RightButton' then
		self:LoadSettingMenu(this:GetID())
	else
		self.old_FCF_Tab_OnClick(button)
	end
end

-- Directly hook ChatFrame_OnEvent to suppress the damage.
SimpleCombatLog.ChatFrame_OnEvent = function(event)
	local id = this:GetID()
	if not id or not self.savedVars[id] or not self.savedVars[id].suppress or not self:GetEventCat(event) then
		self.old_ChatFrame_OnEvent(event)
	end
end

-- Hook this to refresh chatframe events when user changes interface options.
--[[
SimpleCombatLog.UIOptionsFrame_Save = function()
	
	self.old_UIOptionsFrame_Save()

	self.needRefreshChatEvent = true 
	self:RefreshSettings() 

end
]]



-- Search for the event in eventList and return its category.
function SimpleCombatLog:SearchList(text)
	local eventCat, events
	local list = self.eventCats
	for i in ipairs(list) do
		eventCat = list[i]
		i = next(list, i)
		events = list[i]
		for j in events do
			if events[j] == text then return eventCat end
		end
	end
end


-- Is this an event of SimpleCombatLog?
function SimpleCombatLog:GetEventCat(event)
	if not self.eventList then
		self.eventList = {}
		local eventCat, events
		for i in ipairs(self.eventCats) do
			eventCat = self.eventCats[i]
			i = next(self.eventCats, i)
			events = self.eventCats[i]
			for j, e in events do
				self.eventList[e] = eventCat
			end
		end
	end
	
	return self.eventList[event]
end




self.eventCats = {

	'selfhit' , {
		'CHAT_MSG_COMBAT_PET_HITS',
		'CHAT_MSG_COMBAT_PET_MISSES',
		'CHAT_MSG_COMBAT_SELF_HITS',
		'CHAT_MSG_COMBAT_SELF_MISSES',
		
	},
	
	'otherhit' , {
		'CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS',
		'CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_MISSES',
		'CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS',
		'CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES',
		'CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS',
		'CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES',
		'CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS',
		'CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES',
		'CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS',
		'CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES',
		'CHAT_MSG_COMBAT_PARTY_HITS',
		'CHAT_MSG_COMBAT_PARTY_MISSES',
	},
		
	'selfspell' , {
		'CHAT_MSG_SPELL_PET_BUFF',
		'CHAT_MSG_SPELL_PET_DAMAGE',
		'CHAT_MSG_SPELL_SELF_BUFF',
		'CHAT_MSG_SPELL_SELF_DAMAGE',
	},

	'otherspell' , {
		'CHAT_MSG_SPELL_CREATURE_VS_CREATURE_BUFF',
		'CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE',
		'CHAT_MSG_SPELL_CREATURE_VS_PARTY_BUFF',
		'CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE',
		'CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF',
		'CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE',
		'CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF',
		'CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE',
		'CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF',
		'CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE',
		'CHAT_MSG_SPELL_PARTY_BUFF',
		'CHAT_MSG_SPELL_PARTY_DAMAGE',
	},
	
	'selfdot' , {
		'CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS',
		'CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE',
		'CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF',
	},

	'otherdot' , {
		'CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS',
		'CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE',
		'CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS',
		'CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE',
		'CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS',
		'CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE',
		'CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS',
		'CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE',
		'CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS',
	},
	
	'aura' , {
		'CHAT_MSG_SPELL_AURA_GONE_OTHER',
		'CHAT_MSG_SPELL_AURA_GONE_SELF',
		'CHAT_MSG_SPELL_AURA_GONE_PARTY',
		'CHAT_MSG_SPELL_BREAK_AURA',
	},

	'death' , {
		'CHAT_MSG_COMBAT_FRIENDLY_DEATH',
		'CHAT_MSG_COMBAT_HOSTILE_DEATH',
	},
	
	'enchant' , {
		'CHAT_MSG_SPELL_ITEM_ENCHANTMENTS',
	},
	

	'experience' , {
		'CHAT_MSG_COMBAT_XP_GAIN',
	},

	'honor' , {
		'CHAT_MSG_COMBAT_HONOR_GAIN',
	},

	'reputation' , {
		'CHAT_MSG_COMBAT_FACTION_CHANGE',
	},
	
	'trade' , {
		'CHAT_MSG_SPELL_TRADESKILLS',
	},

	'fail' , {
		'CHAT_MSG_SPELL_FAILED_LOCALPLAYER',
	},
	
}


-- Available filters.
self.filterList = {
	'player', 'pet', 'party', 'raid', 'target', 'other', 	'', -- '' means an empty line.
	'hit', 'heal', 'miss', 'cast', 'gain', 'drain', 'leech', 'dispel', 
	'buff', 'debuff', 'fade', 'interrupt', 'environment', 'extraattack', 'enchant', 
}


function SimpleCombatLog:OnEvent()
	ChatFrame1:AddMessage(event)
	if event == 'VARIABLES_LOADED' then
		self:Initialize()
	end
end

function SimpleCombatLog:Initialize()

	if self.initialized then return end
		
	local formatIndex = function(t, k)
		for i in ipairs(t) do			
			if t[i] == k then
				t[k] = t[next(t, i)]
				return t[k]
			end
			i = next(t, i)
		end
	end
	setmetatable(self.formats, { __index = formatIndex })
	setmetatable(self.eventCats, { __index = formatIndex })
	
	
	-- Checking saved variables.	
	if not SCL_Config then SCL_Config = {} end
	self.savedVars = SCL_Config
	
	-- Check for old version.
	for i in self.savedVars do
		if type(i) ~= "number" then
			self:PromptReset("SCL: found deprecated data '"..i.."', confirm to reset data")
			break
		elseif not self.savedVars[i].formats then
			self:PromptReset("SCL: old data format detected, confirm to reset data")
			break
		end
	end	

	-- Slash commands.
	SLASH_SCL1 = '/scl';
	SlashCmdList['SCL'] = function (msg) self:SlashCommand(msg) end		


	-- Hook this for Alt-RightClick.
	self.old_FCF_Tab_OnClick = FCF_Tab_OnClick
	FCF_Tab_OnClick = SimpleCombatLog.FCF_Tab_OnClick
	
	-- Hook this to refresh settings after user opened Blizzard interface options.
	-- self.old_UIOptionsFrame_Save = UIOptionsFrame_Save
	-- UIOptionsFrame_Save = self.UIOptionsFrame_Save
	
	-- Hook ChatFrame_OnEvent to suppress combat messages.
	self.old_ChatFrame_OnEvent = ChatFrame_OnEvent
	ChatFrame_OnEvent = self.ChatFrame_OnEvent
	
	--self.needRefreshChatEvent = true
	self:RefreshSettings()

	self.frame:UnregisterAllEvents()
	
	self:Print(self.loc.loaded_help1)
	self:Print(self.loc.loaded_help2)

	
	self.initialized = true

	
end

function SimpleCombatLog:LoadEditBox(id, msgType)


	if not self.editBox then

		self.editBox = CreateFrame('Editbox',nil,UIParent)
		self.editBox:SetHeight(25)
		self.editBox:SetWidth(300)
		self.editBox:SetPoint('CENTER',0,0)

		self.editBox:SetBackdrop({
			bgFile='Interface\\Tooltips\\UI-Tooltip-Background',
			edgeFile='Interface\\Tooltips\\UI-Tooltip-Border',
			edgeSize=16, tileSize=16, tile=true,
			insets={left=5, right=5, top=5, bottom=5}})

		self.editBox:SetBackdropColor(0,0,0,1)
		self.editBox:SetFont('Fonts\\FRIZQT__.TTF',13)
		self.editBox:SetTextInsets(5,5,0,0)
		
			
		local f = CreateFrame('Button',nil,UIParent)
		f:SetFrameStrata('BACKGROUND')
		f:SetWidth(300)  -- Set These to whatever height/width is needed 
		f:SetHeight(30) -- for your Texture

		f:SetPoint('BOTTOMLEFT', self.editBox, 'TOPLEFT')
		f:SetFont('Fonts\\FRIZQT__.TTF',13)
		f:Hide()


		self.editBox.title = f

		self.editBox:SetScript('OnEscapePressed',function()
			this.title:Hide()
			this:Hide()
		end)
		
		self.editBox:SetScript('OnEnterPressed',function()
			SimpleCombatLog:Reformat(this.id, this.msgType, this:GetText() )
			SimpleCombatLog:Print("|cff3333ffChatFrame"..this.id.."|r |cffeda55f"..this.msgType.."|r = '"..this:GetText() .. "'", 1)
			this.title:Hide()
			this:Hide()
		end)

		self.editBox:SetScript('OnShow', function()
			this.title:Show()
		end)

		self.editBox:Hide()

	end


	self.editBox.id = id
	self.editBox.msgType = msgType
	self.editBox:SetText(  self:GetFormat(id, msgType) )
	self.editBox.title:SetText(string.format(self.loc.editbox_title, msgType))
	self.editBox:Show()

end


function SimpleCombatLog:LoadSettingMenu(id)

	if not self.savedVars[id] then self:InitSavedVars(id) end
	local tabFrame = getglobal("ChatFrame" .. id .. "Tab")
	
	if not dewdrop:IsRegistered(tabFrame) then
		dewdrop:Register(tabFrame, 
			'children', function(level, value) self:OptionOpen(id, level, value) end, 
			'dontHook', true
		)
	end
		
	dewdrop:Open(tabFrame)
end

function SimpleCombatLog:SlashCommand(msg)

	if msg == 'simplemode' then
		self:LoadSimpleMode()
		
	elseif string.find(msg, '^option') then
	
		local _, _, n = string.find(msg, '^option (%d+)')
		if n then self:LoadSettingMenu(tonumber(n)) end
		
	elseif string.find(msg, '^clear') then
	
		local _, _, n = string.find(msg, '^clear (%d+)')		
		if n then self:ClearSettings(tonumber(n))	end

	-- Hidden command.
	elseif string.find(msg, '^format') then
	
		local _, _, n, msgType, msgFormat = string.find(msg, '^format (%d+) (.-) (.+)')
		
		if n and msgType and msgFormat then self:Reformat(tonumber(n), msgType, msgFormat) 
		else self:Print("invalid parameters.") end


	else

		self:PrintHelp()
	end
	
end

function SimpleCombatLog:PromptReset(message)
	StaticPopupDialogs["SCL_RESET"] = {
		text = message,
		button1 = TEXT(OKAY),
		button2 = TEXT(CANCEL),
		OnAccept = function()
			self:LoadSimpleMode();
		end,
		timeout = 0,
		exclusive = 1
	};
	StaticPopup_Show("SCL_RESET");
end	


function SimpleCombatLog:OnCombatEvent(event, info)

	local eventCat = self:GetEventCat(event)

	for i in self.savedVars do
		if self.savedVars[i].events[eventCat] then
			self:ParseInfo(i, info)
		end
	end
	
end

function SimpleCombatLog:ParseInfo(id, info)

	local source, victim, sourceGained, skill, amount

	if not self:FilterCheck(id, info) then return end
	
	-- Do some common info parsing here first.
	if info.source == ParserLib_SELF then source = self.loc.you else source = info.source end
	if info.victim == ParserLib_SELF then victim = self.loc.you else victim = info.victim end
	if info.sourceGained == ParserLib_SELF then sourceGained = self.loc.you else sourceGained = info.sourceGained end
	
	
	if info.skill == ParserLib_MELEE then 
		skill = self.loc.melee 
	elseif info.skill == ParserLib_DAMAGESHIELD then
		skill = self.loc.dmgshield 
	else 
		skill = info.skill 
	end
	
	
	amount = info.amount
	if info.isCrit then amount = string.format("*%s*", info.amount) end
	if info.isDOT then amount = string.format("~%s~", info.amount) end
	
	
	source = self:Colorize(id, source, self:SearchName(info.source))
	victim = self:Colorize(id, victim, self:SearchName(info.victim))
	sourceGained = self:Colorize(id, sourceGained, self:SearchName(info.sourceGained))
	
	local extra, trailer
		
	
	
	if skill and info.type ~= "hit"  and info.type ~= "heal" then
		skill = self:Colorize(id, skill, "skill")
	end
	
	
	if info.type == "hit" then

		local elementType

		if info.element then
			elementType = self:GetElementType(info.element)
		else
			elementType = "physical"
		end
			
		if self.savedVars[id].colorspell then
			skill = self:Colorize(id, skill, elementType)
		else
			skill = self:Colorize(id, skill, "skill")
		end
		
		amount = self:Colorize(id, amount, elementType)
		
		if info.isCrit then
			extra = "crit"
		elseif info.isDOT then
			extra = "dot"
		else
			extra = "hit"
		end
		
		trailer = self:GetTrailerString(id, info)
		self:Print(string.format(self:GetFormat(id, "hit"), source, skill, extra, victim, amount, trailer), id)
				
	elseif info.type == "heal" then

		if self.savedVars[id].colorspell then
			skill = self:Colorize(id, skill, "heal")
		else
			skill = self:Colorize(id, skill, "skill")
		end
		
		amount = self:Colorize(id, amount, "heal")
		self:Print(string.format(self:GetFormat(id, "heal"), source, skill, victim, amount), id)
		
	elseif info.type == "debuff" then
	
		extra = self:Colorize(id, "++", "debuff")
		if amountRank then
			skill = string.format("%s(%s)", skill, amountRank)
		end
		
		self:Print(string.format(self:GetFormat(id, "debuff"), victim, extra, skill), id)
		
	elseif info.type == "buff" then
	
		extra = self:Colorize(id, "++", "buff")
		if amountRank then
			skill = string.format("%s(%s)", skill, amountRank)
		end		
		self:Print(string.format(self:GetFormat(id, "buff"), victim, extra, skill), id)
	

	elseif info.type == "fade" then
	
		self:Print(string.format(self:GetFormat(id, "fade"), victim, skill), id)
		
	elseif info.type == "dispel" then
		

		if not info.isFailed then
			self:Print(string.format(self:GetFormat(id, "fade"), victim, skill), id) -- Use the same pattern 
		else
			self:Print(string.format(self:GetFormat(id, "failDispel"), source, victim, skill), id)
		end


		
	elseif info.type == "gain" then
		self:Print(string.format(self:GetFormat(id, "gain"), source, skill, victim, amount, info.attribute), id)
		
	elseif info.type == "extraattack" then

		self:Print(string.format(self:GetFormat(id, "extraattack"), victim, amount, skill), id)
		
	elseif info.type == "honor" then
		
		if info.isDishonor then
			self:Print(string.format(self:GetFormat(id, "dishonor"), source), id)
		else
			
			if source then
				trailer = string.format(" (%s %s)", info.sourceRank, source)
			else
				trailer = ""
			end
			
			self:Print(string.format(self:GetFormat(id, "honor"), amount)..trailer, id)
		
		end
		
	elseif info.type == "experience" then
		
		trailer = ""
		if source then trailer = string.format("%s(%s)", trailer, source) end
		if info.bonusAmount then	trailer = string.format("%s(%s%s)", trailer, info.bonusType, info.bonusAmount)	end
		if info.penaltyAmount then trailer = string.format("%s(%s%s)", trailer, info.penaltyType, info.penaltyAmount) end
		if info.amountGroupBonus then trailer = string.format("%s(G+%s)", trailer, info.amountGroupBonus) end
		if info.amountRaidPenalty then trailer = string.format("%s(R-%s)", trailer, info.amountRaidPenalty) end		
		self:Print(string.format(self:GetFormat(id, "experience"), amount).. trailer, id)
		
	elseif info.type == "reputation" then
	
		
		if not amount then
			trailer = info.rank
		else
			if info.isNegative then 
				trailer = string.format("-%s", amount)
			else
				trailer = string.format("+%s", amount)
			end
		end

		self:Print(string.format(self:GetFormat(id, "reputation"), info.faction, trailer), id)
		
		
	elseif info.type == "feedpet" then

		self:Print(string.format(self:GetFormat(id, "feedpet"), victim, info.item), id)		

	elseif info.type == "enchant" then
			
		self:Print(string.format(self:GetFormat(id, "enchant"), source, skill, victim, info.item), id)
		
	elseif info.type == "miss" then
			
		self:Print(string.format(self:GetFormat(id, "miss"), source, skill, self:Colorize(id, info.missType, "miss"), victim), id)

	elseif info.type == "cast" then
		
		if info.isBegin then
			self:Print(string.format(self:GetFormat(id, "beginCast"), source, skill), id)
		else
			if victim then
				self:Print(string.format(self:GetFormat(id, "castTargetted"), source, skill, victim), id)
			else
				self:Print(string.format(self:GetFormat(id, "cast"), source, skill), id)
			end
		end
		
		
	elseif info.type == "interrupt" then
	
		self:Print(string.format(self:GetFormat(id, "interrupt"), source, victim, skill), id)
				
	elseif info.type == "death" then
	
		if source then trailer = string.format("(%s)", source) else trailer = "" end
		self:Print(string.format(self:GetFormat(id, "death"), victim)..trailer, id)		
		
	elseif info.type == "environment" then

		trailer = self:GetTrailerString(id, info)
		self:Print(string.format(self:GetFormat(id, "environment"), victim, info.damageType, amount, trailer), id)
		
	elseif info.type == "create" then
	
	
		self:Print(string.format(self:GetFormat(id, "create"), source, info.item), id)
				
	elseif info.type == "fail" then
	
		self:Print(string.format(self:GetFormat(id, "fail"), skill, info.reason), id)		
		
	elseif info.type == "drain" then
		
		self:Print(string.format(self:GetFormat(id, "drain"), source, skill, victim, amount, info.attribute), id)
		
		
	elseif info.type == "leech" then
	
		self:Print(string.format(self:GetFormat(id, "leech"), source, skill, victim, amount, info.attribute, sourceGained, info.amountGained, info.attributeGained), id)
		
	elseif info.type == "unknown" then
	
		self:Print(info.message, id, 1, 0, 0)
	
	end
		
end


function SimpleCombatLog:Colorize(id, value, valueType)
	if not valueType then return value end
	
	local c, d = self:GetColor(id, valueType)
	
	if not c then return value end

	return string.format('|cff%02x%02x%02x%s|r', (c.r*255), (c.g*255), (c.b*255), value)

end


-- Return color, bDefault
function SimpleCombatLog:GetColor(id, valueType)
	if not self.savedVars[id].colors or not self.savedVars[id].colors[valueType] then
		return self.defaultColors[valueType], true
	else
		return self.savedVars[id].colors[valueType]
	end
end

function SimpleCombatLog:GetFormat(id, msgType)
	if not self.savedVars[id].formats[msgType] then
		return self.formats[msgType], true
	else
		return self.savedVars[id].formats[msgType]
	end
end



function SimpleCombatLog:PrintHelp()
	self:Print("Simple Combat Log v" .. version, 1)
	self:Print("/scl simplemode : ".. self.loc.help_slash1, 1)
	self:Print("/scl option [n] : ".. self.loc.help_slash2, 1)
	self:Print("/scl clear [n] : ".. self.loc.help_slash3, 1)
end
		

function SimpleCombatLog:RefreshSettings()

--[[
	-- Default message suppressing.
	if self.needRefreshChatEvent then
		for i in self.savedVars do
			local frame = getglobal('ChatFrame' .. i)
			if frame then	for index, value in frame.messageTypeList do
				for eventIndex, eventValue in ChatTypeGroup[value] do
					if self:GetEventCat(eventValue) then
						if self.savedVars[i].suppress then
							frame:UnregisterEvent(eventValue);
						else
							frame:RegisterEvent(eventValue);
						end
					end
				end end
			end
		end
		self.needRefreshChatEvent = nil
	end
]]

	-- ParserLib registeration and track used events.
	local usedEvents = {}
	local eventCat, events
	for i in ipairs(self.eventCats) do
		eventCat = self.eventCats[i]
		i = next(self.eventCats, i)
		events = self.eventCats[i]
		for j in self.savedVars do
			if self.savedVars[j].events[eventCat] then
				usedEvents[eventCat] = true
				if not parser:IsEventRegistered('SimpleCombatLog', events[1]) then
					for k in events do
						parser:RegisterEvent('SimpleCombatLog', events[k], function(event, info) self:OnCombatEvent(event, info) end)
					end
				end
			end
		end
	end

	-- Unregister non-used events from ParserLib.
	for i in ipairs(self.eventCats) do
		eventCat = self.eventCats[i]
		i = next(self.eventCats, i)
		events = self.eventCats[i]
		if not usedEvents[eventCat] and parser:IsEventRegistered('SimpleCombatLog', events[1]) then
			for j in events do
				parser:UnregisterEvent('SimpleCombatLog', events[j], OnCombatEvent)
			end
		end
	end

end



-- Get constant element string from localized element string.
function SimpleCombatLog:GetElementType(element)
	if element == SPELL_SCHOOL0_CAP then return 'physical'
	elseif element == SPELL_SCHOOL1_CAP then return 'holy'
	elseif element == SPELL_SCHOOL2_CAP then return 'fire'
	elseif element == SPELL_SCHOOL3_CAP then return 'nature'
	elseif element == SPELL_SCHOOL4_CAP then return 'frost'
	elseif element == SPELL_SCHOOL5_CAP then return 'shadow'
	elseif element == SPELL_SCHOOL6_CAP then return 'arcane'
	else return element end
end


-- Get trailer string by parsing info.
function SimpleCombatLog:GetTrailerString(id, info)
	local trailer = ''
	if info.isCrushing then trailer = trailer .. self:GetFormat(id, 'crushing')end
	if info.isGlancing then trailer = trailer .. self:GetFormat(id, 'glancing')end
	if info.amountAbsorb then trailer = trailer .. format(self:GetFormat(id, 'absorb'), info.amountAbsorb) end
	if info.amountResist then trailer = trailer .. format(self:GetFormat(id, 'resist'), info.amountResist) end
	if info.amountBlock then trailer = trailer .. format(self:GetFormat(id, 'block'), info.amountBlock) end
	if info.amountVulnerable then trailer = trailer .. format(self:GetFormat(id, 'vulnerable'), info.amountVulnerable) end
	return trailer
end


-- Check for the filter settings, return true if this message can be shown, false if the message is filtered.
function SimpleCombatLog:FilterCheck(id, info)
	
	local f = self.savedVars[id].filters

	
	-- Check for type filter.
	
	for i, v in f do
		if info.type == i and v then return false end
	end

	-- Death ignore name filter by option.
	if info.type == 'death' and self.savedVars[id].deathIgnore then
		return true
	end

	
	-- These message ignore name filters.
	if info.type == 'experience'
	or info.type == 'honor'
	or info.type == 'reputation' 
	or info.type == 'fail' then
		return true
	end
	

	-- Checking names
	if not ( info.source or info.victim ) then return true end	
	if info.source and not f[self:SearchName(info.source)] then return true end
	if info.victim and not f[self:SearchName(info.victim)] then return true end
	
	-- The message does not match any filter setting, block.
	return false
	
end


-- Get what is this name : player, pet, party, raid, target or others.
function SimpleCombatLog:SearchName(name)
	if not name then return end
	if name == ParserLib_SELF then return 'player' end
	-- if name == UnitName('player') then return 'player' end
	if name == UnitName('pet') then return 'pet' end
	for i=1, GetNumPartyMembers() do 
		if name == UnitName('party'..i) then return 'party' end
	end
	for i=1, GetNumRaidMembers() do
		if name == UnitName('raid'..i) then return 'raid' end
	end
	if name == UnitName('target') then return 'target' end	
	
	return 'other'
end


function SimpleCombatLog:Print(msg, id, r,g,b)

	if not msg then return end

	local frame
	if not id then
		msg = "SimpleCombatLog " .. version .. " : " .. msg
		frame = DEFAULT_CHAT_FRAME
	else
		frame = getglobal('ChatFrame'..id)
	end
	
	frame:AddMessage(msg, r, g, b)

end


function SimpleCombatLog:OptionOpen(id, level, value)


	if level == 1 then

		dewdrop:AddLine(
			'text', self.loc.setting_title..id,
			'isTitle', true,
			'notCheckable', true
		)
		
		dewdrop:AddLine()


		dewdrop:AddLine(
			'text', self.loc.category_filter,
			'hasArrow', true,
			'value', 'filter'
		)
		
		dewdrop:AddLine(
			'text', self.loc.category_event,
			'hasArrow', true,
			'value', 'event'
		)		

		dewdrop:AddLine(
			'text', self.loc.category_color,
			'hasArrow', true,
			'value', 'color'
		)		
		
		dewdrop:AddLine(
			'text', self.loc.category_format,
			'hasArrow', true,
			'value', 'format'
		)		
		
	

		dewdrop:AddLine()

		dewdrop:AddLine(
			'text', self.loc.setting_suppress,
			'func', 
			function() 
				self.savedVars[id].suppress = not self.savedVars[id].suppress
--				self.needRefreshChatEvent = true
				self:RefreshSettings()
			end,
			'checked', self.savedVars[id].suppress
		)

		dewdrop:AddLine(
			'text', self.loc.setting_colorSpell,
			'func', 
			function() 
				self.savedVars[id].colorspell = not self.savedVars[id].colorspell
			end,
			'checked', self.savedVars[id].colorspell
		)

		dewdrop:AddLine(
			'text', self.loc.setting_deathIgnore,
			'func', 
			function() 
				self.savedVars[id].deathIgnore = not self.savedVars[id].deathIgnore
			end,
			'checked', self.savedVars[id].deathIgnore
		)
		
	
		
		dewdrop:AddLine()
		
		dewdrop:AddLine(
			'text', self.loc.option_clearSetting,
			'notCheckable', true,
			'closeWhenClicked', true,
			'func', function() self:ClearSettings(id) end
		)
		
		dewdrop:AddLine(
			'text', self.loc.option_loadCommon,
			'notCheckable', true,
			'func', function() self:LoadCommonSettings(id) end
		)
		


	elseif level == 2 then
	
	
		if value == 'color' then

			local c, d, title
			
			c, d = self:GetColor(id, 'player')
			if not d then title = "|cffeda55f"..self.loc.player.."|r" else title = self.loc.player end
			dewdrop:AddLine(
				'text', title,
				'hasColorSwatch', true,
				'r', c.r,
				'g', c.g,
				'b', c.b,		
				'notCheckable', true,
				'cancelFunc', function(r,g,b) self:OnColorCancel(id, 'player', r,g,b) end,
				'swatchFunc', function(r,g,b) self:OnColorChange(id, 'player', r,g,b) end
			)
			
			c, d = self:GetColor(id, 'pet')
			if not d then title = "|cffeda55f"..self.loc.pet.."|r" else title = self.loc.pet end
			dewdrop:AddLine(
				'text', title,
				'hasColorSwatch', true,
				'r', c.r,
				'g', c.g,
				'b', c.b,
				'notCheckable', true,
				'cancelFunc', function(r,g,b) self:OnColorCancel(id, 'pet', r, g, b) end,
				'swatchFunc', function(r,g,b) self:OnColorChange(id, 'pet',r,g,b) end
			)
			
			c, d = self:GetColor(id, 'party')
			if not d then title = "|cffeda55f"..self.loc.party.."|r" else title = self.loc.party end
			dewdrop:AddLine(
				'text', title,
				'hasColorSwatch', true,
				'r', c.r,
				'g', c.g,
				'b', c.b,
				'notCheckable', true,
				'cancelFunc', function(r,g,b) self:OnColorCancel(id, 'party', r, g, b) end,
				'swatchFunc', function(r,g,b) self:OnColorChange(id, 'party',r,g,b) end
			)
			
			c, d = self:GetColor(id, 'raid')
			if not d then title = "|cffeda55f"..self.loc.raid.."|r" else title = self.loc.raid end
			dewdrop:AddLine(
				'text', title,
				'hasColorSwatch', true,
				'r', c.r,
				'g', c.g,
				'b', c.b,
				'notCheckable', true,
				'cancelFunc', function(r,g,b) self:OnColorCancel(id, 'raid', r, g, b) end,
				'swatchFunc', function(r,g,b) self:OnColorChange(id, 'raid',r,g,b) end
			)
			
			c, d = self:GetColor(id, 'target')
			if not d then title = "|cffeda55f"..self.loc.target.."|r" else title = self.loc.target end
			dewdrop:AddLine(
				'text', title,
				'hasColorSwatch', true,
				'r', c.r,
				'g', c.g,
				'b', c.b,
				'notCheckable', true,
				'cancelFunc', function(r,g,b) self:OnColorCancel(id, 'target', r, g, b) end,
				'swatchFunc', function(r,g,b) self:OnColorChange(id, 'target',r,g,b) end
			)
			
			c, d = self:GetColor(id, 'other')
			if not d then title = "|cffeda55f"..self.loc.other.."|r" else title = self.loc.other end
			dewdrop:AddLine(
				'text', title,
				'hasColorSwatch', true,
				'r', c.r,
				'g', c.g,
				'b', c.b,
				'notCheckable', true,
				'cancelFunc', function(r,g,b) self:OnColorCancel(id, 'other', r, g, b) end,
				'swatchFunc', function(r,g,b) self:OnColorChange(id, 'other',r,g,b) end
			)
			
			dewdrop:AddLine() 
			
						
			c, d = self:GetColor(id, 'skill')
			if not d then title = "|cffeda55f"..self.loc.skill.."|r" else title = self.loc.skill end
			dewdrop:AddLine(
				'text', title,
				'hasColorSwatch', true,
				'r', c.r,
				'g', c.g,
				'b', c.b,
				'notCheckable', true,
				'cancelFunc', function(r,g,b) self:OnColorCancel(id, 'skill', r, g, b) end,
				'swatchFunc', function(r,g,b) self:OnColorChange(id, 'skill',r,g,b) end
			)


			c, d = self:GetColor(id, 'buff')
			if not d then title = "|cffeda55f"..self.loc.buff.."|r" else title = self.loc.buff end
			dewdrop:AddLine(
				'text', title,
				'hasColorSwatch', true,
				'r', c.r,
				'g', c.g,
				'b', c.b,
				'notCheckable', true,
				'cancelFunc', function(r,g,b) self:OnColorCancel(id, 'buff', r, g, b) end,
				'swatchFunc', function(r,g,b) self:OnColorChange(id, 'buff',r,g,b) end
			)

			c, d = self:GetColor(id, 'debuff')
			if not d then title = "|cffeda55f"..self.loc.debuff.."|r" else title = self.loc.debuff end
			dewdrop:AddLine(
				'text', title,
				'hasColorSwatch', true,
				'r', c.r,
				'g', c.g,
				'b', c.b,
				'notCheckable', true,
				'cancelFunc', function(r,g,b) self:OnColorCancel(id, 'debuff', r, g, b) end,
				'swatchFunc', function(r,g,b) self:OnColorChange(id, 'debuff',r,g,b) end
			)
			
			c, d = self:GetColor(id, 'heal')
			if not d then title = "|cffeda55f"..self.loc.heal.."|r" else title = self.loc.heal end
			dewdrop:AddLine(
				'text', title,
				'hasColorSwatch', true,
				'r', c.r,
				'g', c.g,
				'b', c.b,
				'notCheckable', true,
				'cancelFunc', function(r,g,b) self:OnColorCancel(id, 'heal', r, g, b) end,
				'swatchFunc', function(r,g,b) self:OnColorChange(id, 'heal',r,g,b) end
			)
			
			c, d = self:GetColor(id, 'miss')
			if not d then title = "|cffeda55f"..self.loc.miss.."|r" else title = self.loc.miss end
			dewdrop:AddLine(
				'text', title,
				'hasColorSwatch', true,
				'r', c.r,
				'g', c.g,
				'b', c.b,
				'notCheckable', true,
				'cancelFunc', function(r,g,b) self:OnColorCancel(id, 'miss', r, g, b) end,
				'swatchFunc', function(r,g,b) self:OnColorChange(id, 'miss',r,g,b) end
			)
						
			c, d = self:GetColor(id, 'physical')
			if not d then title = "|cffeda55f"..self.loc.physical.."|r" else title = self.loc.physical end
			dewdrop:AddLine(
				'text', title,
				'hasColorSwatch', true,
				'r', c.r,
				'g', c.g,
				'b', c.b,
				'notCheckable', true,
				'cancelFunc', function(r,g,b) self:OnColorCancel(id, 'physical', r, g, b) end,
				'swatchFunc', function(r,g,b) self:OnColorChange(id, 'physical',r,g,b) end
			)
			
			c, d = self:GetColor(id, 'holy')
			if not d then title = "|cffeda55f"..self.loc.holy.."|r" else title = self.loc.holy end
			dewdrop:AddLine(
				'text', title,
				'hasColorSwatch', true,
				'r', c.r,
				'g', c.g,
				'b', c.b,
				'notCheckable', true,
				'cancelFunc', function(r,g,b) self:OnColorCancel(id, 'holy', r, g, b) end,
				'swatchFunc', function(r,g,b) self:OnColorChange(id, 'holy',r,g,b) end
			)
			
			c, d = self:GetColor(id, 'fire')
			if not d then title = "|cffeda55f"..self.loc.fire.."|r" else title = self.loc.fire end
			dewdrop:AddLine(
				'text', title,
				'hasColorSwatch', true,
				'r', c.r,
				'g', c.g,
				'b', c.b,
				'notCheckable', true,
				'cancelFunc', function(r,g,b) self:OnColorCancel(id, 'fire', r, g, b) end,
				'swatchFunc', function(r,g,b) self:OnColorChange(id, 'fire',r,g,b) end
			)
			
			c, d = self:GetColor(id, 'nature')
			if not d then title = "|cffeda55f"..self.loc.nature.."|r" else title = self.loc.nature end
			dewdrop:AddLine(
				'text', title,
				'hasColorSwatch', true,
				'r', c.r,
				'g', c.g,
				'b', c.b,
				'notCheckable', true,
				'cancelFunc', function(r,g,b) self:OnColorCancel(id, 'nature', r, g, b) end,
				'swatchFunc', function(r,g,b) self:OnColorChange(id, 'nature',r,g,b) end
			)
			
			c, d = self:GetColor(id, 'frost')
			if not d then title = "|cffeda55f"..self.loc.frost.."|r" else title = self.loc.frost end
			dewdrop:AddLine(
				'text', title,
				'hasColorSwatch', true,
				'r', c.r,
				'g', c.g,
				'b', c.b,
				'notCheckable', true,
				'cancelFunc', function(r,g,b) self:OnColorCancel(id, 'frost', r, g, b) end,
				'swatchFunc', function(r,g,b) self:OnColorChange(id, 'frost',r,g,b) end
			)
			
			c, d = self:GetColor(id, 'shadow')
			if not d then title = "|cffeda55f"..self.loc.shadow.."|r" else title = self.loc.shadow end
			dewdrop:AddLine(
				'text', title,
				'hasColorSwatch', true,
				'r', c.r,
				'g', c.g,
				'b', c.b,
				'notCheckable', true,
				'cancelFunc', function(r,g,b) self:OnColorCancel(id, 'shadow', r, g, b) end,
				'swatchFunc', function(r,g,b) self:OnColorChange(id, 'shadow',r,g,b) end
			)
			
			c, d = self:GetColor(id, 'arcane')
			if not d then title = "|cffeda55f"..self.loc.arcane.."|r" else title = self.loc.arcane end
			dewdrop:AddLine(
				'text', title,
				'hasColorSwatch', true,
				'r', c.r,
				'g', c.g,
				'b', c.b,
				'notCheckable', true,
				'cancelFunc', function(r,g,b) self:OnColorCancel(id, 'arcane', r, g, b) end,
				'swatchFunc', function(r,g,b) self:OnColorChange(id, 'arcane',r,g,b) end
			)
			

			dewdrop:AddLine()
		
			dewdrop:AddLine(
				'text', self.loc.option_defaultColor,
				'notCheckable', true,
				'func', function() self:RestoreDefaultColors(id) end
			)
			
	
		elseif value == 'filter' then

			local title = self.loc.tooltip_nameFilterTitle
			local desc = self.loc.tooltip_nameFilterDescription
			
			for i, v in self.filterList do
				if v == '' then
					dewdrop:AddLine()
					title = self.loc.tooltip_typeFilterTitle
					desc = self.loc.tooltip_typeFilterDescription
				else
					dewdrop:AddLine(
						'text', self.loc[v],
						'tooltipTitle', title,
						'tooltipText', desc,
						'func', function(id, filter) self.savedVars[id].filters[filter] = not self.savedVars[id].filters[filter] end,
						'arg1', id,
						'arg2', v,
						'checked', not self.savedVars[id].filters[v]
					)
				end
			end

					
		elseif value == 'event' then
		
			for i, v in ipairs(self.eventCats) do
				dewdrop:AddLine(
					'text', self.loc[v],
					'tooltipTitle', self.loc.tooltip_eventTitle,
					'tooltipText', self.loc.tooltip_eventDescription,
					'func', 
					function(id, eventCat) 
						self.savedVars[id].events[eventCat] = not self.savedVars[id].events[eventCat]
						self:RefreshSettings() 
					end,
					'arg1', id,
					'arg2', v,
					'checked', self.savedVars[id].events[v]
				)
				i = next(self.eventCats, i)
			end

	elseif value == 'format' then
			
			local msgType, formats, isDefault
			
			for i, v in ipairs(self.formats) do
				msgType = v
				formats, isDefault = self:GetFormat(id, v)
				if not isDefault then msgType = "|cffeda55f"..msgType.."|r" end
				dewdrop:AddLine(
					'text', string.format("%s = '%s'", msgType, formats),
					'notCheckable', true,
					'tooltipTitle', "Token Sequence for " .. v,
					'tooltipText', self.formatTooltips[v],
					'func', self.LoadEditBox,
					'arg1', self,
					'arg2', id,
					'arg3', v
				)
				i = next(self.formats, i)
			end
			dewdrop:AddLine()
			dewdrop:AddLine(
				'text', self.loc.option_defaultFormat,
				'notCheckable', true,
				'func', function() self:RestoreDefaultFormats(id) end
			)
					
		end
	end


end



function SimpleCombatLog:OnColorChange(id, item, r,g,b)

	if not self.savedVars[id].colors[item] then self.savedVars[id].colors[item] = {} end
	
	self.savedVars[id].colors[item].r = r
	self.savedVars[id].colors[item].g = g
	self.savedVars[id].colors[item].b = b
end

function SimpleCombatLog:OnColorCancel(id, item, r, g, b)

	if self.defaultColors[item].r == r 
	and self.defaultColors[item].g == g
	and self.defaultColors[item].b == b then
		self.savedVars[id].colors[item] = nil
	else
		self.savedVars[id].colors[item].r = r
		self.savedVars[id].colors[item].g = g
		self.savedVars[id].colors[item].b = b
	end
		

end

function SimpleCombatLog:InitSavedVars(id)

	self.savedVars[id] = {}
	self.savedVars[id].colors = {}
	self.savedVars[id].filters = {}
	self.savedVars[id].events = {}
	self.savedVars[id].formats = {}
	
end


function SimpleCombatLog:LoadCommonSettings(id)
	self:Print("ChatFrame"..id..": "..self.loc.message_loadCommon)
	self:InitSavedVars(id)
	self.savedVars[id].filters.party = true
	self.savedVars[id].filters.raid = true
	self.savedVars[id].filters.target = true
	self.savedVars[id].filters.other = true
	self.savedVars[id].deathIgnore = true
	self.savedVars[id].suppress = true
	
	
	for i, v in ipairs(self.eventCats) do
		if v ~= 'fail' then
			self.savedVars[id].events[v] = true
		end
		i = next(self.eventCats, i)
	end
	--self.needRefreshChatEvent = true	
	self:RefreshSettings()
end
function SimpleCombatLog:RestoreDefaultColors(id)
	self:Print("ChatFrame"..id..": "..self.loc.message_defaultColor)
	self.savedVars[id].colors = {}
end
function SimpleCombatLog:RestoreDefaultFormats(id)
	self:Print("ChatFrame"..id..": "..self.loc.message_defaultFormat)
	self.savedVars[id].formats = {}
end

function SimpleCombatLog:LoadSimpleMode()
	SCL_Config = {}
	self.savedVars = SCL_Config
	self:LoadCommonSettings(2)
end

function SimpleCombatLog:Reformat(id, msgType, msgFormat)
	self.savedVars[id].formats[msgType] = msgFormat
end
function SimpleCombatLog:ClearSettings(id)
	self:Print("ChatFrame"..id..": "..self.loc.message_clearSetting)
	if not self.savedVars[id] then return end
	self.savedVars[id].events = {}
	self:RefreshSettings()
	self.savedVars[id] = nil
end

if not GetParser then function GetParser() 	return parser end end

