--==================================================
-- Scroll Combat Text - Dennie
-- 修改日期: 2008年4月2日
-- 作者: Dennie、dugu@bigfoot
-- 描述: 提供受到的伤害情况、效果、对敌法术预警等显示
-- 版权所有: 艾泽拉斯国家地理
--==================================================
-- global flags/vars
EVENT_LIST = {["CUSTOMEVENT"] = {},};
DSCTPlayer = nil;
DSCT_NameRegistered = 0;
initCE_OK = false;
local fixfor_sw_stats = true;
local accModeFalg = true;

--UPDATE_FACTION

local DSCT_PLAYER_CLASS = nil;
local DSCT_LastHPPercent = 0;
local DSCT_LastTargetHPPercent = 0;
local DSCT_LastManaPercent = 0;
local DSCT_EventRecord = nil;
DSCT_This = nil;


-- local constants
DSCT_Ani_Fix = {{0,0,1},{0,0,1},{0,0,1}};
DSCT_DIR3_LIST = {{0,0},{100,40},{100,-40},{-100,-40},{-100,40}};

DENNIE_cusMessLast = 1;
DENNIE_CUSMESS_TEXTSIZE = 18;
DENNIE_cusMess_posX = 0;
DENNIE_cusMess_posY = 180;
DENNIE_ani_posX = 0;
DENNIE_ani_posY = 0;
DSCT_HEX_LIST = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"}

SpellAlert_Mob_head = "";
SpellAlert_Spell_head = "";
DSCT_ROTATION_COS = 0;
DSCT_ROTATION_SIN = 0;
DSCT_MESS_TIMER = 4;
DSCT_MESS_FADETIMER = 3;
DSCT_MESS_ALPHAMAX = 1;
DSCT_ANI_SPEED = 1;
DSCT_ANI_TEXTSIZE = 20;
DSCT_ANI_ENTEXTSIZE = 20;
DSCT_ANI_ALPHAMAX = 1;
DSCT_ANI_PARAM1 = 1;
DSCT_ANI_PARAM2 = 1;
DSCT_ENTEXT = 1;
DSCT_CUSTOMEVENT = nil;
DSCT_EventRecord = {};
--Animation System variables
DSCT_LastBar = 1;					-- Holds what the next avalible fontstring for the animation system is
arrAniData = {
		["aniData1"] = {},					-- These are structures that define the animation data
		["aniData2"] = {},
		["aniData3"] = {},
		["aniData4"] = {},
		["aniData5"] = {},
		["aniData6"] = {},
		["aniData7"] = {},
		["aniData8"] = {},
		["aniData9"] = {},
		["aniData10"] = {}
}

arrCusMessData = {
		["cusMessData1"] = {},					-- These are structures that define the animation data
		["cusMessData2"] = {},
		["cusMessData3"] = {}
}

local default_config = {
		["VERSION"] = DSCT_Version,
		["ENABLED"] = 1,
		["ANIMATIONSPEED"] = 1,
		["TEXTSIZE"] = 22,
		["ENTEXTSIZE"] = 22,
		["MESSAGESIZE"] = 16,
		["LOWHP"] = .4,
		["LOWMANA"] = .4,
		["CRITANI"] = 1,
		["SHOWHIT"] = 1,
		["SHOWMISS"] = 1,
		["SHOWDODGE"] = 1,
		["SHOWPARRY"] = 1,
		["SHOWBLOCK"] = 1,
		["SHOWIMMUNE"] = 2,
		["SHOWSPELL"] = 1,
		["SHOWHEAL"] = 1,
		["SHOWRESIST"] = 2,
		["SHOWDEBUFF"] = 2,
		["SHOWBUFF"] = 4,
		["SHOWFADE"] = 4,
		["SHOWABSORB"] = 2,
		["SHOWLOWHP"] = 2,
		["SHOWLOWMANA"] = 2,
		["SHOWPOWER"] = 1,
		["SHOWCOMBATIN"] = 2,
		["SHOWCOMBATOUT"] = 2,
		["SHOWCOMBOPOINTS"] = 3,
		["SHOWHONOR_DSCT"] = 1,
		["SHOWSPELLALERT"] = 4,
		["SHOWEMOTE"] = 4,
		["SHOWYELL"] = 4,
		["SHOWSPELLCRIT"] = 0,
		["SHOWDMGCRIT"] = 0,
		["SHOWCUSTOM"] = 0,
		["SHOWSPELLTIMER"] = 0,
		["ALPHA"] = 1,
		["SHOWSELF"] = 0,
		["ANIMODE"] = 3,
		["FONT"] = 1,
		["ENFONT"] = 1,
		["MESSAGEFONT"] = 3,
		["MESSAGETIMER"] = 4,
		["MESSAGEFADETIMER"] = 3,
		["FONTOUTLINE"] = 1,
		["MESSAGEPOSX"] = 0,
		["MESSAGEPOSY"] = 180,
		["MESSFONTOUTLINE"] = 1,
		["ANIPOSX"] = 0,
		["ANIPOSY"] = 0,
		["MESSAGEALPHA"] = 1,
		["ANIC"] = 10,
		["ROTATION"] = 0,
		["DAMAGETYPE"] = 1,
		["CUSTOMEVENT"] = 0,
		["HEALERNAME"] = 1,
		["ENTEXT"] = 0,
		["SHORTALERT"] = 0,
		["SHOWEXECUTE"] = 4,
		["SHOWSA_BEGINCAST"] = 1,
		["SHOWSA_CAST"] = 1,
		["SHOWSA_GAIN"] = 1,
		["CUSTOM_EVENT_LIST"] = {},
		["ACCMode"] = 0,
		
		["ANIMODE0_Param1"] = 1,
		["ANIMODE0_Param2"] = 1,
		["ANIMODE1_Param1"] = 1,
		["ANIMODE1_Param2"] = 1,
		["ANIMODE2_Param1"] = 1,
		["ANIMODE2_Param2"] = 1,
		["ANIMODE3_Param1"] = 1,
		["ANIMODE3_Param2"] = 1,
		["ANIMODE4_Param1"] = 1,
		["ANIMODE4_Param2"] = 1,
		["ANIMODE5_Param1"] = 1,
		["ANIMODE5_Param2"] = 1,
		["ANIMODE6_Param1"] = 1,
		["ANIMODE6_Param2"] = 1,

		["COLORS"] = {
			["SHOWHIT"] = {	b = 0,g = 0,r = 1,},
			["SHOWMISS"] = {b = 0.8,g = 0.5,r = 0,},
			["SHOWDODGE"] = {
				b = 0.8,
				g = 0.5,
				r = 0,
			},
			["SHOWPARRY"] = {
				b = 0.8,
				g = 0.5,
				r = 0,
			},
			["SHOWBLOCK"] = {
				b = 0.8,
				g = 0.5,
				r = 0,
			},
			["SHOWRESIST"] = {
				b = 0.780392,
				g = 0.388235,
				r = 0.905882,
			},
			["SHOWABSORB"] = {
				b = 0,
				g = 0.85,
				r = 1,
			},
			["SHOWIMMUNE"] = {
				b = 0,
				g = 0.85,
				r = 1,
			},
			["SHOWCOMBATIN"] = {
				b = 0,
				g = 0.7,
				r = 1,
			},
			["SHOWCOMBATOUT"] = {
				b = 0,
				g = 1,
				r = 0,
			},
			["SHOWSPELLCRIT"] = {
				b = 0,
				g = 1,
				r = 1,
			},
			["SHOWLOWHP"] = {
				b = 0.5,
				g = 0.5,
				r = 1,
			},
			["SHOWLOWMANA"] = {
				b = 1,
				g = 0.5,
				r = 0.5,
			},
			["SHOWDMGCRIT"] = {
				b = 1,
				g = 1,
				r = 1,
			},
			["SHOWSPELL"] = {
				b = 1,
				g = 0,
				r = 1,
			},
			["SHOWHEAL"] = {
				b = 0,
				g = 1,
				r = 0,
			},
			["SHOWDEBUFF"] =  {r = 1.0, g = 0.17, b = 0.0},
			["SHOWBUFF"] =  {r = 0, g = 1.0, b = 0},
			["SHOWFADE"] =  {r = 1.0, g = 0.5, b = 0.0},
			["SHOWPOWER"] =  {r = 1.0, g = 1.0, b = 0.0},
			["SHOWCOMBOPOINTS"] =  {r = 0.0, g = 1.0, b = 0.0},
			["SHOWHONOR_DSCT"] =  {r = 1, g = 1, b = 0.0},
			["SHOWEMOTE"] =  {r = 1.0, g = 0.5, b = 0.0},
			["SHOWYELL"] =  {r = 1.0, g = 0.5, b = 0.0},
			["SHOWCUSTOM"] =  {r = 1.0, g = 1.0, b = 0.0},
			["SHOWSPELLALERT"] =  {r = 1.0, g = 1.0, b = 1.0},
			["SPELLALERT_MOB_COLOR"] =  {r = 0.47, g = 1, b = 0.57},
			["SPELLALERT_SPELL_COLOR"] =  {r = 1, g = 0.42, b = 0.32},
			["SHOWEXECUTE"] = {r = 1, g = 1, b = 0},
		}
	};

function DSCT_Debug(...)
	DEFAULT_CHAT_FRAME:AddMessage("SCT DEBUG: ");
	for i=1, select("#", ...) do
		DEFAULT_CHAT_FRAME:AddMessage("==>" .. tostring(select(i, ...)), 1, 1, 1);
	end
end

-- Modified by AndyXiao
-- Modified by dugu@bigfoot - 4/2/2008
function DSCT_Enable(enabled)
	--DSCT_Debug("Toggle Enable")
	if (enabled) then
		DSCT_RegisterEvent("PLAYER_REGEN_ENABLED");
		DSCT_RegisterEvent("PLAYER_REGEN_DISABLED");
		DSCT_RegisterEvent("UNIT_HEALTH");
		DSCT_RegisterEvent("UNIT_MANA");
		DSCT_RegisterEvent("PLAYER_COMBO_POINTS");
		DSCT_RegisterEvent("UNIT_COMBAT");
		DSCT_RegisterEvent("COMBAT_TEXT_UPDATE");
		DSCT_RegisterEvent("PLAYER_CONTROL_LOST");	
		DSCT_RegisterEvent("CHAT_MSG_MONSTER_EMOTE");
		DSCT_RegisterEvent("CHAT_MSG_MONSTER_YELL");
		DSCT_RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
		DSCT_NameRegistered = 1;
	else
		SLASH_DSCTMENU1 = nil;		

		DSCT_UnRegisterEvent("PLAYER_REGEN_ENABLED");
		DSCT_UnRegisterEvent("PLAYER_REGEN_DISABLED");
		DSCT_UnRegisterEvent("UNIT_HEALTH");
		DSCT_UnRegisterEvent("UNIT_MANA");
		DSCT_UnRegisterEvent("PLAYER_COMBO_POINTS");
		DSCT_UnRegisterEvent("UNIT_COMBAT");
		DSCT_UnRegisterEvent("COMBAT_TEXT_UPDATE");
		DSCT_UnRegisterEvent("PLAYER_CONTROL_LOST");
		DSCT_UnRegisterEvent("CHAT_MSG_MONSTER_EMOTE");
		DSCT_UnRegisterEvent("CHAT_MSG_MONSTER_YELL");
		DSCT_UnRegisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
		DSCT_NameRegistered = 0;

		if (DSCTOptions:IsVisible()) then
			HideUIPanel(DCTOptions);
		end
	end
end

--Called when its loaded
function DSCT_OnLoad()	
	--DSCT_Debug("On Load!")
	this:RegisterEvent("ADDON_LOADED");
end

-- Show the Option Menu
function DSCT_showMenu()
	if DSCTOptions then
		PlaySound("igMainMenuOpen");
		ShowUIPanel(DSCTOptions);	
		DSCT_openPreView();
	else
		DSCT_Debug("None Menu");
	end
end

--Hide the Option Menu
function DSCT_hideMenu()
	if DSCTOptions then
		--PlaySound("igMainMenuClose");
		HideUIPanel(DSCTOptions);
		
		--DSCT_RefreshAllEvent();
		DSCT_closePreView();
		DSCT_RefreshStaticVar();
		DSCT_aniInit();--reload with Current Config	
		DSCT_cusMessInit();
	end
end

--Get a clean config
function DSCT_FreshVar()
	DSCT_NEWCONFIG = {};
end

function DSCT_RegisterEvent(event)
	if (DSCT_EventRecord[event]) then
		if DSCT_EventRecord[event] ~= 1 then
			DSCT_This:RegisterEvent(event);
			DSCT_EventRecord[event] = 1;
		end
	else
		DSCT_This:RegisterEvent(event);
		DSCT_EventRecord[event] = 1;
	end
end

function DSCT_UnRegisterEvent(event)	
	DSCT_This:UnregisterEvent(event);
	DSCT_EventRecord[event] = 0;
end

--Set the global player config
function DSCT_Initialize()
	if DSCT_NameRegistered == 1 then return;end
	
	if ( DSCT_NEWCONFIG == nil) then DSCT_FreshVar();end	
	DSCTPlayer = DSCT_Config_GetPlayer();
	
	if DSCT_Get("ENABLED") ~= 1 then return;end
	local playerName = UnitName("player");
	
	if DSCT_Support_NewFont then DSCT_Support_NewFont();end
	
	DSCT_PLAYER_CLASS = UnitClass("player");
	DSCT_PLAYER_GUID = UnitGUID("player");		
	DSCT_This = this;	

	-- Add my options frame to the global UI panel list	
	DSCTOptions:SetAttribute("UIPanelLayout-defined", true);
	DSCTOptions:SetAttribute("UIPanelLayout-enabled", true);
	DSCTOptions:SetAttribute("UIPanelLayout-area", "center");
	DSCTOptions:SetAttribute("UIPanelLayout-pushable", 0);

	-- Add Slash Commands
	SlashCmdList["DSCT"] = function(msg) DSCT_Cmd(msg); end
	SLASH_DSCT1 = "/sct";	
	
	SlashCmdList["DSCTMENU"] = DSCT_showMenu;
	SLASH_DSCTMENU1 = "/sctmenu";	
	
	DSCT_RefreshStaticVar();
	DSCT_aniInit();--reload with Current Config	
	DSCT_cusMessInit();

	--DSCT_Enable(true);

	DSCT_InitCustomEvent();	
	DSCT_NameRegistered = 1;
end	

function DSCT_RefreshStaticVar()
	local tmp = DSCT_nGetColor("SPELLALERT_MOB_COLOR");
	SpellAlert_Mob_head = DSCT_ColorFlip(tmp.r,tmp.g,tmp.b);
	tmp = DSCT_nGetColor("SPELLALERT_SPELL_COLOR");
	SpellAlert_Spell_head = DSCT_ColorFlip(tmp.r,tmp.g,tmp.b);
	DSCT_ROTATION_SIN = sin(360 - DSCT_Get("ROTATION"));
	DSCT_ROTATION_COS = cos(360 - DSCT_Get("ROTATION"));
	
	DSCT_MESS_TIMER = DSCT_Get("MESSAGETIMER");
	DSCT_MESS_FADETIMER = DSCT_Get("MESSAGEFADETIMER");
	DSCT_MESS_ALPHAMAX = DSCT_Get("MESSAGEALPHA");
	DSCT_ANI_SPEED = DSCT_Get("ANIMATIONSPEED");
	DSCT_ANI_TEXTSIZE = DSCT_Get("TEXTSIZE");
	DSCT_ANI_ENTEXTSIZE = DSCT_Get("ENTEXTSIZE");
	DSCT_ANI_ALPHAMAX = DSCT_Get("ALPHA");
	DSCT_ENTEXT = DSCT_Get("ENTEXT") + 1;
	
	DENNIE_cusMess_posX = DSCT_Get("MESSAGEPOSX");
	DENNIE_cusMess_posY = DSCT_Get("MESSAGEPOSY");
	DENNIE_ani_posX = DSCT_Get("ANIPOSX");
	DENNIE_ani_posY = DSCT_Get("ANIPOSY");
	
	local paramList = {[0]={1,1},[1]={1,1},[2]={1,1},[3]={1,1},[4]={1,1},[5]={1,1},[6]={1,1}};
	for i = 0,6 do
		paramList[i][1] = DSCT_Get("ANIMODE"..i.."_Param1");
		paramList[i][2] = DSCT_Get("ANIMODE"..i.."_Param2");
	end
	
	DSCT_ANI_PARAM1 = paramList[DSCT_Get("ANIMODE")][1];
	DSCT_ANI_PARAM2 = paramList[DSCT_Get("ANIMODE")][2];
	
	DSCT_CUSTOMEVENT = DSCT_Get("CUSTOM_EVENT_LIST");
end

--Get or Create a config based on the current player
function DSCT_Config_GetPlayer()
	if (DSCT_NEWCONFIG[UnitName("player").." of "..GetCVar("realmName")] == nil) then
		DSCT_Config_NewPlayer(UnitName("player").." of "..GetCVar("realmName"));
	end
	return DSCT_NEWCONFIG[UnitName("player").." of "..GetCVar("realmName")];
end

--Set up a default config
function DSCT_Config_NewPlayer(PlayerName)
	DSCT_NEWCONFIG[PlayerName] = DSCT_clone(default_config);
end

--Copy a whole table
function DSCT_clone(t)             -- return a copy of the table t
  local new = {};             -- create a new table
  local i, v = next(t, nil);  -- i is an index of t, v = t[i]
  while i do
  	if type(v)=="table" then 
  		v=DSCT_clone(v);
  	end 
    new[i] = v;
    i, v = next(t, i);        -- get next index
  end
  return new;
end

function DSCT_Load(config)
	DSCT_NEWCONFIG[UnitName("player").." of "..GetCVar("realmName")] = nil;
	DSCT_NEWCONFIG[UnitName("player").." of "..GetCVar("realmName")] = DSCT_clone(config);
	DSCTPlayer = DSCT_Config_GetPlayer();
	
	DSCT_AddCustomEventToPlayer();
	DSCT_aniInit();
	DSCT_cusMessInit();		
	DSCT_RefreshStaticVar();
end
--Reset everything to default
function DSCT_Reset()
	DSCT_Load(default_config);
	DSCT_hideMenu();
	DSCT_showMenu();
end

--Get a value from player config
function DSCT_Get(option)
	if (DSCTPlayer ~= nil) and (DSCTPlayer[option]) then
		return DSCTPlayer[option];
	else
		if default_config[option] then
			return default_config[option];
		else
			return nil;
		end
	end
end

----------------------
--Set a value in player config
function DSCT_Set(option, newVal)
	if (DSCTPlayer ~= nil) then
		if ( option ) then
			DSCTPlayer[option] = newVal;			
		end
	end
end

----------------------
--Get a color in the player config
function DSCT_nGetColor(key)
	local color = {r = 1.0, g = 1.0, b = 1.0};	
	if (DSCTPlayer ~= nil) and (DSCTPlayer["COLORS"][key] ~= nil) then
		color.r = DSCTPlayer["COLORS"][key].r;
		color.g = DSCTPlayer["COLORS"][key].g;
		color.b = DSCTPlayer["COLORS"][key].b;		
	else
		if default_config["COLORS"][key] ~= nil then
			color.r = default_config["COLORS"][key].r;
			color.g = default_config["COLORS"][key].g;
			color.b = default_config["COLORS"][key].b;
		else
			DSCT_Debug("DSCT_Debug:"..key);
		end		
	end
	return color;
end
function DSCT_GetColor(key)
	return {r = 1.0, g = 1.0, b = 1.0};
end
----------------------
--Set a color in the player config
function DSCT_SetColor(key, r, g, b)
	if (DSCTPlayer ~= nil) and (DSCTPlayer["COLORS"][key] ~= nil) then
		DSCTPlayer["COLORS"][key].r = r;
		DSCTPlayer["COLORS"][key].g = g;
		DSCTPlayer["COLORS"][key].b = b;
	else
		local color = {r = 1.0, g = 1.0, b = 1.0};
		color.r = default_config["COLORS"][key].r;
		color.g = default_config["COLORS"][key].g;
		color.b = default_config["COLORS"][key].b;
		DSCTPlayer["COLORS"][key] = color;
	end
end

----------------------
-- Event Handler
-- this function parses events that are printed in the combat
-- chat window then displays the health changes
function DSCT_OnEvent(...)
	if (event == "ADDON_LOADED" and arg1 == "sct") then	
		--DSCT_Debug(event)
		DSCT_Initialize();
		return;
	end
	if DSCT_NameRegistered == 0 then		
		return;
	end
	if DSCT_Get("ENABLED") == 0 then return;end

	if event == "UNIT_HEALTH" then		
		if (arg1 == "player" and DSCT_Get("SHOWLOWHP") ~= 0 and DSCT_NameRegistered == 1) then
			local warnlevel = DSCT_Get("LOWHP");
			local HPPercent = UnitHealth("player") / UnitHealthMax("player");
			if (HPPercent < warnlevel) and (DSCT_LastHPPercent >= warnlevel) then
				local txt = (DSCT_Get("LOWHP") *100).."%";
				txt = string.sub(txt,1,2);
				if DSCT_ENTEXT == 2 then
					DSCT_Display_Toggle("SHOWLOWHP",2,DSCT_LowHP[DSCT_ENTEXT]..UnitHealth("player").."* <"..txt.."%");
				else
					DSCT_Display_Toggle("SHOWLOWHP",3,UnitHealth("player").."* <"..txt.."%",DSCT_LowHP[DSCT_ENTEXT]);
				end
			end
			DSCT_LastHPPercent = HPPercent;
		end
		return;	
	elseif event == "UNIT_MANA" then
		if arg1 == "player" and DSCT_Get("SHOWLOWMANA") ~= 0 and DSCT_NameRegistered == 1 and UnitPowerType("player")== 0 then
			local warnlevel = DSCT_Get("LOWMANA");
			local ManaPercent = UnitMana("player") / UnitManaMax("player");
			if (ManaPercent < warnlevel) and (DSCT_LastManaPercent >= warnlevel) then
				local txt = (DSCT_Get("LOWMANA") *100).."%";
				txt = string.sub(txt,1,2);
				if DSCT_ENTEXT == 2 then
					DSCT_Display_Toggle("SHOWLOWMANA",2,DSCT_LowMana[DSCT_ENTEXT]..UnitMana("player").."* <"..txt.."%");
				else
					DSCT_Display_Toggle("SHOWLOWMANA",3,UnitMana("player").."* <"..txt.."%",DSCT_LowMana[DSCT_ENTEXT]);
				end
			end
			DSCT_LastManaPercent = ManaPercent;
		end
		return;
	elseif event =="PLAYER_REGEN_DISABLED" then
		if DSCT_Get("SHOWCOMBATIN") ~= 0 then
			--PlaySoundFile("Sound\\Doodad\\BellTollNightElf.wav");
			DSCT_Display_Toggle("SHOWCOMBATIN",DSCT_ENTEXT,DSCT_Combat[DSCT_ENTEXT]);		
		end
		return;
	elseif event =="PLAYER_REGEN_ENABLED" then
		if DSCT_Get("SHOWCOMBATOUT") ~= 0 then			
			DSCT_Display_Toggle("SHOWCOMBATOUT",DSCT_ENTEXT,DSCT_NoCombat[DSCT_ENTEXT]);		
		end
		return;
	elseif event == "PLAYER_COMBO_POINTS" then
		if DSCT_Get("SHOWCOMBOPOINTS") ~= 0 then
			local DSCT_CP = GetComboPoints();
			if (DSCT_CP ~= 0) then				
				if (DSCT_CP == 5) then
					DSCT_Display_Toggle("SHOWCOMBOPOINTS",DSCT_ENTEXT,DSCT_CP,DSCT_FiveCPMessage[DSCT_ENTEXT]);
				else
					DSCT_Display_Toggle("SHOWCOMBOPOINTS",DSCT_ENTEXT,DSCT_CP,DSCT_ComboPoint[DSCT_ENTEXT]);
				end;				
			end
		end
		return;
	elseif (event == "UNIT_COMBAT") then
		local critical = (arg3 and arg3 == "CRITICAL") and 1 or 0;
		
		if (arg1 == "player" and arg2 == "WOUND" and (arg4 and arg4 ~= 0))then			
			if (arg5 and arg5 > 1) then
				if (DSCT_Get("SHOWSPELL") ~= 0) then
					if DSCT_Get("DAMAGETYPE") == 1 then
						DSCT_Display_Toggle("SHOWSPELL",DSCT_ENTEXT,"-"..arg4.."  ",sct_spelltypes[arg5][DSCT_ENTEXT] or "" , critical);
					else
						DSCT_Display_Toggle("SHOWSPELL",2,"-"..arg4,nil, critical);
					end
				end
			else
				if (DSCT_Get("SHOWHIT") ~= 0) then
					DSCT_Display_Toggle("SHOWHIT",2,"-"..arg4 ,nil, critical);
				end
			end			
			return;
		end
	elseif (event == "COMBAT_TEXT_UPDATE") then
		local _type, data = arg1,  arg2;	
		--[[if (_type == "DAMAGE" and  DSCT_Get("SHOWHIT") ~= 0) then
			DSCT_Display_Toggle("SHOWHIT",2,"-"..data ,nil, nil);
		elseif (_type == "SPELL_DAMAGE" and DSCT_Get("SHOWSPELL") ~= 0) then
			if DSCT_Get("DAMAGETYPE") == 1 then
				DSCT_Display_Toggle("SHOWSPELL",DSCT_ENTEXT,"-"..data.."  ",nil , nil);
			else
				DSCT_Display_Toggle("SHOWSPELL",2,"-"..data,nil, nil);
			end
		
		elseif (_type == "DAMAGE_CRIT" and DSCT_Get("SHOWHIT") ~= 0) then
			if DSCT_ENTEXT == 1 then
				DSCT_Display_Toggle("SHOWDMGCRIT",3,data,DSCT_CRIT[DSCT_ENTEXT]);
			else
				DSCT_Display_Toggle("SHOWDMGCRIT",2,data,DSCT_CRIT[DSCT_ENTEXT]);
			end
		elseif (_type == "SPELL_DAMAGE_CRIT" and DSCT_Get("SHOWSPELL") ~= 0) then
			DSCT_Display_Toggle("SHOWSPELLCRIT",3,data,DSCT_CRIT[DSCT_ENTEXT].." ");
		]]
		if (_type == "HONOR_GAINED" and DSCT_Get("SHOWHONOR_DSCT") ~= 0 and data > 0) then
			DSCT_Display_Toggle("SHOWHONOR_DSCT",DSCT_ENTEXT,"+"..data.." ",DSCT_Honor[DSCT_ENTEXT]);
		elseif ((_type == "MANA" or _type == "RAGE" --[[or _type == "FOCUS"]] or _type == "ENERGY") and DSCT_Get("SHOWPOWER") ~= 0) then
			if (tonumber(data) > 0) then
				local id = 1;
				id = (_type == "ENERGY") and 2 or id;
				id = (_type == "RAGE") and 3 or id;				
				DSCT_Display_Toggle("SHOWPOWER",DSCT_ENTEXT,"+"..tostring(data),DSCT_PowerList[id][DSCT_ENTEXT]);
			end
		elseif (_type == "FACTION" and DSCT_Get("SHOWHONOR_DSCT") ~= 0) then
			if (tonumber(arg3) > 0) then
				DSCT_Display_Toggle("SHOWHONOR_DSCT",DSCT_ENTEXT,"+"..tonumber(arg3).." ",data);
			end
		elseif (_type == "SPELL_AURA_START" and DSCT_Get("SHOWBUFF") ~= 0) then
			DSCT_Display_Toggle("SHOWBUFF",1,nil,DSCT_YOU_GAIN_UNM..data.."*", 0, DSCT_YOU_GAIN..data);
		elseif (_type == "SPELL_AURA_START_HARMFUL"  and DSCT_Get("SHOWDEBUFF") ~= 0) then
			DSCT_Display_Toggle("SHOWDEBUFF",1,nil,"「"..data.."」",0,format(DSCT_AFFLICTED_BY, data));
		elseif ((_type == "SPELL_AURA_END" or _type== "SPELL_AURA_END_HARMFUL") and DSCT_Get("SHOWFADE") ~= 0) then
			DSCT_Display_Toggle("SHOWFADE",1,nil,DSCT_YOU_FADE_UNM..data.."*",0, DSCT_YOU_FADE..data);	
		elseif ((_type == "HEAL" or _type== "PERIODIC_HEAL") and DSCT_Get("SHOWHEAL") ~= 0) then
			if (UnitName("player") == data) then
				DSCT_Display_Toggle("SHOWHEAL",2,"+"..arg3);				
			else
				if (DSCT_Get("HEALERNAME") ~= 0) then
					DSCT_Display_Toggle("SHOWHEAL",2,"+"..arg3.." ["..data.."]");
				else
					DSCT_Display_Toggle("SHOWHEAL",2,"+"..arg3);
				end				
			end			
		elseif (_type == "HEAL_CRIT" and DSCT_Get("SHOWHEAL") ~= 0) then
			if (UnitName("player") == data) then
				DSCT_Display_Toggle("SHOWHEAL",2,"+"..arg3,nil,1);
			else
				if (DSCT_Get("HEALERNAME") ~= 0) then
					DSCT_Display_Toggle("SHOWHEAL",2,"+"..arg3.." ["..data.."]",nil,1);
				else
					DSCT_Display_Toggle("SHOWHEAL",2,"+"..arg3,nil,1);
				end				
			end
		elseif ((_type == "RESIST" or _type == "SPELL_RESISTED") and DSCT_Get("SHOWRESIST") ~= 0) then			
			DSCT_Display_Toggle("SHOWRESIST",DSCT_ENTEXT,DSCT_ResistMsg[DSCT_ENTEXT]);
		elseif ((_type == "MISS" or _type == "SPELL_MISS") and DSCT_Get("SHOWMISS") ~= 0) then
			DSCT_Display_Toggle("SHOWMISS",DSCT_ENTEXT,DSCT_MissMsg[DSCT_ENTEXT]);
		elseif ((_type == "DODGE" or _type == "SPELL_DODGE") and DSCT_Get("SHOWDODGE") ~= 0) then
			DSCT_Display_Toggle("SHOWDODGE",DSCT_ENTEXT,DSCT_DodgeMsg[DSCT_ENTEXT]);
		elseif ((_type == "PARRY" or _type == "SPELL_PARRY") and DSCT_Get("SHOWPARRY") ~= 0) then
			DSCT_Display_Toggle("SHOWPARRY",DSCT_ENTEXT,DSCT_ParryMsg[DSCT_ENTEXT]);
		elseif ((_type == "EVADE" or _type == "SPELL_EVADE") and DSCT_Get("SHOWMISS") ~= 0) then
			DSCT_Display_Toggle("SHOWMISS",DSCT_ENTEXT,DSCT_EvadeMsg[DSCT_ENTEXT]);
		elseif ((_type == "IMMUNE" or _type == "SPELL_IMMUNE") and DSCT_Get("SHOWIMMUNE") ~= 0) then
			DSCT_Display_Toggle("SHOWIMMUNE",DSCT_ENTEXT,DSCT_ImmuneMsg[DSCT_ENTEXT]);	
		elseif ((_type == "DEFLECT" or _type == "SPELL_DEFLECT") and DSCT_Get("SHOWRESIST") ~= 0) then
			DSCT_Display_Toggle("SHOWRESIST",DSCT_ENTEXT,DSCT_DeflectMsg[DSCT_ENTEXT]);
		elseif ((_type == "REFLECT" or _type == "SPELL_REFLECT") and DSCT_Get("SHOWRESIST") ~= 0) then
			DSCT_Display_Toggle("SHOWRESIST",DSCT_ENTEXT,DSCT_ReflectMsg[DSCT_ENTEXT]);	
		elseif ((_type == "ABSORB" or _type == "SPELL_ABSORBED") and DSCT_Get("SHOWABSORB") ~= 0) then
			if (arg3) then
				DSCT_Display_Toggle("SHOWABSORB",DSCT_ENTEXT,arg3.." *",DSCT_AbsorbMsg[DSCT_ENTEXT]);
			else
				DSCT_Display_Toggle("SHOWABSORB",DSCT_ENTEXT,DSCT_AbsorbMsg[DSCT_ENTEXT]);
			end
		elseif ((_type == "BLOCK" or _type == "SPELL_BLOCKED") and DSCT_Get("SHOWBLOCK") ~= 0) then
			if (arg3) then
				DSCT_Display_Toggle("SHOWBLOCK",DSCT_ENTEXT,arg3.." *",DSCT_BlockMsg[DSCT_ENTEXT]);
			else
				DSCT_Display_Toggle("SHOWBLOCK",DSCT_ENTEXT,DSCT_BlockMsg[DSCT_ENTEXT]);
			end
		elseif (_type == "SPELL_ACTIVE" and DSCT_Get("SHOWEXECUTE") ~= 0) then
			DSCT_Display_Toggle("SHOWEXECUTE", 1, data);
		end	
		return;	
	elseif (event == "COMBAT_LOG_EVENT_UNFILTERED") then
		-- 该事件处处理自定义事件、法术预警事件以及一些特殊情况。
		local evt, srcGUID = select(2, ...);
		--local amount, critcal = 0, false;
		if (srcGUID == DSCT_PLAYER_GUID) then
			if ((evt == "RANGE_DAMAGE" or evt == "SWING_DAMAGE") and select(14, ...) and DSCT_Get("SHOWDMGCRIT") ~= 0) then
				local amount = select(9, ...) or 0;				
				if (DSCT_ENTEXT == 1) then
					DSCT_Display_Toggle("SHOWDMGCRIT",3,amount,DSCT_CRIT[DSCT_ENTEXT]);
				else
					DSCT_Display_Toggle("SHOWDMGCRIT",2,amount,DSCT_CRIT[DSCT_ENTEXT]);
				end
			elseif ((evt == "SPELL_DAMAGE" or evt == "SPELL_PERIODIC_DAMAGE") and select(17, ...) and DSCT_Get("SHOWSPELLCRIT") ~= 0) then
				local spell = select(10, ...) or "";
				local amount = select(12, ...) or 0;				
				DSCT_Display_Toggle("SHOWSPELLCRIT",3,amount,DSCT_CRIT[DSCT_ENTEXT]..spell.." ");
			end
		end

		if (DSCT_SP_OnEvent) then
			DSCT_SP_OnEvent(select(2, ...));
		end

		if (DSCT_OnCustomEvent) then			
			DSCT_OnCustomEvent(select(2, ...));
		end
		return;
	else
		if (DSCT_SP_OnEvent) then
			DSCT_SP_OnEvent(event, ...);
		end
	end
end

function DSCT_InitCustomEvent()
	if initCE_OK == true then return;end
	if SCT_Event_Config == nil then return;end
	
	for custkey , custval in pairs(SCT_Event_Config) do
		if (not custval.event) then
			SCT_Event_Config[custkey] = nil;
		else
			if custval.class then
				if custval.class ~= "failed" and custval.class ~= "ok" then
					if DSCT_PLAYER_CLASS ~= custval.class then
						custval.class = "failed";
					else
						custval.class = "ok";
					end
				end
			else
				custval.class = "ok";
			end
			
			custval.name = string.upper(custval.name);
			custval.ani = custval.ani or 4;		
			custval.title = custval.title or custval.name;
			custval.tooltipText = custval.tooltipText or "?";
			custval.r = custval.r or 1;
			custval.g = custval.g or 1;
			custval.b = custval.b or 1;
		end
	end	
	initCE_OK = true;
	DSCT_AddCustomEventToPlayer();
end

function DSCT_AddCustomEventToPlayer()
	if initCE_OK ~= true then return;end
	if SCT_Event_Config == nil then return;end
	
	local playerList = DSCT_Get("CUSTOM_EVENT_LIST");
	
	for custkey , custval in pairs(SCT_Event_Config) do
		if (custval.class == "ok") then
			local canAdd = true;
			for k, v in pairs(playerList) do
				if (v.title == custval.title) then
					for key, val in pairs(custval) do
						if (key~="ani") then
							v[key] = val;
						end
					end
					canAdd = false;
				end
			end

			if (canAdd) then
				table.insert(playerList, custval);
			end
		end
	end
	DSCT_Set("CUSTOM_EVENT_LIST", playerList);
end

do
local function compare(a, b)
	if (not a or type(a ~= "string")) then return true; end

	if (strfind(a, "^!")) then
		return getglobal(string.gsub(a, "!", "")) ~= b;
	else
		return getglobal(a) == b;
	end
end

function DSCT_OnCustomEvent(event, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, ...)
	local re, er = false, false; local val = nil;
	if (DSCT_CUSTOMEVENT == nil) then return;end	

	for k , c in pairs(DSCT_CUSTOMEVENT) do
		er = false;
		if (c.event == event and c.class == "ok" and c.ani > 0 and compare(c.src, srcGUID) and compare(c.dest, dstGUID)) then
			--DSCT_Debug(...);
			for i=1, 8 do
				val = select(i, ...);
				c.name = string.gsub(c.name, "$ARG" .. i, val);
				if (not c["arg" .. i] or c["arg" .. i] == val) then
					er = true;
				else
					er = false;
					break;
				end
			end
			
			if (er) then
				local ani = c.ani or 5;
				local iscrit = (c.iscrit == 1) and 1 or 0;
				string.gsub(c.name, "$DEST", dstName);
				string.gsub(c.name, "$SOURCE", srcGUID);
				DSCT_Set("SHOWCUSTOM", ani);
				DSCT_SetColor("SHOWCUSTOM", c.r, c.g, c.b);
				DSCT_Display_Toggle("SHOWCUSTOM", 1, nil, c.name, iscrit);
				if c.sound then PlaySoundFile(c.sound); end
				re = true;
			end
		end
	end
	return re;
end
end

function DSCT_Display()
end

function DSCT_Display_New( msgL ,msgR , txtFlag,color, direction,iscrit )

	local adat, adatpre;
	--DSCT_Set("ANIMODE",2);
	local theType = DSCT_Get("ANIMODE");
	
	if (DSCT_NameRegistered == 0) then
		return;
	end

	if direction > 3 or direction < 1 then direction = 1;end
	
	local parentName = "DSCTaniData"..DSCT_LastBar;
	--Set up  text animation
	adat = arrAniData["aniData"..DSCT_LastBar];
	--get last number
	local LastLastBar = DSCT_LastBar-1;
	if(LastLastBar == 0) then
		LastLastBar = DSCT_Get("ANIC");
	end
	adatpre = arrAniData["aniData"..LastLastBar];
	
	adat.Active = true;
	adat.starttimer = GetTime();
	
	--水平
	if (theType == 0) then
		adat.status = 0;
		adat.baseX = 60;
		adat.posX = 0;
		adat.posY = 0;
		adat.timer1 = 2;
		adat.timer2 = 2;
		adat.timer3 = adat.timer1 + 0.4;
		if direction == 1 then
			adat.angle1 = 180;--a
			adat.angle2 = 180;--b
			adat.distance1 = 200 * DSCT_ANI_PARAM1;
			adat.distance2 = adat.distance1 / adat.timer1 * 0.4;
		else
			adat.baseX = -adat.baseX;
			adat.angle1 = 0;--a
			adat.angle2 = 0;--b
			adat.distance1 = 200 * DSCT_ANI_PARAM1;
			adat.distance2 = adat.distance1 / adat.timer1 * 0.4;
			direction = 2;
		end

		adat.alpha = 0;
		adat.lastupdate = 0;

		if adat.starttimer - DSCT_Ani_Fix[direction][1] < 2 / DSCT_ANI_SPEED then			
			DSCT_Ani_Fix[direction][2] = DSCT_Ani_Fix[direction][2] + 1;
			if DSCT_Ani_Fix[direction][2] > 2 then DSCT_Ani_Fix[direction][2] = 0;end
			adat.baseY = -(DSCT_ANI_TEXTSIZE + 2) * DSCT_Ani_Fix[direction][2];
		else
			DSCT_Ani_Fix[direction][2] = 0;
		end
	end
	--垂直
	if (theType == 1) then
		adat.status = 0;
		adat.baseY = 25;
		adat.posX = 0;
		adat.posY = 0;
		adat.timer1 = 1.5;
		adat.timer2 = 1.5;
		adat.timer3 = adat.timer1 + 0.4;

		if direction == 1 then
			adat.angle1 = 90;--a
			adat.angle2 = 90;--b
			adat.distance1 = 100 * DSCT_ANI_PARAM1;
			adat.distance2 = adat.distance1 / adat.timer1 * 0.4;			
			local obj = arrAniData["aniData"..DSCT_Ani_Fix[direction][3]];
			local fix = 0;
			if obj.Active == true and obj.posY + obj.baseY < adat.baseY + DSCT_ANI_TEXTSIZE + 2 then
				fix = adat.baseY + DSCT_ANI_TEXTSIZE + 2 - (obj.posY + obj.baseY);
			end
			if fix ~= 0 then
				for i = 1,DSCT_Get("ANIC") do
					if i ~= DSCT_LastBar then
						obj = arrAniData["aniData"..i];
						if obj.Active == true and obj.angle1 == 90 then						
							obj.baseY = obj.baseY + fix;
						end
					end
				end
			end
		else
			direction = 2;
			adat.baseY = -adat.baseY;
			adat.angle1 = 270;--a
			adat.angle2 = 270;--b
			adat.distance1 = 100 * DSCT_ANI_PARAM1;
			adat.distance2 = adat.distance1 / adat.timer1 * 0.4;			
			local obj = arrAniData["aniData"..DSCT_Ani_Fix[direction][3]];
			local fix = 0;
			if obj.Active == true and obj.posY + obj.baseY > adat.baseY - DSCT_ANI_TEXTSIZE - 2 then
				fix = obj.posY + obj.baseY - (adat.baseY - DSCT_ANI_TEXTSIZE - 2);
			end
			if fix ~= 0 then
				for i = 1,DSCT_Get("ANIC") do
					if i ~= DSCT_LastBar then
						obj = arrAniData["aniData"..i];
						if obj.Active == true and obj.angle1 == 270 then						
							obj.baseY = obj.baseY - fix;
						end
					end
				end
			end
		end		
		adat.alpha = 0;
		adat.lastupdate = 0;		
	end
	--抛物线
	if (theType == 2) then
		adat.status = 0;
		adat.baseX = -55;
		adat.posX = 0;
		adat.posY = 0;
		adat.timer1 = 1.5;	
		adat.distance1 = 100 * DSCT_ANI_PARAM2;
		adat.distance2 = 2.6 * DSCT_ANI_PARAM1;
		adat.angle1 = -1;
		
		if direction > 1 then
			adat.baseX = -adat.baseX;
			adat.angle1 = -adat.angle1;
			direction = 2;
		end

		adat.alpha = 0;
		adat.lastupdate = 0;

		if adat.starttimer - DSCT_Ani_Fix[direction][1] < 0.9 / DSCT_ANI_SPEED then			
			DSCT_Ani_Fix[direction][2] = DSCT_Ani_Fix[direction][2] + 1;
			if DSCT_Ani_Fix[direction][2] > 2 then DSCT_Ani_Fix[direction][2] = 0;end
			adat.distance2 = adat.distance2 + 0.5 * DSCT_Ani_Fix[direction][2];
		else
			DSCT_Ani_Fix[direction][2] = 0;
		end
	end
	--弹出1
	if (theType == 3 or theType == 5) then
		adat.status = 0;
		adat.posX = 0;
		adat.posY = 0;
		adat.timer1 = 0.3;
		adat.timer2 = 1;
		adat.timer3 = 1.8;
		if direction == 1 then
			adat.angle1 = 5;
			adat.angle2 = 310;
			adat.distance1 = 150 * DSCT_ANI_PARAM1;
			adat.distance2 = 70 * DSCT_ANI_PARAM2;
		elseif direction == 2 then
			adat.angle1 = 130;
			adat.angle2 = 200;
			adat.distance1 = 80 * DSCT_ANI_PARAM1;
			adat.distance2 = 55 * DSCT_ANI_PARAM2;
		else
			adat.angle1 = 175;
			adat.angle2 = 200;
			adat.distance1 = 130 * DSCT_ANI_PARAM1;
			adat.distance2 = 70 * DSCT_ANI_PARAM2;
		end		
		adat.alpha = 1;
		adat.lastupdate = 0;

		if adat.starttimer - DSCT_Ani_Fix[direction][1] < 0.8 / DSCT_ANI_SPEED then
			DSCT_Ani_Fix[direction][2] = DSCT_Ani_Fix[direction][2] + 1;
			if DSCT_Ani_Fix[direction][2] > 2 then DSCT_Ani_Fix[direction][2] = 0;end
			adat.angle1 = adat.angle1 + random(18) - 9;
			adat.distance1 = adat.distance1 + 20 * DSCT_Ani_Fix[direction][2];
			local obj = arrAniData["aniData"..DSCT_Ani_Fix[direction][3]];
			obj.skip = true;
		else
			DSCT_Ani_Fix[direction][2] = 0;
		end
		if theType == 5 then
			adat.angle2 = 0;
			adat.distance2 = 0;
			adat.timer3 = 1.4;
		end
	end
	--弹出2
	if (theType == 4) then
		adat.status = 0;
		adat.posX = 0;
		adat.posY = 0;
		adat.timer1 = 0.5;
		adat.timer2 = 1.1;
		adat.timer3 = 2;
		if direction == 1 then
			adat.angle1 = 330;--a
			adat.angle2 = 30;--b
			adat.distance1 = 160 * DSCT_ANI_PARAM1;
			adat.distance2 = 60 * DSCT_ANI_PARAM2;
		elseif direction == 2 then
			adat.angle1 = 200;
			adat.angle2 = 150;
			adat.distance1 = 160 * DSCT_ANI_PARAM1;
			adat.distance2 = 60 * DSCT_ANI_PARAM2;
		else
			adat.angle1 = 270;
			adat.angle2 = 270;
			adat.distance1 = 110 * DSCT_ANI_PARAM1;
			adat.distance2 = 40 * DSCT_ANI_PARAM2;
		end		
		adat.alpha = 1;
		adat.lastupdate = 0;
		
		if adat.starttimer - DSCT_Ani_Fix[direction][1] < 0.8 / DSCT_ANI_SPEED then			
			DSCT_Ani_Fix[direction][2] = DSCT_Ani_Fix[direction][2] + 1;
			if DSCT_Ani_Fix[direction][2] > 2 then DSCT_Ani_Fix[direction][2] = 0;end
			--if direction ~= 3 then
			adat.angle1 = adat.angle1 + random(20) - 10;
			adat.distance1 = adat.distance1 + 20 * DSCT_Ani_Fix[direction][2];
			local obj = arrAniData["aniData"..DSCT_Ani_Fix[direction][3]];
			obj.skip = true;
		else
			DSCT_Ani_Fix[direction][2] = 0;
		end
	end
	--弹出3
	if (theType == 6) then
		adat.status = 0;
		adat.posX = 0;
		adat.posY = 0;
		adat.timer1 = 0.5;
		adat.timer2 = 1.0;
		adat.timer3 = 1.8;
		if direction == 1 then
			adat.angle1 = 25;
			adat.angle2 = 90;
			adat.distance1 = 100 * DSCT_ANI_PARAM1;
			adat.distance2 = 110 * DSCT_ANI_PARAM2;
		elseif direction == 2 then
			adat.angle1 = 155;
			adat.angle2 = 100;
			adat.distance1 = 90 * DSCT_ANI_PARAM1;
			adat.distance2 = 110 * DSCT_ANI_PARAM2;
		else
			adat.timer1 = 0.4;
			adat.angle1 = 330;
			adat.angle2 = 0;
			adat.distance1 = 100 * DSCT_ANI_PARAM1;
			adat.distance2 = 100 * DSCT_ANI_PARAM2;
		end		
		adat.alpha = 1;
		adat.lastupdate = 0;
		
		if adat.starttimer - DSCT_Ani_Fix[direction][1] < 0.8 / DSCT_ANI_SPEED then			
			DSCT_Ani_Fix[direction][2] = DSCT_Ani_Fix[direction][2] + 1;
			if DSCT_Ani_Fix[direction][2] > 2 then DSCT_Ani_Fix[direction][2] = 0;end
			local obj = arrAniData["aniData"..DSCT_Ani_Fix[direction][3]];
			obj.skip = true;
		else
			DSCT_Ani_Fix[direction][2] = 0;
		end		
	end
	DSCT_Ani_Fix[direction][3] = DSCT_LastBar;
	DSCT_Ani_Fix[direction][1] = adat.starttimer;
	
	--If they want to tag all self events

	adat.crit = 0;
	if iscrit then
		if iscrit == 1 then
			if DSCT_Get("CRITANI") == 1 then adat.crit = 1;end
		end
	end

	--set the color
	DSCT_SetAniTextColor(adat,color.r, color.g, color.b);
	--set alpha
	DSCT_SetAniTextAlpha(adat,adat.alpha);
	--Position
	adat.FObject:SetPoint("CENTER", "WorldFrame", "CENTER", adat.posX + adat.baseX, adat.posY + adat.baseY);--UIParent
	--Set the text to display
	
	if txtFlag == 3 then
		if (DSCT_Get("SHOWSELF") == 1) then		
			if msgL ~= nil and msgR ~= nil then
				msgL = msgL..DSCT_SelfFlag;
				msgR = DSCT_SelfFlag..msgR;			
			end
		end
		adat.txtObject1:ClearAllPoints();
		adat.txtObject2:ClearAllPoints();
		adat.txtObject2:SetPoint("RIGHT", parentName, "CENTER", 0, 0);
		adat.txtObject1:SetPoint("LEFT", parentName, "CENTER", 0, 0);
		if msgL then adat.txtObject1:SetText(msgL);end
		if msgR then adat.txtObject2:SetText(msgR);end
	else
		if (DSCT_Get("SHOWSELF") == 1) then		
			if msgL ~= nil and msgR ~= nil then
				msgL = DSCT_SelfFlag..msgL;
				msgR = msgR..DSCT_SelfFlag;
			elseif msgL ~= nil then
				msgL = DSCT_SelfFlag..msgL..DSCT_SelfFlag;
			else
				msgR = DSCT_SelfFlag..msgR..DSCT_SelfFlag;
			end
		end
		adat.txtObject1:ClearAllPoints();
		adat.txtObject2:ClearAllPoints();
		adat.txtObject2:SetPoint("LEFT", parentName, "CENTER", 0, 0);
		adat.txtObject1:SetPoint("RIGHT", parentName, "CENTER", 0, 0);
		if msgL then
			adat.txtObject1:SetText(msgL);
		else
			adat.txtObject1:SetText("");
		end		
		if msgR then
			adat.txtObject2:SetText(msgR);			
		else
			adat.txtObject2:SetText("");
		end
		if not msgL then
			adat.txtObject2:ClearAllPoints();
			adat.txtObject2:SetPoint("CENTER", parentName, "CENTER", 0, 0);
		end
		if not msgR then
			adat.txtObject1:ClearAllPoints();
			adat.txtObject1:SetPoint("CENTER", parentName, "CENTER", 0, 0);
		end
	end
	local Lw = adat.txtObject1:GetWidth();
	local Rw = adat.txtObject2:GetWidth();
	
	if msgL and msgR then
		if txtFlag == 3 then
			adat.txtObject2:SetPoint("RIGHT", parentName, "CENTER", Rw - (Lw + Rw) / 2, 0);
			adat.txtObject1:SetPoint("LEFT", parentName, "CENTER", Rw - (Lw + Rw) / 2, 0);
		else
			adat.txtObject1:SetPoint("RIGHT", parentName, "CENTER", Lw - (Lw + Rw) / 2, 0);
			adat.txtObject2:SetPoint("LEFT", parentName, "CENTER", Lw - (Lw + Rw) / 2, 0);
		end
	end
	--update current text being used
	DSCT_LastBar = DSCT_LastBar + 1;
	
	--if we reached the end, set to first
	if DSCT_LastBar >= (DSCT_Get("ANIC") + 1) then
		DSCT_LastBar = 1;
	end
	
end

----------------------
--Displays a message at the top of the screen
function DSCT_Display_Message(msg, color)
		--UIErrorsFrame:AddMessage(msg, color.r, color.g, color.b, 1.0, 1);
		local adat;
		
		if (DSCT_NameRegistered == 0) then
			return;
		end
		if (msg == nil) then
			return;
		end
	
		adat = arrCusMessData["cusMessData"..DENNIE_cusMessLast];
		DSCT_cusMessReset(adat);
		adat.txtbak = msg;
		adat.posX = DENNIE_cusMess_posX
		adat.posY = DENNIE_cusMess_posY;
		for i = 1,3 do
			if (i ~= DENNIE_cusMessLast) then
				local tmpdat;
				tmpdat = arrCusMessData["cusMessData"..i];
				if (tmpdat.Active == true) then					
					tmpdat.posY = tmpdat.posY + DENNIE_CUSMESS_TEXTSIZE;
				end
			end
		end	
		
		adat.alpha = DSCT_Get("MESSAGEALPHA");

		adat.FObject:SetTextHeight(DENNIE_CUSMESS_TEXTSIZE);
		--set the color
		adat.FObject:SetTextColor(color.r, color.g, color.b);
		--set alpha
		adat.FObject:SetAlpha(adat.alpha);
		--Position
		adat.FObject:SetPoint("CENTER", "UIParent", "CENTER", adat.posX, adat.posY);
		--Set the text to display
		adat.FObject:SetText(msg);
		
		adat.lastupdate = GetTime();
		
		adat.Active = true;

		DENNIE_cusMessLast = DENNIE_cusMessLast + 1;
		if (DENNIE_cusMessLast > 3) then
			DENNIE_cusMessLast = 1;
		end
end

function DSCT_Display_Toggle(name,txtFlag,msgL,msgR,iscrit, msg2)
	if (msgL == nil and msgR == nil) or name == nil then return;end
	
	local val = DSCT_Get(name);
	if val == nil then return;end
	if val == 0 then return;end
	if val > 3 then		
		if msg2 ~= nil then
			DSCT_Display_Message( msg2, DSCT_nGetColor(name) );
		else
			if not msgL then msgL = "";end
			if not msgR then msgR = "";end
			DSCT_Display_Message( msgL..msgR, DSCT_nGetColor(name) );
		end
	else
		--如果是中文，判断第二个是不是nil，是的话将第一个移动到第二个
		if txtFlag == 1 and msgR == nil then
			msgR = msgL;
			msgL = nil;
		end
		if txtFlag == 2 and msgR ~= nil then
			msgL = msgL..msgR;
			msgR = nil;
		end
		DSCT_Display_New( msgL ,msgR, txtFlag,DSCT_nGetColor(name), val,iscrit );
	end	
end

-- Update the animcation
function DSCT_TextUpdate()	
	DSCT_updateAnimation();
	local aaa = sin(GetTime() * 20) * 20;
	if aaa < 0 then aaa = -aaa;end
end

----------------------
-- Upate animations that are being used
function DSCT_updateAnimation()		
	local timer;
	local timer2;
	local bak;
	local beupdataed = false;
	
	DENNIE_TYPE4_FixFlag = true;
	local posx,posy;
	for key, value in pairs(arrAniData) do
		if (value.Active == true) then
			DSCT_doAnimation(value);
			posx = (value.posX + value.baseX)  * DSCT_ROTATION_COS - (value.posY + value.baseY) * DSCT_ROTATION_SIN;
			posy = (value.posX + value.baseX) * DSCT_ROTATION_SIN + (value.posY + value.baseY) * DSCT_ROTATION_COS;
			posx = posx + DENNIE_ani_posX;
			posy = posy + DENNIE_ani_posY;
			if value.alpha > DSCT_ANI_ALPHAMAX then				
				DSCT_SetAniTextAlpha(value,DSCT_ANI_ALPHAMAX);
			else
				DSCT_SetAniTextAlpha(value,value.alpha);
			end
			value.FObject:SetPoint("CENTER", "UIParent", "CENTER", posx ,posy );--Dennie Add
		end
	end	
	for key, value in pairs(arrCusMessData) do
		--if (value.Active) then
			DSCT_doCusMess(value);
		--end
	end

end

----------------------
function DSCT_doCusMess(cusMessData)
	if ( cusMessData.Active == true) then
		local curtime = GetTime();
		if cusMessData.SpellTime ~= -1 then
			local spelltime = cusMessData.SpellTime - curtime + cusMessData.SpellStartTimer;
			if spelltime > 0 then
				if spelltime > 1 then
					cusMessData.FObject:SetText(format(cusMessData.txtbak.." |cffffffff%.1f|r", spelltime));
				else
					cusMessData.FObject:SetText(format(cusMessData.txtbak.." |cffffff00%.1f|r", spelltime));
				end
			else
				cusMessData.FObject:SetText(cusMessData.txtbak.." |cffffffff---|r");
			end
		end
		if ((curtime  - cusMessData.lastupdate) > DSCT_MESS_TIMER) then
			if curtime - cusMessData.lastupdate - DSCT_MESS_TIMER < DSCT_MESS_FADETIMER then
				cusMessData.alpha = (1 - (curtime - cusMessData.lastupdate - DSCT_MESS_TIMER) / DSCT_MESS_FADETIMER) * DSCT_MESS_ALPHAMAX;
			else			
				DSCT_cusMessReset(cusMessData);
				return;
			end			
		end
		if cusMessData.alpha > DSCT_MESS_ALPHAMAX then cusMessData.alpha = DSCT_MESS_ALPHAMAX;end
		cusMessData.FObject:SetAlpha(cusMessData.alpha);
		cusMessData.FObject:SetPoint("CENTER", "UIParent", "CENTER", cusMessData.posX, cusMessData.posY);--Dennie Add

	end	
end

--Move text to get the animation
function DSCT_doAnimation(adat)	--If a crit			
	
	
	--[[
		if (DENNIE_aniDelay > 0) then
			DENNIE_aniDelay = DENNIE_aniDelay - 1;
			aniData.lastupdate = GetTime();
		end]]		
	--if its time to update, move the text step positions
	if ( adat.Active == true) then
		local theType = DSCT_Get("ANIMODE");		
		local curtime = GetTime() - adat.starttimer;
		curtime = DSCT_ANI_SPEED * curtime;
		if adat.sp == true then theType = 99;end
		if theType == 99 then
			if curtime < 0.2 then
				adat.alpha = curtime * 5;
			elseif curtime < 1.5 then
				adat.alpha = 1;
			elseif curtime < 1.9 then
				adat.alpha = 1 - (curtime - 1.5) / 0.4;
			else
				DSCT_aniReset(adat);
				return;
			end
		end
		if theType == 2 then
			if curtime < adat.timer1 then
				adat.posX = (curtime / adat.timer1) * adat.distance1;
				adat.posY = -adat.posX * adat.posX * 0.04 + adat.distance2 * adat.posX;
				adat.posX = adat.angle1 * adat.posX;
				if curtime < 0.2 then
					adat.alpha = curtime * 5;
				elseif curtime > adat.timer1 - 0.4 then
					adat.alpha = 1 - (curtime - (adat.timer1 - 0.4)) / 0.4;	
				else
					adat.alpha = 1;
				end
			else
				DSCT_aniReset(adat);
				return;
			end
		end
		if theType == 3 then
			if curtime < adat.timer1 then
				adat.posX = -cos(adat.angle1) * adat.distance1 * curtime / adat.timer1;
				adat.posY = sin(adat.angle1) * adat.distance1 * curtime / adat.timer1;
			elseif curtime < adat.timer2 then
				if adat.status ~= 1 then
					adat.status = 1;
					adat.posX = -cos(adat.angle1) * adat.distance1;
					adat.posY = sin(adat.angle1) * adat.distance1;
				end
				if curtime < adat.timer1 + 0.4 then
					if curtime - adat.lastupdate > 0.1 then
						adat.lastupdate = curtime;
						adat.posX = adat.posX + adat.baseX;
						adat.posY = adat.posY + adat.baseY;
						adat.bakX = random(70) - 35;
						adat.bakY = random(70) - 35;
						adat.baseX = 0;
						adat.baseY = 0;
					end
					adat.baseX = adat.bakX * (curtime - adat.lastupdate);
					adat.baseY = adat.bakY * (curtime - adat.lastupdate);
				end
				if adat.skip == true then
					adat.starttimer = adat.starttimer - (adat.timer2 - curtime);
				end
			elseif curtime < adat.timer3 then				
				if adat.status ~= 2 then
					adat.status = 2;
					adat.baseX = adat.baseX + adat.posX;
					adat.baseY = adat.baseY + adat.posY;
				end
				if curtime > adat.timer3 - 0.4 then
					adat.alpha = 1 - (curtime - (adat.timer3 - 0.4)) / 0.4;
				end
				adat.posX = -cos(adat.angle2) * adat.distance2 * (curtime - adat.timer2) / (adat.timer3 - adat.timer2);
				adat.posY = sin(adat.angle2) * adat.distance2 * (curtime - adat.timer2) / (adat.timer3 - adat.timer2);			
			else
				DSCT_aniReset(adat);
				return;
			end
		end
		if theType == 0 or theType == 1 or theType == 4 or theType == 5 or theType == 6 then			
			if curtime < adat.timer1 then
				adat.posX = -cos(adat.angle1) * adat.distance1 * curtime / adat.timer1;
				adat.posY = sin(adat.angle1) * adat.distance1 * curtime / adat.timer1;
				if adat.alpha ~= 1 then
					if curtime < 0.25 then
						adat.alpha = curtime * 4;
					else
						adat.alpha = 1;
					end
				end
			elseif curtime < adat.timer2 then
				if adat.status ~= 1 then
					adat.status = 1;
					adat.posX = -cos(adat.angle1) * adat.distance1;
					adat.posY = sin(adat.angle1) * adat.distance1;
				end
				if adat.skip == true then
					adat.starttimer = adat.starttimer - (adat.timer2 - curtime);
				end
			elseif curtime < adat.timer3 then
				if adat.status ~= 2 then
					adat.status = 2;
					adat.baseX = adat.baseX + adat.posX;
					adat.baseY = adat.baseY + adat.posY;
				end
				if curtime > adat.timer3 - 0.4 then
					adat.alpha = 1 - (curtime - (adat.timer3 - 0.4)) / 0.4;
				else
					adat.alpha = 1;
				end
				adat.posX = -cos(adat.angle2) * adat.distance2 * (curtime - adat.timer2) / (adat.timer3 - adat.timer2);
				adat.posY = sin(adat.angle2) * adat.distance2 * (curtime - adat.timer2) / (adat.timer3 - adat.timer2);				
			else
				DSCT_aniReset(adat);
				return;
			end
		end		
		--=============================================================Dennie Add end
		
		if adat.crit > 0 then
			if curtime < 0.2 then
				DSCT_SetAniTextHeight(adat,1.6);		
			elseif curtime <= 0.4 then
				DSCT_SetAniTextHeight(adat, (1.6 - (curtime - 0.2) * 3 ));
			else
				DSCT_SetAniTextHeight(adat,1);
				adat.crit = 0;
			end	
		end
	end
	return true;
end

----------------------
--count the number of crits active
function DSCT_critCount()
	local count = 0
	
	for key, value in pairs(arrAniData) do
		if (value.crit) then
			count = count + 1;
		end
	end
	
	return count;
end

----------------------
--Rest the text animation
function DSCT_aniReset(aniData)	
	
	aniData.Active = false;
	aniData.crit = 0;
	aniData.posY = 0;
	aniData.posX = 0;
	aniData.baseX = 0;
	aniData.baseY = 0;
	aniData.sp = false;
	aniData.alpha = 0;
	aniData.addY = 0;--Dennie Add
	aniData.addX = 0;--Dennie Add
	aniData.skip = false;
	aniData.mir = 1;
	aniData.critdelay = 0;
	
	DSCT_SetAniTextAlpha(aniData,aniData.alpha);
	aniData.FObject:SetPoint("CENTER", "UIParent", "CENTER", aniData.posX, aniData.posY);
end

----------------------
--Rest all the text animations
function DSCT_aniResetAll()
	
	for key, value in pairs(arrAniData) do
		DSCT_aniReset(value);
	end

end


function DSCT_cusMessReset(cusMessData)	
	
	cusMessData.Active = false;
	cusMessData.posY = 0;
	cusMessData.posX = 0;
	cusMessData.alpha = 0;
	cusMessData.lastupdate = 0;
	cusMessData.txtbak = "";
	cusMessData.SpellTime = -1;
	cusMessData.SpellStartTimer = 0;
	
	cusMessData.FObject:SetAlpha(0);
	cusMessData.FObject:SetPoint("CENTER", "UIParent", "CENTER", cusMessData.posX, cusMessData.posY);
end

function DSCT_cusMessResetAll()	
	for key, value in pairs(arrCusMessData) do
		DSCT_cusMessReset(value);
	end
end

----------------------
--Initial animation settings
function DSCT_cusMessInit()
	local MessFontSize;
	MessFontSize = DSCT_Get("MESSAGESIZE");
	if (MessFontSize < 12) then
		MessFontSize = 12;
	end
	if (MessFontSize > 36) then
		MessFontSize = 36;
	end
	DENNIE_cusMessLast = 1;
	
	
	local FontNumber = DSCT_Get("MESSAGEFONT");
	if DSCT_FONTLIST[FontNumber] == nil then
		--DSCT_Set("MESSAGEFONT",1);
		FontNumber = 1;
	end
	local FontName = DSCT_FONTLIST[FontNumber].path;
	local FontOutTxt = "";
	FontOutline = DSCT_Get("MESSFONTOUTLINE");

	if (FontOutline == 2) then
		FontOutTxt = "OUTLINE";
	elseif (FontOutline == 3) then
		FontOutTxt = "THICKOUTLINE";	
	end

	for key, value in pairs(arrCusMessData) do
		--value.FObject = getglobal("DSCT"..key);
		value.FObject = getglobal("DSCT"..key);
		value.FObject:SetFont(FontName, MessFontSize,FontOutTxt);
		if FontOutline > 3 then
			value.FObject:SetShadowColor(0,0,0);
			value.FObject:SetShadowOffset(FontOutline - 3,-FontOutline + 3);
		end
	end
	
	DENNIE_CUSMESS_TEXTSIZE = MessFontSize;
	DSCT_cusMessResetAll();
end

function DSCT_ToDec(a)
	local i = 0;
	while a - i > 1 do
		i = i + 1;
	end
	return i;
end
function DSCT_ToHEX(a)
	local b = a * 256;
	return ""..DSCT_HEX_LIST[DSCT_ToDec(b / 16) + 1]..DSCT_HEX_LIST[ DSCT_ToDec( ( b / 16 - DSCT_ToDec(b / 16) ) * 16 ) + 1];
end
function DSCT_ColorFlip(r,g,b)
	return "|cff"..DSCT_ToHEX(r)..DSCT_ToHEX(g)..DSCT_ToHEX(b);
end

function DSCT_aniInit()
	local FontNumber;

	local FontOutTxt = "";
	local FontOutline = DSCT_Get("FONTOUTLINE");
	
	local FontName = DSCT_DEF_FONT;
	local FontNumber = DSCT_Get("FONT");		
	local FontSize = DSCT_Get("TEXTSIZE");
	
	local EnFontNumber = DSCT_Get("ENFONT");
	local EnFontSize = DSCT_Get("ENTEXTSIZE");
	if DSCT_FONTLIST[FontNumber] == nil then
		--DSCT_Set("FONT",1);
		FontNumber = 1;		
	end
	if DSCT_ENFONTLIST[EnFontNumber] == nil then
		EnFontNumber = 1;
	end

	if (FontOutline == 2) then
		FontOutTxt = "OUTLINE";
	elseif (FontOutline == 3) then
		FontOutTxt = "THICKOUTLINE";	
	end
	
	for key, value in pairs(arrAniData) do
		--value.FObject = getglobal("DSCT"..key);
		value.FObject = getglobal("DSCT"..key);
		value.txtObject1 = getglobal("DSCT"..key.."_LEFT");
		value.txtObject2 = getglobal("DSCT"..key.."_RIGHT");		
		value.txtObject1:SetFont(DSCT_ENFONTLIST[EnFontNumber].path, EnFontSize,FontOutTxt);
		value.txtObject2:SetFont(DSCT_FONTLIST[FontNumber].path, FontSize,FontOutTxt);
		if FontOutline > 3 then
			value.txtObject1:SetShadowColor(0,0,0);
			value.txtObject2:SetShadowColor(0,0,0);
			value.txtObject1:SetShadowOffset(FontOutline - 3,-FontOutline + 3);
			value.txtObject2:SetShadowOffset(FontOutline - 3,-FontOutline + 3);
		end
		value.lastupdate = 0;		
	end
	
	DSCT_aniResetAll();
end

----------------------
--function of spell alert
function DSCT_isParty(name)
	for i = 1, 4, 1 do
		local partyname = UnitName("party" .. i);
		if (name == partyname ) then
			if not UnitCanAttack("party" .. i, "player") then return 1;end
		end
	end
	return nil;
end

function DSCT_openPreView()
	local adat;
	if (DSCT_NameRegistered == 0) then
		return;
	end
	
	local pre = getglobal("DSCT_PreMessBox");
	pre:ClearAllPoints();
	pre:SetPoint("CENTER", "UIParent", "CENTER", DSCT_Get("MESSAGEPOSX",x), DSCT_Get("MESSAGEPOSY",y));
	pre:Show();
	
	pre = getglobal("DSCT_PreAniBox");
	pre:ClearAllPoints();
	pre:SetPoint("CENTER", "UIParent", "CENTER", DSCT_Get("ANIPOSX",x), DSCT_Get("ANIPOSY",y));
	pre:Show();
	
	DSCT_RefreshStaticVar();
end

function DSCT_closePreView()	
	if (DSCT_NameRegistered == 0) then
		return;
	end
	local pre = getglobal("DSCT_PreMessBox");
	pre:Hide();	
	pre = getglobal("DSCT_PreAniBox");
	pre:Hide();	
end

function DSCT_Cmd(msg)
	if DSCT_NameRegistered ~= 1 then return;end	
	if DSCT_Get("ENABLED") ~= 1 then return;end
	local cmdlist = {nil,nil,nil,nil,nil,nil};
	local i = 1;
	local findval = 0;
	if msg == "" then
		if DSCTOptions then DSCT_showMenu();else DSCT_Debug("无菜单");end
		return;
	end	
	while msg ~= nil do
		if strfind(msg," ") then
			findval = strfind(msg," ");
			cmdlist[i] = strsub(msg,1,findval - 1);
			val = strsub(msg,strfind(msg," ") + 1,strlen(msg));
			msg = strsub(msg,strfind(msg," ") + 1,strlen(msg));
		else
			cmdlist[i] = msg;
			msg = nil;
		end		
		i = i + 1;
	end
	
	if cmdlist[1] and cmdlist[2] then
		if strlower(cmdlist[1]) == "save" then
			DSCT_NEWCONFIG[strlower(cmdlist[2]).."_save"] = nil;
			DSCT_NEWCONFIG[strlower(cmdlist[2]).."_save"] = DSCT_clone(DSCTPlayer);
			DSCT_Debug("保存到: "..strlower(cmdlist[2]));			
		end
		if strlower(cmdlist[1]) == "load" then
			if DSCT_NEWCONFIG[strlower(cmdlist[2]).."_save"] then
				DSCT_Load(DSCT_NEWCONFIG[strlower(cmdlist[2]).."_save"]);
				DSCT_Debug("已读取: "..strlower(cmdlist[2]));
			else
				DSCT_Debug("不存在的存档: "..strlower(cmdlist[2]));
			end
		end
		if strlower(cmdlist[1]) == "delete" then
			if DSCT_NEWCONFIG[strlower(cmdlist[2]).."_save"] then
				DSCT_NEWCONFIG[strlower(cmdlist[2]).."_save"] = nil;
				DSCT_Debug("已删除: "..strlower(cmdlist[2]));
			else
				DSCT_Debug("不存在的存档: "..strlower(cmdlist[2]));
			end
		end
		
		return;
	end
	if strlower(cmdlist[1]) == "list" then
		DSCT_Debug("目前所有的存档列表: ");
		for key,val in pairs(DSCT_NEWCONFIG) do
			if string.sub(key,string.len(key) - 4,string.len(key)) == "_save" then
				DSCT_Debug(string.sub(key,1,string.len(key) - 5) );
			end
		end
		return;
	end
	
	DSCT_Debug("|cffffff00DSCT 命令帮助:|r");
	DSCT_Debug("/sct save |cffff0000name|r:保存当前设置到指定档案名,例:/sct save myconfig1");
	DSCT_Debug("/sct load |cffff0000name|r:读取指定档案,例:/sct load myconfig1");
	DSCT_Debug("/sct delete |cffff0000name|r:删除指定档案,例:/sct delete myconfig1");
	DSCT_Debug("/sct list:列出目前所有存档的名字");
end

function DSCT_SetAniTextHeight(adat,p)
	adat.txtObject1:SetTextHeight(DSCT_ANI_ENTEXTSIZE * p);
	adat.txtObject2:SetTextHeight(DSCT_ANI_TEXTSIZE * p);
end

function DSCT_SetAniTextAlpha(adat,a)
	adat.txtObject1:SetAlpha(a);
	adat.txtObject2:SetAlpha(a);
end

function DSCT_SetAniTextColor(adat,r,g,b)
	adat.txtObject1:SetTextColor(r,g,b);
	adat.txtObject2:SetTextColor(r,g,b);
end