--[[
Spell Alert
        Author:         Awen
        Thanks:			Quu (Code contribution)
                        Cyron (German Translation)
        Version:        3.0
        Change Log :  
        	2005.06.20 Spams (trivial spells) are largely reduced
        			   Alerts can be filtered by healing spells, CC spells, dispelable abilities and other abilities
        			   German Translation	
        	2005.06.12 Add "Target Only" option and bug fixes.
        	2005.05.31 Retarget after Hunter's FD
        	2005.05.31 Retarget after Polymorph
        	2005.05.21 Retarget after Core Hound's Ancient Despair
        	2005.05.17 Retarget after Onyxia's Bellowing Roar.
        	2005.05.17 Fixed a bug affecting retarget
        	2005.05.17 Added alerts when "Will of Forsaken" & "Berserker Rage" fade from the hostile unit
        	2005.05.16 Option dialog.
        	2005.05.16 Alert color is customizable
        	2005.05.05 Added many missed alerts
        	2005.05.14 Retarget after Fear/Scatter Shot
        	2005.05.14 Bug fixes
        	2005.05.14 Alerts now in a separate window other than the Error window
        	2005.05.09 Warnings of Onyxia Deep Breath & Living Bomb
            2005.04.07 Rejuvenation should not warned       

	    2005.03.30 Add Option 'Soulstone Announce'.

	    2005.03.29 Support totem casting.
                       Party casting is no longer warned.
        	2005.03.21 "Renew" & "Regrowth" are no longer warned.

]]
-- Configuration variables  Spell_Fire_Incinerate

sa_on = 1;
sa_announce = 1;
sa_color = {r=1, g=1, b=1};
sa_emote_on = 1;
sa_warning_on = 1;
sa_retarget_on = 1;
sa_targetonly = nil;
sa_heals = 1;
sa_cc = 1;
sa_dispelable = 1;
sa_damage = 1;
sa_misc = 1;
sa_debug = nil;

-- Local variables

local sa_targetName = nil;
local sa_targetClass = nil;
local sa_targetHostile = nil;
local sa_color_prev = {};
local sa_gains = {};
--local sa_archimonde = nil;

function SpellAlert_OnLoad()
	this:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE");
	this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS");
	this:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_CREATURE_BUFF");
	this:RegisterEvent("CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE");
	this:RegisterEvent("CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF");
	this:RegisterEvent("CHAT_MSG_SPELL_AURA_GONE_SELF");
	this:RegisterEvent("CHAT_MSG_MONSTER_EMOTE");
	this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE");
	this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS");
	this:RegisterEvent("CHAT_MSG_SPELL_AURA_GONE_OTHER");

--[[
	RegisterForSave("sa_on");
	RegisterForSave("sa_color");
	RegisterForSave("sa_emote_on");
	RegisterForSave("sa_warning_on");
	RegisterForSave("sa_retarget_on");
	RegisterForSave("sa_targetonly");
	RegisterForSave("sa_heals");
	RegisterForSave("sa_cc");
	RegisterForSave("sa_dispelable");
	RegisterForSave("sa_misc");
	RegisterForSave("sa_damage");
	RegisterForSave("sa_debug");
]]
--[[	if (GetCVar("realmName") == "아키몬드") then
		sa_archimonde = 1;
	end]]

	if (Cosmos_RegisterConfiguration) then
		SpellAlert_CosmosRegisterOptions();
	else
		SlashCmdList["SpellAlertCOMMAND"] = SpellAlertHandler;
		SLASH_SpellAlertCOMMAND1 = "/spellalert";
		SpellAlert_print("SpellAlert 3.0 by Awen. Type /spellalert for options.")
	end
end

function SpellAlert_CosmosRegisterOptions()
	Cosmos_RegisterConfiguration(
		"COS_SA",
		"SECTION",
		SA_SEP,
		SA_SEP_INFO
	);
	Cosmos_RegisterConfiguration(
		"COS_SA_SECTION",
		"SEPARATOR",
		SA_SEP,
		SA_SEP_INFO
	);
	Cosmos_RegisterConfiguration(
		"COS_SA_ENABLE",
		"CHECKBOX",
		SA_ENABLE,
		SA_ENABLE_INFO,
		SA_Toggle,
		sa_on
	);
	Cosmos_RegisterConfiguration(
		"COS_SA_TARGETONLY",
		"CHECKBOX",
		SA_TARGETONLY,
		SA_TARGETONLY_INFO,
		SA_ToggleTargetonly,
		sa_targetonly
	);
	Cosmos_RegisterConfiguration(
		"COS_SA_HEALING",
		"CHECKBOX",
		SA_HEALING,
		SA_HEALING_INFO,
		SA_ToggleHealing,
		sa_heals
	);
	Cosmos_RegisterConfiguration(
		"COS_SA_CC",
		"CHECKBOX",
		SA_CC,
		SA_CC_INFO,
		SA_ToggleCC,
		sa_cc
	);
	Cosmos_RegisterConfiguration(
		"COS_SA_DISPEL",
		"CHECKBOX",
		SA_DISPEL,
		SA_DISPEL_INFO,
		SA_ToggleDispel,
		sa_dispelable
	);
	Cosmos_RegisterConfiguration(
		"COS_SA_DAMAGE",
		"CHECKBOX",
		SA_DAMAGE,
		SA_DAMAGE_INFO,
		SA_ToggleDamage,
		sa_damage
	);
	Cosmos_RegisterConfiguration(
		"COS_SA_MISC",
		"CHECKBOX",
		SA_MISC,
		SA_MISC_INFO,
		SA_ToggleMisc,
		sa_misc
	);
	Cosmos_RegisterConfiguration(
		"COS_SA_SOULSTONE",
		"CHECKBOX",
		SA_SOULSTONE,
		SA_SOULSTONE_INFO,
		SA_ToggleAnnounce,
		sa_announce
	);
	Cosmos_RegisterConfiguration(
		"COS_SA_EMOTE",
		"CHECKBOX",
		SA_EMOTE,
		SA_EMOTE_INFO,
		SA_ToggleEmote,
		sa_emote_on
	);
	Cosmos_RegisterConfiguration(
		"COS_SA_COLOR",
		"BUTTON",
		SA_COLOR, 
		SA_COLOR_INFO,
		SA_SetTextColor,
		0,
		0,
		0,
		0,
		SA_COLOR_BUTTONTEXT
	);
end

function SpellAlert_OnEvent()
	if (event == "CHAT_MSG_SPELL_AURA_GONE_SELF") then
		if (sa_announce == 0) then
			return;
		end
		if ( string.find(arg1, "영혼석 부활 효과가 사라졌습니다.") ) then
			if ( GetNumRaidMembers() > 0 ) then
				SendChatMessage("영혼석이 사라졌습니다. 영혼석을 걸어주세요!", "RAID");
			elseif ( UnitInParty("player") ) then
				SendChatMessage("영혼석이 사라졌습니다. 영혼석을 걸어주세요!", "PARTY");
			end
		end
	end
	if (sa_on == 0) then
		return;
	end

	local mob, spell;
	if (event == "CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE") then
		for mob, spell in string.gmatch(arg1, SA_PTN_SPELL_BEGIN_CAST) do
			if (not SpellAlert_isParty(mob)) then
				SpellAlert_alert(mob, spell, arg1);
			end
			return;
		end
	elseif (event == "CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF") then
		for mob, spell, k in string.gmatch(arg1, SA_PTN_SPELL_GAINS_X) do
			return;
		end
		for mob, spell in string.gmatch(arg1, SA_PTN_SPELL_BEGIN_CAST) do
			if (not SpellAlert_isParty(mob)) then
				SpellAlert_alert(mob, spell, arg1);
			end
			return;
		end
		for mob, spell in string.gmatch(arg1, SA_PTN_SPELL_TOTEM) do
			if (not SpellAlert_isParty(mob)) then
				SpellAlert_alert(mob, spell, arg1);
			end
			return;
		end
		for mob, spell in string.gmatch(arg1, SA_PTN_SPELL_GAINS) do
			SpellAlert_alert(mob, spell, arg1);
			return;
		end
	elseif (event == "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_BUFF") then
		for mob, spell in string.gmatch(arg1, SA_PTN_SPELL_BEGIN_CAST) do
			SpellAlert_alert(mob, spell, arg1);
			return;
		end
	elseif (event == "CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS") then
		for mob, spell, k in string.gmatch(arg1, SA_PTN_SPELL_GAINS_X) do
			return;
		end
		for mob, spell in string.gmatch(arg1, SA_PTN_SPELL_GAINS) do
			SpellAlert_alert(mob, spell, arg1);
			return;
		end
	elseif (event == "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE") then
		for mob, spell in string.gmatch(arg1, SA_PTN_SPELL_BEGIN_CAST) do
			SpellAlert_alert(mob, spell, arg1);
			return;
		end
	elseif (event == "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS") then
		for mob, spell, temp in string.gmatch(arg1, SA_PTN_SPELL_GAINS_X) do
			return;
		end
		for mob, spell in string.gmatch(arg1, SA_PTN_SPELL_GAINS) do
			if ( (spell == SA_WOTF) or
			     (spell == SA_BERSERKER_RAGE) ) then
				sa_gains[mob] = {};
				sa_gains[mob].spell = spell;
				sa_gains[mob].time = GetTime();
			end
			SpellAlert_alert(mob, spell, arg1);
			return;
		end
	elseif (event == "CHAT_MSG_SPELL_AURA_GONE_OTHER") then
		for spell, mob in string.gmatch(arg1, SA_PTN_SPELL_FADE) do
			if ( (spell == SA_WOTF) or
			     (spell == SA_BERSERKER_RAGE) ) then
				local tt = sa_gains[mob];
				if (tt) then
					if (tt.spell == spell) then
						if (GetTime() - tt.time <= 30) then
							SpellAlert_alert(mob, spell, arg1);
						end
					end
					tt[mob] = nil;
					return;
				end
			end
		end           
	elseif (event == "CHAT_MSG_EMOTE") then
		if (arg1) then
			if (sa_emote_on == 1) then
				SpellAlert_alert("", "", arg1);
			end
		end
	elseif (event == "CHAT_MSG_MONSTER_EMOTE") then
		local name = arg2;
		if (not name) then
			name = "nil";
		end
		if (arg1) then
			if (sa_emote_on == 1 and name) then
				AlertFrame:AddMessage(string.format(arg1, name), sa_color.r, sa_color.g, sa_color.b, 1, 5);
			else
				SpellAlert_alert(name, arg1, name .. "|1이;가; " .. arg1);
			end
		end
	end
end

function SA_Toggle(toggle)
	if ( toggle == 1 ) then
		sa_on = 1;
	else
		sa_on = 0;
	end
end

function SA_ToggleTargetonly(toggle)
	if ( toggle == 1 ) then
		sa_targetonly = 1;
	else
		sa_targetonly = 0;
	end
end

function SA_ToggleHealing(toggle)
	if ( toggle == 1 ) then
		sa_heals = 1;
	else
		sa_heals = 0;
	end
end

function SA_ToggleCC(toggle)
	if ( toggle == 1 ) then
		sa_cc = 1;
	else
		sa_cc = 0;
	end
end

function SA_ToggleDispel(toggle)
	if ( toggle == 1 ) then
		sa_dispelable = 1;
	else
		sa_dispelable = 0;
	end
end

function SA_ToggleDamage(toggle)
	if ( toggle == 1 ) then
		sa_damage = 1;
	else
		sa_damage = 0;
	end
end

function SA_ToggleMisc(toggle)
	if ( toggle == 1 ) then
		sa_misc = 1;
	else
		sa_misc = 0;
	end
end

function SA_ToggleAnnounce(toggle)
	if ( toggle == 1 ) then
		sa_announce = 1;
	else
		sa_announce = 0;
	end
end

function SA_ToggleEmote(toggle)
	if ( toggle == 1 ) then
		sa_emote_on = 1;
	else
		sa_emote_on = 0;
	end
end

function SA_SetTextColor()
	SpellAlert_OpenColorPicker(this:GetParent());
end

function SpellAlertHandler(msg)
	for i, j in string.gmatch(msg, "test ([%w_]+) (.+)") do
		event = i;
		arg1 = j;
		SpellAlert_test();
		return;
	end
	SpellAlert_OptionsLoad();
	SAOptions:Show();

--[[
	ClearTarget();
	sa_targetHostile = 1;
]]
end

function SpellAlert_alert(mob, spell, msg)
	if (GetLocale()=="koKR") then
		if (SA_SPELLS_IGNORE[spell]) then
			return;
		end
		
		if (sa_heals == 0) then
			if (SA_SPELLS_HEALS[spell] == 1) then
				return;
			end
		end
		
		if (sa_cc == 0) then
			if (SA_SPELLS_CC[spell] == 1) then
				return;
			end
		end
		
		if (sa_dispelable == 0) then
			if (SA_SPELLS_DISPELABLE[spell] == 1) then
				return;
			end
		end
		
		if (sa_damage == 0) then
			if (SA_SPELLS_DAMAGE[spell] == 1) then
				return;
			end
		end
	end
	
	SpellAlert_banner(msg, mob);
end

function SpellAlert_banner(msg, mob)
--[[	if (sa_archimonde) then
		if (mob == "Awen") then
			if (math.random(10) == 7) then
				if (DEFAULT_CHAT_FRAME) then
					DEFAULT_CHAT_FRAME:AddMessage("Awen is upset as you are using her Spell Alert against her.", 1, 0.5, 0.25);
				end
			end
		end
	end]]
	
	
	if (sa_targetonly == 0) then
		--SpellAlert_debug(msg);
		AlertFrame:AddMessage(msg, sa_color.r, sa_color.g, sa_color.b, 1, 5);
	else
		local targetname = UnitName("target");
		if (mob == targetname) then
			--SpellAlert_debug(msg);
			AlertFrame:AddMessage(msg, sa_color.r, sa_color.g, sa_color.b, 1, 5);
		end
	end
end

function SpellAlert_print(msg)
	if (DEFAULT_CHAT_FRAME) then
		DEFAULT_CHAT_FRAME:AddMessage(msg);
	end
end

function SpellAlert_warn(msg)
	if (sa_warning_on == 1) then
		WarningFrame:AddMessage(msg, sa_color.r, sa_color.g, sa_color.b, 1, 5);
	end
end

function SpellAlert_debug(msg)
	if (sa_debug) then
		if (ChatFrame3) then
			msg = "Alert: " .. msg;
			ChatFrame3:AddMessage(msg);
		end
	end
end

function SpellAlert_isParty(name)
	for i = 1, 4, 1 do
		local partyname = UnitName("party" .. i);
		if (name == partyname) then
			return 1;
		end
	end
	return nil;
end

function SpellAlert_test()
	SpellAlert_OnEvent();
end

function SpellAlert_OpenColorPicker(button)
	if ( not button ) then
		button = this;
	end
	if (Cosmos_RegisterConfiguration) then
		ColorPickerFrame.func = SpellAlert_CosmosSetColor;
	else
		ColorPickerFrame.func = SpellAlert_SetColor;
	end
	sa_color_prev.r = sa_color.r;
	sa_color_prev.g = sa_color.g;
	sa_color_prev.b = sa_color.b;
	ColorPickerFrame:SetColorRGB(sa_color.r, sa_color.r, sa_color.r);
	ColorPickerFrame.cancelFunc = SpellAlert_CancelColor;
	if ( CosmosMasterFrame ) then
		CosmosMasterFrame:Hide();
	end
	ColorPickerFrame:Show();
end

function SpellAlert_OptionsClose()
	if ( ColorPickerFrame:IsVisible() ) then
		ColorPickerFrame:Hide();
	end
	sa_on = SpellAlert_Bool2Int(SAOptionsEnable:GetChecked());
	sa_emote_on = SpellAlert_Bool2Int(SAOptionsEmote:GetChecked());
	sa_warning_on = SpellAlert_Bool2Int(SAOptionsWarning:GetChecked());
	sa_targetonly = SpellAlert_Bool2Int(SAOptionsTargetOnly:GetChecked());
	sa_heals = SpellAlert_Bool2Int(SAOptionsHeals:GetChecked());
	sa_cc = SpellAlert_Bool2Int(SAOptionsCC:GetChecked());
	sa_dispelable = SpellAlert_Bool2Int(SAOptionsDispelable:GetChecked());
	sa_misc = SpellAlert_Bool2Int(SAOptionsMisc:GetChecked());
	sa_damage = SpellAlert_Bool2Int(SAOptionsDamage:GetChecked());
	SAOptions:Hide();
end

function SpellAlert_CosmosSetColor()
	SpellAlert_SetColor();
	if(not ColorPickerFrame:IsVisible()) then
		if ( CosmosMasterFrame ) then
			CosmosMasterFrame:Show();
		end
	end
end

function SpellAlert_SetColor()
	local r,g,b = ColorPickerFrame:GetColorRGB();
	local swatch,frame;
	swatch = getglobal("SAColor_NormalTexture");
	swatch:SetVertexColor(r,g,b);
	sa_color.r = r;
	sa_color.g = g;
	sa_color.b = b;
end

function SpellAlert_CancelColor()
	swatch = getglobal("SAColor_NormalTexture");
	sa_color.r = sa_color_prev.r;
	sa_color.g = sa_color_prev.g;
	sa_color.b = sa_color_prev.b;
	swatch:SetVertexColor(sa_color.r, sa_color.g, sa_color.b);
	if ( CosmosMasterFrame ) then
		CosmosMasterFrame:Show();
	end
end

function SpellAlert_OptionsLoad()
	SAOptionsEnable:SetChecked(SpellAlert_Int2Bool(sa_on));
	SAOptionsEmote:SetChecked(SpellAlert_Int2Bool(sa_emote_on));
	SAOptionsWarning:SetChecked(SpellAlert_Int2Bool(sa_warning_on));
	SAOptionsTargetOnly:SetChecked(SpellAlert_Int2Bool(sa_targetonly));
	SAOptionsHeals:SetChecked(SpellAlert_Int2Bool(sa_heals));
	SAOptionsCC:SetChecked(SpellAlert_Int2Bool(sa_cc));
	SAOptionsDispelable:SetChecked(SpellAlert_Int2Bool(sa_dispelable));
	SAOptionsMisc:SetChecked(SpellAlert_Int2Bool(sa_misc));
	SAOptionsDamage:SetChecked(SpellAlert_Int2Bool(sa_damage));
end

function SpellAlert_Bool2Int(val)
	if (val) then
		return 1;
	else
		return 0;
	end
end

function SpellAlert_Int2Bool(val)
	if (val == 0) then
		return nil;
	else
		return 1;
	end
end
