--[[

Natur EnemyCastBar
.
. This mod was originally coded by "Limited" - I, Naturfreund, added all codes after Limited's version Carnival Enemy Cast Bar 1.5c
.
=================================
Read Changelog.txt for more info!
=================================
]]--

CECB_status_version_txt = "7.0.0";

function CEnemyCastBar_DefaultVars()

		CEnemyCastBar = { };
		CEnemyCastBar.bStatus = true;
		CEnemyCastBar.bPvP = true;
		CEnemyCastBar.bPvE = true;
		CEnemyCastBar.bLocked = true;
		CEnemyCastBar.bTimer = true;
		CEnemyCastBar.bScale = 1.0;
		CEnemyCastBar.bAlpha = 0.8;
		CEnemyCastBar.bShowafflict = true;
		CEnemyCastBar.bCDown = true;
		CEnemyCastBar.bNumBars = 15;
		-- new variables for new versions (check onload variables!)
		CEnemyCastBar.bParseC = true;
		CEnemyCastBar.bGains = true;
		CEnemyCastBar.bFlipB = false;
		CEnemyCastBar.bSmallTSize = true; -- not an option any longer
		CEnemyCastBar.bFlashit = true; -- not an option any longer
		CEnemyCastBar.bGlobalFrag = true;
		CEnemyCastBar.bBCaster = false;
		CEnemyCastBar.bSoloD = true;
		CEnemyCastBar.bSpace = 15;
		CEnemyCastBar.bDRTimer = true;
		CEnemyCastBar.bMageC = false;
		CEnemyCastBar.bMiniMap = true;
		CEnemyCastBar.bMiniMapPos = 356;
		CEnemyCastBar.bMiniMapRadius = 80;
		CEnemyCastBar.bClassDR = true;
		CEnemyCastBar.bShowIcon = true;
		CEnemyCastBar.bSDoTs = true;
		CEnemyCastBar_SetBarColors();
		CEnemyCastBar.bGlobalPvP = false;
		CEnemyCastBar.bnecbCBLBias = 20;
		CEnemyCastBar.bPvEWarn = true;
		CEnemyCastBar.bGainsOnly = false;
		CEnemyCastBar.bTempFPSBar = false;
		CEnemyCastBar.bFPSBarLocked = false;
		CEnemyCastBar.bSpellBreaks = false;
		CEnemyCastBar.bMouseBar = true;
		CEnemyCastBar.bDisBorder = true;
		CEnemyCastBar.bBarTexture = 0;
		CEnemyCastBar.bHostileOnly = false;
		CEnemyCastBar.bBossDebuff = true;
		CEnemyCastBar.bSeparateBars = false;
		CEnemyCastBar.bNumBarsSep = 4;
		CEnemyCastBar.tFramePoints = { };
		CEnemyCastBar.bBarFont = 0;
		CEnemyCastBar.bTimerInside = false;
		CEnemyCastBar.bFocusPvP = true;
		CEnemyCastBar.bFocusDebuffs = true;
		CEnemyCastBar.bFillupGains = true;
		CEnemyCastBar.bFillupDebuffs = true;
		CEnemyCastBar.bFillupDoTs = true;
		CEnemyCastBar.bPvPSoundWarn = true;

end

function CEnemyCastBar_SetBarColors(msg)

		--initialize colors
		cecbcolors = {"Hostile", "Friendly", "Cooldown", "GainsFoe", "GainsFriend", "Grey", "Afflict", "Stuns", "DoTs"};

		if (msg == "SetColors") then
			local i = 1;
			while (CEnemyCastBar.tColor[i]) do
				getglobal("CECBPickColorOptions_"..cecbcolors[i].."NormalTexture"):SetVertexColor(CEnemyCastBar.tColor[i][1], CEnemyCastBar.tColor[i][2], CEnemyCastBar.tColor[i][3]);

				for j=1, 3 do
					getglobal("CECBPickColorOptions_"..cecbcolors[i])[j] = CEnemyCastBar.tColor[i][j];
				end
			i = i + 1;
			end

		else
			--default colors
			CEnemyCastBar.tColor = {
				{ 1, 0, 0 },		--Hostile
				{ 0, 1, 0 },		--Friendly
				{ 0, 0, 1 },		--Cooldown
	 			{ 1, 0, 1 },		--GainsFoe
	 			{ 0.5, 0, 0.65 },	--GainsFriend
				{ 0.8, 0.8, 0.8 },	--Grey
				{ 0.8, 0.8, 0 },   	--Afflict						
				{ 0.5, 0.2, 0.1 },	--Stuns, also in 'Variables Loaded'!
				{ 0, 0.8, 0.8 },	--DoTs
			}
		end
end

function CEnemyCastBar_RegisterEvents(command)

	local events_sc = {	"UNIT_SPELLCAST_START", "UNIT_SPELLCAST_DELAYED", "UNIT_SPELLCAST_STOP",
				"CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE", "CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE", "CHAT_MSG_SPELL_PARTY_DAMAGE",
				"UNIT_SPELLCAST_CHANNEL_START", "UNIT_SPELLCAST_CHANNEL_STOP", "UNIT_SPELLCAST_CHANNEL_UPDATE" };

	local events_pve = {	"CHAT_MSG_MONSTER_YELL", "CHAT_MSG_MONSTER_EMOTE", "PLAYER_REGEN_DISABLED" };

	local events_chat = {	"CHAT_MSG_RAID", "CHAT_MSG_PARTY", "CHAT_MSG_RAID_LEADER", "CHAT_MSG_BATTLEGROUND", "CHAT_MSG_BATTLEGROUND_LEADER" };

	local events_gains = {	"CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF", "CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF", "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS",
				"CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS", "CHAT_MSG_SPELL_PARTY_BUFF", "CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS",
				"CHAT_MSG_SPELL_CREATURE_VS_CREATURE_BUFF", "CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS" };

	local events_afflicted = {
				"CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE", "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE", "CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE",
				"CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE",	"CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE",
				"CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE",
				"CHAT_MSG_SPELL_SELF_DAMAGE", "PLAYER_COMBO_POINTS" };

	local eventpacket = {	"CHAT_MSG_SPELL_BREAK_AURA", "CHAT_MSG_SPELL_AURA_GONE_OTHER", "CHAT_MSG_SPELL_AURA_GONE_SELF", "CHAT_MSG_SPELL_AURA_GONE_PARTY",
				"PLAYER_TARGET_CHANGED",
				"CHAT_MSG_ADDON", "UNIT_SPELLCAST_SENT", "UNIT_SPELLCAST_SUCCEEDED",
				"CHAT_MSG_COMBAT_HOSTILE_DEATH", "CHAT_MSG_COMBAT_FRIENDLY_DEATH", "CHAT_MSG_COMBAT_XP_GAIN" };

			--	"CHAT_MSG_SPELL_SELF_BUFF", "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS", "CHAT_MSG_COMBAT_SELF_HITS" -- for testing self buffs etc.
			--	"CHAT_MSG_SPELL_FAILED_LOCALPLAYER"
				--CarniEnemyCastBarFrame:RegisterEvent("CHAT_MSG_CHANNEL"); -- (register for debugging)--

	for k,v in pairs (eventpacket) do
		if (command == "unreg_main") then
				CarniEnemyCastBarFrame:UnregisterEvent(v);
		elseif (command == "reg_main") then
				CarniEnemyCastBarFrame:RegisterEvent(v);
		end
	end

	local pvploadfailed; --prevents that a lod failure of pvp is printed to screen twice
	for k,v in pairs (events_sc) do
		if (CEnemyCastBar.bStatus and CEnemyCastBar.bPvP and not CEnemyCastBar.bGainsOnly and command ~= "unreg_main") then
			-- load pvp module
			if (not NECB_PvP_Module_loaded) then

				local loaded, reason = LoadAddOn("CECB_PvPModule");
				if (loaded) then
					CEnemyCastBar_LoadDisabledSpells("mute");
				else
					DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffffff00'CECB_PvPModule' |rAddOn |cffff9999can not be loaded! |rReason: |cffff0000"..reason)
					CEnemyCastBar.bPvP = false;
					pvploadfailed = true;
					break;
				end
			end
			CarniEnemyCastBarFrame:RegisterEvent(v);
		else
			CarniEnemyCastBarFrame:UnregisterEvent(v);
		end
	end

	for k,v in pairs (events_chat) do
		if (CEnemyCastBar.bStatus and CEnemyCastBar.bParseC and command ~= "unreg_main") then
			CarniEnemyCastBarFrame:RegisterEvent(v);
		else
			CarniEnemyCastBarFrame:UnregisterEvent(v);
		end
	end

	for k,v in pairs (events_gains) do
		if (CEnemyCastBar.bStatus and ((CEnemyCastBar.bPvP and CEnemyCastBar.bGains) or (CEnemyCastBar.bPvE and IsInInstance() and not (GetNumBattlefieldStats() > 1 or IsActiveBattlefieldArena() )) ) and command ~= "unreg_main") then

			-- load pvp module
			if (not NECB_PvP_Module_loaded) then

				local loaded, reason = LoadAddOn("CECB_PvPModule");
				if (loaded) then
					CEnemyCastBar_LoadDisabledSpells("mute");
				elseif (not pvploadfailed) then
					DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffffff00'CECB_PvPModule' |rAddOn |cffff9999can not be loaded! |rReason: |cffff0000"..reason)
					CEnemyCastBar.bPvP = false;
					break;
				end
			end
			CarniEnemyCastBarFrame:RegisterEvent(v);
		else
			CarniEnemyCastBarFrame:UnregisterEvent(v);
		end
	end

	for k,v in pairs (events_afflicted) do
		if (CEnemyCastBar.bStatus and (CEnemyCastBar.bShowafflict or (CEnemyCastBar.bPvE and IsInInstance() and not (GetNumBattlefieldStats() > 1 or IsActiveBattlefieldArena() )) ) and command ~= "unreg_main") then

			-- load Debuff module
			if (not NECB_Debuffs_Module_loaded) then

				local loaded, reason = LoadAddOn("CECB_Debuffs");
				if (loaded) then
					CEnemyCastBar_LoadDisabledSpells("mute");
				else
					DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffffff00'CECB_Debuffs' |rAddOn |cffff9999can not be loaded! |rReason: |cffff0000"..reason)
					CEnemyCastBar.bPvE = false;
					CEnemyCastBar.bShowafflict = false;
					break;
				end
			end
			CarniEnemyCastBarFrame:RegisterEvent(v);
		else
			CarniEnemyCastBarFrame:UnregisterEvent(v);
		end
	end

	local PvE_DBInit_Done;
	-- this needs to be loaded after afflictions module, because there are Boss debuffs set inside the Module since 6.6.x
	for k,v in pairs (events_pve) do
		if (CEnemyCastBar.bStatus and (CEnemyCastBar.bPvE or (CEnemyCastBar.bShowafflict and CEnemyCastBar.bBossDebuff)) and IsInInstance() and not (GetNumBattlefieldStats() > 1 or IsActiveBattlefieldArena() ) and command ~= "unreg_main") then

			-- load pve module
			if (not NECB_PvE_Module_loaded) then

				local loaded, reason = LoadAddOn("CECB_PvEModule");
				if (loaded) then
					--CEnemyCastBar_LoadDisabledSpells("mute"); --do it later on DBInit()
				else
					DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffffff00'CECB_PvEModule' |rAddOn |cffff9999can not be loaded! |rReason: |cffff0000"..reason)
					CEnemyCastBar.bPvE = false;
					CEnemyCastBar.bBossDebuff = false;
					break;
				end
			end
			CarniEnemyCastBarFrame:RegisterEvent(v);

			--load database
			if (NECB_PvE_Module_loaded and not PvE_DBInit_Done) then
				if (command) then --entered world and NOT called by options
					necb_fauxtimer = {GetTime(), nil, nil, nil, 2, "pass_instance"};
					CECBFauxFrameButton:Show(); -- wait some seconds
					CEnemyCastBar_Show("NECB", "Getting Instance Name", 2, "cooldown", nil, "", nil, nil, nil, true);
				else
					if (CEnemyCastBar.bShowafflict and CEnemyCastBar.bBossDebuff) then
						NECB_PvE_DBInit(); -- load all spells for this instance PvE/Debuffs
					end
					NECB_PvE_DBInit(not CEnemyCastBar.bPvE); -- if not PvE then delete all but Debuff spells
					NECB_PvE_CodeInit(not CEnemyCastBar.bPvE);
					CEnemyCastBar_LoadDisabledSpells("mute");
				end
				PvE_DBInit_Done = true;
			end
		else
			CarniEnemyCastBarFrame:UnregisterEvent(v);
			if (NECB_PvE_Module_loaded and not PvE_DBInit_Done) then
				NECB_PvE_DBInit(true); --clear database
				NECB_PvE_CodeInit(true);
				CarniEnemyCastBarFrame:UnregisterEvent("UNIT_TARGET"); -- theoretically can be enabled but not been cleared
				PvE_DBInit_Done = true;
			end
		end
	end

	-- remove previously loaded boss debuffs on leaving world
	if (NECB_BossDB_loaded and (command == "unreg_main" or not CEnemyCastBar.bBossDebuff) ) then
		for k, v in pairs (CEnemyCastBar_Afflictions) do
			if (CEnemyCastBar_Afflictions[k].global and CEnemyCastBar_Afflictions[k].t > 0) then
			--clear any boss removal (0.1), but not global removals (0.0)
				CEnemyCastBar_Afflictions[k] = nil;
			end
		end
		NECB_BossDB_loaded = false;
		if (CECBOptionsFrame and CECBOptionsFrame:IsVisible()) then
			CECB_ReloadOptionsUI(); -- update tooltip
		end
	end

	--CarniEnemyCastBarFrame:RegisterAllEvents(); --for debug purposes

	if (CEnemyCastBar.bDebug) then
		if (command == "unreg_main") then
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r Debug, |cffff0000Events UNRegistered!");
		else
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r Debug, |cff00ff00Events Registered!");
		end
	end

end

function CEnemyCastBar_OnLoad()

	this:RegisterEvent("VARIABLES_LOADED");
	this:RegisterEvent("PLAYER_LEAVING_WORLD");
	this:RegisterEvent("PLAYER_ENTERING_WORLD");

	SLASH_CARNIVALENEMYCASTBAR1 = "/necb";  
	SlashCmdList["CARNIVALENEMYCASTBAR"] = function(msg)
		CEnemyCastBar_Handler(msg);
	end

end

function CEnemyCastBar_FauxUpdater(clear)

	if (clear) then
		CECBFauxFrameButton:Hide();
		necb_fauxtimer = false;
		--DEFAULT_CHAT_FRAME:AddMessage("|cff990000Cleared Fauxtimer!"..GetTime())--
	elseif (necb_fauxtimer and GetTime() - necb_fauxtimer[1] > necb_fauxtimer[5] ) then
		--DEFAULT_CHAT_FRAME:AddMessage(necb_fauxtimer[1] .. " - "..necb_fauxtimer[2]);
		--this is only called for Afflictions! (no need to check if exists)
		--control even checks if this is still running and disables it :D
		CECBFauxFrameButton:Hide();

		-- check for delayed DB_Init, because the AreaName is passed so slowly
		if (necb_fauxtimer[6] == "pass_instance") then

			if (IsActiveBattlefieldArena()) then -- reset cooldowns for arena fights
				--DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|cffffaaaa ARENA DETECTED!");
				if (#NECB_CD_DB > 0) then
					NECB_CD_DB = { };
					NECB_InfoFrame:AddMessage("|cffaaaaaaNECB:|r Arena detected -> Cooldown database cleared!", 0, 1, 0, 1, UIERRORS_HOLD_TIME);
				end

			elseif (NECB_PvE_Module_loaded and CEnemyCastBar.bStatus and (CEnemyCastBar.bPvE or (CEnemyCastBar.bShowafflict and CEnemyCastBar.bBossDebuff)) ) then


				if (CEnemyCastBar.bShowafflict and CEnemyCastBar.bBossDebuff) then
					NECB_PvE_DBInit(); -- load all spells for this instance PvE/Debuffs
				end
				NECB_PvE_DBInit(not CEnemyCastBar.bPvE);
				NECB_PvE_CodeInit(not CEnemyCastBar.bPvE);
				CEnemyCastBar_RegisterEvents(); --clears Boss Debuffs
				CEnemyCastBar_LoadDisabledSpells("mute");

				-- reapply obsolete cooldowns (modified to duration = 0); needed to add this if you enter/leave an instance (spell db reset/reloaded!)
				for k,v in pairs (NECBtchangeSourcePerm) do
					if (CEnemyCastBar_Raids[v]) then
						CEnemyCastBar_Raids[ CEnemyCastBar_Raids[v].tchange[1] ].t = CEnemyCastBar_Raids[ v ].tchange[3];
					end
				end

				local NECB_RaidsDB;
				for k,v in pairs (CEnemyCastBar_Raids) do
					NECB_RaidsDB = true;
					break;
				end
				if (not NECB_RaidsDB and not NECB_BossDB_loaded) then
					NECB_InfoFrame:AddMessage("|cffaaaaaaNECB:|r No PvE Spells for this instance found -> Sub functions cleared!", 1, 0.5, 0, 1, UIERRORS_HOLD_TIME);
				else
					NECB_InfoFrame:AddMessage("|cffaaaaaaNECB:|r PvE and/or Debuff Spells for |cff6666ff"..GetRealZoneText().."|r loaded! See tooltip(s) for details.", 0, 1, 0, 1, UIERRORS_HOLD_TIME);
				end
			end

		elseif (necb_fauxtimer[6] == "VictoryRush") then

			if (IsUsableSpell(NECB_Victory_Rush)
				and CEnemyCastBar_UniqueCheck(NECB_Victory_Rush, CEnemyCastBar_Spells[NECB_Victory_Rush].t, UnitName("player"), nil, nil, nil, "allgains") == 0
			) then
				CEnemyCastBar_Show(UnitName("player"), NECB_Victory_Rush, CEnemyCastBar_Spells[NECB_Victory_Rush].t - 0.75, "gainsfriend", nil, CEnemyCastBar_Spells[NECB_Victory_Rush].icontex);
			end
		else

			if (not (CEnemyCastBar_Afflictions[necb_fauxtimer[2]].spellbreaker and not necb_fauxtimer[6]) ) then
			--necb_fauxtimer[6] will be set by 'spellbreakers' in interrupt function
				if (CEnemyCastBar_Afflictions[necb_fauxtimer[2]].callspell) then
					necb_fauxtimer[2] = CEnemyCastBar_Afflictions[necb_fauxtimer[2]].callspell;
				end

				local spell = necb_fauxtimer[2];
				if (necb_fauxtimer[7]) then
					spell = spell .." ".. necb_fauxtimer[7]; -- rebuild spell's brackets
				end

				if (CEnemyCastBar_Afflictions[necb_fauxtimer[2]].periodicdmg) then

					CEnemyCastBar_Control(necb_fauxtimer[3], spell, "periodicdmg", nil, event);
				else
					CEnemyCastBar_Control(necb_fauxtimer[3], spell, "afflicted", nil, event); --even broadcasts CC's
				end
		
				if (necb_fauxtimer[4] and necb_fauxtimer[4] > 1) then
					-- don't use 'spell' here, it is stored without brackets in bar (although it appears in bar's label)
					-- add necb_fauxtimer[7] to necb_fauxtimer[4] if anyday spells with brackets have a stack counter, too ;-)
					CEnemyCastBar_UniqueCheck(necb_fauxtimer[2], "renew", necb_fauxtimer[3], "trueupdate", "("..necb_fauxtimer[4]..")", nil, nil); --+1 because debuff not updated, yet.; last 'nil' was "allgains" before, but debuffs need to be updated, too.
				end
			end
		end
		necb_fauxtimer = false;
	end

end

function NECB_ConvertPattern(pattern) --convert patterns

	pattern = string.gsub(pattern, "%%%d", ""); --remove %n

	pattern = string.gsub(pattern, "%$ss ", "$s "); --change $ss to $s --fix german problem; NECB only uses string.match, so it does not matter if mob's or mobs and not mob ;-)
	 pattern = string.gsub(pattern, "'%$s'", "(.+)"); --change '$s' to (.+)
	  pattern = string.gsub(pattern, "%$s", "(.+)"); --change $s to (.+)
	  pattern = string.gsub(pattern, "%$d", "(.+)"); --change $d to (.+)

	pattern = string.gsub(pattern, "'%%s'", "(.+)"); --change '%s' to (.+)
	 pattern = string.gsub(pattern, "%%s", "(.+)"); --change %s to (.+)
	 pattern = string.gsub(pattern, "%%d", "(.+)"); --change %d to (.+)

	--DEFAULT_CHAT_FRAME:AddMessage(pattern);--

	return pattern;
end



function NECB_SpellStart(arg1, update) --SpellCastStart outsourced

	if ((arg1 == "target" or (arg1 == "focus" and CEnemyCastBar.bFocusPvP)) and not UnitIsUnit(arg1, "player")) then
		local UCI_spell, UCI_rank, UCI_icon, UCI_startTime, UCI_endTime, channeling;
		UCI_spell, UCI_rank, _, UCI_icon, UCI_startTime, UCI_endTime = UnitCastingInfo(arg1);
		if (not UCI_spell) then -- try again with channeling (since on target swap we can't catch start event :/)
			UCI_spell, UCI_rank, _, UCI_icon, UCI_startTime, UCI_endTime = UnitChannelInfo(arg1);
			channeling = true;
		end
		if (not UCI_spell or (CEnemyCastBar_PvECheck((UnitName(arg1)), UCI_spell, bcasted, event) and CEnemyCastBar_Raids[UCI_spell].c ~= "hostile") ) then
			return;	-- do not overwrite PvE cooldowns with same same; they will be called globally anyway!
		end
		local TargetName = UnitName(arg1);

		-- check if spell has brackets in its name; REMOVE if color makes no difference (not red colored if unknown)!
		local fbracket,_,spellstacks = string.find(UCI_spell, "(%(.+%))" );
		if (fbracket) then
			UCI_spell = string.sub(UCI_spell, 1, fbracket - 2);
		end

		if (UnitIsPlayer(arg1)) then
			UCI_rank = string.match(UCI_rank, "(%d+)");
		else
			UCI_rank = nil;
		end

		if (CEnemyCastBar_Spells[UCI_spell]) then

			-- disable gains bar permanently, because it will be catched as channeled cast since 6.6.x (bad for global pvp :/)
			if (channeling) then
				CEnemyCastBar_Spells[UCI_spell].channeled = true; -- do not clear CD if interrupted! *oh well, so many points to consider*
				if (CEnemyCastBar.bGains and not CEnemyCastBar.bGlobalPvP and CEnemyCastBar_Spells[UCI_spell].t) then
					CEnemyCastBar_Spells[UCI_spell].tdis = CEnemyCastBar_Spells[UCI_spell].t; -- reset with gloabl pvp
					CEnemyCastBar_Spells[UCI_spell].t = 0;
				end
			end

			-- rebuild original spellname for casts
			if (spellstacks) then
				UCI_spell = UCI_spell.." "..spellstacks;
			end

			local castime = (UCI_endTime - UCI_startTime)/1000;
			local alreadyshowing = CEnemyCastBar_UniqueCheck(UCI_spell, castime, TargetName, "trueupdate", nil, channeling,"casts");
			if (alreadyshowing == 0) then
				if (channeling) then
					--calls control, because of cooldown database!
					CEnemyCastBar_Control(TargetName, UCI_spell, "casts", castime, "UNIT_SPELLCAST_CHANNEL_START", UCI_rank);
				else
					CEnemyCastBar_Control(TargetName, UCI_spell, "casts", castime, "UNIT_SPELLCAST_START", UCI_rank);
				end

			end
			--DEFAULT_CHAT_FRAME:AddMessage("Duration: "..castime.." - Mob: "..TargetName);

		elseif (not CEnemyCastBar_Raids[UCI_spell]) then -- reinserted check, because of spell channel detection with 6.6.x
			UCI_icon = string.sub(UCI_icon, 17, string.len(UCI_icon) );
			local castime = (UCI_endTime - UCI_startTime)/1000;
			local alreadyshowing = CEnemyCastBar_UniqueCheck(UCI_spell, castime, TargetName, "trueupdate", nil, channeling, "casts");
			if (alreadyshowing == 0) then
				local ctype;
				if (UnitIsEnemy("player", arg1) ) then
					ctype = "hostile";
				else
					ctype = "friendly";
				end
				CEnemyCastBar_Show(TargetName, UCI_spell, castime, ctype, turnlabel_, UCI_icon, "unkown spell", UCI_rank, nil, channeling) -- "unkown spell" colors the text green to know about it
			end
			--DEFAULT_CHAT_FRAME:AddMessage("Duration: "..castime.." - Mob: "..TargetName.." - Icon: "..UCI_icon);
		end

		if (update) then
			-- copied from spelldelay event:
			CEnemyCastBar_UniqueCheck(UCI_spell, UCI_startTime/1000, (UnitName(arg1)), "trueupdate", "delay", UCI_endTime/1000,"casts");
		end
	end
end

function CEnemyCastBar_OnEvent(event) --onevent

	-- for debug purposes
	if (CEnemyCastBar and CEnemyCastBar.bDebug) then
		if (not arg1) then
			arg1 = "";
		end
		--if (event == "CHAT_MSG_SPELL_SELF_DAMAGE") then
		DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r Debug, OnEvent: "..arg1.." (event: |cffffff00"..event.."|r)");
		--end
	end
	
	if (event == "PLAYER_COMBO_POINTS") then

		if (CECBownCPsLast and GetComboPoints() < CECBownCPsLast) then

			CECBownCPsHit = CECBownCPsLast;
			CECBownCPsHitTime = GetTime();

			-- check if there was a finishing move right before you lost all CPs (the server might create a difference up to 500ms between those two events!)
			--CECBownCPsHitBuffer = {mob, spell, GetTime(), DRTimer }; -- just to understand what 1,2,3,4 stands for; defined in 'control' function (affliction)^
			if (CECBownCPsHitBuffer and (CECBownCPsHitTime - CECBownCPsHitBuffer[3]) < 1) then

				local CPSpell = CECBownCPsHitBuffer[2];
				castime = CEnemyCastBar_Afflictions[CPSpell].t - (CEnemyCastBar_Afflictions[CPSpell].cpinterval * (5 - CECBownCPsHit));

				local CPDRTimer = CECBownCPsHitBuffer[4];
				if (CPDRTimer == 4 or CPDRTimer == 6) then
					castime = castime / (CPDRTimer - 2);
				end

				CEnemyCastBar_UniqueCheck(CPSpell, castime - (CECBownCPsHitTime - CECBownCPsHitBuffer[3]), CECBownCPsHitBuffer[1], "trueupdate", nil, nil, "afflictions"); --update bar duration
				CECBownCPsHitTime = false; -- spell already updated no need to wait 1 (before 3) secs for new afflictions
			end
		end
		CECBownCPsLast = GetComboPoints();
		CECBownCPsHitBuffer = false;

	elseif (event == "UNIT_SPELLCAST_SENT") then
		necbsc_sent_target = arg4;
		--DEFAULT_CHAT_FRAME:AddMessage(arg1 .. " - "..arg2.." - " .. arg3 .. " - ".. necbsc_sent_target);

	elseif (event == "UNIT_SPELLCAST_SUCCEEDED") then
		--DEFAULT_CHAT_FRAME:AddMessage(arg1 .. " - "..arg2.." - " .. arg3);
		--"player", spell, rank

		 -- specials
		if (arg2 == NECB_Summon_Water and CEnemyCastBar.bPvP) then
			if (CEnemyCastBar_Spells[NECB_Summon_Water] and not CEnemyCastBar_Spells[NECB_Summon_Water].disabled) then
				CEnemyCastBar_Show(UnitName("player"), NECB_Summon_Water, CEnemyCastBar_Spells[NECB_Summon_Water].t, "gainsfriend", nil, CEnemyCastBar_Spells[NECB_Summon_Water].icontex);
			end
		elseif (arg2 == NECB_Shadowfiend and CEnemyCastBar.bPvP) then
			if (CEnemyCastBar_Spells[NECB_Shadowfiend] and not CEnemyCastBar_Spells[NECB_Shadowfiend].disabled) then
				CEnemyCastBar_Show(UnitName("player"), NECB_Shadowfiend, CEnemyCastBar_Spells[NECB_Shadowfiend].t, "gainsfriend", nil, CEnemyCastBar_Spells[NECB_Shadowfiend].icontex);
			end
		 -- common
		elseif ((necbsc_sent_target and necbsc_sent_target ~= "") or UnitName("target")) then

			-- new with NECB 6.9.x, to update focus bars
			local necb_unit = "target";
			if (UnitName("focus") == necbsc_sent_target) then
				necb_unit = "focus";
			end

			local mob = UnitName(necb_unit);
			if (necbsc_sent_target and necbsc_sent_target ~= "") then
				mob = necbsc_sent_target;
			end

 			-- check if spell has brackets, remove and store separately
			local fbracket,_,spellstacks = string.find(arg2, "(%(.+%))" );
			if (fbracket) then
				arg2 = string.sub(arg2, 1, fbracket - 2);
			end

			if (CEnemyCastBar_Afflictions[arg2]
				and not CEnemyCastBar_Afflictions[arg2].multi --will show/renew the bar anyway
				and not (CEnemyCastBar_Afflictions[arg2].stun or CEnemyCastBar_Afflictions[arg2].stuntype) --block them, DRs+Immunity...
				and not (CEnemyCastBar_Afflictions[arg2].disabled)
				and not (CEnemyCastBar_Afflictions[arg2].magecold and not CEnemyCastBar.bMageC) -- currently only frostbolt
			) then

				local dilate = 0.25;
				if (CEnemyCastBar_Afflictions[arg2].flying) then
					if (not CheckInteractDistance(necb_unit, 4)) then
						dilate = 1.45;
					elseif (CheckInteractDistance(necb_unit, 1)) then
						dilate = 0.5;
					else
						dilate = 1.2;
					end
				end
					--DEFAULT_CHAT_FRAME:AddMessage(dilate); --
				if (	(CEnemyCastBar_Afflictions[arg2].periodicdmg
					or CEnemyCastBar_Afflictions[arg2].notdetected) -- trigger bar if not detected by combatlog spells
					and not UnitIsFriend("player", necb_unit)
				) then

					if (CEnemyCastBar_Afflictions[arg2].notdetected and CEnemyCastBar_Afflictions[arg2].spellbreaker) then
						dilate = 0.4; -- 'Counterspell' needs from 5 to 350ms; will be instantly triggered anyway if red bar found
						--DEFAULT_CHAT_FRAME:AddMessage("|cff009900Fauxtimer Set!"..GetTime())--
					end
					if (not necb_fauxtimer) then -- protect instance entered timer
						necb_fauxtimer = {GetTime(), arg2, mob, 0, dilate};
						CECBFauxFrameButton:Show(); -- wait for spell 'failed' events
					end

				elseif ( mob == UnitName(necb_unit)
					and not(CEnemyCastBar_Afflictions[arg2].fragile and UnitIsPlayer(necb_unit)) -- block PvP CC's
					and not CEnemyCastBar_Afflictions[arg2].norenew -- fix for german clients Freezing Trap (without 'effect' :/ )
				) then

					local oldarg2 = arg2;
					if (CEnemyCastBar_Afflictions[arg2].callspell) then
						if (CEnemyCastBar_Afflictions[arg2].tskill) then -- only used by scorch and checks talent points
							local _, _, _, _, currRank = GetTalentInfo(CEnemyCastBar_Afflictions[arg2].tskill[1], CEnemyCastBar_Afflictions[arg2].tskill[2]);
							if (currRank ~= CEnemyCastBar_Afflictions[arg2].tskill[3]) then -- no class check needed, because this spellname can only be triggered by the proper one
								return;
							end
						end
						arg2 = CEnemyCastBar_Afflictions[arg2].callspell;
					end
					local i, stack = 1, 0;
					while ( UnitDebuff(necb_unit,i) ) do

						if (string.match(UnitDebuff(necb_unit,i), arg2)) then
							--use string.match because of removed spell brackets
							_,_,_,stack = UnitDebuff(necb_unit,i);
							if (not necb_fauxtimer) then -- protect instance entered timer
								necb_fauxtimer = {GetTime(), oldarg2, mob, stack, dilate, nil, spellstacks};
								CECBFauxFrameButton:Show(); -- wait for spell 'failed' events
							end
							i = nil;
							break;
						end
						i=i+1;
					end
					if (i and CEnemyCastBar_Afflictions[arg2].periodicdmg) then --dot not found on mob
						CEnemyCastBar_Handler("deletebar "..arg2);
					end
				end

			elseif (CEnemyCastBar_Spells[arg2]) then

				 -- specials
				if (arg2 == NECB_Victory_Rush) then
					CEnemyCastBar_DelBar(NECB_Victory_Rush);
				end

				if (CEnemyCastBar_Spells[arg2].HoT or CEnemyCastBar_Spells[arg2].cgain) then

					local i, stack, pseudostack, DRText = 1, 0, 0;
					-- get stack counter for non HoT gains (remote gains); Livebloom +possibly others in the future
					-- and count HoTs (since 6.8.x)
					if ( mob == UnitName(necb_unit) ) then

						while ( UnitBuff(necb_unit,i) ) do
							if (UnitBuff(necb_unit,i) == arg2) then
								_,_,_,stack = UnitBuff(necb_unit,i);
								if (stack > 1 or CEnemyCastBar_Spells[arg2].cgain) then
									DRText = "("..stack..")";
									break; -- no more than one stackable spell (or cgain) possible
								else
									pseudostack = pseudostack + 1;
								end
							end
							i=i+1;
						end

						if (pseudostack > 1) then
							DRText = "("..pseudostack..")";
						end
					end
					if (CEnemyCastBar_UniqueCheck(arg2, "renew", mob, "trueupdate", DRText, nil, "allgains") == 0) then
						if (DRText or pseudostack > 0) then
							CEnemyCastBar_Control(mob, arg2, "gains", nil, "friendlyEvent"); -- trigger new bar
							if (DRText) then -- update stack counter (only Livebloom) currently, all others will trigger a new bar anyway
								CEnemyCastBar_UniqueCheck(arg2, "renew", mob, "trueupdate", DRText, nil, "allgains");
							end
						end
					end
				end
			end
		end


	--BC detects casts out of combat range and adjusts casttime duration, even detects and displays unknown spells now!
 	--Events deregistered if PvP disabled or Onlygains enabled
	elseif (event == "UNIT_SPELLCAST_START" or event == "UNIT_SPELLCAST_CHANNEL_START") then

		NECB_SpellStart(arg1); -- outsourced since used by TargetChanged function (6.6.x)

	--BC add this to detect casttime delays
	elseif (event == "UNIT_SPELLCAST_DELAYED" or event == "UNIT_SPELLCAST_CHANNEL_UPDATE") then
		if ((arg1 == "target" or (arg1 == "focus" and CEnemyCastBar.bFocusPvP)) and not UnitIsUnit(arg1, "player") ) then
			local UCI_spell, UCI_startTime, UCI_endTime;
			if (event == "UNIT_SPELLCAST_DELAYED") then
				UCI_spell, _, _, _, UCI_startTime, UCI_endTime = UnitCastingInfo(arg1);
			else
				UCI_spell, _, _, _, UCI_startTime, UCI_endTime = UnitChannelInfo(arg1);
			end
			if (not UCI_spell or (CEnemyCastBar_PvECheck((UnitName(arg1)), UCI_spell, bcasted, event) and CEnemyCastBar_Raids[UCI_spell].c ~= "hostile") ) then
				return;	-- do not overwrite PvE cooldowns with same same; they will be called globally anyway!
			end
			CEnemyCastBar_UniqueCheck(UCI_spell, UCI_startTime/1000, (UnitName(arg1)), "trueupdate", "delay", UCI_endTime/1000,"casts");
			--DEFAULT_CHAT_FRAME:AddMessage("Time: "..GetTime().." - Start: "..UCI_startTime.." - End: "..UCI_endTime);
			--BC changes made to unique function to support this
		end

	elseif (event == "UNIT_SPELLCAST_STOP" or event == "UNIT_SPELLCAST_CHANNEL_STOP") then
		if ((arg1 == "target" or (arg1 == "focus" and CEnemyCastBar.bFocusPvP)) and not UnitIsUnit(arg1, "player") and not (CEnemyCastBar_PvECheck((UnitName(arg1)), UCI_spell, bcasted, event) and CEnemyCastBar_Raids[UCI_spell].c ~= "hostile") ) then
			CEnemyCastBar_Control((UnitName(arg1)), (UnitName(arg1)), "interrupt");
		end

	elseif (event == "CHAT_MSG_MONSTER_YELL" and NECB_PvE_Module_loaded) then
	
		NECB_PvE_Yell(arg1, arg2);

	elseif (event == "CHAT_MSG_MONSTER_EMOTE" and NECB_PvE_Module_loaded) then
	
		NECB_PvE_Emote(arg1, arg2);

	elseif (event == "PLAYER_LEAVING_WORLD" and CEnemyCastBar.bStatus) then

		CEnemyCastBar_RegisterEvents("unreg_main");

		if (not CEnemyCastBar.bStatus) then
			CEnemyCastBar_Raids = { }; -- in case bStatus has been disabled while in instance (then the init function won't be called)
		end

		-- if player leaves world or does a reloadUI while movable bars, set points
		CEnemyCastBar.bLocked = false;
		CEnemyCastBar_LockPos();

	elseif (event == "PLAYER_ENTERING_WORLD") then

		-- check for loaded localized code and warn if unknown client language
		if (NECB_client_unknown) then
			UIErrorsFrame:AddMessage("Your client language is not beeing supported by NECB!", 1, 1, 1, 1, UIERRORS_HOLD_TIME);
			PlaySoundFile("Sound\\Spells\\PVPFlagTakenHorde.wav");
			NECB_client_unknown = nil;
		else
			NECB_client_known = nil;
		end

		-- big, fat initialization part after vars loaded
		-- can't be warned by VARIABLES_LOADED, because the event is fired before cvars are loaded
		if (not necbalreadywarned) then

			-- create combatlog patterns now
			NECB_create_patterns();

			if (tonumber(GetCVar("CombatLogRangeCreature")) > 30 ) then
				NECB_InfoFrame:AddMessage("|cffaaaaaaNECB:|r Increased Combatlog Range for Creatures detected!", 1, 1, 0, 1, UIERRORS_HOLD_TIME);
			end
			if (tonumber(GetCVar("CombatLogRangeFriendlyPlayers")) > 50 ) then
				NECB_InfoFrame:AddMessage("|cffaaaaaaNECB:|r Increased Combatlog Range for Players detected!", 1, 1, 0, 1, UIERRORS_HOLD_TIME);
			end
			NECB_CombatRange_warned = true;

			-- check if variable not set and catch possible points (only done once for pre 6.4.5 versions)
			if (not CEnemyCastBar.tFramePoints) then
				CEnemyCastBar.tFramePoints = { };

				-- bars have been created in vars loaded and { } initialized
				CEnemyCastBar_FPSBar_DragStop(); -- catches points and delete them: fpsbar

				CEnemyCastBar.bLocked = false;
				CEnemyCastBar_LockPos(); -- also catches points and deletes them: button
			else
				NECBCreateBars(); -- CREATE castbar buttons here, AFTER their points were cleared, because they were not found (points got from database now)

				-- set their points
				if (CEnemyCastBar.tFramePoints) then -- only set points if already catched them; otherwise they will be generated in Enter_World
					for k,v in pairs (CEnemyCastBar.tFramePoints) do
						if (getglobal(k)) then
							getglobal(k):SetPoint("TOPLEFT", "UIParent", "TOPLEFT", CEnemyCastBar.tFramePoints[k][1], CEnemyCastBar.tFramePoints[k][2] );
						end
					end
				end
			end
		end

		-- now register events AFTER all Bars have been created
		if (CEnemyCastBar.bStatus) then
			CEnemyCastBar_RegisterEvents("reg_main"); -- do not forget this loads the modules, too ;-)

			if (CEnemyCastBar.bPvP and CEnemyCastBar.bCDown and IsInInstance() ) then
				necb_fauxtimer = {GetTime(), nil, nil, nil, 2, "pass_instance"}; -- do arena check after 2 secs.
				CECBFauxFrameButton:Show(); -- wait some seconds
			end

		end

		-- initialize disabled spells AFTER Spell Database has been loaded through RegisterEvents
		if (not necbalreadywarned) then
			if ( CEnemyCastBar.tDisabledSpells and #CEnemyCastBar.tDisabledSpells > 0 ) then
				NECB_InfoFrame:AddMessage("|cffaaaaaaNECB:|r Manually disabled Spells detected!\n|cffffffffSee ChatWindow for more info.", 1, 0.5, 0, 1, UIERRORS_HOLD_TIME);
				CEnemyCastBar_LoadDisabledSpells("mute");
				CEnemyCastBar_Handler("disabled");
			end
		end

		necbalreadywarned = true;

	elseif ((event == "PLAYER_REGEN_DISABLED" or (event == "UNIT_TARGET" and (arg1 == "target" or arg1 == "focus"))) and NECB_PvE_Module_loaded) then

		CEnemyCastBar_Player_Enter_Combat(arg1);

	elseif (event == "PLAYER_TARGET_CHANGED") then

		CEnemyCastBar_Player_Target_Changed();

	elseif (event == "CHAT_MSG_RAID" or event == "CHAT_MSG_RAID_LEADER" or event == "CHAT_MSG_BATTLEGROUND" or event == "CHAT_MSG_BATTLEGROUND_LEADER") then

		CEnemyCastBar_Parse_RaidChat(arg1, arg2, "Raid");

	elseif (event == "CHAT_MSG_PARTY") then

		CEnemyCastBar_Parse_RaidChat(arg1, arg2, "Party");

	elseif (event == "CHAT_MSG_ADDON") then
	
		if (string.sub(arg1, 1, 4) == "NECB") then

			-- necb network infos + calls the parse function: CEnemyCastBar_Parse_RaidChat(arg2, arg4, arg1="NECB, NECBCHAT, NECBCTRA");

			local msg = arg2;
			local msgsender = arg4;

			local necbcmdcheck, necbtcolor = CEnemyCastBar_Parse_RaidChat(msg, msgsender, arg1); -- calls the parse function!
			if (not necbtcolor) then
				necbtcolor = "|cffcccccc";
			end
			if (necbcmdcheck) then

				if ( NECBParserCollect[100] ) then
					table.remove (NECBParserCollect, 1);
				end

				local startpos;
				if (string.sub (msg, 1, 11) == ".cecbspell ") then
					startpos = 12;
					if (necb_numspellcast == 99) then
						necb_numspellcast = 0;
						numsender = " (|cffffffffS|cffffaaaa):";
					elseif (wrongclient) then
						numsender = " (|cffccccccC|cffffaaaa):";
					elseif (necb_numspellcast > 0 and msgsender ~= UnitName("player")) then
						numsender = " (|cffffff00"..necb_numspellcast.."|cffffaaaa):";
					else
						numsender = ":";
					end

				elseif (string.sub (msg, 1, 7) == "<NECB> ") then
					startpos = 8;
					numsender = ":";
					
				else
					startpos = 1;
					numsender = ":";
				end

				-- reduce length of line
				local i, cropped = 0, "";
				CECBParserFauxText:SetText("|cffffaaaa"..msgsender..numsender.." |cffcccccc"..string.sub (msg, startpos, string.len (msg)));
				if(necbprint2combat and ChatFrame2) then
					ChatFrame2:AddMessage("|cffaaaaaaNECB: [ |cffffaaaa"..msgsender..numsender.." "..necbtcolor..string.sub (msg, startpos, string.len (msg)) .."|cffaaaaaa ]");
				end
				while (CECBParserFauxText:GetStringWidth() > 410) do
					i = i + 1;
					CECBParserFauxText:SetText("|cffffaaaa"..msgsender..numsender.." |cffcccccc"..string.sub (msg, startpos, string.len (msg) -i));
				end

				if (i ~= 0) then
					cropped = "|cffffaaaa...";
				else
					cropped = "";
				end

				table.insert (NECBParserCollect, "|cffffaaaa"..msgsender..numsender.." "..necbtcolor..string.sub (msg, startpos, string.len (msg) -i)..cropped);

				if (CECBParser) then
					if (necb_parserline == 0) then
						CEnemyCastBar_ParserOnClick();
					else
						CECBCTRAParserFrameBOTTOMArrowFlash:Show();
						CEnemyCastBar_ParserOnClick("up");
					end
				end

			end
		end

	elseif ( event == "VARIABLES_LOADED" ) then

		DEFAULT_CHAT_FRAME:AddMessage("|cffffff00Natur EnemyCastBar |cffcccc00("..CECB_status_version_txt..")|cffffff00:|cffffffff AddOn loaded. Use |cff00ff00/necb|cffffffff to configure.");
		NECBVersionDB = { };
		NECBVersionNames = { };
		NECBParserCollect = { };
		NECBtchangeSource = { };
		NECBtchangeSourcePerm = { };
		NECB_CD_DB = { };
		NECB_DR_DB = { }; --DR

		-- needed for disabled colors set with Entering_world event
		CEnemyCastBar_Colors = {
		["Bartype friendly"] = { };
		["Bartype hostile"] = { };
		["Bartype gainsfoe"] = { };
		["Bartype gainsfriend"] = { };
		["Bartype afflict"] = { };
		["Bartype stuns"] = { };
		["Bartype dots"] = { };
		["Bartype cooldown"] = { };
		["Bartype grey"] = { };
		}

		if ( not CEnemyCastBar ) then
			CEnemyCastBar_DefaultVars();
		end

		-- my addons support, used for helpframe, too!

			CEnemyCastBarHelp = {}; 
			CEnemyCastBarHelp[1] = "|cff00ff00/necb |cffffffff- Toggles the options window.";
			CEnemyCastBarHelp[1] = CEnemyCastBarHelp[1].."\n".."|cff00ff00/necb |cffff0000clear |cffffffff- Removes all castbars from screen";
			CEnemyCastBarHelp[1] = CEnemyCastBarHelp[1].."\n".."|cff00ff00/necb |cffff0000gcinfo |cffffffff- Display memory usage of all addons";
			CEnemyCastBarHelp[1] = CEnemyCastBarHelp[1].."\n".."|cff00ff00/necb |cffff0000versions |cffffffffor |cff00ff00gversions |cffffffff- Show Group/GuildMembers NECB versions.";
			CEnemyCastBarHelp[1] = CEnemyCastBarHelp[1].."\n".."|cff00ff00/necb |cffff0000parser |cffffffff- Opens the NECB - AddOn Channel parser.";
			CEnemyCastBarHelp[1] = CEnemyCastBarHelp[1].."\n".."|cff00ff00/necb |cffff0000chat |cffffff99Text |cffffffff- Sends '|cffffff99Text|cffffffff' to other NECB's in your group. Happy Chatting...";
			CEnemyCastBarHelp[1] = CEnemyCastBarHelp[1].."\n".."|cff00ff00/necb |cffff0000cooldowns |cffffffff- Displays all Cooldowns currently in Database.";
			CEnemyCastBarHelp[1] = CEnemyCastBarHelp[1].."\n".."|cff00ff00/necb |cffff0000wipe |cffffffff- Plays the Benny Hill sound for the Raid's joy."
			CEnemyCastBarHelp[1] = CEnemyCastBarHelp[1].."\n".."|cff00ff00/necb |cffff0000setrange |cff00ff00allmax |cffffffffor |cff00ff00cmax |cffffffff- Adjusts the CombatLogRange! |cff00ff00allmax|cffffffff = set all Ranges to max, |cff00ff00cmax|cffffffff = only creature messages maxed, |cff00ff00leave blank|cffffffff = defaults.\n\n";

			CEnemyCastBarHelp[2] = "|cff00ff00/necb deletebar |cffffff99Label |cffffffff- Deletes ALL CastBars which inherit '|cffffff99Label|cffffffff' |cffccccccand|cffffffff match your targets name!";
			CEnemyCastBarHelp[2] = CEnemyCastBarHelp[2].."\n".."|cff00ff00/necb showbar |cffffff99Spell |cfffffffftriggers a bar for your current target. It |cffccccccincludes a check|cffffffff: HoTs are only triggered on friendly targets, DoTs only on hostile targets!";
			CEnemyCastBarHelp[2] = CEnemyCastBarHelp[2].."\n\n".."|cff00ff00/necb |cffff0000countsec|cffffff99 sss Label |cffffffff- Starts a countdown of |cffffff99sss|cffffffff seconds. |cffffff99Label|cffffffff is optional.";
			CEnemyCastBarHelp[2] = CEnemyCastBarHelp[2].."\n".."|cff00ff00/necb countmin |cffffff99mmm Label |cffffffff- Starts a countdown of |cffffff99mmm|cffffffff minutes";
			CEnemyCastBarHelp[2] = CEnemyCastBarHelp[2].."\n".."|cff00ff00/necb repeat |cffffff99sss Label |cffffffff- Repeated countdown of |cffffff99sss|cffffffff seconds";
			CEnemyCastBarHelp[2] = CEnemyCastBarHelp[2].."\n".."|cff00ff00/necb stopcount |cffffff99Label |cffffffff- Stops all grey CastBars which inherit '|cffffff99Label|cffffffff'\n";

			CEnemyCastBarHelp[3] = "|cffff0000* |cff00ff00countmin|cffffffff, |cff00ff00countsec|cffffffff, |cff00ff00stopcount|cffffffff and |cff00ff00chat|cffffffff support these placeholders:";
			CEnemyCastBarHelp[3] = CEnemyCastBarHelp[3].."\n".."|cffffff99%t|cffffffff = TargetName, |cffffff99%tt|cffffffff = ToTName, |cffffff99%c|cffffffff = TClassName, |cffffff99%g|cffffffff = TRaidGroupNumber; |cffffff99Example|cffffffff: |cff00ff00/necb countmin |cffffff995 ReBuff %t in Group%g";
			CEnemyCastBarHelp[3] = CEnemyCastBarHelp[3].."\n".."|cffff0000* |cffffffffYou may also try |cffff0000.|cff00ff00countsec|cffffffff, |cff00ff00.countmin|cffffffff, |cff00ff00.stopcount|cffffffff. (A point at first!)";
			CEnemyCastBarHelp[3] = CEnemyCastBarHelp[3].."\n".."|cffffff99Example: |cffffffffType |cff00ff00.countsec |cffffff9910 Ten Seconds|cffffffff into the raid-channel. Everyone in your Raid with NECB and enabled Channel-Parsing will see the bar!";
			CEnemyCastBarHelp[3] = CEnemyCastBarHelp[3].."\n".."|cffff0000/script NECB_SendMessage(\"|cffffff99.countmin 15 Nefe respawn|cffff0000\"); |cffffffffwill trigger a bar for all your group members in a '|cffccccccsilent|cffffffff' way!";
			CEnemyCastBarHelp[3] = CEnemyCastBarHelp[3].."\n\n".."|cffff0000SHIFT + LeftClick |cffffffffdeletes the bar, |cffff0000ALT + LeftClick |cffffffffdeletes all bars\n\n";

			CEnemyCastBarHelp[4] = "|cffff0000SHIFT + RightClick |cffffffffdisables the Spell! |cffff0000ALT + RightClick |cffffffffdisables the Color!";
			CEnemyCastBarHelp[4] = CEnemyCastBarHelp[4].."\n".."|cff00ff00/necb disabled |cfffffffflists disabled spells.";
			CEnemyCastBarHelp[4] = CEnemyCastBarHelp[4].."\n".."|cff00ff00/necb restore |cffffffffrestores ALL disabled spells!";
			CEnemyCastBarHelp[4] = CEnemyCastBarHelp[4].."\n".."|cff00ff00/necb enable |cffffff99spell |cffffffffor |cffffff99No. |cffffffffremoves the spell from the list of disabled spells!";
			CEnemyCastBarHelp[4] = CEnemyCastBarHelp[4].."\n".."|cff00ff00/necb disable |cffffff99spell |cffffffffadds the spell to the list of disabled spells!";
			CEnemyCastBarHelp[4] = CEnemyCastBarHelp[4].."\n\n".."|cff00ff00/necb |cffff0000forcebc|cffffff99 Raidmember |cffffffffwill force '|cffffff99Raidmember|cffffffff' to broadcast CastBars by changing his/her settings!";
			CEnemyCastBarHelp[4] = CEnemyCastBarHelp[4].."\n".."|cff00ff00/necb stopbc |cffffff99Raidmember |cffffffffstops broadcasting Bars!\n|cffffff99Hint:|cffffffff Instead of using '|cffffff99Raidmember|cffffffff' you may simply target the player.\nBoth, force and stop, require 'leader' or 'promoted'!\n\n";

			CEnemyCastBarHelp[5] = "|cffffff99LeftClick|cffffffff on the 'movable bar' Button fastly to increase the bars duration up to 5 Minutes.";
			CEnemyCastBarHelp[5] = CEnemyCastBarHelp[5].."\n".."|cffffff99RightClick|cffffffff on the 'movable bar' Button will clear all bars.";

		if (myAddOnsFrame_Register) then

			CEnemyCastBarDetails = { 
				name = "CEnemyCastBar", 
				version = CECB_status_version_txt, 
				releaseDate = "2006", 
				author = "Naturfreund", 
				email = "Use my forum or curse-gaming.com", 
				website = "http://www.digital-joker.de/forum", 
				category = MYADDONS_CATEGORY_COMBAT
				};

			myAddOnsFrame_Register(CEnemyCastBarDetails, CEnemyCastBarHelp); 
		end 
                
		-- new variables for new versions
		if (CEnemyCastBar.bParseC == nil) then CEnemyCastBar.bParseC = true; end
		if (CEnemyCastBar.bGains == nil) then CEnemyCastBar.bGains = true; end
		if (CEnemyCastBar.bFlashit == nil) then CEnemyCastBar.bFlashit = true; end
		if (CEnemyCastBar.bGlobalFrag == nil) then CEnemyCastBar.bGlobalFrag = true; end
		if (CEnemyCastBar.bSpace == nil) then CEnemyCastBar.bSpace = 15; end
		if (CEnemyCastBar.bMiniMap == nil or (CEnemyCastBar.bMiniMap ~= false and CEnemyCastBar.bMiniMap ~= 0) ) then
			CEnemyCastBar.bMiniMap = true;
		else 	CEnemyCastBar.bMiniMap = false;
		end
		if (not CEnemyCastBar.bMiniMapPos) then CEnemyCastBar.bMiniMapPos = 356; end
		if (not CEnemyCastBar.bMiniMapRadius) then CEnemyCastBar.bMiniMapRadius = 80; end
		if (CEnemyCastBar.bShowIcon == nil) then CEnemyCastBar.bShowIcon = true; end
		if (CEnemyCastBar.bnecbCBLBias == nil) then CEnemyCastBar.bnecbCBLBias = 20; end
		if (CEnemyCastBar.bSpellBreaks == nil) then CEnemyCastBar.bSpellBreaks = false; end
		if (CEnemyCastBar.bCDown == nil) then CEnemyCastBar.bCDown = true; end
		if (CEnemyCastBar.bSmallTSize == nil) then CEnemyCastBar.bSmallTSize = true; end
		if (CEnemyCastBar.bSoloD == nil) then CEnemyCastBar.bSoloD = true; end
		if (CEnemyCastBar.bDRTimer == nil) then CEnemyCastBar.bDRTimer = true; end
		if (CEnemyCastBar.bClassDR == nil) then CEnemyCastBar.bClassDR = true; end
		if (CEnemyCastBar.bSDoTs == nil) then CEnemyCastBar.bSDoTs = true; end
		if (CEnemyCastBar.bPvEWarn == nil) then CEnemyCastBar.bPvEWarn = true; end
		if (CEnemyCastBar.bMouseBar == nil) then -- settings for upgrade to 5.7.0
			CEnemyCastBar.bMouseBar = true; CEnemyCastBar.bDisBorder = true; CEnemyCastBar.bBarTexture = 0;
			CEnemyCastBar.bSpace = 15; CEnemyCastBar.bAlpha = 0.8; CEnemyCastBar.bnecbCBLBias = 20;
		end
		if (CEnemyCastBar.bBossDebuff == nil) then CEnemyCastBar.bBossDebuff = true; end
		if (CEnemyCastBar.tColor == nil) then
			CEnemyCastBar_SetBarColors();
		else
			if (CEnemyCastBar.tColor[8] == nil) then
				table.insert(CEnemyCastBar.tColor, 7, { 0.5, 0.2, 0.1 } );
			end
			if (CEnemyCastBar.tColor[9] == nil) then
				table.insert(CEnemyCastBar.tColor, 5, { 0.7, 0, 0.85 } );
			end
			if (#CEnemyCastBar.tColor ~= 9) then
				CEnemyCastBar_SetBarColors(); -- reset, something has gone wrong
			end
		end
		if (not CEnemyCastBar.tDisabledSpells) then CEnemyCastBar.tDisabledSpells = { }; end
		if (not CEnemyCastBar.bNumBarsSep) then CEnemyCastBar.bNumBarsSep = 4; end
		if (not CEnemyCastBar.bBarFont) then CEnemyCastBar.bBarFont = 0; end
		if (CEnemyCastBar.bFocusPvP == nil) then CEnemyCastBar.bFocusPvP = true; CEnemyCastBar.bFocusDebuffs = true; end
		if (CEnemyCastBar.bFillupGains == nil) then CEnemyCastBar.bFillupGains = true; CEnemyCastBar.bFillupDebuffs = true; CEnemyCastBar.bFillupDoTs = true; end
		if (CEnemyCastBar.bPvPSoundWarn == nil) then CEnemyCastBar.bPvPSoundWarn = true; end

		-- initialize addon from settings now
		if (CEnemyCastBar.bTempFPSBar) then
			CECB_FPSBarFree:Show();
		end
		if (CEnemyCastBar.bFPSBarLocked) then
			CECB_FPSBarFree:EnableMouse(0);
		end
		if (CEnemyCastBar.bSeparateBars) then
			CEnemyCastBar.bNumBars = CEnemyCastBar.bNumBarsSep * 9;
		end
		if (not CEnemyCastBar.tFramePoints) then
			NECBCreateBars(); -- CREATE castbar buttons to catch their points in entering_world, before their points were cleared (because they were not found if loaded on entering_world)
		end

		CEnemyCastBar.bDebug = false;

		-- all called in NECBCreateBars(); and because at least some bars are created those functions will be called!
			-- and because the layout cache is loaded after variables I have to move the initialization into entering_world for non seperated!!! took me hours to understand :O
			--CEnemyCastBar_FlipBars();
			--CEnemyCastBar_SetTextSize();
			--CEnemyCastBar_SetBorder();
			--CEnemyCastBar_SetTexture();
			--CEnemyCastBar.bLocked = true; -- remove if lock-option is inserted again
			--CEnemyCastBar_LockPos();
		CECBownCPsHit = 5; -- Set Combopoints to max for all classes, Rogue/DruidClass will fire an event to change this dynamically


		-- show/hide Minimap button and set localized tooltip
		if (CEnemyCastBar.bMiniMap) then

			if (not CEnemyCastBar.bStatus) then
				CECBMiniMapButtonTexture:SetTexture("Interface\\AddOns\\CEnemyCastBar\\Images\\CECBButton_off");
			end
			CECBMiniMapButton:SetPoint("TOPLEFT", "Minimap", "TOPLEFT", 52 - (CEnemyCastBar.bMiniMapRadius * cos(CEnemyCastBar.bMiniMapPos)), (CEnemyCastBar.bMiniMapRadius * sin(CEnemyCastBar.bMiniMapPos)) - 52);
			CECBMiniMapButton:Show();
		else
			CECBMiniMapButton:Hide();
		end
		CECBMiniMapButton.tooltip = NECB_Minimap_Tooltip;

 		-- variables for the addon channel parser
		necb_numspellcast = 0; necb_parserline = 0;
		for i=1, 85 do
			table.insert (NECBParserCollect, "|cffcccccc- |cff666666"..i.."|cffcccccc -");
		end
		table.insert (NECBParserCollect, " ");
		table.insert (NECBParserCollect, "|r==================================");
		table.insert (NECBParserCollect, "|cffffff00Welcome to the NECB AddOn Channel Parser!");
		table.insert (NECBParserCollect, "This parser displays all NECB commands/broadcasts received by your client.");
		table.insert (NECBParserCollect, " ");
		table.insert (NECBParserCollect, "It follows this pattern:");
		table.insert (NECBParserCollect, "|cffffaaaaBroadcaster: |cffccccccDetected AddOn Message [, ClientLanguage, Latency]|cffffff00");
		table.insert (NECBParserCollect, "|cffccccccgrey|cffffff00 = automatic message; |cffffffccbright yellow|cffffff00 = triggered by user input");
		table.insert (NECBParserCollect, "|cffffaaaa(|cffffffffS|cffffaaaa)|cffffff00 = Sender who triggered a castbar for you. |cffffaaaa(|cffccccccC|cffffaaaa)|cffffff00 = Wrong client!");
		table.insert (NECBParserCollect, "|cffffaaaa(|cffffff00n|cffffaaaa)|cffffff00 = n useless broadcasts of this spell event.|cffffff00");
		table.insert (NECBParserCollect, " ");
		table.insert (NECBParserCollect, "100 lines are buffered. Use up/down at topright to scroll the lines.");
		table.insert (NECBParserCollect, "I tried to make it work like the default chatframe :D");
		table.insert (NECBParserCollect, "|r==================================");
		table.insert (NECBParserCollect, " ");
		-- necb parser finished

		necbEPTime = 180; -- Duration (in s) until the Engage Protection is shut off

	else

		CEnemyCastBar_Gfind(arg1, event);
	
	end
	
end

function CEnemyCastBar_ParserOnClick(msg)

	if (msg) then
		if ((msg == "down" or msg == -1) and necb_parserline < 0) then
			necb_parserline = necb_parserline + 1;
	
		elseif ((msg == "up"  or msg == 1) and necb_parserline > -80) then
			necb_parserline = necb_parserline - 1;
	
		elseif (msg == 0) then
			necb_parserline = 0;
			CECBCTRAParserFrameUPArrow:Enable();
		end

		if (necb_parserline == -80) then
			CECBCTRAParserFrameUPArrow:Disable();
		elseif (necb_parserline == 0) then
			CECBCTRAParserFrameDOWNArrow:Disable();
			CECBCTRAParserFrameBOTTOMArrow:Disable();
			CECBCTRAParserFrameBOTTOMArrowFlash:Hide();
		else
			CECBCTRAParserFrameUPArrow:Enable();
			CECBCTRAParserFrameDOWNArrow:Enable();
			CECBCTRAParserFrameBOTTOMArrow:Enable();
		end
	end

	CECBCTRAParserFrameLineText:SetText(necb_parserline);
	local parserstring = table.concat (NECBParserCollect, "\n", 81 + necb_parserline, 100 + necb_parserline);
	CECBCTRAParserFrameBGText:SetText(parserstring);
	
end

function CEnemyCastBar_ParserButton_OnUpdate(elapsed)
	if (this:GetButtonState() == "PUSHED") then
		this.clickDelay = this.clickDelay - elapsed;
		if ( this.clickDelay < 0 ) then
			local name = this:GetName();
			if ( name == this:GetParent():GetName().."DOWNArrow" ) then
				CEnemyCastBar_ParserOnClick("down");
			elseif ( name == this:GetParent():GetName().."UPArrow" ) then
				CEnemyCastBar_ParserOnClick("up");
			end
			this.clickDelay = MESSAGE_SCROLLBUTTON_SCROLL_DELAY;
		end
	end
end

function CEnemyCastBar_DelBar(msg, type) --delete castbar by label

	for i=1, CEnemyCastBar.bNumBars do
		local label = getglobal("Carni_ECB_"..i).label;
		local ctype = getglobal("Carni_ECB_"..i).ctype;
		if (label and string.find(label, msg) and not (type and not (ctype == "friendly" or ctype == "hostile")) ) then
				CEnemyCastBar_HideBar(i);
		end
	end
end

function CEnemyCastBar_HideBar(num, shiftright, useradd) --hide + disable spells

	local button, fauxbutton

	if (num) then
		button = getglobal("Carni_ECB_"..num);
	end

	if (shiftright or useradd) then
		local disabled = false;
		local spell;

		if (useradd) then
			spell = useradd;
		elseif (shiftright == "delcolor") then
			spell = "Bartype "..button.ctype;
		else
			spell = button.spell;
			spell = string.gsub(spell, " %(D%)", "");
			if (spell ~= CECB_SPELL_FRENZY_CD) then
				spell = string.gsub(spell, " %(CD%)", "");
			end
		end

		if (spell ~= CECB_SPELL_STUN_DR and not string.find(spell, "DR:") ) then

			if (CEnemyCastBar_Raids[spell]) then
				CEnemyCastBar_Raids[spell].disabled = true;
				disabled = true;
			end
	
			if (CEnemyCastBar_Spells[spell]) then
				CEnemyCastBar_Spells[spell].disabled = true;
				disabled = true;
			end
	
			if (CEnemyCastBar_Afflictions[spell]) then
				CEnemyCastBar_Afflictions[spell].disabled = true;
				disabled = true;
			end

			if (CEnemyCastBar_Colors[spell]) then
				CEnemyCastBar_Colors[spell].disabled = true;
				disabled = true;
				local color = button.ctype; -- without that, does not work, because this instance clears button.ctype before other instances are called
				for i=1, CEnemyCastBar.bNumBars do
					if (getglobal("Carni_ECB_"..i).ctype == color) then
						CEnemyCastBar_HideBar(i);
					end
				end
			end
		end

		if (disabled) then
			local spellexists = false;
			for i=1, #CEnemyCastBar.tDisabledSpells do
				if (CEnemyCastBar.tDisabledSpells[i] and CEnemyCastBar.tDisabledSpells[i] == spell) then
					spellexists = true;
					break;
				end
			end

			if (spellexists) then
				DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|cffffaaaa Spell or Color already disabled!");
			else
				table.insert (CEnemyCastBar.tDisabledSpells, spell);
				local color = "|cffffff00";
				if (string.match(spell, "Bartype")) then
					color = "|cffff9900";
				end
				DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r Disabled \""..color..spell.."|r\" (|cffffff00".. #CEnemyCastBar.tDisabledSpells .."|r total).");
				if (not necbdisabledyell) then
					necbdisabledyell = true;
				end
			end
		else
			if (num and button.ctype == "grey" ) then
				DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |rManual timers are not allowed to disable spells!");
			else
				if (useradd) then
					DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|cffffaaaa Entered Spell not found! |r(Spellname is case sensitive.)");
				else
					DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|cffffaaaa Spell not found! |rMaybe it was a DR of some spell?");
				end
			end
		end
	end

	if (num) then
		button:Hide();
		--DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r Deleted \""..button.label.."\"");
		button.spell = "";
		button.mob = "";
		button.ctype = "";
		button.label = "";
		button.channeling = false;
	end
	
end

function CEnemyCastBar_LockPos() --lockpos
	
	CEnemyCastBar.bLocked = not CEnemyCastBar.bLocked;

	if (CEnemyCastBar.bLocked) then

		local i=1;
		while (getglobal("Carni_ECB_"..i)) do

			local frame = getglobal("Carni_ECB_"..i);
			frame:StopMovingOrSizing();
			if (CEnemyCastBar.bMouseBar) then
				frame:EnableMouse(1);
			else
				frame:EnableMouse(0);
			end

			-- write positions, clear userplaced
			if (frame:IsUserPlaced() ) then
				local _,_,_,x,y = frame:GetPoint();
				CEnemyCastBar.tFramePoints[frame:GetName()] = { x, y };
				frame:SetUserPlaced(false);
			end
		i=i+1;
		end

	else

		local i=1;
		while (getglobal("Carni_ECB_"..i)) do
	
			local frame = getglobal("Carni_ECB_"..i);

			if (CEnemyCastBar.bSeparateBars) then
				--if (i==1 or i==6 or i==11 or i==16 or i==21 or i==26 or i==31 or i==36 or i==41) then --old code
				if (i % CEnemyCastBar.bNumBarsSep == 1 or CEnemyCastBar.bNumBarsSep == 1) then
					frame:EnableMouse(1);
				else
					frame:EnableMouse(0);
				end

			elseif (i==1) then
				frame:EnableMouse(1);
			else
				frame:EnableMouse(0);
			end
		i=i+1;
		end	

	end
	
end

function CEnemyCastBar_ResetPos() --resetpos

	local i=1;
	while (getglobal("Carni_ECB_"..i)) do
			CEnemyCastBar_HideBar(i);
			getglobal("Carni_ECB_"..i):SetUserPlaced(false);

			--reset database
			for k,v in pairs (CEnemyCastBar.tFramePoints) do
				if (k ~= "CECB_FPSBarFree") then
					CEnemyCastBar.tFramePoints[k] = nil;
				end
			end
	i=i+1;
	end

	getglobal("Carni_ECB_1"):SetPoint("TOPLEFT", "UIParent", 50, -500); -- set in xml by parent frame
	local _,_,_,x,y = getglobal("Carni_ECB_1"):GetPoint();
	CEnemyCastBar.tFramePoints["Carni_ECB_1"] = { x,y };
	CEnemyCastBar_FlipBars(); -- reorder frame
end

function CEnemyCastBar_FlipBars() --flipbars; sets the SPACE, ICONSIZE and BarLength, too! Called when variables loaded

	local o=1;
	while (getglobal("Carni_ECB_"..o)) do

		local i = o + 1;
		if (getglobal("Carni_ECB_"..i)) then
			local frame = getglobal("Carni_ECB_"..i);
			local factor = 1;
			if (CEnemyCastBar.bFlipB) then
				factor = -1;
			end
			if (CEnemyCastBar.bSeparateBars) then
				--if (not (i==6 or i==11 or i==16 or i==21 or i==26 or i==31 or i==36 or i==41)) then -- old code
				-- still needed for flipbars etc.
				if (i % CEnemyCastBar.bNumBarsSep ~= 1 and CEnemyCastBar.bNumBarsSep ~= 1) then
					frame:SetPoint("TOPLEFT", "Carni_ECB_"..o, "TOPLEFT", 0, factor*CEnemyCastBar.bSpace);
				end
			else
				frame:SetPoint("TOPLEFT", "Carni_ECB_"..o, "TOPLEFT", 0, factor*CEnemyCastBar.bSpace);
			end
		end

		local buttonicon = getglobal("Carni_ECB_"..o.."_Icon");
		buttonicon:SetHeight(CEnemyCastBar.bSpace);
		buttonicon:SetWidth(CEnemyCastBar.bSpace);
		buttonicon:SetPoint("LEFT", "Carni_ECB_"..o, "LEFT", -CEnemyCastBar.bSpace + 4, 1);

		-- set bar length
		getglobal("Carni_ECB_"..o):SetWidth(206 + CEnemyCastBar.bnecbCBLBias);
		getglobal("Carni_ECB_"..o.."_Border"):SetWidth(205 + CEnemyCastBar.bnecbCBLBias);
		getglobal("Carni_ECB_"..o.."_StatusBar"):SetWidth(195 + CEnemyCastBar.bnecbCBLBias);

		getglobal("Carni_ECB_"..o.."_Text"):ClearAllPoints();
		getglobal("Carni_ECB_"..o.."_CastTimeText"):ClearAllPoints();
		if (CEnemyCastBar.bTimerInside) then

				getglobal("Carni_ECB_"..o.."_Text"):SetPoint("LEFT", "Carni_ECB_"..o, "LEFT", 8, 2);
				getglobal("Carni_ECB_"..o.."_Text"):SetJustifyH("LEFT");
				if (CEnemyCastBar.bDisBorder) then
					getglobal("Carni_ECB_"..o.."_Text"):SetWidth(160 + CEnemyCastBar.bnecbCBLBias);
					getglobal("Carni_ECB_"..o.."_CastTimeText"):SetPoint("RIGHT", getglobal("Carni_ECB_"..o), "RIGHT", -6, 2);
				else
					getglobal("Carni_ECB_"..o.."_Text"):SetWidth(156 + CEnemyCastBar.bnecbCBLBias);
					getglobal("Carni_ECB_"..o.."_CastTimeText"):SetPoint("RIGHT", getglobal("Carni_ECB_"..o), "RIGHT", -10, 2);
				end
				if (not CEnemyCastBar.bTimer) then
						getglobal("Carni_ECB_"..o.."_Text"):SetWidth(190 + CEnemyCastBar.bnecbCBLBias);
				end
		else
				getglobal("Carni_ECB_"..o.."_Text"):SetWidth(190 + CEnemyCastBar.bnecbCBLBias);
				getglobal("Carni_ECB_"..o.."_Text"):SetPoint("CENTER", "Carni_ECB_"..o, "CENTER", 0, 2);
				getglobal("Carni_ECB_"..o.."_Text"):SetJustifyH("CENTER");
				getglobal("Carni_ECB_"..o.."_CastTimeText"):SetPoint("LEFT", getglobal("Carni_ECB_"..o), "LEFT", 202 + CEnemyCastBar.bnecbCBLBias, 2);
		end

		getglobal("Carni_ECB_"..o):SetScale(CEnemyCastBar.bScale);
	o=o+1;
	end
end

function CEnemyCastBar_SetTextSize() --settextsize, called when variables loaded

	local i, size = 1;
	while (getglobal("Carni_ECB_"..i)) do
		if (CEnemyCastBar.bSmallTSize) then
			size = 10;
		else
			size = 12;			
		end
		getglobal("Carni_ECB_"..i.."_Text"):SetFont(NECB_Fonts[CEnemyCastBar.bBarFont + 1].path, size);
		getglobal("Carni_ECB_"..i.."_CastTimeText"):SetFont(NECB_Fonts[CEnemyCastBar.bBarFont + 1].path, size);
		CECB_FPSBarFree_Text:SetFont(NECB_Fonts[CEnemyCastBar.bBarFont + 1].path, 12);
	i=i+1;
	end
end

function CEnemyCastBar_SetBorder() --called when variables loaded

	local i=1;
	while (getglobal("Carni_ECB_"..i)) do
		local border = getglobal("Carni_ECB_"..i.."_Border");
		if (CEnemyCastBar.bDisBorder) then
			border:Hide();
			CECB_FPSBarFree_Border:Hide(); --fps bar
		else
			border:Show();
			CECB_FPSBarFree_Border:Show(); --fps bar
		end
	i=i+1;
	end
end

function CEnemyCastBar_SetIcon() --called when variables loaded

	local i=1;
	while (getglobal("Carni_ECB_"..i)) do
		local icon = getglobal("Carni_ECB_"..i.."_Icon");
		if (CEnemyCastBar.bShowIcon) then
			icon:Show();
		else
			icon:Hide();
		end
	i=i+1;
	end
end

function CEnemyCastBar_SetTexture() --called when variables loaded

	local i=1;
	while (getglobal("Carni_ECB_"..i)) do
		local statusbar = getglobal("Carni_ECB_"..i.."_StatusBar");
			statusbar:SetStatusBarTexture("Interface\\AddOns\\CEnemyCastBar\\Images\\bartex"..CEnemyCastBar.bBarTexture);
	i=i+1;
	end
	CECB_FPSBarFree_StatusBar:SetStatusBarTexture("Interface\\AddOns\\CEnemyCastBar\\Images\\bartex"..CEnemyCastBar.bBarTexture); --fps bar
end

function CEnemyCastBar_Boolean(var)

	if (var) then
		return "on";	
	else
		return "off";
	end
end

function CEnemyCastBar_Handler(msg) --Handler

	if (msg == "help" or msg == "?") then

		if (CECBHELPFrame:IsVisible() and CECBHELPFrameText:GetText() == "NECB - HELP" ) then
			CECBHELPFrame:Hide();
		else
			CECBHELPFrameScrollFrameBGText:SetText("|cffffff00Natur EnemyCastBar |cffcccc00("..CECB_status_version_txt..")|cffffff00:|cffff0000 /necb help\n\n" .. table.concat (CEnemyCastBarHelp, "") );
			CECBHELPFrame:SetHeight(465);
			CECBHELPFrameScrollFrame:SetHeight(CECBHELPFrame:GetHeight() - 45);
			CECBHELPFrameScrollFrameBorder:SetHeight(CECBHELPFrameScrollFrame:GetHeight() - 28);
			CECBHELPFrameScrollFrameBG:SetHeight(550);
			CECBHELPFrameScrollFrameBGText:SetHeight(CECBHELPFrameScrollFrameBG:GetHeight() - 10);
			CECBHELPFrameScrollFrame:UpdateScrollChildRect();

			if (GetCurrentResolution() == 1) then
				CECBHELPFrameScrollFrameBG:SetHeight(CECBHELPFrameScrollFrameBG:GetHeight() + 50);
				CECBHELPFrameScrollFrameBGText:SetHeight(CECBHELPFrameScrollFrameBGText:GetHeight() + 50);
			end

			CECBHELPFrameText:SetText("NECB - HELP");
			CECBHELPFrame:Show();
			CECBHELPFrameWhisper:Hide();
		end


	elseif (msg == "" or msg == nil) then

		local loaded, reason = LoadAddOn("CECB_Options");
		if (loaded) then

			if (CECBOptionsFrame:IsVisible()) then
				necbfademenue = 1;
			else
				CECBOptionsFrame:SetAlpha(0);
				necbfademenue = 2;
				CECB_ShowHideOptionsUI();
			end
		else
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffffff00'CECB_Options' |rAddOn |cffff9999can not be loaded! |rReason: |cffff0000"..reason)
		end

	elseif (msg == "gcinfo") then

		if (CECBGCFrame:IsVisible()) then
			CECBGCFrame:Hide();
			cecbgc_last = nil;
		else
			CECBGCFrame:Show();
			collectgarbage("collect"); --BC
		end

	-- see "printversions" in OPTIONS part!
	elseif (msg == "versions") then

		if (CEnemyCastBar.bStatus) then

			if (CEnemyCastBar.bParseC and (GetNumRaidMembers() ~= 0 or GetNumPartyMembers() ~= 0 or GetNumBattlefieldStats() > 1 or IsActiveBattlefieldArena() ) ) then
				CECBHELPFrameScrollFrameBGText:SetText("|cffffff00Natur EnemyCastBar |cffcccc00("..CECB_status_version_txt..")|cffffff00:|cffff0000 /necb versions\n\n|cffaaaaaaNECB: |cffffff00Requesting Versions from Raidmembers! |cffff0000Please wait...");
				
				CECBHELPFrameText:SetText("NECB - VERSIONS");

				CECBHELPFrame:SetHeight(165);
				CECBHELPFrameScrollFrame:SetHeight(CECBHELPFrame:GetHeight() - 45);
				CECBHELPFrameScrollFrameBorder:SetHeight(CECBHELPFrameScrollFrame:GetHeight() - 28);
				CECBHELPFrameScrollFrameBG:SetHeight(120);
				CECBHELPFrameScrollFrameBGText:SetHeight(CECBHELPFrameScrollFrameBG:GetHeight() - 10);
				CECBHELPFrameScrollFrame:UpdateScrollChildRect();
				CECBHELPFrame:Show();
	
				NECB_SendMessage("<NECB> Force version collection.");
	
			else
				if (not CEnemyCastBar.bParseC) then
					DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999You have to enable NECB's channel parsing to use this!")
				else
					DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999You have to be in a Group to use this command!")
				end
			end

		else
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999Enable NECB to use this feature!")

		end

	-- see "printversions" in OPTIONS part!
	elseif (msg == "gversions") then

		if (CEnemyCastBar.bStatus) then

			if (CEnemyCastBar.bParseC and IsInGuild() ) then
				CECBHELPFrameScrollFrameBGText:SetText("|cffffff00Natur EnemyCastBar |cffcccc00("..CECB_status_version_txt..")|cffffff00:|cffff0000 /necb gversions\n\n|cffaaaaaaNECB: |cffffff00Requesting Versions from Guildmembers! |cffff0000Please wait...");
				
				CECBHELPFrameText:SetText("NECB - GVERSIONS");
				CECBHELPFrame:SetHeight(165);
				CECBHELPFrameScrollFrame:SetHeight(CECBHELPFrame:GetHeight() - 45);
				CECBHELPFrameScrollFrameBorder:SetHeight(CECBHELPFrameScrollFrame:GetHeight() - 28);
				CECBHELPFrameScrollFrameBG:SetHeight(120);
				CECBHELPFrameScrollFrameBGText:SetHeight(CECBHELPFrameScrollFrameBG:GetHeight() - 10);
				CECBHELPFrameScrollFrame:UpdateScrollChildRect();
				CECBHELPFrame:Show();
	
				NECB_SendMessage("<NECB> Force gversion collection.", nil, "toguild");
	
			else
				if (not CEnemyCastBar.bParseC) then
					DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999You have to enable NECB's channel parsing to use this!")
				else
					DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999You have to be in a Guild to use this command!")
				end
			end

		else
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999Enable NECB to use this feature!")

		end

	elseif (msg == "parser") then

		if (CECBParser) then
	
			CECBParser = false;
			CECBCTRAParserFrame:Hide();
			--DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r Broadcast Parser |cffff9999disabled")
	
		else
		
			CECBParser = true;
				CEnemyCastBar_ParserOnClick(0);
			CECBCTRAParserFrame:Show();
			--DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r Broadcast Parser |cff99ff99temporary enabled")
		
		end

	elseif (msg == "clear") then		

		necblockshow = nil;

		if (not CEnemyCastBar.bLocked) then
			CEnemyCastBar_LockPos();
		end

		for i=1, CEnemyCastBar.bNumBars do

			CEnemyCastBar_HideBar(i);
		end

	elseif (msg == "restore") then		

		for k,v in pairs (CEnemyCastBar.tDisabledSpells) do

			if (CEnemyCastBar_Raids[v]) then
				CEnemyCastBar_Raids[v].disabled = nil;
			end
	
			if (CEnemyCastBar_Spells[v]) then
				CEnemyCastBar_Spells[v].disabled = nil;
			end
	
			if (CEnemyCastBar_Afflictions[v]) then
				CEnemyCastBar_Afflictions[v].disabled = nil;
			end

			if (CEnemyCastBar_Colors[v]) then
				CEnemyCastBar_Colors[v].disabled = nil;
			end
		end			

		DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r Restored (|cffffff00".. #CEnemyCastBar.tDisabledSpells .."|r) spells which were disabled.");
		CEnemyCastBar.tDisabledSpells = { };

	elseif (msg == "disabled") then

		local DSpells = "";
		local SpellsTotal = #CEnemyCastBar.tDisabledSpells;
		
		if (SpellsTotal == 0) then
			DSpells = "-.-";
		else
			for i=1, SpellsTotal do
				DSpells = DSpells .. table.concat (CEnemyCastBar.tDisabledSpells, "", i, i) .. " |cffffffff(|r" .. i .. "|cffffffff)";
				if (i < SpellsTotal ) then
					DSpells = DSpells .. "|cffff0000 | |r";
				end
			end
		end
		DSpells = string.gsub(DSpells, "Bartype", "|cffff9900Bartype");
		DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|cffffffff Disabled Spells: |r"..DSpells, 1, 1, 0);

	elseif (msg == "cooldowns") then

		local DSpells = "";
		local SpellsTotal = #NECB_CD_DB;
		
		if (SpellsTotal == 0) then
			DSpells = "-.-";
		else
			for i=1, SpellsTotal do
				local CDLeft = floor (NECB_CD_DB[i][3] + NECB_CD_DB[i][4] - GetTime() );
				if ( CDLeft < 0 ) then
					CDLeft = 0;
				end
				DSpells = DSpells .. NECB_CD_DB[i][1] .. "|cffffffff - |r" .. NECB_CD_DB[i][2] .. " |cffffffff(|r" .. CDLeft .. "|cffffffff)|r";
				if (i < SpellsTotal ) then
					DSpells = DSpells .. "|cffff0000 | |r";
				end
			end
		end
		DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|cffffffff Cooldowns: |r"..DSpells, 1, 1, 0);

	elseif (string.sub (msg, 1, 8) == "disable " and CEnemyCastBar.bStatus) then

		local msg1 = string.sub (msg, 9, string.len(msg) );
		CEnemyCastBar_HideBar(nil, nil, msg1); -- Hidebar also used for disabled spell commands! Shift + Rightclick...

	elseif (string.sub (msg, 1, 7) == "enable " and CEnemyCastBar.bStatus) then

		local msg1 = string.sub (msg, 8, string.len(msg) );
		local spellfound = false;

		local i = 1;
		while CEnemyCastBar.tDisabledSpells[i] do

			if (string.lower(CEnemyCastBar.tDisabledSpells[i]) == string.lower(msg1) or ( tonumber(msg1) and CEnemyCastBar.tDisabledSpells[tonumber(msg1)] ) ) then

					local spell;
					if (tonumber(msg1) and CEnemyCastBar.tDisabledSpells[tonumber(msg1)] ) then
						i = tonumber(msg1);
					end

					spell = CEnemyCastBar.tDisabledSpells[i];

					if (CEnemyCastBar_Raids[spell]) then
						CEnemyCastBar_Raids[spell].disabled = nil;
					end
			
					if (CEnemyCastBar_Spells[spell]) then
						CEnemyCastBar_Spells[spell].disabled = nil;
					end
			
					if (CEnemyCastBar_Afflictions[spell]) then
						CEnemyCastBar_Afflictions[spell].disabled = nil;
					end

					if (CEnemyCastBar_Colors[spell]) then
						CEnemyCastBar_Colors[spell].disabled = nil;
					end

				local color = "|r";
				if (string.match(CEnemyCastBar.tDisabledSpells[i], "Bartype")) then
					color = "|cffff9900";
				end
				DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|cffffffff Restored Spell: ".. color .. table.concat (CEnemyCastBar.tDisabledSpells, "", i, i), 1, 1, 0);
				table.remove (CEnemyCastBar.tDisabledSpells, i);
				spellfound = true;
				--CEnemyCastBar_Handler("disabled");
				break;
			end
			i = i + 1;
		end

		if (not spellfound) then
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|cffffaaaa Spell not found!");
		end

	elseif (string.sub (msg, 1, 7) == "forcebc" and CEnemyCastBar.bStatus) then

		local msg1 = string.sub (msg, 9, string.len(msg) );

		if (msg1 == "") then
			msg1 = UnitName("target");
		end

		if (msg1 == nil) then
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999No name specified and no target selected!")

		elseif (CEnemyCastBar_CheckRaidStatus( UnitName("player") ) == false ) then
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999You have to be leader or promoted to do this!")

		elseif (CEnemyCastBar_CheckRaidStatus( msg1 ) == nil ) then
			if (UnitInRaid("player") ) then
				DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999The name/target you selected is not found in your raid!")
			else
				DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999You have to be in a RaidGroup!")
			end

		else
			NECB_SendMessage("<NECB> FORCE "..msg1.." to Broadcast! Change Settings!");
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |rForced |cffffff00"..msg1.." |rto broadcast!")
		end

	elseif (string.sub (msg, 1, 6) == "stopbc" and CEnemyCastBar.bStatus) then

		local msg1 = string.sub (msg, 8, string.len(msg) );

		if (msg1 == "") then
			msg1 = UnitName("target");
		end

		if (msg1 == nil) then
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999No name specified and no target selected!")

		elseif (CEnemyCastBar_CheckRaidStatus( UnitName("player") ) == false ) then
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999You have to be leader or promoted to do this!")

		elseif (CEnemyCastBar_CheckRaidStatus( msg1 ) == nil ) then
			if (UnitInRaid("player") ) then
				DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999The name/target you selected is not found in your raid!")
			else
				DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999You have to be in a RaidGroup!")
			end

		else
			NECB_SendMessage("<NECB> STOP "..msg1.." to Broadcast! Change Settings!");
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |rStopped broadcasts of |cffffff00"..msg1.." |r!")
		end

	elseif (string.sub (msg, 1, 9) == "countsec " and CEnemyCastBar.bStatus) then

		local msg1 = tonumber (string.sub (msg, 10, 12));

		local textlen = string.len (msg);
		local textinput = string.sub (msg, 10, textlen);
		local firstspace = string.find (textinput, " ");
		local msg2;
		if (firstspace and textlen >= (firstspace + 10)) then
			msg2 = string.sub (msg, firstspace + 10, textlen);
			if ((firstspace +8) <= 12) then
				msg1 = tonumber (string.sub (msg, 10, firstspace + 8));
			end
		end

		if (msg1) then

			if (msg1 < 0) then
	
				DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999Invalid value to start the countdown!")
		
			else
		
				if (msg2 == nil) then
					msg2 = "Countdown";
				else
					msg2 = NECB_ChatJokers(msg2);
				end
	
				if ( CEnemyCastBar_UniqueCheck(msg2, msg1, "("..msg1.." Seconds)", nil, nil, nil, "grey") == 0 ) then
					CEnemyCastBar_Show("("..msg1.." Seconds)", msg2, msg1, "grey", nil, "INV_Misc_Bomb_03.blp");
				end

			end

		end

	elseif (string.sub (msg, 1, 9) == "countmin " and CEnemyCastBar.bStatus) then

		local msg1 = tonumber (string.sub (msg, 10, 12));

		local textlen = string.len (msg);
		local textinput = string.sub (msg, 10, textlen);
		local firstspace = string.find (textinput, " ");
		local msg2;
		if (firstspace and textlen >= (firstspace + 10)) then
			msg2 = string.sub (msg, firstspace + 10, textlen);
			if ((firstspace +8) <= 12) then
				msg1 = tonumber (string.sub (msg, 10, firstspace + 8));
			end
		end

		if (msg1) then

			if (msg1 * 60 < 0) then
	
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999Invalid value to start the countdown!")
	
			else
			
				if (msg2 == nil) then
					msg2 = "Countdown";
				else
					msg2 = NECB_ChatJokers(msg2);
				end

				if ( CEnemyCastBar_UniqueCheck(msg2, msg1 * 60, "("..msg1.." Minutes)", nil, nil, nil,"grey") == 0 ) then
					CEnemyCastBar_Show("("..msg1.." Minutes)", msg2, msg1 * 60, "grey", nil, "INV_Misc_Bomb_03.blp");
				end
				
	
			end

		end
		
	elseif (string.sub (msg, 1, 7) == "repeat " and CEnemyCastBar.bStatus) then

		local msg1 = tonumber (string.sub (msg, 8, 10));

		local textlen = string.len (msg);
		local textinput = string.sub (msg, 8, textlen);
		local firstspace = string.find (textinput, " ");
		local msg2;
		if (firstspace and textlen >= (firstspace + 8)) then
			msg2 = string.sub (msg, firstspace + 8, textlen);
			if ((firstspace +6) <= 10) then
				msg1 = tonumber (string.sub (msg, 8, firstspace + 6));
			end
		end

		if (msg1) then

			if (msg1 < 0) then
	
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999Invalid value to start the repeater!")

			else

				if (msg2 == nil) then
					msg2 = "Repeater";
				else
					msg2 = "Repeater: "..NECB_ChatJokers(msg2);
				end
				if ( CEnemyCastBar_UniqueCheck(msg2, msg1, "("..msg1.." Seconds)", nil, nil, nil, "grey") == 0 ) then
					CEnemyCastBar_Show("("..msg1.." Seconds)", msg2, msg1, "grey", nil, "INV_Misc_Bomb_04.blp");
				end
					
			end

		end
		
	elseif (string.sub (msg, 1, 10) == "stopcount " and CEnemyCastBar.bStatus) then

		local msg1;
		local textlen = string.len (msg);
		if (textlen >= 11) then
			msg1 = string.sub (msg, 11, textlen);
		end

		if (msg1) then

			if (msg1 == "all") then
				msg1 = " ";
			else
				msg1 = NECB_ChatJokers(msg1);
			end

			local minbar, maxbar = 1, CEnemyCastBar.bNumBars;
			if (CEnemyCastBar.bSeparateBars) then
				minbar, maxbar = 8 * CEnemyCastBar.bNumBarsSep + 1, 9 * CEnemyCastBar.bNumBarsSep; --41, 45
			end
			for i=minbar, maxbar do
			
				local label = getglobal("Carni_ECB_"..i).label;

				if (label and string.find (label, msg1) and getglobal("Carni_ECB_"..i).ctype == "grey" ) then
						CEnemyCastBar_HideBar(i);
				end
			end
		end

	elseif (string.sub (msg, 1, 10) == "deletebar " and CEnemyCastBar.bStatus) then

		local msg1;
		local textlen = string.len (msg);
		if (textlen >= 11) then
			msg1 = string.sub (msg, 11, textlen);
		end

		if (msg1) then

			if (msg1 == "all") then msg1 = " ";
			end

			for i=1, CEnemyCastBar.bNumBars do
			
				local label = getglobal("Carni_ECB_"..i).label;
				local mob = getglobal("Carni_ECB_"..i).mob;

				if (label and string.find(label, msg1) and mob == UnitName("target") ) then
						CEnemyCastBar_HideBar(i);
				end
			end

		end

	elseif (string.sub (msg, 1, 8) == "showbar " and CEnemyCastBar.bStatus) then
	
		local spell;
		local textlen = string.len (msg);
		if (textlen >= 9) then
			spell = string.sub (msg, 9, textlen);
		end

		local mob = UnitName("target");
		if (not mob) then
			return;
		end

		if (CEnemyCastBar_Afflictions[spell]) then
			if (not UnitIsFriend("player", "target") ) then
				if (CEnemyCastBar_Afflictions[spell].periodicdmg) then
					CEnemyCastBar_Control(mob, spell, "periodicdmg", nil, "customdot");
				else
					CEnemyCastBar_Control(mob, spell, "afflicted");
				end
			end

		elseif (CEnemyCastBar_Spells[spell]) then
			if (UnitIsFriend("player", "target") ) then
				CEnemyCastBar_Control(mob, spell, "gains");
			end

		end

	elseif (msg == "combatlog") then

		if (necbprint2combat) then
	
			necbprint2combat = nil;
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r Also write parser messages to combatlog |cffff9999disabled")
		
		else
		
			necbprint2combat = true;
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r Also write parser messages to combatlog |cff99ff99enabled")

		end
	
	elseif (string.sub (msg, 1, 5) == "chat " and CEnemyCastBar.bStatus) then

		if (GetNumPartyMembers() ~= 0 or GetNumRaidMembers() ~= 0 ) then
			local text;
			local textlen = string.len (msg);
			if (textlen >= 6) then
				text = string.sub (msg, 6, textlen);
				text = NECB_ChatJokers(text);
			end
			
			NECB_SendMessage(text, "CHAT");

		else 
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999You have to be in a Group to use NECB's Chat!")
		end

	elseif ((string.sub (msg, 1, 9) == "setrange " or msg == "setrange") and CEnemyCastBar.bStatus) then

		local text;
		local textlen = string.len (msg);
		if (textlen >= 10) then
			text = string.sub (msg, 10, textlen);
		end
		-- "allmax", "cmax", nil for defaults
		CEnemyCastBar_SetRange(text);

	elseif (msg == "wipe") then

		if (GetNumRaidMembers() ~= 0) then
			if (CEnemyCastBar_CheckRaidStatus( UnitName("player") ) == false ) then
				DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999You have to be leader or promoted to do this!")
			else
				CEnemyCastBar_BHWipe();
				NECB_SendMessage("<NECB> Play Benny Hill for us!");
			end

		else
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999You have to be in a RaidGroup!")
		end

	elseif (msg == "debug") then

		if (CEnemyCastBar.bDebug) then
	
			CEnemyCastBar.bDebug = false;
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r DebugMode |cffffff99disabled")
		
		else
		
			CEnemyCastBar.bDebug = true;
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r DebugMode |cffffff99enabled")

		end

	else
		DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff0000Unknown|r command entered! (try '|cff00ff00/necb help|r') :O")

	end
end

function NECB_ChatJokers(msg)

	if (UnitName("targettarget")) then
		msg = string.gsub(msg, "%%tt", (UnitName("targettarget")));
	else
		msg = string.gsub(msg, "%%tt", "[TargetTarget]");
	end

	if (UnitName("target")) then
		msg = string.gsub(msg, "%%t", (UnitName("target")));
		msg = string.gsub(msg, "%%c", (UnitClass("target")));

		if (string.match(msg, "%%g")) then
			local group = "[Group]";
			for i = 1, GetNumRaidMembers() do
				if ( (UnitName("raid" .. i)) == (UnitName("target")) ) then
					_, _, group, _, _, plfileName = GetRaidRosterInfo(i);
					break;
				end
			end
			msg = string.gsub(msg, "%%g", group);
		end
	else
		msg = string.gsub(msg, "%%t", "[Target]");
		msg = string.gsub(msg, "%%c", "[Class]");
	end

	return msg;
end


-- Internal Handler -----------------------
function CEnemyCastBar_InternalHandler(msg) --Internal

	if (msg == "printversions") then

		local NECBVersionDBTemp = { };

		if (NECBVersionDB and NECBVersionDB[1]) then
			for i=1, #NECBVersionDB do
				NECBVersionDB[i] = string.gsub (NECBVersionDB[i], "BC5.6.0", "5.6.0"); -- fix for old BC5.6.0 version transmits
				table.insert (NECBVersionDBTemp, "|cffaaaaaaNECB: |rVersion |cff00ff00"..NECBVersionDB[i].."|r is used by "..NECBVersionNames[i].."§.");
				NECBVersionDBTemp[i] = string.gsub (NECBVersionDBTemp[i], ", BCASTER", "");
			end


			table.sort (NECBVersionDBTemp);
			local counter, vcounter = 1, 1;
			while NECBVersionDBTemp[counter] do

				local o = counter + 1;
				if (NECBVersionDBTemp[o]) then
					local nextversion = string.match (NECBVersionDBTemp[o], "Version (.+) is used")
					local thisversion = string.match (NECBVersionDBTemp[counter], "Version (.+) is used")
	
					if (nextversion and thisversion and nextversion == thisversion) then
						local nextname = string.match (NECBVersionDBTemp[o], "is used by (.+).")
						table.remove (NECBVersionDBTemp, o);
						NECBVersionDBTemp[counter] = string.sub (NECBVersionDBTemp[counter], 1, string.len( NECBVersionDBTemp[counter] ) - 1 ) .. ", " ..nextname ..".";
						--DEFAULT_CHAT_FRAME:AddMessage("1)"..counter.." - "..NECBVersionDBTemp[counter]);
						counter = counter - 1;
						vcounter = vcounter + 1;

					else
						if (vcounter > 1) then
							NECBVersionDBTemp[counter] = NECBVersionDBTemp[counter] .. " (|cff00ff00" ..vcounter.. "|r Users)";
						end
						vcounter = 1;
						--DEFAULT_CHAT_FRAME:AddMessage("2)"..counter.." - "..NECBVersionDBTemp[counter]);
					end
	
				else
					if (vcounter > 1 and NECBVersionDBTemp[counter]) then
						NECBVersionDBTemp[counter] = NECBVersionDBTemp[counter] .. " (|cff00ff00" ..vcounter.. "|r Users)";
					end
						--DEFAULT_CHAT_FRAME:AddMessage("3)"..counter);
	
				end
				counter = counter + 1;	
			end

			-- calculate usage ratio
			local necb_ratio = 0;
			if (CECBHELPFrame:IsVisible() and CECBHELPFrameText:GetText() == "NECB - GVERSIONS" ) then
				GuildRoster();
				necb_ratio = ceil(#NECBVersionDB / GetNumGuildMembers() * 100);
			elseif (CECBHELPFrame:IsVisible() and CECBHELPFrameText:GetText() == "NECB - VERSIONS" ) then
				if (GetNumRaidMembers() ~= 0) then
					necb_ratio = ceil(#NECBVersionDB / GetNumRaidMembers() * 100);
				elseif (GetNumPartyMembers() ~= 0) then
					necb_ratio = ceil(#NECBVersionDB / (GetNumPartyMembers() + 1) * 100);
				end
			end

			-- set output text
			CECBHELPFrameScrollFrameBGText:SetText("|cffffff00Natur EnemyCastBar |cffcccc00("..CECB_status_version_txt..")|cffffff00:|cffff0000 /necb (g)versions\n\n|cffaaaaaaNECB: |cffffff00Client versions which answered (|cff00ff00"..#NECBVersionDB.." |cfffffffftotal -> |cff00ff00"..necb_ratio.."|cffffffff%, |cff9999ffblue|cffffff00 = broadcaster):\n\n");
			local necblinebreak = 0;

			for i=#NECBVersionDBTemp, 1, -1 do
				CECBHELPFrameScrollFrameBGText:SetText(CECBHELPFrameScrollFrameBGText:GetText()..NECBVersionDBTemp[i].."\n" );
				CECBParserFauxText:SetText(NECBVersionDBTemp[i]);
				if (CECBParserFauxText:GetStringWidth() > 420) then
					--DEFAULT_CHAT_FRAME:AddMessage(i.." "..CECBParserFauxText:GetStringWidth());
					necblinebreak = necblinebreak + floor(CECBParserFauxText:GetStringWidth() / 420);
				end

			end

			-- recolor
			for i=1, #NECBVersionDB do
				local necbbccolor = "|cffcccc00";
				if (string.find(NECBVersionDB[i], ", BCASTER") ) then
					necbbccolor = "|cff9999ff";
				end
				CECBHELPFrameScrollFrameBGText:SetText(string.gsub(CECBHELPFrameScrollFrameBGText:GetText(), NECBVersionNames[i].."§", necbbccolor..NECBVersionNames[i].."|r") );
			end

			local necbpixellines = (#NECBVersionDBTemp + necblinebreak ) *10;
			--CECBHELPFrameText:SetText("NECB - VERSIONS");
			if (necbpixellines > 60) then
				necbpixellines = necbpixellines - 60;
				CECBHELPFrameScrollFrameBG:SetHeight(110 + necbpixellines);
				CECBHELPFrameScrollFrameBGText:SetHeight(CECBHELPFrameScrollFrameBG:GetHeight() - 10);
				CECBHELPFrameScrollFrame:UpdateScrollChildRect();
			end
			--CECBHELPFrame:Show();
			if (#NECBVersionDBTemp > 1) then
				CECBHELPFrameWhisper:Show();
			end

		else
			CECBHELPFrameScrollFrameBGText:SetText("|cffffff00Natur EnemyCastBar |cffcccc00("..CECB_status_version_txt..")|cffffff00:|cffff0000 /necb (g)versions\n\n|cffaaaaaaNECB: |cffff0000Unknown error! No data found :/");
		end

	elseif (msg == "WhisperToObsolete") then

		local NECBVersionDBTemp = { };
		for i=1, #NECBVersionDB do
			table.insert (NECBVersionDBTemp, NECBVersionDB[i]);
			NECBVersionDBTemp[i] = string.gsub (NECBVersionDBTemp[i], ", BCASTER", "");
		end

		local necb_newest = " ";
		local necb_whispered;
		for i=1, #NECBVersionDBTemp do
			local necb_checked = string.sub( NECBVersionDBTemp[i], 1, string.len(NECBVersionDBTemp[i]) - 6 );
			if ( necb_checked > necb_newest) then
				necb_newest = necb_checked;
			end
		end

		for i=1, #NECBVersionDBTemp do
			local necb_checked = string.sub( NECBVersionDBTemp[i], 1, string.len(NECBVersionDBTemp[i]) - 6 );
			if ( necb_checked < necb_newest and NECBVersionNames[i] ~= UnitName("player") ) then
				if (not necb_whispered) then
					NECB_SendMessage("<NECB> Whisper old versions of NECB to update!");
				end
				SendChatMessage("*** NECB: Your version ("..necb_checked..") is outdated! Update to the newest detected version ("..necb_newest..") please! ***", "WHISPER", nil, NECBVersionNames[i]);
				necb_whispered = true;
			end
		end

		if (CECB_status_version_txt < necb_newest) then
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffffff00Your own version is out of date!")

		elseif (not necb_whispered) then
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999Noone is using an outdated version!")
		end

	elseif (msg == "enable") then

		CEnemyCastBar.bStatus = true;
		CEnemyCastBar_RegisterEvents("reg_main");
		CECBMiniMapButtonTexture:SetTexture("Interface\\AddOns\\CEnemyCastBar\\Images\\CECBButton");
		NECB_InfoFrame:AddMessage("|cffaaaaaaNECB:|r AddOn |cff99ff99enabled|cffffffff. (Events |cff99ff99registered|cffffffff.)", 1, 0.5, 0, 1, UIERRORS_HOLD_TIME);
		--DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r AddOn Core |cff99ff99enabled|cffffffff. Events |cff99ff99registered|cffffffff.")
		
	elseif (msg == "disable") then

		CEnemyCastBar_Handler("clear");
		CEnemyCastBar.bStatus = false;
		CEnemyCastBar_RegisterEvents("unreg_main");
		CECBMiniMapButtonTexture:SetTexture("Interface\\AddOns\\CEnemyCastBar\\Images\\CECBButton_off");
		NECB_InfoFrame:AddMessage("|cffaaaaaaNECB:|r AddOn |cffff9999disabled|cffffffff. (Events |cffff9999unregistered|cffffffff.)", 1, 0.5, 0, 1, UIERRORS_HOLD_TIME);
		--DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r AddOn Core |cffff9999disabled|cffffffff. Events |cffff9999unregistered|cffffffff.")

	end
end

function CEnemyCastBar_CheckRaidStatus(checkplayer) -- check players raidstatus, leader or promoted -> 1,2 else false or nil

	local plrank, plfileName;
	for i = 1, GetNumRaidMembers() do
		if ( UnitName("raid" .. i) == checkplayer ) then
			_, plrank, _, _, _, plfileName = GetRaidRosterInfo(i);
			break;
		end
	end

	if (plrank == 0) then
		plrank = false;
	end

	return plrank, plfileName;

end

function CEnemyCastBar_BHWipe(author) --wipe sound

	if (not author or (author ~= UnitName("player") and CEnemyCastBar_CheckRaidStatus(author)) ) then
		PlaySoundFile("Interface\\AddOns\\CEnemyCastBar\\Sounds\\BennyHill.mp3");
	end

end

function CEnemyCastBar_Show(mob, spell, castime, ctype, turnlabel, icontexture, starttime, DRText, falpha, channeling) --Show

 if (not necblockshow) then

	-- fix for non colored castbars with the new sorting routine ("Boss incoming" fix in general)
	if (not ctype) then
		ctype = "black";
	end

 	-- new "if" for separated feature
	local findctype, foundspace, firstused, insertpos;
	if (not CEnemyCastBar.bSeparateBars) then

		-- new magic sorting routine, don't ask me how it works ;P coded while in delirium
		for i=CEnemyCastBar.bNumBars, 1, -1 do
			if (not getglobal("Carni_ECB_"..i):IsVisible() ) then
				foundspace = true;
			elseif (not firstused) then
				firstused = i;
			end
			if (foundspace and getglobal("Carni_ECB_"..i).ctype == ctype) then
				findctype = i;
				break;
			end
		end
	
		-- lets push the bars up to insert a new one
		if (foundspace and findctype) then
	
			for i=CEnemyCastBar.bNumBars-1, findctype+1, -1 do
		
				local CECname = getglobal("Carni_ECB_"..i);
				local CECno = i;
			
				local CECpre = CECno + 1;
				local cecbuttonpre = getglobal("Carni_ECB_"..CECpre);
			
				if (not cecbuttonpre:IsShown() and CECname:IsShown() ) then
			
					cecbuttonpre.startTime = CECname.startTime
					cecbuttonpre.label = CECname.label;
			
					local r,g,b = getglobal("Carni_ECB_"..CECno.."_Text"):GetShadowColor();
					getglobal("Carni_ECB_"..CECpre.."_Text"):SetShadowColor(r,g,b);
			
					if (getglobal("Carni_ECB_"..CECno.."_Icon"):IsShown()) then
						getglobal("Carni_ECB_"..CECpre.."_Icon"):SetTexture(getglobal("Carni_ECB_"..CECno.."_Icon"):GetTexture());
						getglobal("Carni_ECB_"..CECpre.."_Icon"):Show();
					end

					cecbuttonpre.channeling = CECname.channeling;
					cecbuttonpre.spell = CECname.spell;
					cecbuttonpre.mob = CECname.mob;
					cecbuttonpre.ctype = CECname.ctype;
					cecbuttonpre.endTime = CECname.endTime;
					getglobal("Carni_ECB_"..CECpre.."_StatusBar"):SetMinMaxValues(getglobal("Carni_ECB_"..CECno.."_StatusBar"):GetMinMaxValues());
					getglobal("Carni_ECB_"..CECpre.."_StatusBar"):SetValue(getglobal("Carni_ECB_"..CECno.."_StatusBar"):GetValue());
					getglobal("Carni_ECB_"..CECpre.."_StatusBar"):SetStatusBarColor(getglobal("Carni_ECB_"..CECno.."_StatusBar"):GetStatusBarColor());
					cecbuttonpre:SetAlpha(CEnemyCastBar.bAlpha);
					cecbuttonpre:Show();
			
					CEnemyCastBar_HideBar(CECno);
				end
			end
	
		end
	
		-- prepare to fire the bar into the right position
		--local i; -- now 'insertpos' above
		if (findctype) then
			insertpos = findctype+1;
		elseif (firstused and firstused < CEnemyCastBar.bNumBars) then
			insertpos = firstused+1;
		elseif (firstused and firstused == CEnemyCastBar.bNumBars) then
			insertpos = CEnemyCastBar.bNumBars; -- will call the red barrier (is a visible button)
		else
			insertpos = 1;
		end
	end
	-- "if end" for new separated feature

	local deliverpoint, maxbars; -- new for separated feature
	local red, green, blue = 0, 0, 0;
	if (ctype == "friendly") then
		if (turnlabel ~= "forceshow" and CEnemyCastBar_Colors["Bartype "..ctype].disabled) then return; end
		red = CEnemyCastBar.tColor[2][1];
		green = CEnemyCastBar.tColor[2][2];
		blue = CEnemyCastBar.tColor[2][3];
		deliverpoint = 1;

	elseif (ctype == "hostile") then
		if (turnlabel ~= "forceshow" and CEnemyCastBar_Colors["Bartype "..ctype].disabled) then return; end
		red = CEnemyCastBar.tColor[1][1];
		green = CEnemyCastBar.tColor[1][2];
		blue = CEnemyCastBar.tColor[1][3];
		deliverpoint = CEnemyCastBar.bNumBarsSep + 1;
		
	elseif (ctype == "gainsfoe") then
		if (turnlabel ~= "forceshow" and CEnemyCastBar_Colors["Bartype "..ctype].disabled) then return; end
		red = CEnemyCastBar.tColor[4][1];
		green = CEnemyCastBar.tColor[4][2];
		blue = CEnemyCastBar.tColor[4][3];
		deliverpoint = 2* CEnemyCastBar.bNumBarsSep + 1;

	elseif (ctype == "gainsfriend") then
		if (turnlabel ~= "forceshow" and CEnemyCastBar_Colors["Bartype "..ctype].disabled) then return; end
		red = CEnemyCastBar.tColor[5][1];
		green = CEnemyCastBar.tColor[5][2];
		blue = CEnemyCastBar.tColor[5][3];
		deliverpoint = 3 * CEnemyCastBar.bNumBarsSep + 1;

	elseif (ctype == "afflict") then
		if (turnlabel ~= "forceshow" and CEnemyCastBar_Colors["Bartype "..ctype].disabled) then return; end
		red = CEnemyCastBar.tColor[7][1];
		green = CEnemyCastBar.tColor[7][2];
		blue = CEnemyCastBar.tColor[7][3];
		deliverpoint = 4 * CEnemyCastBar.bNumBarsSep + 1;

	elseif (ctype == "stuns") then
		if (turnlabel ~= "forceshow" and CEnemyCastBar_Colors["Bartype "..ctype].disabled) then return; end
		red = CEnemyCastBar.tColor[8][1];
		green = CEnemyCastBar.tColor[8][2];
		blue = CEnemyCastBar.tColor[8][3];
		deliverpoint = 5 * CEnemyCastBar.bNumBarsSep + 1;

	elseif (ctype == "dots") then
		if (turnlabel ~= "forceshow" and CEnemyCastBar_Colors["Bartype "..ctype].disabled) then return; end
		red = CEnemyCastBar.tColor[9][1];
		green = CEnemyCastBar.tColor[9][2];
		blue = CEnemyCastBar.tColor[9][3];
		deliverpoint = 6 * CEnemyCastBar.bNumBarsSep + 1;

	elseif (ctype == "cooldown") then
		if (turnlabel ~= "forceshow" and CEnemyCastBar_Colors["Bartype "..ctype].disabled) then return; end
		red = CEnemyCastBar.tColor[3][1];
		green = CEnemyCastBar.tColor[3][2];
		blue = CEnemyCastBar.tColor[3][3];	
		deliverpoint = 7 * CEnemyCastBar.bNumBarsSep + 1;

	elseif (ctype == "grey") then
		if (turnlabel ~= "forceshow" and CEnemyCastBar_Colors["Bartype "..ctype].disabled) then return; end
		red = CEnemyCastBar.tColor[6][1];
		green = CEnemyCastBar.tColor[6][2];
		blue = CEnemyCastBar.tColor[6][3];
		deliverpoint = 8 * CEnemyCastBar.bNumBarsSep + 1;

	else
		deliverpoint = 8 * CEnemyCastBar.bNumBarsSep + 1;
	end


	if (not CEnemyCastBar.bSeparateBars) then -- new "if else end" for separated feature
		deliverpoint = insertpos;
		maxbars = insertpos;
	else
		maxbars = deliverpoint + (CEnemyCastBar.bNumBarsSep - 1);
	end

	--CEnemyCastBar.bNumBars
	for i=deliverpoint, maxbars do -- new for separated feature
	
		local button = getglobal("Carni_ECB_"..i);

		if (not button:IsVisible()) then
		
			if (tonumber(starttime)) then
				getglobal("Carni_ECB_"..i).startTime = starttime;
			else
				getglobal("Carni_ECB_"..i).startTime = GetTime();
			end

			if (turnlabel) then
				if (DRText) then
					getglobal("Carni_ECB_"..i).label = mob.." - "..spell .." "..DRText;
				else
					getglobal("Carni_ECB_"..i).label = mob .." - ".. spell;
				end
			else
				if (DRText) then
					getglobal("Carni_ECB_"..i).label = spell .." "..DRText.." - ".. mob;
				else
					getglobal("Carni_ECB_"..i).label = spell .." - ".. mob;
				end
			end

			if (mob == UnitName("player") ) then
				getglobal("Carni_ECB_"..i.."_Text"):SetShadowColor(1,0,0);
			elseif (starttime == "unkown spell") then
				getglobal("Carni_ECB_"..i.."_Text"):SetShadowColor(0, 0.3, 0);
			elseif (turnlabel and turnlabel ~= "forceshow") then
				getglobal("Carni_ECB_"..i.."_Text"):SetShadowColor(0,0,1);
			else
				getglobal("Carni_ECB_"..i.."_Text"):SetShadowColor(0,0,0);
			end

			if (CEnemyCastBar.bShowIcon) then
				if (not icontexture or icontexture == "") then
					icontexture = "INV_Misc_QuestionMark";
				end
				getglobal("Carni_ECB_"..i.."_Icon"):SetTexture("Interface\\Icons\\"..icontexture);
				getglobal("Carni_ECB_"..i.."_Icon"):Show();
			else
				getglobal("Carni_ECB_"..i.."_Icon"):Hide();
			end


			if (channeling
				--uncomment below to change direction of castbar types
				or (not CEnemyCastBar.bFillupGains and (ctype == "gainsfriend" or ctype == "gainsfoe"))
				or (not CEnemyCastBar.bFillupDebuffs and (ctype == "afflict" or ctype == "stuns"))
				or (not CEnemyCastBar.bFillupDoTs and ctype == "dots")
			) then
				getglobal("Carni_ECB_"..i).channeling = true;
			end

			getglobal("Carni_ECB_"..i).spell = spell;
			getglobal("Carni_ECB_"..i).mob = mob;
			getglobal("Carni_ECB_"..i).ctype = ctype;
			getglobal("Carni_ECB_"..i).endTime = getglobal("Carni_ECB_"..i).startTime + castime;
			getglobal("Carni_ECB_"..i.."_StatusBar"):SetMinMaxValues(button.startTime,button.endTime);
			getglobal("Carni_ECB_"..i.."_StatusBar"):SetValue(button.startTime);
			getglobal("Carni_ECB_"..i.."_StatusBar"):SetStatusBarColor(red, green, blue);
			if (not falpha) then
				falpha = 0; -- for movable bars reduced alpha dummies
			end
			button:SetAlpha(falpha);
			button:Show();

			break; -- new for separated feature

		elseif (not CEnemyCastBar.bSeparateBars) then -- new for separated feature, only "else" before
			-- the limit has been reached if we got here
			NECB_BarrierShown = GetTime();
			CECBBarrierFrame:SetScale(CEnemyCastBar.bScale);
			if (CEnemyCastBar.bFlipB) then
				CECBBarrierFrame:SetPoint("TOP", "Carni_ECB_"..CEnemyCastBar.bNumBars, 0, -13);
			else
				CECBBarrierFrame:SetPoint("TOP", "Carni_ECB_"..CEnemyCastBar.bNumBars, 0, 8);
			end
			CECBBarrierFrame:Show();
			
		end
		
	end
	
 end  

end

function CEnemyCastBar_BarrierUpdater() --barrier updater

	if (GetTime() > NECB_BarrierShown + 5) then 
		CECBBarrierFrame:Hide();
	end
end

function CEnemyCastBar_UniqueCheck(spellname, castime, mob, gspell, DRText, turnit, ctype) --Unique

	-- define search area for maximum performance with new separated bar feature:
	local firstbutton = 1;
	local lastbutton = CEnemyCastBar.bNumBars;
	if (CEnemyCastBar.bSeparateBars) then

		if (ctype == "casts") then
			firstbutton = 1; --1
			lastbutton = 2 * CEnemyCastBar.bNumBarsSep; --10

		elseif (ctype == "allgains") then
			firstbutton = 2 * CEnemyCastBar.bNumBarsSep + 1; --11
			lastbutton = 4 * CEnemyCastBar.bNumBarsSep; --20

		elseif (ctype == "afflictions") then
			firstbutton = 4 * CEnemyCastBar.bNumBarsSep + 1; --21
			lastbutton = 7 * CEnemyCastBar.bNumBarsSep; --35

		elseif (ctype == "cooldown") then
			firstbutton = 7 * CEnemyCastBar.bNumBarsSep + 1; --36
			lastbutton = 8 * CEnemyCastBar.bNumBarsSep; --40

		elseif (ctype == "grey") then
			firstbutton = 8 * CEnemyCastBar.bNumBarsSep + 1; --41
			lastbutton = 9 * CEnemyCastBar.bNumBarsSep; --45
		end
	end


	local ashowing, drstate = 0, 0;

	-- check only, no update
	if (gspell == "true") then

		for i=firstbutton, lastbutton do
		
			if (spellname == getglobal("Carni_ECB_"..i).spell and mob == getglobal("Carni_ECB_"..i).mob) then

				ashowing = 1;

				break; -- there can be only one :D
			end
		end

	-- check + update if mob AND spell are the same
	elseif (gspell == "trueupdate") then

		for i=firstbutton, lastbutton do
		
			if ((spellname == getglobal("Carni_ECB_"..i).spell and mob == getglobal("Carni_ECB_"..i).mob)
				and not (turnit == true and not getglobal("Carni_ECB_"..i).channeling)
				and (CEnemyCastBar.bSeparateBars -- used for update of buff/debuff
					or
					not ((ctype == "allgains" or ctype == "afflictions") and (getglobal("Carni_ECB_"..i).ctype == "friendly" or getglobal("Carni_ECB_"..i).ctype == "hostile")) )
					and not (ctype == "casts" and (getglobal("Carni_ECB_"..i).ctype == "gainsfoe" or getglobal("Carni_ECB_"..i).ctype == "gainsfriend") )-- needed for channel_update (possibly gains are updated, not the channeling)
					and not (ctype == "cooldown" and getglobal("Carni_ECB_"..i).ctype ~= "cooldown" )-- the gain is followed after channel start event and CD will overwrite the cast otherwise in non sep mode
				) then

				ashowing = 1;

					local button = getglobal("Carni_ECB_"..i); --START unique updater

					if (DRText == "delay") then
						-- only allow real casts to be delayed
						if (button.ctype == "friendly" or button.ctype == "hostile") then
							button.startTime = castime;
							button.endTime = turnit;
							getglobal("Carni_ECB_"..i.."_StatusBar"):SetMinMaxValues(button.startTime,button.endTime);
							getglobal("Carni_ECB_"..i.."_StatusBar"):SetValue(GetTime());
						end

					-- main updater
					else

						if (castime == "renew") then -- debuff/gain renew system
							castime = button.endTime - button.startTime;
						end
						button.startTime = GetTime();
						button.endTime = getglobal("Carni_ECB_"..i).startTime + castime;
						getglobal("Carni_ECB_"..i.."_StatusBar"):SetMinMaxValues(button.startTime,button.endTime);
						getglobal("Carni_ECB_"..i.."_StatusBar"):SetValue(button.startTime);
					end


					if (DRText and DRText ~= "delay") then
						if (DRText == "HoT") then
							local HoTLabel = button.label;
							local HoTStack = string.match(HoTLabel, "(%(%d+%))" );
							if (HoTStack) then
								HoTStack = tonumber( string.sub(HoTStack, 2, string.len (HoTStack) - 1) );
								HoTStack = HoTStack + 1;
								DRText = "("..HoTStack..")";
							else
								DRText = "(2)";
							end
						end

						if (turnit and turnit ~= true) then
							getglobal("Carni_ECB_"..i).label = mob.." - "..spellname .." "..DRText;
						else
							getglobal("Carni_ECB_"..i).label = spellname .." "..DRText.." - "..mob;
						end
					end

				break; -- there can be only one :D
			end
		end

	-- check + update if spell is the same
	else

		for i=firstbutton, lastbutton do
			
			if ((spellname == getglobal("Carni_ECB_"..i).spell)
				and (CEnemyCastBar.bSeparateBars
					or not ((ctype == "allgains" or ctype == "afflictions") and (getglobal("Carni_ECB_"..i).ctype == "friendly" or getglobal("Carni_ECB_"..i).ctype == "hostile") ) )
				) then
	
				ashowing = 1;

					local button = getglobal("Carni_ECB_"..i); --START unique updater

					if (mob == UnitName("player")) then
						getglobal("Carni_ECB_"..i.."_Text"):SetShadowColor(1,0,0);
					else
						getglobal("Carni_ECB_"..i.."_Text"):SetShadowColor(0,0,0);
					end

					if (DRText) then
						if (string.find(button.label, "1/2")) then
							drstate = 4; DRText = "(|cffff00001/4|r)"; castime = castime/2 + 15;
						elseif (string.find(button.label, "1/4")) then
							drstate = 6; DRText = "(|cffff0000"..CECB_MISC_IMMUNE.."|r)"; castime = castime/4 + 15;
						elseif (string.find(button.label, CECB_MISC_IMMUNE)) then
							drstate = 2; DRText = "(|cffff00001/2|r)"; castime = castime + 15;
						end
						getglobal("Carni_ECB_"..i).label = spellname .." "..DRText.." - "..mob;
					else
						getglobal("Carni_ECB_"..i).label = spellname .." - ".. mob;
					end

					button.startTime = GetTime();
					button.endTime = getglobal("Carni_ECB_"..i).startTime + castime;
					getglobal("Carni_ECB_"..i.."_StatusBar"):SetMinMaxValues(button.startTime,button.endTime);
					getglobal("Carni_ECB_"..i.."_StatusBar"):SetValue(button.startTime);

					button.mob = mob; --END unique updater
					
				break; -- there can be only one :D
			end
		end
	end

	return ashowing, drstate;
end

function CEnemyCastBar_BCast_Control(bcasted) --BCast Control

	local down, up, latency = GetNetStats();

	if (not bcasted and latency < 750 and CEnemyCastBar.bBCaster and CEnemyCastBar.bParseC and (GetNumRaidMembers() ~= 0 or GetNumPartyMembers() ~= 0 or GetNumBattlefieldStats() > 1 or IsActiveBattlefieldArena()) ) then
		if (LastSentBCPacket) then
			if (BCPacket[1] == LastSentBCPacket[1] and BCPacket[2] == LastSentBCPacket[2] and BCPacket[3] == LastSentBCPacket[3] and (GetTime() - LastSentBCPacket[4]) < 5) then
				return false, latency;
			end
		end
		return true, latency;
	end
	return false, latency;
end

function NECB_SetInterruptCheck()

	if (	not CEnemyCastBar.bGlobalPvP
		or CEnemyCastBar.bGainsOnly
		or not CEnemyCastBar.bPvP
		) then
		CEnemyCastBar.bSpellBreaks = false;
	else
		CEnemyCastBar.bSpellBreaks = true;
	end
end

function NECB_interrupt_casting(spell, mob) --INTERRUPTING Function, idea by Lazarus

	if ( UnitName("target") == mob or (UnitName("focus") == mob and CEnemyCastBar.bFocusPvP) ) then
		--will be catched by new spellcastSTOP event (WoW2.0)
		return;

	elseif ( string.find(NECB_Interruptions, spell) ) then
		CEnemyCastBar_Control(mob, mob, "interrupt");
	end
end

function CEnemyCastBar_Player_Target_Changed() --Target changed

	-- refire delayed Unit updates of WoW API for unit death
	if (CheckMobDeath) then
		--DEFAULT_CHAT_FRAME:AddMessage("|cffffff00CheckMobDeath: "..GetTime() - CheckMobDeath[1])--
		if (GetTime() - CheckMobDeath[1] < 0.5) then
			CEnemyCastBar_Control(CheckMobDeath[2], CheckMobDeath[2], "died");
		end
		CheckMobDeath = false;
	end

	-- show possible cast bar instantly on target change
	if ((UnitCastingInfo("target") or UnitChannelInfo("target"))and CEnemyCastBar.bStatus and CEnemyCastBar.bPvP and not CEnemyCastBar.bGainsOnly) then
		NECB_SpellStart("target", true); -- true = update line from delay func
	end

	-- cooldown database updater
	if (CEnemyCastBar.bCDown or CEnemyCastBar.bClassDR) then

		-- remove other Player CD Bars first
		local minbar, maxbar = 1, CEnemyCastBar.bNumBars;
		if (CEnemyCastBar.bSeparateBars) then
			minbar, maxbar = 7 * CEnemyCastBar.bNumBarsSep + 1, 8 * CEnemyCastBar.bNumBarsSep; --36, 40
		end
		for i=minbar, maxbar do
			local spell = getglobal("Carni_ECB_"..i).spell;
	
			if (spell and string.find(spell, " %(CD%)") ) then
	
				spell = string.gsub(spell, " %(CD%)", "");
				if (CEnemyCastBar_Spells[spell]) then
					CEnemyCastBar_HideBar(i);
				end
			--DR, remove as well
			elseif (spell and string.match(spell, "DR: ") ) then
				CEnemyCastBar_HideBar(i);
	
			end
		end
	
		-- display CDs from Database for new target and remove obsolete CDs
		local i = 1;
		while i <= #NECB_CD_DB do
			if ( GetTime() > ( NECB_CD_DB[i][3] + NECB_CD_DB[i][4] ) ) then
				table.remove(NECB_CD_DB, i);
				i = i - 1;
			else
				if (NECB_CD_DB[i][1] == UnitName("target") ) then
					if (UnitIsPlayer("target") and not CEnemyCastBar_Spells[NECB_CD_DB[i][2]].disabled) then
						CEnemyCastBar_Show(NECB_CD_DB[i][1], NECB_CD_DB[i][2].." (CD)", NECB_CD_DB[i][4], "cooldown", nil, CEnemyCastBar_Spells[NECB_CD_DB[i][2]].icontex, NECB_CD_DB[i][3]);
					else
						table.remove(NECB_CD_DB, i);
						i = i - 1;
					end
				end
			end
			i = i + 1;
		end
	
		--DR display DRs from Database for new target and remove obsolete DRs
		local i = 1;
		local _, playersclass = UnitClass("player");
		while i <= #NECB_DR_DB do
			if ( GetTime() > ( NECB_DR_DB[i][3] + NECB_DR_DB[i][4] ) or UnitIsDeadOrGhost("target") ) then
				table.remove(NECB_DR_DB, i);
				i = i - 1;
			else
				if (NECB_DR_DB[i][1] == UnitName("target") and playersclass == CEnemyCastBar_Afflictions[ NECB_DR_DB[i][6] ].sclass) then
					CEnemyCastBar_Show(NECB_DR_DB[i][1], NECB_DR_DB[i][2], NECB_DR_DB[i][4], "cooldown", nil, CEnemyCastBar_Afflictions[ NECB_DR_DB[i][6] ].icontex, NECB_DR_DB[i][3], NECB_DR_DB[i][5]);
				end
			end
			i = i + 1;
		end
	end

end

function CEnemyCastBar_IsHostile(event) --ishostile?

	if (event == "CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE" or event == "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE"
		or event == "CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF" or event == "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS"
		or event == "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_BUFF" or event == "CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS"
		) then
		return true;
	else
		return false;
	end
end

function CEnemyCastBar_PvECheck(mob, spell, bcasted, event) --some checks to reduce the situations in which PvP spells are blocked by PvE Spells!

	if (
		CEnemyCastBar_Raids[spell]
		and not (CEnemyCastBar_Raids[spell].mcheck and not string.find(CEnemyCastBar_Raids[spell].mcheck, mob))
		and (bcasted or not (CEnemyCastBar_Raids[spell].checkevent and (not event or not string.find(CEnemyCastBar_Raids[spell].checkevent, event) ) ) )
		) then
		return true;
	end
end

function CEnemyCastBar_Control(mob, spell, special, bcasted, event, rank) --Control

	if (not CEnemyCastBar.bStatus) then
		return;
	end

	-- Convert "You" into Playername, important for broadcasts
	if (mob == CECB_SELF1 or mob == CECB_SELF2) then
		mob = UnitName("player");
	end

	local spelllength = string.len (spell);
	-- crop the german aposthrophes from some spells (')
	local spell_de = string.sub(spell, 2, spelllength - 1);
	if (CEnemyCastBar_Raids[spell_de]) then spell = spell_de;
	end

		-- stop mirroring spells! only specified Mob, Zone, Event produces castbars else check pvp, debuff section
	if (	NECB_PvE_Module_loaded
		and special ~= "fades"
		and CEnemyCastBar_PvECheck(mob, spell, bcasted, event)
		) then

		NECB_PvE_Control(mob, spell, special, bcasted, event); -- load on demand addon
		
	else

		-- Network BC TempBCaster
		local clientlang = GetLocale();
	
		-- initialize vars
		local ctype, castime;

		if (NECB_PvP_Module_loaded) then
			NECB_PvP_Control(mob, spell, special, bcasted, event, rank); -- load on demand addon
		end
	-- new block
	-- other than PvE, independent of PvP
		-- now check everytime, since some gains shall be removed, too (see REMOVALS in afflictions section of localization.lua)
		if (special == "fades") then -- spells fading earlier than bar, not very important since most spells can't end earlier and aren't listed in c-log after recast and still afflicted

			spell = string.gsub(spell, " %(.+%)", ""); -- remove suffix brackets
			-- crop the german aposthrophes from some spells (')
			local spell_de = string.sub(spell, 2, spelllength - 1);
			if (CEnemyCastBar_Afflictions[spell_de] or CEnemyCastBar_Spells[spell_de]) then spell = spell_de;
			end

			local NECBAfflictSpell = false;
			if (CEnemyCastBar_Afflictions[spell]) then
				NECBAfflictSpell = true;
			end

			-- don't remove 'multi' on fade -> REMOVED; they 'stack' now!
			-- don't hide dmg debuffs, can be other player's fade!
			if (NECBAfflictSpell and not (CEnemyCastBar_Afflictions[spell].periodicdmg)
				or CEnemyCastBar_Spells[spell] ) then


				-- some spells ('Inner Focus') start their CD on fade
				if (CEnemyCastBar.bCDown and CEnemyCastBar_Spells[spell] and CEnemyCastBar_Spells[spell].onfade and mob ~= UnitName("player") ) then
					-- update CD in database
					local i = 1;
					while i <= #NECB_CD_DB do
						if ( NECB_CD_DB[i][1] == mob and NECB_CD_DB[i][2] == spell ) then
							NECB_CD_DB[i][3] = GetTime();
							if (mob == UnitName("target") ) then
								CEnemyCastBar_UniqueCheck(spell.." (CD)", CEnemyCastBar_Spells[spell].d, mob, "trueupdate", nil, nil, "cooldown");
							end
						elseif ( GetTime() > ( NECB_CD_DB[i][3] + NECB_CD_DB[i][4] ) ) then -- remove 'old' cooldowns
							table.remove(NECB_CD_DB, i);
							i = i - 1;
						end
						i = i + 1;
					end
				end

				-- correct DR if a DR Spell fades earlier, NECBAfflictSpell can only be true if Debuffs module loaded (for CEnemyCastBar_DR_DBCheck) ;-)
				if (CEnemyCastBar.bClassDR and NECBAfflictSpell and CEnemyCastBar_Afflictions[spell].spellDR) then
					local drshare = CEnemyCastBar_Afflictions[spell].drshare;
					local drspell;
					if (drshare) then
						drspell = "DR: "..drshare;
					else
						drspell = "DR: "..spell;
					end
					CEnemyCastBar_UniqueCheck(drspell, 15, mob, "trueupdate", nil, nil, "cooldown"); -- update screen
					CEnemyCastBar_DR_DBCheck(mob, drspell, 15, "fadeupdate"); -- update DR DB
				end

				local minbar, maxbar = 1, CEnemyCastBar.bNumBars;
				if (CEnemyCastBar.bSeparateBars) then
					maxbar = 7 * CEnemyCastBar.bNumBarsSep; --35
				end
				for i=minbar, maxbar do
	
					local spellrunning = getglobal("Carni_ECB_"..i).spell;
					if (spellrunning) then

						local mobrunning = getglobal("Carni_ECB_"..i).mob;
						if (mob == mobrunning and spell == spellrunning and getglobal("Carni_ECB_"..i).ctype ~= "cooldown") then

							--BC stacking HoT counter (and Debuff multi counter)
							local NECBNoDel;
							if ((CEnemyCastBar_Spells[spell] and CEnemyCastBar_Spells[spell].HoT)
								or (NECBAfflictSpell and CEnemyCastBar_Afflictions[spell].multi)
								) then
								local HoTLabel = getglobal("Carni_ECB_"..i).label;
								local HoTStack = string.match(HoTLabel, "(%(%d+%))" );
								if (HoTStack) then
									HoTStack = tonumber( string.sub(HoTStack, 2, string.len (HoTStack) - 1) );
									HoTStack = HoTStack - 1;
									if (HoTStack > 1) then
										getglobal("Carni_ECB_"..i).label = spell .." ("..HoTStack..") - "..mob;
									else
										getglobal("Carni_ECB_"..i).label = spell .." - "..mob;
									end
									NECBNoDel = true; --don't clear bar with stack
								end
							end

							if (not NECBNoDel) then
								CEnemyCastBar_HideBar(i);
							end

							if (NECBAfflictSpell and (CEnemyCastBar_Afflictions[spell].global or CEnemyCastBar_Afflictions[spell].fragile) ) then
							-- Network BCasting
								BCPacket = {mob, spell, special};
								local freetosend, latency = CEnemyCastBar_BCast_Control(bcasted);
								if ( freetosend ) then
									NECB_SendMessage(".cecbspell "..mob..", "..spell..", "..special..", "..clientlang..", "..latency);
									LastSentBCPacket = {mob, spell, special, GetTime()};
									LastGotBCPacket = {mob, spell, special, GetTime()};
									necb_numspellcast = 0;
								end
							end

							break; -- there can be only one :D
					
						end
					end
				end
			end

		-- LAZARUS Interrupt effect, modified by Natur
		elseif (special == "interrupt") then

			local minbar, maxbar = 1, CEnemyCastBar.bNumBars;
			if (CEnemyCastBar.bSeparateBars) then
				maxbar = 2 * CEnemyCastBar.bNumBarsSep; --10
			end
			for i=minbar, maxbar do

				local spellrunning = getglobal("Carni_ECB_"..i).spell;
				if (spellrunning) then

					if (not CEnemyCastBar_Raids[spellrunning]) then
						local mobrunning = getglobal("Carni_ECB_"..i).mob;

						if (mob == mobrunning and ( getglobal("Carni_ECB_"..i).ctype == "hostile" or getglobal("Carni_ECB_"..i).ctype == "friendly" ) ) then
							CEnemyCastBar_HideBar(i);

							-- Clear Spell in CD Buffer
							if (CEnemyCastBar.bCDown and CEnemyCastBar_Spells[spellrunning] and CEnemyCastBar_Spells[spellrunning].d and not CEnemyCastBar_Spells[spellrunning].channeled) then
								local cdi = 1;
								while cdi <= #NECB_CD_DB do
									if ( NECB_CD_DB[cdi][1] == mobrunning and NECB_CD_DB[cdi][2] == spellrunning ) then
										table.remove(NECB_CD_DB, cdi);
										-- clear visible bar now
										if (CEnemyCastBar.bSeparateBars) then
											minbar, maxbar = 7 * CEnemyCastBar.bNumBarsSep + 1, 8 * CEnemyCastBar.bNumBarsSep; --36, 40
										end
										for i=minbar, maxbar do
											local cdspell = getglobal("Carni_ECB_"..i).spell;
											if (cdspell and string.find(cdspell, " %(CD%)") ) then

												cdspell = string.gsub(cdspell, " %(CD%)", "");
												if (CEnemyCastBar_Spells[cdspell] and cdspell == spellrunning) then
													CEnemyCastBar_HideBar(i);
												end
											end
										end
										break;
									end
									cdi = cdi + 1;
								end
							end
							-- Clear Spell in CD Buffer finished

							-- allow spellbreaker debuff bar to appear now
							if (necb_fauxtimer and CEnemyCastBar_Afflictions[necb_fauxtimer[2]] and CEnemyCastBar_Afflictions[necb_fauxtimer[2]].spellbreaker and mob == necb_fauxtimer[3]) then
								necb_fauxtimer[6] = true; -- done
								necb_fauxtimer[5] = 0; -- triggers the bar instantly (not after delay went off); resists will still be catched

								--DEFAULT_CHAT_FRAME:AddMessage("|cff000099Got Fauxtimer!"..GetTime())--
								--else--
								--DEFAULT_CHAT_FRAME:AddMessage("|cffff0000NO Fauxtimer :O"..GetTime())--
							end
							return; -- no one is able to cast more than one spell at once
						end
					end
				end
			end

		-- clear on mob died; to save some CPU time breackit it out
		elseif (special == "died") then

			-- Check if mob with same name dies, but was not 'your' mob; refired on "PLAYER_TARGET_CHANGED" (usually happens after mob dies)
			if (UnitName("target") == mob and not UnitIsDeadOrGhost("target")) then
				--sometimes UnitIsDead() is not updated fast enough by WoW API and it is still not true even if combatlog death fired (rare)
				CheckMobDeath = { GetTime(), mob };
				return;
			end

			-- first clear pending debuff casted on the mob; if dead and pending then can not resist etc. -> bar shows up after death
			if (necb_fauxtimer and mob == necb_fauxtimer[3]) then
				CEnemyCastBar_FauxUpdater("clear");
			end

			local minbar, maxbar = 1, CEnemyCastBar.bNumBars;
			if (CEnemyCastBar.bSeparateBars) then
				maxbar = 8 * CEnemyCastBar.bNumBarsSep; --40 (not only 35 to include Cooldowns (DRs))
			end
			for i=minbar, maxbar do

				local spellrunning = getglobal("Carni_ECB_"..i).spell;
				if (spellrunning) then

					-- remove DR Timers upon death
					if (string.find(spellrunning, "DR:")) then
						spellrunning = CECB_SPELL_STUN_DR;
					end

					local mobrunning = getglobal("Carni_ECB_"..i).mob;
					if (CEnemyCastBar_Afflictions[spellrunning]) then

						-- "if" mob can't die without removing the debuff, so this wasn't the 'afflicted' mob
						-- "death" negates the above
						local fragile = CEnemyCastBar_Afflictions[spellrunning].fragile;
						local death = CEnemyCastBar_Afflictions[spellrunning].death;

						if (mob == mobrunning and (not fragile or death)) then
							
							CEnemyCastBar_HideBar(i);

							if (CEnemyCastBar_Afflictions[spellrunning].global) then
							-- Network BCasting
								BCPacket = {mob, spell, special};
								local freetosend, latency = CEnemyCastBar_BCast_Control(bcasted);
								if ( freetosend ) then
									NECB_SendMessage(".cecbspell "..mob..", "..spell..", "..special..", "..clientlang..", "..latency);
									LastSentBCPacket = {mob, spell, special, GetTime()};
									LastGotBCPacket = {mob, spell, special, GetTime()};
									necb_numspellcast = 0;
								end
							end
						
						end

					-- to clear all but CD bars if mob dies
					elseif (CEnemyCastBar_Spells[spellrunning]) then

						if (mob == mobrunning and not string.find(getglobal("Carni_ECB_"..i).label, "(CD)") ) then
							CEnemyCastBar_HideBar(i);
						end --
					end
				end
			end

		-- other than faded/died
		elseif (NECB_Debuffs_Module_loaded) then
			NECB_Debuffs_Control(mob, spell, special, bcasted, event) -- load on demand addon
		end

	end -- finishes pve 'else' pvp, died if afflictions/fades
		
end

function CEnemyCastBar_Parse_RaidChat(msg, author, origin) --parse Raid/PartyChat for commands

	local detectedCECBcommand = true;

	-- fix for battleground names from other realms
	if (string.match(author, "%-") ) then
		author = string.sub(author, 1, string.find(author, "%-") - 1);
	end

	if (CEnemyCastBar.bParseC and origin ~= "NECBCHAT") then

		if (
			string.sub (msg, 1, 10) == ".countsec "
			or string.sub (msg, 1, 10) == ".countmin "
			or string.sub (msg, 1, 8) == ".repeat "
			or string.sub (msg, 1, 11) == ".stopcount "
			or string.sub (msg, 1, 11) == ".cecbspell "
			or string.sub (msg, 1, 32) == "<NECB> version request detected."
			or string.sub (msg, 1, 33) == "<NECB> gversion request detected."
			) then


			--Network BC
			if (string.sub (msg, 1, 11) == ".cecbspell ") then

				wrongclient = false;
				if (UnitName("player") == author and origin ~= "NECBCTRA") then return detectedCECBcommand;
				end
				--/script NECB_SendMessage(".cecbspell Genesarumia, Verbannen, afflicted, deDE, 250");
				for bcmob, bcspell, bcspecial, bcclientlang, bclatency in string.gmatch (msg, ".cecbspell (.+), (.+), (.+), (.+), (.+)") do

					if (bcclientlang ~= GetLocale()) then
						wrongclient = true;
						return detectedCECBcommand;
					end

					-- Check if last receive was the same packet within 5 seconds -> then break!
					if (LastGotBCPacket) then
						if (bcmob == LastGotBCPacket[1] and bcspell == LastGotBCPacket[2] and bcspecial == LastGotBCPacket[3] and (GetTime() - LastGotBCPacket[4]) < 5) then
							necb_numspellcast = necb_numspellcast + 1; 
							return detectedCECBcommand;
						end
					end

				--DEFAULT_CHAT_FRAME:AddMessage("m:"..bcmob.." s:"..bcspell.." t:"..bcspecial)
				necb_numspellcast = 99;
				LastGotBCPacket = {bcmob, bcspell, bcspecial, GetTime()};
				CEnemyCastBar_Control(bcmob, bcspell, bcspecial, "true");
				return detectedCECBcommand;
				end

			else

				-- version harvester
				if (CECBHELPFrame:IsVisible() and CECBHELPFrameText:GetText() == "NECB - VERSIONS" ) then
					for version in string.gmatch(msg, "<NECB> version request detected. (.+)") do
							version = string.sub(version, 2, string.len (version) - 1); -- remove brackets
							table.insert (NECBVersionDB, version);
							table.insert (NECBVersionNames, author);
							CEnemyCastBar_InternalHandler("printversions");
						return detectedCECBcommand;
					end

				-- gversion harvester
				elseif (CECBHELPFrame:IsVisible() and CECBHELPFrameText:GetText() == "NECB - GVERSIONS" ) then
					for version in string.gmatch(msg, "<NECB> gversion request detected. (.+)") do
							version = string.sub(version, 2, string.len (version) - 1); -- remove brackets
							table.insert (NECBVersionDB, version);
							table.insert (NECBVersionNames, author);
							CEnemyCastBar_InternalHandler("printversions");
						return detectedCECBcommand;
					end
				end

				local msg1 = string.sub (msg, 2, string.len(msg));
				if (string.sub(msg, 1, 6) ~= "<NECB>") then
					CEnemyCastBar_Handler(msg1);
				end
				return detectedCECBcommand, "|cffffffcc";
			end

		elseif (string.sub (msg, 1, 30) == "<NECB> Play Benny Hill for us!") then
			CEnemyCastBar_BHWipe(author);
			return detectedCECBcommand, "|cffffffcc";

		end

	end

	if (origin == "NECB") then

		if string.find(msg, "<NECB> Force version collection.") then
			--DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r Version request detected. Sending data.", 1, 0.5, 0);
			NECBVersionDB = { };
			NECBVersionNames = { };
			local playerbcaster = "";
			if (CEnemyCastBar.bBCaster and CEnemyCastBar.bParseC) then
				playerbcaster = ", BCASTER";
			end
			NECB_SendMessage("<NECB> version request detected. ("..CECB_status_version_txt..", "..GetLocale()..playerbcaster..")");
			return detectedCECBcommand, "|cffffffcc";

		elseif string.find(msg, "<NECB> Force gversion collection.") then
			--DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r GVersion request detected. Sending data.", 1, 0.5, 0);
			NECBVersionDB = { };
			NECBVersionNames = { };
			local playerbcaster = "";
			if (CEnemyCastBar.bBCaster and CEnemyCastBar.bParseC) then
				playerbcaster = ", BCASTER";
			end
			NECB_SendMessage("<NECB> gversion request detected. ("..CECB_status_version_txt..", "..GetLocale()..playerbcaster..")", nil, "toguild");
			return detectedCECBcommand, "|cffffffcc";

		elseif string.find(msg, "<NECB> Whisper old versions of NECB to update!") then
			DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffffff00"..author.."|r notified some users!");
			return detectedCECBcommand, "|cffffffcc";

		elseif string.find(msg, "<NECB> FORCE (.+) to Broadcast! Change Settings!") then

			for forceplayer in string.gmatch(msg, "<NECB> FORCE (.+) to Broadcast! Change Settings!") do

				if (forceplayer == UnitName("player") and CEnemyCastBar_CheckRaidStatus(author) ) then
					DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffffff00"..author.."|r has FORCED your NECB client to broadcast!");
					DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999Settings have been changed.");

					CEnemyCastBar.bPvE = true;
					CEnemyCastBar.bShowafflict = true;
					CEnemyCastBar.bGlobalFrag = true;
					CEnemyCastBar.bBossDebuff = true;
					CEnemyCastBar.bParseC = true;
					CEnemyCastBar.bBCaster = true;

 					-- load on demand PvE/Debuffs if not done already
					CEnemyCastBar_RegisterEvents();

					if (CECBOptionsFrame and CECBOptionsFrame:IsVisible()) then
						CECB_ReloadOptionsUI();
					end
				end
			end
			return detectedCECBcommand, "|cffffffcc";

		elseif string.find(msg, "<NECB> STOP (.+) to Broadcast! Change Settings!") then

			for forceplayer in string.gmatch(msg, "<NECB> STOP (.+) to Broadcast! Change Settings!") do

				if (forceplayer == UnitName("player") and CEnemyCastBar_CheckRaidStatus(author) ) then
					DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffffff00"..author.."|r has STOPPED your NECB client to broadcast!");
					DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB: |cffff9999Settings have been changed.");

					CEnemyCastBar.bBCaster = false;

					if (CECBOptionsFrame and CECBOptionsFrame:IsVisible()) then
						CECB_ReloadOptionsUI();
					end
				end
			end
			return detectedCECBcommand, "|cffffffcc";

		end

	elseif (origin == "NECBCHAT") then

		local rank, fileName = CEnemyCastBar_CheckRaidStatus(author);
		local color = { };
		if ( not fileName ) then
			color.r, color.g, color.b = 1, 1, 1;
		else
			color = RAID_CLASS_COLORS[fileName];
		end

		DEFAULT_CHAT_FRAME:AddMessage("|cffcc99ff\[NECB\] \[|r"..author.."|cffcc99ff\]: "..msg, color.r, color.g, color.b);
	end
end

function NECB_SendMessage(msgs, prefixadd, toguild) --send

	-- patch 1.12
	if (not prefixadd) then
		prefixadd = "";
	end

	if (toguild) then
		SendAddonMessage("NECB"..prefixadd, msgs, "GUILD");
	elseif (GetNumBattlefieldStats() > 1 or IsActiveBattlefieldArena() ) then
		SendAddonMessage("NECB"..prefixadd, msgs, "BATTLEGROUND");
	elseif (GetNumRaidMembers() ~= 0) then
		SendAddonMessage("NECB"..prefixadd, msgs, "RAID");
	elseif (GetNumPartyMembers() ~= 0 ) then
		SendAddonMessage("NECB"..prefixadd, msgs, "PARTY");
	end

end

function CEnemyCastBar_OnUpdate() --Update

	local CECname=this:GetName();
	local CECno=this:GetID();

	if (this.endTime) then

		local now = GetTime();
		-- Update the spark, status bar and label
		local remains = this.endTime - now;
		local sparkPos = ((now - this.startTime) / (this.endTime - this.startTime)) * (195 + CEnemyCastBar.bnecbCBLBias);

		if (this.channeling) then
			getglobal(CECname .. "_StatusBar"):SetValue(this.startTime + remains);
			getglobal(CECname .. "_StatusBar_Spark"):SetPoint("CENTER", getglobal(CECname .. "_StatusBar"), "RIGHT", -sparkPos, 0);
		else
			getglobal(CECname .. "_StatusBar"):SetValue(now);
			getglobal(CECname .. "_StatusBar_Spark"):SetPoint("CENTER", getglobal(CECname .. "_StatusBar"), "LEFT", sparkPos, 0);
		end

		getglobal(CECname .. "_Text"):SetText( this.label );	

		local cbtext = "";
		if (CEnemyCastBar.bTimer) then
			cbtext = CEnemyCastBar_NiceTime(remains);
		end

		if (getglobal(CECname).mob == UnitName("focus") and (CEnemyCastBar.bFocusPvP or CEnemyCastBar.bFocusDebuffs)) then
			--cbtext = cbtext.." |cffff0000(F)|r";
			getglobal(CECname .. "_FocusIcon"):Show();
		else
			getglobal(CECname .. "_FocusIcon"):Hide();
		end
		getglobal(CECname .. "_CastTimeText"):SetText( cbtext );
		


		-- fantastic fading routine + flashing, fps independent :D
		local framerate = GetFramerate();
		local stepping = 2/framerate;
		if (stepping > 0.4 ) then stepping = 0.4; -- security for very low fps (< 5fps)
		end

		local baralpha = this:GetAlpha();
		local totalTime = this.endTime - this.startTime;
		if (CEnemyCastBar.bFlashit and (remains/totalTime) < 0.20 and remains < 10 and totalTime >= 20 and not necblockshow) then

			stepping2 = stepping/1.2 -- manipulate flashing-speed
			if ((baralpha - stepping2) >= 0.1) then
				baralpha = baralpha - stepping2;
				this:SetAlpha(baralpha);
			else
				this:SetAlpha(1);
			end

			-- Raidwarning /rw
			if (CEnemyCastBar.bPvEWarn and not this.warned and CEnemyCastBar_Raids[this.spell] ) then
				PlaySoundFile("Interface\\AddOns\\CEnemyCastBar\\Sounds\\bottleopen2.mp3");
				this.warned = true;
			end

		elseif (not necblockshow) then

			-- Raidwarning, reset to allow new warnings for this spell
			if (this.warned) then
				this.warned = nil;
			end

			if (baralpha + stepping <= CEnemyCastBar.bAlpha) then
				baralpha = baralpha + stepping;
				this:SetAlpha(baralpha);
			else
				if (baralpha ~= CEnemyCastBar.bAlpha) then
					this:SetAlpha(CEnemyCastBar.bAlpha);
				end
			end
		end
		-- fading routine finished

		if (remains < 0) then

			if (string.find (getglobal(CECname).label, "Repeater") ) then

				local castime = getglobal(CECname).endTime - getglobal(CECname).startTime;
				getglobal(CECname).startTime = GetTime();
				getglobal(CECname).endTime = getglobal(CECname).startTime + castime;
				getglobal(CECname.."_StatusBar"):SetMinMaxValues(getglobal(CECname).startTime,getglobal(CECname).endTime);
				getglobal(CECname.."_StatusBar"):SetValue(getglobal(CECname).startTime);

				if (castime == 0) then
					getglobal(CECname).label = "delete me!";
				end

			else

				local tmpmob = getglobal(CECname).mob;
				local tmpspell = getglobal(CECname).spell;
				if (necblockshow) then
					necblockshow = nil;
					if (CEnemyCastBar.bLocked == false) then
						CEnemyCastBar_LockPos();
					end

				-- check special flags for bars running out
				elseif ( UnitAffectingCombat("player") or UnitIsDead("player") ) then

 					-- check for tchange flag; changes the 't' of castbars if current bar runs out
					if (CEnemyCastBar_Raids[tmpspell] and CEnemyCastBar_Raids[tmpspell].tchange) then
						CEnemyCastBar_Raids[CEnemyCastBar_Raids[tmpspell].tchange[1]].t = CEnemyCastBar_Raids[tmpspell].tchange[3];
						if (CEnemyCastBar_Raids[tmpspell].tchange[2] == true) then --change permanently if [4] is set
							table.insert (NECBtchangeSourcePerm, tmpspell);
						else
							table.insert (NECBtchangeSource, tmpspell);
							necbengagecd = GetTime(); -- starts the EngageProtection to reset 't' to default for next combat
						end
					end

					-- check for aBar flag; Fires 'aBar' if current bar runs out
					if (CEnemyCastBar_Raids[tmpspell] and CEnemyCastBar_Raids[tmpspell].aBar ) then
						CEnemyCastBar_HideBar(CECno);
						CEnemyCastBar_Control(tmpmob, CEnemyCastBar_Raids[tmpspell].aBar, "casts", "true"); -- won't be broadcasted!
						return;
					end

				end

				-- trigger cooldown bar at the end of the cast
				if ( CEnemyCastBar.bCDown and CEnemyCastBar_Spells[tmpspell] and ( getglobal(CECname).ctype == "hostile" or getglobal(CECname).ctype == "friendly" ) ) then

					if ( CEnemyCastBar_Spells[tmpspell].d and CEnemyCastBar_Spells[tmpspell].t and UnitName("target") == tmpmob and UnitIsPlayer("target") ) then
	
						local castime = CEnemyCastBar_Spells[tmpspell].d;
						if (CEnemyCastBar_UniqueCheck(tmpspell.." (CD)", castime, tmpmob, "trueupdate", nil, nil, "cooldown") == 0) then
							CEnemyCastBar_HideBar(CECno);
							CEnemyCastBar_Show(tmpmob, tmpspell.." (CD)", castime, "cooldown", nil, CEnemyCastBar_Spells[tmpspell].icontex);
							return;
						end

					end
				end

				CEnemyCastBar_HideBar(CECno);

			end


			-- pull the bars together
		elseif (remains >= 1 ) then

			local CECpre = CECno - 1;
			local cecbuttonpre = getglobal("Carni_ECB_"..CECpre);

			-- stop falldown of bars through frames for new separation routine
			if (CECpre > 0 and not cecbuttonpre:IsShown() and (not CEnemyCastBar.bSeparateBars or CECpre % CEnemyCastBar.bNumBarsSep ~= 0) ) then

				cecbuttonpre.startTime = this.startTime
				cecbuttonpre.label = this.label;
	
				local r,g,b = getglobal("Carni_ECB_"..CECno.."_Text"):GetShadowColor();
				getglobal("Carni_ECB_"..CECpre.."_Text"):SetShadowColor(r,g,b);
	
				if (getglobal("Carni_ECB_"..CECno.."_Icon"):IsShown()) then
					getglobal("Carni_ECB_"..CECpre.."_Icon"):SetTexture(getglobal("Carni_ECB_"..CECno.."_Icon"):GetTexture());
					getglobal("Carni_ECB_"..CECpre.."_Icon"):Show();
				end

				cecbuttonpre.channeling = this.channeling;	
				cecbuttonpre.spell = this.spell;
				cecbuttonpre.mob = this.mob;
				cecbuttonpre.ctype = this.ctype;
				cecbuttonpre.endTime = this.endTime;
				getglobal("Carni_ECB_"..CECpre.."_StatusBar"):SetMinMaxValues(getglobal("Carni_ECB_"..CECno.."_StatusBar"):GetMinMaxValues());
				getglobal("Carni_ECB_"..CECpre.."_StatusBar"):SetValue(getglobal("Carni_ECB_"..CECno.."_StatusBar"):GetValue());
				getglobal("Carni_ECB_"..CECpre.."_StatusBar"):SetStatusBarColor(getglobal("Carni_ECB_"..CECno.."_StatusBar"):GetStatusBarColor());
				cecbuttonpre:SetAlpha(CEnemyCastBar.bAlpha);
				cecbuttonpre:Show();
	
				CEnemyCastBar_HideBar(CECno);
			end
		end
	end
end

-- Format seconds into m:ss
function CEnemyCastBar_NiceTime(secs)
	if (secs > 60) then
		secs = ceil(secs);
		return string.format("%d:%02d", secs / 60, math.fmod(secs, 60));
	elseif (secs > 10) then
		secs = ceil(secs);
		return string.format("%.f", secs); -- I noticed sometimes the ceil command does not work, so it is formatted for that case as well
	else
		return string.format("%.1f", secs);
	end
end


function CEnemyCastBar_FPSBar_OnUpdate() --FPSBar

	local framerate = GetFramerate();
	local g = framerate/30;
	local r = 30/framerate;

	if (g > 1) then g = 1;	end
	if (r > 1) then r = 1;	end

	if (framerate > 60) then frameratesafe = 60;
	else frameratesafe = framerate;
	end

	CECB_FPSBarFree_StatusBar:SetMinMaxValues(1,60);
	CECB_FPSBarFree_StatusBar:SetValue(frameratesafe);
	CECB_FPSBarFree_StatusBar_Spark:SetPoint("CENTER", "CECB_FPSBarFree_StatusBar", "LEFT", frameratesafe*1.95, 0);
	CECB_FPSBarFree_Text:SetText("|cffffffaaFPS: |cffffcc00"..ceil(framerate));
	CECB_FPSBarFree_StatusBar:SetStatusBarColor(r,g,0);
end

function CEnemyCastBar_FPSBar_DragStop()

	local _,_,_,x,y = CECB_FPSBarFree:GetPoint();
	CEnemyCastBar.tFramePoints["CECB_FPSBarFree"] = {x,y}
	CECB_FPSBarFree:SetUserPlaced(false);
end

function CECB_GCInfo_OnUpdate() --gcinfo

	local GCTime = GetTime();

	if (not lastgcupdate or GCTime - lastgcupdate > 0.5) then
		lastgcupdate = GCTime;

		local cecbgc_now = collectgarbage("count"); --BC after BC, delete above!
		if (cecbgc_max and cecbgc_now > cecbgc_max) then
			collectgarbage("collect");
		end

		if (not cecbgc_last or cecbgc_last > cecbgc_now) then
			cecbgc_last = cecbgc_now;
			cecbgc_min = cecbgc_now;
			if (cecbgc_now*2 > tonumber(GetCVar("scriptMemory")) ) then
				cecbgc_max = tonumber(GetCVar("scriptMemory"));
			else
				cecbgc_max = cecbgc_now*2; --BC after BC and use global
			end
			cecbgc_minupdate = GCTime;
			lastgcdiffupdate = nil;
			cecbgc_purge30 = 0;
		end

		if (not lastgcdiffupdate or GCTime - lastgcdiffupdate > 5) then
			lastgcdiffupdate = GCTime;
	
			cecbgcdiff = (cecbgc_now - cecbgc_last) / 5;
			cecbgc_last = cecbgc_now;

			--BC, clear from here downwards, remove time presumption; BUT possibly not necessary!!! Might still work
			local GCPurgeCalcLength = 30;
			if ((GCTime - cecbgc_minupdate) > GCPurgeCalcLength) then
				if (cecbgc_min == cecbgc_now) then
					cecbgc_purge30 = 0;
				else
					cecbgc_purge30 = (cecbgc_max - cecbgc_now) * (GCTime - cecbgc_minupdate) / (cecbgc_now - cecbgc_min);
				end
				cecbgc_min = cecbgc_now;
				cecbgc_minupdate = GCTime;
			end

			if (cecbgc_min == cecbgc_now and cecbgc_purge30 == 0) then
				--cecbgcpurge = "waiting...";
				cecbgcpurge = "collecting!"; --BC after BC
			else
				if (cecbgc_min == cecbgc_now) then
					cecbgcpurge = cecbgc_purge30;
				else
					if (GCTime - cecbgc_minupdate > GCPurgeCalcLength or cecbgc_purge30 == 0) then
						cecbgcpurge = (cecbgc_max - cecbgc_now) * (GCTime - cecbgc_minupdate) / (cecbgc_now - cecbgc_min);
					else
						cecbgcpurge = (cecbgc_purge30 * (GCPurgeCalcLength - (GCTime - cecbgc_minupdate)) / GCPurgeCalcLength) + (cecbgc_max - cecbgc_now) * (GCTime - cecbgc_minupdate) / (cecbgc_now - cecbgc_min) * (GCTime - cecbgc_minupdate) / GCPurgeCalcLength;
					end
				end

				if (cecbgcpurge >= 3600) then
					cecbgcpurge = string.format("%d:%02d (|cffffccccHour|r:|cffccffccMin|r)", cecbgcpurge / 3600, math.fmod(cecbgcpurge / 60, 60));
				elseif (cecbgcpurge >= 60) then
					cecbgcpurge = string.format("%d:%02d (|cffccffccMin|r:|cffccccffSec|r)", cecbgcpurge / 60, math.fmod(cecbgcpurge, 60));
				else
					if (cecbgcpurge < 0) then
						cecbgcpurge = 0;
					end
					cecbgcpurge = string.format("%d (|cffccccffSeconds|r)", cecbgcpurge);
				end
			end

		end

		local gctext1 = "|cffffff00This displays the memory usage of all addons!\n\n";
		local gctext2 = "|cffcccc00Estimated time until purge: |r"..cecbgcpurge.."\n\n";
		local gctext3 = "|cffccccffUsed Memory |r- |cffffccccGainRate |r- |cffccffccMaximum\n";
		cecbgcdiff = floor(cecbgcdiff * 10) / 10;
		local gctext4 = "|cff9999ff"..floor(cecbgc_now).."|rkb - |cffff9999"..cecbgcdiff.."|rkb/s - |cff99ff99"..floor(cecbgc_max).."|rkb";
		CECBGCFrameBGText:SetText(gctext1..gctext2..gctext3..gctext4, 0.8, 0.8, 0.8);

	end

end

function CEnemyCastBar_Validchar(msg) --validchar

	value = true;

	for i = 1, string.len(msg) do

		local ctable = string.byte(string.sub(msg,i,i));
		if ( not ( (ctable >= 48 and ctable <= 57) or (ctable >= 65 and ctable <= 90) or (ctable >= 97 and ctable <= 122) ) ) then
			value = false;
		end
	end

	return value;
end

function CEnemyCastBar_LoadDisabledSpells(msg) --loaddisabled

	for k,v in pairs (CEnemyCastBar.tDisabledSpells) do

			if (CEnemyCastBar_Raids[v]) then
				CEnemyCastBar_Raids[v].disabled = true;
			end
	
			if (CEnemyCastBar_Spells[v]) then
				CEnemyCastBar_Spells[v].disabled = true;
			end
	
			if (CEnemyCastBar_Afflictions[v]) then
				CEnemyCastBar_Afflictions[v].disabled = true;
			end

			if (CEnemyCastBar_Colors[v]) then
				CEnemyCastBar_Colors[v].disabled = true;
				disabled = true;
			end
	end

	if (not msg) then
		if (#CEnemyCastBar.tDisabledSpells == 0) then
			DSpells = "Nothing disabled found! |rEmpty table loaded.";
		else
			DSpells = #CEnemyCastBar.tDisabledSpells.." |rDisabled Spells loaded. (see |cff00ff00/necb disabled|r)";
		end
		DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|cffffff00 "..DSpells);
	end

end

function CEnemyCastBar_SetRange(param) --setrange

	local RangeValues = { };

	if (param == "allmax") then
		RangeValues = {"150", "150", "150", "150", "150", "150", "150", "150"};
		DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r All CombatLogRanges set to |cffffff00maximum|r!");
	elseif (param == "cmax") then
		RangeValues = {"150", "150", "50", "50", "50", "50", "50", "50"};
		DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r Creature CombatLogRanges set to |cffffff00maximum|r others set to defaults!");
	else
		RangeValues = {"60", "30", "50", "50", "50", "50", "50", "50"};
		DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r All CombatLogRanges set to |cffffff00defaults|r!");
	end

	SetCVar("CombatDeathLogRange" , RangeValues[1]);
	SetCVar("CombatLogRangeCreature" , RangeValues[2]); 
	SetCVar("CombatLogRangeFriendlyPlayers" , RangeValues[3]);
	SetCVar("CombatLogRangeFriendlyPlayersPets" , RangeValues[4]);
	SetCVar("CombatLogRangeHostilePlayers" , RangeValues[5]);
	SetCVar("CombatLogRangeHostilePlayersPets" , RangeValues[6]);
	SetCVar("CombatLogRangeParty" , RangeValues[7]);
	SetCVar("CombatLogRangePartyPet" , RangeValues[8]);
end

-- Thanks to Yatlas, Gello (Atlas Addon) for base code parts
function NECBButton_BeingDragged()

	local xpos,ypos = GetCursorPosition();
	local xmin,ymin = Minimap:GetLeft(), Minimap:GetBottom();
	
	xpos = -xpos/UIParent:GetScale()+70+xmin
	ypos = ypos/UIParent:GetScale()-70-ymin

	local miniradius = (xpos^2 + ypos^2)^0.5;
	if (miniradius < 100 and miniradius > 60 and not IsAltKeyDown()) then
		miniradius = 80;
	end
	--DEFAULT_CHAT_FRAME:AddMessage(xpos.." "..ypos.." "..miniradius);

	local bpoint = (math.deg(math.atan2(ypos,xpos)));

	if(bpoint < 0) then
		bpoint = bpoint + 360;
	end

	CEnemyCastBar.bMiniMapPos = bpoint;
	CEnemyCastBar.bMiniMapRadius = miniradius;
	CECBMiniMapButton:SetPoint("TOPLEFT", "Minimap", "TOPLEFT", 52 - (miniradius * cos(bpoint)), (miniradius * sin(bpoint)) - 52);
	CECBMiniMapButton:SetUserPlaced(false);
end

function NECBButton_OnEnter(update)

	if (update and (not GameTooltip:IsVisible() or not string.match(GameTooltipTextLeft1:GetText(), "EnemyCastBar")) ) then
		return
	end
	GameTooltip:SetOwner(this, "ANCHOR_LEFT");
	GameTooltip:SetText(NECB_Minimap_Tooltip);
	GameTooltip:AddLine(NECB_Minimap_Tooltip1);
	GameTooltip:AddLine(NECB_Minimap_Tooltip2);
	GameTooltip:AddLine(NECB_Minimap_Tooltip3);
	GameTooltip:AddLine(NECB_Minimap_Tooltip4); -- loaded:
	
	if (CECBOptionsFrame) then
		GameTooltip:AddLine("|cffffffffOptions |cffaaaaaa(195kb)");
	end
	if (NECB_PvP_Module_loaded) then
		GameTooltip:AddLine("|cffffffffPvP |cffaaaaaa(50kb)");
	end
	if (NECB_PvE_Module_loaded) then
		GameTooltip:AddLine("|cffffffffPvE/Raid |cffaaaaaa(45-70kb)");
	end
	if (NECB_Debuffs_Module_loaded) then
		GameTooltip:AddLine("|cffffffffDebuffs |cffaaaaaa(50kb)");
	end

	if (tonumber(GetCVar("CombatLogRangeCreature")) > 30 ) then
		GameTooltip:AddLine("\nCreature |cffffffffCombatlog range |rincreased!");
	else
		--GameTooltip:AddLine("\nCreature |cffffffffCombatlog range normal. |cffaaaaaa("..GetCVar("CombatLogRangeCreature")..")");
	end
	if (tonumber(GetCVar("CombatLogRangeFriendlyPlayers")) > 50 ) then
		GameTooltip:AddLine("Player |cffffffffCombatlog range |rincreased!");
	else
		--GameTooltip:AddLine("Player |cffffffffCombatlog range normal. |cffaaaaaa("..GetCVar("CombatLogRangeFriendlyPlayers")..")");
	end

	--GameTooltipTextLeft1:SetTextColor(1, 1, 1);

	if (not CEnemyCastBar.bStatus) then
		GameTooltip:AddLine(NECB_Minimap_Tooltip5);
	end
	GameTooltip:Show();
end


function NECBCreateBars(msg)

	local newbfound;
	for i=2, CEnemyCastBar.bNumBars do

		if (not getglobal("Carni_ECB_"..i)) then
			newbfound = true;

			local newButton = CreateFrame("Button", "Carni_ECB_"..i, UIParent, "CarniEnemyCastBarTemplate");
			newButton:SetID(i);
			newButton:SetPoint("TOPLEFT", "Carni_ECB_"..i-1, "TOPLEFT", 0, 20);
		end
	end

	if (newbfound) then
		CEnemyCastBar_FlipBars(); -- reorder frame, set icon, space, width for bars
		CEnemyCastBar_SetTextSize();
		CEnemyCastBar_SetBorder();
		CEnemyCastBar_SetTexture();

		CEnemyCastBar.bLocked = false;
		CEnemyCastBar_LockPos();
	end

	if (CEnemyCastBar.tFramePoints and not CEnemyCastBar.tFramePoints["Carni_ECB_1"] ) then
		local _,_,_,x,y = getglobal("Carni_ECB_1"):GetPoint();
		CEnemyCastBar.tFramePoints["Carni_ECB_1"] = { x,y };
	end

	if (CEnemyCastBar.bSeparateBars and msg == "reset") then

		local step = 1;
		local _, _, _, x, y = getglobal("Carni_ECB_1"):GetPoint(); -- get bar1 posi instead of hardcoding these points here again
		for i=CEnemyCastBar.bNumBarsSep + 1, CEnemyCastBar.bNumBars, CEnemyCastBar.bNumBarsSep do --i=6, max, 5
			getglobal("Carni_ECB_"..i):SetPoint("TOPLEFT", "UIParent", "TOPLEFT", x, y + step*30);
			getglobal("Carni_ECB_"..i):SetUserPlaced(true); -- and only these points will be stored into savedvariables with LockPos()
			step = step + 1;
		end
	end
end

-- define some last variables
NECB_Fonts = {
	[1] = { name="Blizzard", path="Fonts\\FRIZQT__.TTF"},
	[2] = { name="FuturaBD", path="Interface\\Addons\\CEnemyCastBar\\Fonts\\Futurab.ttf"},
	[3] = { name="Adventure", path="Interface\\Addons\\CEnemyCastBar\\Fonts\\Adventure.ttf"},
	[4] = { name="Enigma", path="Interface\\Addons\\CEnemyCastBar\\Fonts\\Enigma__2.TTF"},
	[5] = { name="Emblem", path="Interface\\Addons\\CEnemyCastBar\\Fonts\\Emblem.ttf"},
	[6] = { name="Diablo", path="Interface\\Addons\\CEnemyCastBar\\Fonts\\Exh_____.ttf"},
	[7] = { name="FuturaBK", path="Interface\\Addons\\CEnemyCastBar\\Fonts\\Futurak.ttf"},
	[8] = { name="Forte", path="Interface\\Addons\\CEnemyCastBar\\Fonts\\Forte.ttf"},
}

NECB_Textures = {
	[1] = "BantoBar";
	[2] = "Dabs";
	[3] = "CharCoal";
	[4] = "Glaze";
	[5] = "Otravi";
	[6] = "Otravi dark";
	[7] = "Claud";
	[8] = "Waves";
	[9] = "Diagonal";
	[10] = "Rain";
	[11] = "Water";
	[12] = "Wisps";
	[13] = "Perl";
	[14] = "Smooth";
	[15] = "Smudge";
	[16] = "Striped";
	[17] = "Marble";
	[18] = "Skewed";
	[19] = "Tube large";
	[20] = "Tube small";
	[21] = "Salinos";
}