
--[[

	CombatStats3 - Stat Damage Tracking
	AUTHOR:	DmgInc on most forums / Glacier on official WoW forums
	THANKS TO:	The dude(ette) who made DPSPlus for showing me the light on how to parse the combat log
				The dude(ette) who made Clock for the time conversion routines 

	Rev. 3.3	- ReEnabled the option to only show the stats on a mouseclick
	2.16.05		- DPS caluculated is now 15 seconds w/no option to change
				- Added end of fight stats option to turn on/off
				- Slash commands will save between sessions when not using w/cosmos
				
	Rev. 3.2	- Added end of fight statistics
	2.09.05		- Using PLAYER_REGEN_DISABLED ENABLED to tell when you
                  are in/out of combat for end of fight info

	Rev. 3.1	- Lots of fixes to track pet stats
	2.07.05	

	Rev. 3.0	- Initial version to track Defensive DPS	
	12.xx.04

	Rev 2.03 	- Now really really works w/o cosmos
	11.15.04
	
	Rev 2.02	- Now works w/o cosmos
	11.14.04	- Changed the text display frame
			- Fixed the crit % running out of the frame when it was 100%
			- Put "Default" attack at top of the list
			- Added in a "Total", put it at the bottom of the list
			- UI is now movalbe
			- UI will update itself while you are attacking if it is visible
			- Fixed a bug where the close "X" button couldn't be pressed
			- Now uses OnEvent and OnUpdate 
			- Pet damage is now tracked
			- DOT damage totals are correctly shown
			- Hopefully got rid of bogus entries
				

	Rev 2.01	- First release w/new UI
	11.05.04
	
  ]]

if ( CT_AddMovable ) then
	CT_AddMovable("CombatStatsFrame", "CombatStats", "TOPLEFT", "TOPLEFT", "UIParent", 150, 0, function(status) end);
end



--
--	Cosmos Cofig variables
--

CombatStats_Config = { };
CombatStats_Config.CombatStats_OnOff = 1;
CombatStats_Config.CombatStats_HideOnNoTarget = 0;
CombatStats_Config.CombatStats_EndOfFight = 0;
CombatStats_Config.CombatStats_UseMouseOver = 0;

CombatStats_LastUpdate = 0;
CombatStats_UpdateFreq = 0.1; 
CombatStats_DPSLen = 15;	-- Calculate DPS over the last 60 seconds
 
defcritCount = 0;
speccritCount= 0;

timestamps = {};
takenTimestamps = {};

players = {};
playersTaken = {};

dmg = {};
dmgTaken = {};

dpstotals = {};
dpsTakenTotals = {};

defCrits = {0};
specCrits = {0};

defCritTotals = {};
specCritTotals = {};

bInCombat = 0;
bHasDefault = 0;

totalDamage = 0;

--
--	Last fight info
--

lastFightStart		=	0;
lastFightFinish		=	 0;
lastFightPlayerDamage	=	0;
lastFightPetDamage	=	0;

mobDied				=	0;
regenEnabled		=	0;
leaveCombat		=	0;

overallCombatTime	=	0;

overallSwings		=	0;
overallMisses		=	0;
overallDodged		=	0;
overallParried		=	0;
overallEvaded		=	0;
overallBlocked		=	0;
overallResisted		=	0;
overallImmuned		=	0;
overallDeflected	=	0;
overallHits		=	0;
overallNonCrits		=	0;
overallCrits		=	0;
overallmaxCrit		=	0;
overallminCrit		=	0;
overallmaxReg		=	0;
overallminReg		=	0;
overallRegDmg		=	0;
overallCritDmg		=	0;
overallLastcrit		=	0;


attackNames = {};
specialAttacks = {};
specialAttackLog = {};

totalHits = 0;
totalCrits = 0;
specialsCount = 0;
combatTime = 1;

CombatStats_Old_TargetFrame_OnShow = nil;
CombatStats_Old_TargetFrame_OnHide = nil;

CombatStats_ChatCommandHandlers={};

bFirstTime = 1;

CombatStatsVars = { };
CombatStatsSessionVars = { };
DeathCount = 0;
DeathLog = { };
CombatStatsRecentVars = { };
CombatStatsByName = { };
CombatStatsSessionByName = { };
CombatStatsDisplay = { };

function CombatStats_ChatCommandHandler(msg)
	msg = string.lower(msg);
	local firsti, lasti, command, setStr = string.find (msg, "(%w+) ([%w%.]+)");
	if ((not command) and msg) then
		command = msg;
	end
	if (command) then
		for curCommand in CombatStats_ChatCommandHandlers do
			if (command == curCommand) then
				if (setStr) then
					CombatStats_ChatCommandHandlers[curCommand](setStr);
				else
					CombatStats_ChatCommandHandlers[curCommand]();
				end
				return;
			end
		end
	end
	Print("All slash command can start with either /cs or /combatstats example: /cs enable or /combatstats enable");
	Print("Then you can pass on or off to them, or pass a number for ones that need a number ex.");
	Print("/cs enable on");
	Print("/cs enable off");
	Print("");
	Print("enable [on | off] - 'Enable/disabwle CombatStats, on or off'");
	Print("target [on | off] - 'Only show DPS meter when you have a target'");
	Print("mouseover [on | off] - 'Show detailed window on mouseover'");
	Print("endoffight [on | off] - 'Show end of fight information'");
	Print("reset yes - 'Rest all stats to 0'");

end

--
--	Slash command handler
--

function CombatStats_Enable_ChatCommandHandler(msg)

	if (msg) then
		msg = string.upper(msg);
		-- Toggle appropriately
		if (string.find(msg, "ON")) then
			CombatStats_Config.CombatStats_OnOff = 1;
		elseif (string.find(msg, "OFF")) then
			CombatStats_Config.CombatStats_OnOff = 0;		
		end
	end
	
	if(Cosmos_RegisterConfiguration ~= nil) then
		Cosmos_UpdateValue("COMBATSTATS_CONFIG_ONOFF", CSM_CHECKONOFF, CombatStats_Config.CombatStats_OnOff);
	end

	CombatStats_UpdateVisibility();

end
CombatStats_ChatCommandHandlers["enable"] = CombatStats_Enable_ChatCommandHandler;

function CombatStats_Target_ChatCommandHandler(msg)

	if (msg) then
		msg = string.upper(msg);
		-- Toggle appropriately
		if (string.find(msg, "ON")) then
			CombatStats_Config.CombatStats_HideOnNoTarget = 1;
		elseif (string.find(msg, "OFF")) then
			CombatStats_Config.CombatStats_HideOnNoTarget = 0;		
		end
	end
	
	if(Cosmos_RegisterConfiguration ~= nil) then
		Cosmos_UpdateValue("COMBATSTATS_CONFIG_HIDEONNOTARGET", CSM_CHECKONOFF, CombatStats_Config.CombatStats_HideOnNoTarget);
	end

	CombatStats_UpdateVisibility();

end
CombatStats_ChatCommandHandlers["target"] = CombatStats_Target_ChatCommandHandler;

function CombatStats_Mouseover_ChatCommandHandler(msg)

	if (msg) then
		msg = string.upper(msg);
		-- Toggle appropriately
		if (string.find(msg, "ON")) then
			CombatStats_Config.CombatStats_UseMouseOver = 1;
		elseif (string.find(msg, "OFF")) then
			CombatStats_Config.CombatStats_UseMouseOver = 0;		
		end
	end
	
	if(Cosmos_RegisterConfiguration ~= nil) then
		Cosmos_UpdateValue("COMBATSTATS_CONFIG_USEMOUSEOVER", CSM_CHECKONOFF, CombatStats_Config.CombatStats_UseMouseOver);
	end

	CombatStats_UpdateVisibility();

end
CombatStats_ChatCommandHandlers["mouseover"] = CombatStats_Target_ChatCommandHandler;

function CombatStats_Endoffight_ChatCommandHandler(msg)

	if (msg) then
		msg = string.upper(msg);
		-- Toggle appropriately
		if (string.find(msg, "ON")) then
			CombatStats_Config.CombatStats_EndOfFight = 1;
		elseif (string.find(msg, "OFF")) then
			CombatStats_Config.CombatStats_EndOfFight = 0;		
		end
	end
	
	if(Cosmos_RegisterConfiguration ~= nil) then
		Cosmos_UpdateValue("COMBATSTATS_CONFIG_ENDOFFIGHT", CSM_CHECKONOFF, CombatStats_Config.CombatStats_EndOfFight);
	end

	CombatStats_UpdateVisibility();

end
CombatStats_ChatCommandHandlers["endoffight"] = CombatStats_Target_ChatCommandHandler;

function CombatStats_Reset_ChatCommandHandler(msg)

	if (msg) then
		msg = string.upper(msg);
		-- Toggle appropriately
		if (string.find(msg, "YES")) then
			CombatStats_Reset();
		end		
	end

end
CombatStats_ChatCommandHandlers["reset"] = CombatStats_Reset_ChatCommandHandler;

--
--	Cosmos Config Handlers
--

function CombatStats_HideOnNoTarget_OnOff(toggle)
	CombatStats_Config.CombatStats_HideOnNoTarget = toggle;
	CombatStats_UpdateVisibility();
end

function CombatStats_Watch_OnOff(toggle) 
	CombatStats_Config.CombatStats_OnOff = toggle;
	CombatStats_UpdateVisibility();	
end

function CombatStats_UseMouseOver_OnOff(toggle)
	CombatStats_Config.CombatStats_UseMouseOver = toggle;
	CombatStats_UpdateVisibility();
end

function CombatStats_EndOfFight_OnOff(toggle)
	CombatStats_Config.CombatStats_EndOfFight = toggle;
	CombatStats_UpdateVisibility();
end


function CombatStats_UpdateVisibility(hasTarget)
	if (not hasTarget) then
		if (TargetFrame:IsVisible()) then
			hasTarget = 1;
		else
			hasTarget = 0;
		end
	end
	if (CombatStats_Config.CombatStats_OnOff == 1) then
		if (CombatStats_Config.CombatStats_HideOnNoTarget == 1) then
			if (hasTarget == 1) then
				CombatStatsFrame:Show();
			else
				CombatStatsFrame:Hide();
			end
		else
			CombatStatsFrame:Show();
		end
		
		--
		--	Register the events to watch
		--
		
		
	else
		CombatStatsFrame:Hide();
	end
end

function CombatStats_Reset()

	defcritCount = 0;
	speccritCount= 0;
	timestamps = {};
	players = {};
	dmg = {};
	dpstotals = {};
	defCrits = {0};
	specCrits = {0};
	defCritTotals = {};
	specCritTotals = {};

	totalDamage = 0;

	attackNames = {};
	specialAttacks = {};
	specialAttackLog = {};

	totalHits = 0;
	totalCrits = 0;
	specialsCount = 0;
	bHasDefault = 0;
	
	overallSwings		=	0;
	overallMisses		=	0;
	overallDodged		=	0;
	overallParried		=	0;
	overallEvaded		=	0;
	overallBlocked		=	0;
	overallResisted		=	0;
	overallImmuned		=	0;
	overallDeflected	=	0;
	overallHits			=	0;
	overallNonCrits		=	0;
	overallCrits		=	0;
	overallmaxCrit		=	0;
	overallminCrit		=	0;
	overallmaxReg		=	0;
	overallminReg		=	0;
	overallRegDmg		=	0;
	overallCritDmg		=	0;
	overallLastcrit		=	0;
	
	CombatStatsText:SetText("Overall DPS :: ");
	
	CombatStatsGeneralNameTextLabel:SetText("N/A");
		
		CombatStatsNonCritHitsStatText:SetText("0");	
		CombatStatsNonCritDamageStatText:SetText("0");		
		CombatStatsNonCritMinMaxStatText:SetText("0 / 0");	
		CombatStatsNonCritAvgStatText:SetText("0.0");	
		CombatStatsNonCritPercentDamageStatText:SetText("0.0 %");	
	
		CombatStatsCritHitsStatText:SetText("0");
		CombatStatsCritDamageStatText:SetText("0");
		CombatStatsCritMinMaxStatText:SetText("0 / 0");
		CombatStatsCritAvgStatText:SetText("0.0");
		CombatStatsCritPercentDamageStatText:SetText("0.0 %");
	
		CombatStatsGeneralTotalHitsHits:SetText("0");	
		CombatStatsGeneralSwingsLabel:SetText("0");
			
		CombatStatsGeneralMissesTextLabel:SetText("0");	
		CombatStatsGeneralMissesPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
		
		CombatStatsGeneralDodgesTextLabel:SetText("0");	
		CombatStatsGeneralDodgesPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
		
		CombatStatsGeneralParriedTextLabel:SetText("0");	
		CombatStatsGeneralParriedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
		
		CombatStatsGeneralBlockedTextLabel:SetText("0");	
		CombatStatsGeneralBlockedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
		
		CombatStatsGeneralResistedTextLabel:SetText("0");	
		CombatStatsGeneralResistedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
		
		CombatStatsGeneralImmunedTextLabel:SetText("0");	
		CombatStatsGeneralImmunedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
		
		CombatStatsGeneralEvadedTextLabel:SetText("0");	
		CombatStatsGeneralEvadedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
		
		CombatStatsGeneralPercentDmgPctLabel:SetText("0.0%");
		
		CombatStatsGeneralTimeLastCritTimeLabel:SetText(GREEN_FONT_COLOR_CODE.."N/A");
	
		CombatStatsOverallCritPctLabel:SetText(RED_FONT_COLOR_CODE.."0.0 %");		
		
		CombatStatsAttackNonCritPctLabel:SetText(GREEN_FONT_COLOR_CODE.."0.0 %");		
		CombatStatsAttackCritPctLabel:SetText(RED_FONT_COLOR_CODE.."0.0 %");
		
		UIDropDownMenu_SetText(CS_DROPDOWN_SELECT_TEXT,CombatStatsAttackDropDown);
				
	
end


function CombatStatDPSLen(checked,value)
	CombatStats_DPSLen = value;	
end

-- Register w/ Cosmos Config and set up a chat watch
function CombatStats_RegisterCosmos()
	if( (Cosmos_RegisterConfiguration ~= nil)) then
		Cosmos_RegisterConfiguration(
			"COS_COMBATSTATS",
			"SECTION",
			COMBATSTATS_CONFIG_HEADER,
			COMBATSTATS_CONFIG_HEADER_INFO
			);
		Cosmos_RegisterConfiguration(
			"COS_COMBATSTATS_HEADER",
			"SEPARATOR",
			COMBATSTATS_CONFIG_HEADER,
			COMBATSTATS_CONFIG_HEADER_INFO
			);
		Cosmos_RegisterConfiguration(
			"COS_COMBATSTATS_ONOFF", 
			"CHECKBOX",
			COMBATSTATS_CONFIG_ONOFF,
			COMBATSTATS_CONFIG_ONOFF_INFO,
			CombatStats_Watch_OnOff,
			CombatStats_Config.CombatStats_OnOff
			);		
		Cosmos_RegisterConfiguration(
			"COS_COMBATSTATS_USEMOUSEOVER_ONOFF", 
			"CHECKBOX",
			COMBATSTATS_CONFIG_USEMOUSEOVER,
			COMBATSTATS_CONFIG_USEMOUSEOVER_INFO,
			CombatStats_UseMouseOver_OnOff,
			CombatStats_Config.CombatStats_UseMouseOver,
			0
			);
		Cosmos_RegisterConfiguration(
			"COS_COMBATSTATS_HIDEONNOTARGET_ONOFF", 
			"CHECKBOX",
			COMBATSTATS_CONFIG_HIDEONNOTARGET,
			COMBATSTATS_CONFIG_HIDEONNOTARGET_INFO,
			CombatStats_HideOnNoTarget_OnOff,
			CombatStats_Config.CombatStats_HideOnNoTarget
			);	
		Cosmos_RegisterConfiguration(
			"COS_COMBATSTATS_ENDOFFIGHT_ONOFF", 
			"CHECKBOX",
			COMBATSTATS_CONFIG_ENDOFFIGHT,
			COMBATSTATS_CONFIG_ENDOFFIGHT_INFO,
			CombatStats_EndOfFight_OnOff,
			CombatStats_Config.CombatStats_EndOfFight
			);	

						
		Cosmos_RegisterChatCommand (
			"COMBATSTATS_COMMANDS",
			{"/cs", "/combatsats"},
			CombatStats_ChatCommandHandler,
			CS_CHAT_COMMAND_INFO
			);					
	end

end

function ShowLastFightDPS()

	--
	--	Show the last fight DPS
	--
	
	local totalFightTime
	local playerDPS
	local petDPS
	local petPct
	local playerText = "%.1f sec.\nTotal Damage :  %d\nOverall Fight DPS : %.1f\n";
	local petText = "Your pet did %d or %.1f%% of your overall damage.\nPet DPS : %.1f";
	local text = "Fight Statistics\nDuration : ";
	
	
	if( (bInCombat == 0) and (lastFightFinish > lastFightStart)) then
			
		totalFightTime = lastFightFinish - lastFightStart;
		petDPS = lastFightPetDamage / totalFightTime;
		playerDPS = lastFightPlayerDamage / totalFightTime;
		
		if(lastFightPetDamge ~=0) then
			petPct =  (lastFightPetDamage / lastFightPlayerDamage) * 100;
		end
		
		text = text ..format(playerText, totalFightTime,lastFightPlayerDamage,playerDPS);
		
		if(lastFightPetDamage ~= 0) then		
			text = text ..format(petText,lastFightPetDamage,petPct,petDPS);		
		end
				
		if(DEFAULT_CHAT_FRAME) then
			
			DEFAULT_CHAT_FRAME:AddMessage(text);
		
		end
			
	end
	
	
end

function CombatStats_OnEvent()

	--
	--	Don't do all this unless
	--	combat stats is turned on
	--
	
	if ( not CombatStats_Config.CombatStats_OnOff ) then
		return;
	end
	
			
	if (event == "PLAYER_REGEN_ENABLED") then
		regenEnabled = GetTime();
		if( (lastFightPlayerDamage > 0) and (bInCombat == 1) ) then
			lastFightFinish = GetTime();
			bInCombat = 0;					
			if(CombatStats_Config.CombatStats_EndOfFight  == 1) then
				ShowLastFightDPS();
			end
		end
		
	end

--	if (event == "PLAYER_LEAVE_COMBAT") then
--		leaveCombat = GetTime();
--		if( (lastFightPlayerDamage > 0) and (bInCombat == 1) ) then
--			lastFightFinish = GetTime();
--			bInCombat = 0;					
--			if(CombatStats_Config.CombatStats_EndOfFight  == 1) then
--				ShowLastFightDPS();
--			end
--		end
--	end
	
	if (event == "PLAYER_REGEN_DISABLED") then	
		if (bInCombat == 0) then
			lastFightStart = GetTime();
 		    	bInCombat = 1;			
			lastFightPlayerDamage = 0;
			lastFightPetDamage = 0;			
		end								
	end	
	
	local p, d;
	local curtime = combatTime;
	
	if(	event == "CHAT_MSG_COMBAT_SELF_HITS" 
		or event == "CHAT_MSG_COMBAT_SELF_MISSES"
		or event == "CHAT_MSG_SPELL_SELF_DAMAGE"
		or event == "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE"
		or event == "CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE"
		) then			

		for creatureName, damage,damageType, spell in string.gfind(arg1, "(.+) suffers (%d+) (.+) damage from your (.+).") do
			CombatStats_AddSpecialData(spell,"dot",damage,curtime);			
			CombatStats_AddDPSEntry("Your", damage);			
			return;
		end
		
		for spell, creatureName, damage in string.gfind(arg1, "Your (.+) hits (.+) for (%d+).") do
			CombatStats_AddSpecialData(spell,"hit",damage,curtime);
			CombatStats_AddDPSEntry("Your", damage);
			return;
		end

		for creatureName, damage in string.gfind(arg1, "You hit (.+) for (%d+)") do
			CombatStats_AddSpecialData("Default","hit",damage,curtime);
			CombatStats_AddDPSEntry("Your", damage);
			return;
		end
		for spell, creatureName, damage in string.gfind(arg1, "Your (.+) crits (.+) for (%d+).") do
			CombatStats_AddSpecialData(spell,"crit",damage,curtime);
			CombatStats_AddDPSEntry("Your", damage);
			return;
		end
		for creatureName, damage in string.gfind(arg1, "You crit (.+) for (%d+)") do
			CombatStats_AddSpecialData("Default","crit",damage,curtime);
			CombatStats_AddDPSEntry("Your", damage);
			return;
		end
		for creatureName in string.gfind(arg1, "You miss (.+).") do
			CombatStats_AddSpecialData("Default","miss",0,curtime);
			return;
		end
		for creatureName in string.gfind(arg1, "You attack. (.+) parries.") do
			CombatStats_AddSpecialData("Default","parry",0,curtime);
			return;
		end
		for creatureName in string.gfind(arg1, "You attack. (.+) evades.") do
			CombatStats_AddSpecialData("Default","evade",0,curtime);
			return;
		end
		for creatureName in string.gfind(arg1, "You attack. (.+) dodges.") do
			CombatStats_AddSpecialData("Default","dodge",0,curtime);
			return;
		end
		for creatureName in string.gfind(arg1, "You attack. (.+) deflects.") do
			CombatStats_AddSpecialData("Default","deflect",0,curtime);
			return;
		end
		for creatureName in string.gfind(arg1, "You attack. (.+) blocks.") do
			CombatStats_AddSpecialData("Default","block",0,curtime);
			return;
		end
		for spell, creatureName in string.gfind(arg1, "Your (.+) was blocked by (.+).") do
			CombatStats_AddSpecialData(spell,"block",0,curtime);
			return;
		end
		for spell, creatureName in string.gfind(arg1, "Your (.+) was deflected by (.+).") do
			CombatStats_AddSpecialData(spell,"deflect",0,curtime);
			return;
		end
		for spell, creatureName in string.gfind(arg1, "Your (.+) was dodged by (.+).") do
			CombatStats_AddSpecialData(spell,"dodge",0,curtime);
			return;
		end
		for spell, creatureName in string.gfind(arg1, "Your (.+) was evaded by (.+).") do
			CombatStats_AddSpecialData(spell,"evade",0,curtime);
			return;
		end
		for spell, creatureName in string.gfind(arg1, "Your (.+) is parried by (.+)") do
			CombatStats_AddSpecialData(spell,"parry",0,curtime);
			return;
		end
		for spell, creatureName in string.gfind(arg1, "Your (.+) was resisted by (.+).") do
			CombatStats_AddSpecialData(spell,"resist",0,curtime);
			return;
		end
		for spell, creatureName in string.gfind(arg1, "Your (.+) failed. (.+) is immune.") do
			CombatStats_AddSpecialData(spell,"immune",0,curtime);
			return;
		end
		for spell, creatureName in string.gfind(arg1, "Your (.+) missed (.+).") do
			CombatStats_AddSpecialData(spell,"miss",0,curtime);
			return;
		end
		
	end
	
	if(	event == "CHAT_MSG_COMBAT_PET_HITS" ) then
		
		bInCombat = 1;
		
		for petName, creatureName, damage in string.gfind(arg1, "(.+) crits (.+) for (%d+).") do
			CombatStats_AddSpecialData("[Pet] Default","crit",damage,curtime);
			CombatStats_AddDPSEntry("Your", damage);
			return;
		end
		
		for petName, creatureName, damage in string.gfind(arg1, "(.+) hits (.+) for (%d+).") do
			CombatStats_AddSpecialData("[Pet] Default","hit",damage,curtime);
			CombatStats_AddDPSEntry("Your", damage);
			return;
		end
	end

	if (event == "CHAT_MSG_SPELL_PET_DAMAGE") then

		for petName, spell, creatureName, damage in string.gfind(arg1, "(.+)'s (.+) hits (.+) for (%d+).") do			
			if (petName == UnitName('pet') or petName == 'your pet') then
				CombatStats_AddSpecialData("[Pet] "..spell,"hit",damage,curtime);
				CombatStats_AddDPSEntry("Your", damage);
			end
			return;
		end
		
		for petName, spell, creatureName, damage in string.gfind(arg1, "(.+)'s (.+) crits (.+) for (%d+).") do
			if (petName == UnitName('pet') or petName == 'your pet') then
				CombatStats_AddSpecialData("[Pet] "..spell,"crit",damage,curtime);
				CombatStats_AddDPSEntry("Your", damage);
			end
			return;
		end
		
		for petName, spell, creatureName in string.gfind(arg1, "(.+)'s (.+) was blocked by (.*).") do
			if (petName == UnitName('pet') or petName == 'your pet') then
				CombatStats_AddSpecialData("[Pet] "..spell,"block",0,curtime);				
			end
			return;
		end
		
		for petName, spell, creatureName in string.gfind(arg1, "(.+)'s (.+) was dodged by (.*).") do
			if (petName == UnitName('pet') or petName == 'your pet') then
				CombatStats_AddSpecialData("[Pet] "..spell,"dodge",0,curtime);				
			end			
			return;
		end
  
        for petName, spell, creatureName in string.gfind(arg1, "(.+)'s (.+) was evaded by (.*).") do
			if (petName == UnitName('pet') or petName == 'your pet') then
				CombatStats_AddSpecialData("[Pet] "..spell,"evade",0,curtime);				
			end			
			return;
		end

       for petName, spell, creatureName in string.gfind(arg1, "(.+)'s (.+) fails. (.+) is immune.") do
			if (petName == UnitName('pet') or petName == 'your pet') then
				CombatStats_AddSpecialData("[Pet] "..spell,"immune",0,curtime);				
			end						
			return;
		end
	
		for petName, spell, creatureName in string.gfind(arg1, "(.+)'s (.+) was resisted by (.*).") do
			if (petName == UnitName('pet') or petName == 'your pet') then
				CombatStats_AddSpecialData("[Pet] "..spell,"resist",0,curtime);				
			end						
			return;
		end

        for petName, spell, creatureName in string.gfind(arg1, "(.+)'s (.+) misses (.*).") do
     		if (petName == UnitName('pet') or petName == 'your pet') then
				CombatStats_AddSpecialData("[Pet] "..spell,"miss",0,curtime);				
			end						
			return;
		end
		
		for petName, spell, creatureName in string.gfind(arg1, "(.+)'s (.+) missed (.*).") do
			if (petName == UnitName('pet') or petName == 'your pet') then
				CombatStats_AddSpecialData("[Pet] "..spell,"miss",0,curtime);				
			end						
			return;
		end
		
		for petName, spell, creatureName in string.gfind(arg1, "(.+)'s (.+) failed. (.+) is immune.") do
			if (petName == UnitName('pet') or petName == 'your pet') then
				CombatStats_AddSpecialData("[Pet] "..spell,"immune",0,curtime);
			end
			return;
		end
		for petName, spell, creatureName in string.gfind(arg1, "(.+)'s (.+) missed (.+).") do
			if (petName == UnitName('pet') or petName == 'your pet') then
				CombatStats_AddSpecialData("[Pet] "..spell,"miss",0,curtime);
			end
			return;
		end
		for petName, spell, creatureName in string.gfind(arg1, "(.+)'s (.+) was deflected by (.+).") do
			if (petName == UnitName('pet') or petName == 'your pet') then
				CombatStats_AddSpecialData("[Pet] "..spell,"deflect",0,curtime);
			end
			return;
		end	
		
	end
	
	if (event == "CHAT_MSG_COMBAT_PET_MISSES") then

		bInCombat = 1;	
	
		for petName, creatureName in string.gfind(arg1, "(.+) misses (.*).") do
			if (petName == UnitName('pet') or petName == 'your pet') then
				CombatStats_AddSpecialData("[Pet] Default","miss",0,curtime);
			end	
			return;
		end
		
		for petName, creatureName in string.gfind(arg1, "(.+) attacks. (.+) parries.") do
			if (petName == UnitName('pet') or petName == 'your pet') then
				CombatStats_AddSpecialData("[Pet] Default","parry",0,curtime);
			end
			return;
		end
		for petName, creatureName in string.gfind(arg1, "(.+) attacks. (.+) evades.") do
			if (petName == UnitName('pet') or petName == 'your pet') then
				CombatStats_AddSpecialData("[Pet] Default","evade",0,curtime);
			end
			return;
		end
		for petName, creatureName in string.gfind(arg1, "(.+) attacks. (.+) dodges.") do
			if (petName == UnitName('pet') or petName == 'your pet') then
				CombatStats_AddSpecialData("[Pet] Default","dodge",0,curtime);
			end
			return;
		end
		for petName, creatureName in string.gfind(arg1, "(.+) attacks. (.+) deflects.") do
			if (petName == UnitName('pet') or petName == 'your pet') then
				CombatStats_AddSpecialData("[Pet] Default","deflect",0,curtime);
			end
			return;
		end
		for petName, creatureName in string.gfind(arg1, "(.+) attacks. (.+) blocks.") do
			if (petName == UnitName('pet') or petName == 'your pet') then
				CombatStats_AddSpecialData("[Pet] Default","block",0,curtime);
			end
			return;
		end
		
		
	end
	
	if(event == "CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS") then

		bInCombat = 1;
	
		for creatureName, damage,tmpStr in string.gfind(arg1, "(.+) hits you for (%d+). (.+) blocked") do
			CombatStats_AddDefDPSEntry("Your",damage);
			CombatStats_AddSpecialData("Defensive","hit",damage,curtime);
			CombatStats_AddSpecialData("Defensive","block",0,curtime);			
			return;
		end
		for creatureName, damage in string.gfind(arg1, "(.+) hits you for (%d+)") do
			CombatStats_AddDefDPSEntry("Your",damage);
			CombatStats_AddSpecialData("Defensive","hit",damage,curtime);			
			return;
		end
		for creatureName, damage in string.gfind(arg1, "(.+) crits you for (%d+).") do
			CombatStats_AddDefDPSEntry("Your",damage);
			CombatStats_AddSpecialData("Defensive","crit",damage,curtime);
			return;
		end
	
	end
	
	if( event == "CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE") then


		for creatureName, spell, damage in string.gfind(arg1, "(.+)'s (.+) hits you for (%d+).") do
			CombatStats_AddDefDPSEntry("Your",damage);
			CombatStats_AddSpecialData("Defensive","hit",damage,curtime);
			return;
		end
		
		for creatureName, spell, damage in string.gfind(arg1, "(.+)'s (.+) crits you for (%d+).") do
			CombatStats_AddDefDPSEntry("Your",damage);
			CombatStats_AddSpecialData("Defensive","crit",damage,curtime);
			return;
		end
	     
		for creatureName, spell in string.gfind(arg1, "(.+)'s (.+) was blocked%.") do
			CombatStats_AddSpecialData("Defensive","block",0,curtime);
			return;
		end
		for creatureName, spell in string.gfind(arg1, "(.+)'s (.+) was deflected%.") do
			CombatStats_AddSpecialData("Defensive","deflect",0,curtime);
			return;
		end
		for creatureName, spell in string.gfind(arg1, "(.+)'s (.+) was dodged%.") do
			CombatStats_AddSpecialData("Defensive","dodge",0,curtime);
			return;
		end
		for creatureName, spell in string.gfind(arg1, "(.+)'s (.+) was evaded%.") do
			CombatStats_AddSpecialData("Defensive","evade",0,curtime);
			return;
		end
		for creatureName, spell in string.gfind(arg1, "(.+)'s (.+) failed. You are immune.") do
			CombatStats_AddSpecialData("Defensive","immune",0,curtime);
			return;
		end
		for creatureName, spell in string.gfind(arg1, "(.+)'s (.+) misses you.") do
			CombatStats_AddSpecialData("Defensive","miss",0,curtime);
			return;
		end
		for creatureName, spell in string.gfind(arg1, "You parry (.+)'s (.+)") do
			CombatStats_AddSpecialData("Defensive","parry",0,curtime);
			return;
		end
		for creatureName, spell in string.gfind(arg1, "(.+)'s (.+) was resisted%.") do
			CombatStats_AddSpecialData("Defensive","resist",0,curtime);
			return;
		end
	end
	if (event == "CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES") then

		
		for creatureName in string.gfind(arg1, "(.+) misses you.") do
			CombatStats_AddSpecialData("Defensive","miss",0,curtime);
			return;
		end
		for creatureName in string.gfind(arg1, "(.+) attacks. You parry.") do
			CombatStats_AddSpecialData("Defensive","parry",0,curtime);
			return;
		end
		for creatureName in string.gfind(arg1, "(.+) attacks. You evade.") do
			CombatStats_AddSpecialData("Defensive","evade",0,curtime);			
			return;
		end
		for creatureName in string.gfind(arg1, "(.+) attacks. You dodge.") do
			CombatStats_AddSpecialData("Defensive","dodge",0,curtime);
			return;
		end
		for creatureName in string.gfind(arg1, "(.+) attacks. You deflect.") do
			CombatStats_AddSpecialData("Defensive","deflect",0,curtime);
			return;
		end
		for creatureName in string.gfind(arg1, "(.+) attacks. You block.") do
			CombatStats_AddSpecialData("Defensive","block",0,curtime);
			return;
		end
	end

	if ( event == "CHAT_MSG_SPELL_SELF_BUFF" or event == "CHAT_MSG_SPELL_PARTY_BUFF" or event == "CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF" ) then
		local useless, useless, spell, amount = string.find(arg1, "Your (.+) critically heals .+ for (%d+)%.");
		if ( spell and amount ) then
			CombatStats_AddSpecialData("[Heal] Total","crit",amount,curtime, 1);
			CombatStats_AddSpecialData("[Heal] "..spell,"crit",amount,curtime, 1);		
		elseif ( string.find(arg1, "Your (.+) heals .+ for (%d+)%.") ) then
			local useless, useless, spell, amount = string.find(arg1, "Your (.+) heals .+ for (%d+)%.");
			if ( spell and amount ) then
				CombatStats_AddSpecialData("[Heal] Total","hit",amount,curtime, 1);
				CombatStats_AddSpecialData("[Heal] "..spell,"hit",amount,curtime, 1);
			end
		end
	end

	if ( event == "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS" or event == "CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS" ) then
		local useless, useless, amount, spell = string.find(arg1, ".+ gains (%d+) health from your (.+)%.");
		if ( spell and amount ) then
			CombatStats_AddSpecialData("[Heal] Total","hit",amount,curtime, 1);
			CombatStats_AddSpecialData("[Heal] "..spell,"hot",amount,curtime, 1);		
		end
	end
	if ( event == "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS" ) then
		local useless, useless, amount, spell = string.find(arg1, "You gain (%d+) health from (.+)%.");
		if ( not string.find(arg1, "'s") and spell and amount ) then
			CombatStats_AddSpecialData("[Heal] Total","hit",amount,curtime, 1);
			CombatStats_AddSpecialData("[Heal] "..spell,"hot",amount,curtime, 1);		
		end
	end
end

--
--	Add/Check for attack(s)
--

function CombatStats_AddSpecialData(specialName,type,dmg,time, heal)
		
	
	--
	--	If we haven't logged this attack
	--	Create a record in the table for it
	--		

	--print2("Adding : "..specialName .." with damage : "..dmg.."at : "..time);	
			
	if(specialName ~= "Defensive" and not heal ) then
		lastFightPlayerDamage = lastFightPlayerDamage + dmg;
		totalDamage = totalDamage + dmg;
	end
	
	for creatureName,tempJunk in string.gfind(specialName, "(.+)Pet(.+)") do
	--	print2("creatureName : "..creatureName);
	--	print2("tempJunk : "..tempJunk);
	--	print2("Adding pet special : "..specialName.. " with damage of : "..dmg);
		lastFightPetDamage = lastFightPetDamage + dmg;
	end
	
	if (type == "dot") then
		specialName = specialName .." [DOT]";
	elseif ( type == "hot" ) then
		specialName = specialName .." [HOT]";
	end

	if(specialName == "Default") then
		bHasDefault = 1;
	end
	
	if ( not specialAttacks[specialName] ) then
		specialsCount = specialsCount + 1;
		table.insert(attackNames,specialName);
		
		specialAttackLog[specialsCount] = {
			index				=	specialsCount,
			name				=	specialName,
			isDOT				=	0,
			dotDmg				=	0,
			dotTicks			=	0,
			totalSwings			=	0,
			totalMisses			=	0,
			totalDodged			=	0,
			totalParried		=	0,
			totalEvaded			=	0,
			totalBlocked		=	0,
			totalResisted		=	0,
			totalImmuned		=	0,
			totalDeflected		=	0,
			totalHits			=	0,
			totalNonCrits		=	0,
			totalCrits			=	0,
			maxCrit				=	0,
			minCrit				=	0,
			maxReg				=	0,
			minReg				=	0,
			totalRegDmg			=	0,
			totalCritDmg		=	0,
			lastCrit			=	0,
		}
		
		specialAttacks[specialName]	= specialAttackLog[specialsCount];
		
		local info;
		
		info = {};
		info.text = specialName;
		info.func = CombatStatsAttack_OnClick;
		UIDropDownMenu_AddButton(info);
				
	end
	
	--
	--	Now add the data
	--


	if(specialName ~= "Defensive" and not heal ) then	
		specialAttacks[specialName].totalSwings = specialAttacks[specialName].totalSwings + 1;	
		overallSwings = overallSwings + 1;
	
		if(type == "crit") then
		
			totalHits = totalHits + 1;
			totalCrits = totalCrits + 1;
			specialAttacks[specialName].totalCrits = specialAttacks[specialName].totalCrits +1;
			specialAttacks[specialName].totalCritDmg = specialAttacks[specialName].totalCritDmg + dmg;
			specialAttacks[specialName].lastCrit = time;	
			specialAttacks[specialName].totalHits = specialAttacks[specialName].totalHits + 1;
		
			overallCrits = overallCrits + 1;
			overallCritDmg = overallCritDmg + dmg;
			overallLastcrit = time;
				
			--
			--	Set the initial min/max		
			--
		
			if(specialAttacks[specialName].maxCrit == 0) then
				specialAttacks[specialName].maxCrit = dmg;
			end
		
			if(specialAttacks[specialName].minCrit == 0) then
				specialAttacks[specialName].minCrit = dmg;
			end
		
			if(overallmaxCrit == 0) then
				overallmaxCrit = dmg;
			end
		
			if(overallminCrit == 0) then
				overallminCrit = dmg;
			end
		
			--
			--	Check to see if this dmg
			--	is a new min or max
			--
				
			if(tonumber(dmg) < tonumber(specialAttacks[specialName].minCrit)) then
				specialAttacks[specialName].minCrit = dmg;
			end
		
			if(tonumber(dmg) > tonumber(specialAttacks[specialName].maxCrit)) then
				specialAttacks[specialName].maxCrit = dmg;
			end	
		
			if(tonumber(dmg) < tonumber(overallminCrit)) then
				overallminCrit = dmg;
			end
		
			if(tonumber(dmg) > tonumber(overallmaxCrit)) then
				overallmaxCrit = dmg;
			end	
		
		end
	
		if(type == "hit") then
		
			totalHits = totalHits + 1;
			specialAttacks[specialName].isDOT = 0;
			specialAttacks[specialName].totalNonCrits = specialAttacks[specialName].totalNonCrits +1;
			specialAttacks[specialName].totalRegDmg = specialAttacks[specialName].totalRegDmg + dmg;
			specialAttacks[specialName].totalHits = specialAttacks[specialName].totalHits + 1;
		
			overallNonCrits = overallNonCrits + 1;
			overallRegDmg = overallRegDmg + dmg;
		
			--
			--	Set the initial min/max		
			--
		
			if(specialAttacks[specialName].maxReg == 0) then
				specialAttacks[specialName].maxReg = dmg;
			end
		
			if(specialAttacks[specialName].minReg == 0) then
				specialAttacks[specialName].minReg = dmg;
			end
		
			if(overallmaxReg == 0) then
				overallmaxReg = dmg;
			end
		
			if(overallminReg == 0) then
				overallminReg = dmg;
			end
		
			--
			--	Check to see if this dmg
			--	is a new min or max
			--
		
			if(tonumber(dmg) < tonumber(specialAttacks[specialName].minReg)) then
				specialAttacks[specialName].minReg = dmg;
			end
		
			if(tonumber(dmg) > tonumber(specialAttacks[specialName].maxReg)) then
				specialAttacks[specialName].maxReg = dmg;
			end
		
			if(tonumber(dmg) < tonumber(overallminReg)) then
				overallminReg = dmg;
			end
		
			if(tonumber(dmg) > tonumber (overallmaxReg)) then
				overallmaxReg = dmg;
			end	
		
		end
	
		if(type == "dot") then
		
			totalHits = totalHits + 1;
			specialAttacks[specialName].isDOT = 1;
			specialAttacks[specialName].dotTicks = specialAttacks[specialName].dotTicks +1;
			specialAttacks[specialName].dotDmg = specialAttacks[specialName].dotDmg + dmg;
			specialAttacks[specialName].totalHits = specialAttacks[specialName].totalHits + 1;		
		
			overallNonCrits = overallNonCrits + 1;
			overallRegDmg = overallRegDmg + dmg;
		
			--
			--	Set the initial min/max		
			--
		
			if(specialAttacks[specialName].maxReg == 0) then
				specialAttacks[specialName].maxReg = dmg;
			end
			
			if(specialAttacks[specialName].minReg == 0) then
				specialAttacks[specialName].minReg = dmg;
			end
		
			if(overallmaxReg == 0) then
				overallmaxReg = dmg;
			end
		
			if(overallminReg == 0) then
				overallminReg = dmg;
			end
		
			--
			--	Check to see if this dmg
			--	is a new min or max
			--
		
			if(tonumber(dmg) < tonumber(specialAttacks[specialName].minReg)) then
				specialAttacks[specialName].minReg = dmg;
			end
		
			if(tonumber(dmg) > tonumber(specialAttacks[specialName].maxReg)) then
				specialAttacks[specialName].maxReg = dmg;
			end
		
			if(tonumber(dmg) < tonumber(overallminReg)) then
				overallminReg = dmg;
			end
		
			if(tonumber(dmg) > tonumber (overallmaxReg)) then
				overallmaxReg = dmg;
			end	
		
		end
	         
		if(type == "miss") then
		
			specialAttacks[specialName].totalMisses = 	specialAttacks[specialName].totalMisses + 1;
			overallMisses = overallMisses +1;
			
		end
	
		if(type == "dodge") then
			
			specialAttacks[specialName].totalDodged = 	specialAttacks[specialName].totalDodged + 1;
			overallDodged = overallDodged + 1;
		
		end
	
		if(type == "parry") then
			
			specialAttacks[specialName].totalParried = 	specialAttacks[specialName].totalParried + 1;
			overallParried = overallParried + 1;
		
		end
	
		if(type == "block") then
		
			specialAttacks[specialName].totalBlocked = 	specialAttacks[specialName].totalBlocked + 1;
			overallBlocked = overallBlocked + 1;
	
		end
	
		if(type == "evade") then
		
			specialAttacks[specialName].totalEvaded = 	specialAttacks[specialName].totalEvaded + 1;
			overallEvaded = overallEvaded + 1;
		
		end
	
		if(type == "resist") then
			
			specialAttacks[specialName].totalResisted = 	specialAttacks[specialName].totalResisted + 1;
			overallResisted = overallResisted + 1;
			
		end
	
		if(type == "immune") then
		
			specialAttacks[specialName].totalImmuned = 	specialAttacks[specialName].totalImmuned + 1;
			overallImmuned = overallImmuned + 1;
		
		end
	
		if(type == "deflect") then
			
			specialAttacks[specialName].totalDeflected = 	specialAttacks[specialName].totalDeflected + 1;
			overallDeflected = overallDeflected + 1;
		
		end
	
	else
	
		--
		--	Defesnsive info
		--	Don't add to overall stats and overa
		--
		
		specialAttacks[specialName].totalSwings = specialAttacks[specialName].totalSwings + 1;
		
		if(type == "crit") then
		
			specialAttacks[specialName].totalCrits = specialAttacks[specialName].totalCrits +1;
			specialAttacks[specialName].totalCritDmg = specialAttacks[specialName].totalCritDmg + dmg;
			specialAttacks[specialName].lastCrit = time;	
			specialAttacks[specialName].totalHits = specialAttacks[specialName].totalHits + 1;
						
			--
			--	Set the initial min/max		
			--
		
			if(specialAttacks[specialName].maxCrit == 0) then
				specialAttacks[specialName].maxCrit = dmg;
			end
		
			if(specialAttacks[specialName].minCrit == 0) then
				specialAttacks[specialName].minCrit = dmg;
			end
				
			--
			--	Check to see if this dmg
			--	is a new min or max
			--
				
			if(tonumber(dmg) < tonumber(specialAttacks[specialName].minCrit)) then
				specialAttacks[specialName].minCrit = dmg;
			end
		
			if(tonumber(dmg) > tonumber(specialAttacks[specialName].maxCrit)) then
				specialAttacks[specialName].maxCrit = dmg;
			end			
		
		end
	
		if(type == "hit") then
		
			specialAttacks[specialName].isDOT = 0;
			specialAttacks[specialName].totalNonCrits = specialAttacks[specialName].totalNonCrits +1;
			specialAttacks[specialName].totalRegDmg = specialAttacks[specialName].totalRegDmg + dmg;
			specialAttacks[specialName].totalHits = specialAttacks[specialName].totalHits + 1;
				
			--
			--	Set the initial min/max		
			--
		
			if(specialAttacks[specialName].maxReg == 0) then
				specialAttacks[specialName].maxReg = dmg;
			end
		
			if(specialAttacks[specialName].minReg == 0) then
				specialAttacks[specialName].minReg = dmg;
			end
			
			--
			--	Check to see if this dmg
			--	is a new min or max
			--
		
			if(tonumber(dmg) < tonumber(specialAttacks[specialName].minReg)) then
				specialAttacks[specialName].minReg = dmg;
			end
		
			if(tonumber(dmg) > tonumber(specialAttacks[specialName].maxReg)) then
				specialAttacks[specialName].maxReg = dmg;
			end			
		
		end

		if(type == "hot") then
			specialAttacks[specialName].isDOT = 2;
			specialAttacks[specialName].dotTicks = specialAttacks[specialName].dotTicks +1;
			specialAttacks[specialName].dotDmg = specialAttacks[specialName].dotDmg + dmg;
			specialAttacks[specialName].totalHits = specialAttacks[specialName].totalHits + 1;
		
			--
			--	Set the initial min/max		
			--
		
			if(specialAttacks[specialName].maxReg == 0) then
				specialAttacks[specialName].maxReg = dmg;
			end
			
			if(specialAttacks[specialName].minReg == 0) then
				specialAttacks[specialName].minReg = dmg;
			end
		
		
			--
			--	Check to see if this dmg
			--	is a new min or max
			--
		
			if(tonumber(dmg) < tonumber(specialAttacks[specialName].minReg)) then
				specialAttacks[specialName].minReg = dmg;
			end
		
			if(tonumber(dmg) > tonumber(specialAttacks[specialName].maxReg)) then
				specialAttacks[specialName].maxReg = dmg;
			end	
		
		end
		
		if(type == "miss") then		
			specialAttacks[specialName].totalMisses = 	specialAttacks[specialName].totalMisses + 1;
		end
	
		if(type == "dodge") then
			specialAttacks[specialName].totalDodged = 	specialAttacks[specialName].totalDodged + 1;
		end
	
		if(type == "parry") then
			specialAttacks[specialName].totalParried = 	specialAttacks[specialName].totalParried + 1;
		end
	
		if(type == "block") then
			specialAttacks[specialName].totalBlocked = 	specialAttacks[specialName].totalBlocked + 1;
		end
	
		if(type == "evade") then
			specialAttacks[specialName].totalEvaded = 	specialAttacks[specialName].totalEvaded + 1;
		end
	
		if(type == "resist") then
			specialAttacks[specialName].totalResisted = 	specialAttacks[specialName].totalResisted + 1;
		end
	
		if(type == "immune") then
			specialAttacks[specialName].totalImmuned = 	specialAttacks[specialName].totalImmuned + 1;
		end
	
		if(type == "deflect") then
			specialAttacks[specialName].totalDeflected = 	specialAttacks[specialName].totalDeflected + 1;
		end
		
	end
	if ( CombatStatsDataFrame.currAttack and CombatStatsDataFrame.currAttack == specialName ) then
		CombatStats_UpdateDetails(specialName);
	end
						
end

-- CombatStats Event Watcher
--
-- Update Handler
--


function CombatStats_OnUpdate(elapsed)
	local curtime = GetTime();
	local oldesttime = 0;
	local oldesttimeTaken = 0;
	local deleteindex = 0;
	local deleteindexTaken = 0;
	local playerFrame;
	if ( bInCombat == 1 ) then
		combatTime = combatTime + elapsed;
	end
	--print2("In Combat == " ..bInCombat);

	
	
	
	if (bInCombat == 1) then

		-- Check to see if its time to update the on screen DPS and only update if there are dps entries to save CPU
		if ( ((curtime - CombatStats_LastUpdate) > CombatStats_UpdateFreq) and (table.getn(timestamps) > 0) ) then
	
			-- TODO: Change this to a high to low loop so we can do our subtracts and deletes in the same run
			
			--
			--	Offensive
			--
		
			for k,v in pairs(timestamps) do
				
				-- Get rid of old dps entries and adjust the totals				
				if ( (curtime - CombatStats_DPSLen) > v ) then

					-- Subtract this entry from the totals
					dpstotals[players[k]] = dpstotals[players[k]] - dmg[k];					
				
					-- Mark for later removal *We can't do the remove here cause table.remove reindexes the list and bones our loop
					deleteindex = k;
				else
					-- were into the good stuff now, stop
					oldesttime = v;
					break;
				end
			end
					
			
			-- Remove entries from deleteindex down so we don't miss em
			while (deleteindex > 0) do
				table.remove(timestamps, deleteindex);
				table.remove(players, deleteindex);
				table.remove(dmg, deleteindex);
				deleteindex = deleteindex -1;
			end
			
		end
			
		if ( ((curtime - CombatStats_LastUpdate) > CombatStats_UpdateFreq) and (table.getn(takenTimestamps) > 0) ) then
		
			--
			--	Defensive
			--
			
			for w,y in pairs(takenTimestamps) do
			
				-- Get rid of old dps entries and adjust the totals				
				if ( (curtime - CombatStats_DPSLen) > y ) then

					-- Subtract this entry from the totals
					dpsTakenTotals[playersTaken[w]] = dpsTakenTotals[playersTaken[w]] - dmgTaken[w];
			
					-- Mark for later removal *We can't do the remove here cause table.remove reindexes the list and bones our loop
					deleteindexTaken = w;
				else
					-- were into the good stuff now, stop
					oldesttimeTaken = y;
					break;
				end
			end
			
			-- Remove entries from deleteindex down so we don't miss em
			while (deleteindexTaken > 0) do
				table.remove(takenTimestamps, deleteindexTaken);
				table.remove(playersTaken, deleteindexTaken);
				table.remove(dmgTaken, deleteindexTaken);
				deleteindexTaken = deleteindexTaken -1;
			end
			
		end
	
				
			-- NOTE: Everyone calcs off the same oldest time, not their own oldest time.
			--       This should give more accurate dps on a per group fight basis.

	
		if ( ((curtime - CombatStats_LastUpdate) > CombatStats_UpdateFreq) and (table.getn(timestamps) > 0) ) then
			
			--local text = "CurTime - Oldesettime : %.1f";
			--text = format(text,(curtime - oldesttime));
			--print2(text);
			
			-- Update player DPS
			if ( dpstotals["Your"] ~= nil ) then
					if(dpsTakenTotals["Your"] ~= nil) then
						CombatStatsText:SetText( RED_FONT_COLOR_CODE.. format(TEXT(DPS_DISPLAY), (dpsTakenTotals["Your"] / (curtime - oldesttimeTaken) )) ..NORMAL_FONT_COLOR_CODE.. " / " ..GREEN_FONT_COLOR_CODE.. format(TEXT(DPS_DISPLAY), (dpstotals["Your"] / (curtime - oldesttime) )) );
					else						
						CombatStatsText:SetText( RED_FONT_COLOR_CODE.. "0.0" ..NORMAL_FONT_COLOR_CODE.. " / " ..GREEN_FONT_COLOR_CODE.. format(TEXT(DPS_DISPLAY), (dpstotals["Your"] / (curtime - oldesttime) )) );
					end
					
				
			end

			CombatStats_LastUpdate = curtime;
		end
		
		--
		--	If the data frame is visible
		--	update the selected attack "Real time"
		--
		
		if (CombatStatsDataFrame:IsVisible()) then
			
			if( UIDropDownMenu_GetText(CombatStatsAttackDropDown) ~= CS_DROPDOWN_SELECT_TEXT) then
				CombatStats_UpdateDetails( UIDropDownMenu_GetText(CombatStatsAttackDropDown));
			end
		end
		
	end
end


-- Called from XML
function CombatStats_OnLoad()
	if ( Cosmos_RegisterConfiguration ~= nil) then 
		CombatStats_RegisterCosmos();
		HookFunction("TargetFrame_OnShow", "CombatStats_TargetFrame_OnShow", "after");
		HookFunction("TargetFrame_OnHide", "CombatStats_TargetFrame_OnHide", "after");
	else
	-- Standalone (chatwatch)
		CombatStats_Old_TargetFrame_OnShow = TargetFrame_OnShow;
		CombatStats_Old_TargetFrame_OnHide = TargetFrame_OnHide;
		TargetFrame_OnShow = CombatStats_TargetFrame_OnShow;
		TargetFrame_OnHide = CombatStats_TargetFrame_OnHide;			
		
		SLASH_CSSLASH1 = "/combatstats";
		SLASH_CSSLASH2 = "/cs";	
		SlashCmdList["CSSLASH"] = CombatStats_ChatCommandHandler;
					
	end
		
		if (not Print) then
				setglobal("Print", function(msg, r, g, b, frame, id)
					if (not r) then r = 1.0; end
					if (not g) then g = 1.0; end
					if (not b) then b = 1.0; end
					if (not frame) then frame = DEFAULT_CHAT_FRAME; end
					if (frame) then
						if (not id) then
							frame:AddMessage(msg,r,g,b);
						else
							frame:AddMessage(msg,r,g,b,id);
						end
					end
				end);
			end		

		this:RegisterEvent("CHAT_MSG_COMBAT_SELF_HITS");
		this:RegisterEvent("CHAT_MSG_COMBAT_SELF_MISSES");
		this:RegisterEvent("CHAT_MSG_COMBAT_PET_HITS");
		this:RegisterEvent("CHAT_MSG_COMBAT_PET_MISSES");
		this:RegisterEvent("CHAT_MSG_SPELL_SELF_DAMAGE");
		this:RegisterEvent("CHAT_MSG_SPELL_PET_DAMAGE");
	
		this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE");
		this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE");
		this:RegisterEvent("CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS");
		this:RegisterEvent("CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES");
		this:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS");
		this:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES");
		
		this:RegisterEvent("CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE");
		this:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE");
		this:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF");
		this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS");
		this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE");
		
		this:RegisterEvent("CHAT_MSG_SYSTEM");
		this:RegisterEvent("PLAYER_REGEN_ENABLED");
		this:RegisterEvent("PLAYER_REGEN_DISABLED");
		this:RegisterEvent("PLAYER_LEAVE_COMBAT");
		this:RegisterEvent("CHAT_MSG_COMBAT_XP_GAIN");	
		this:RegisterEvent("CHAT_MSG_COMBAT_LOG_ENEMY");
		this:RegisterEvent("CHAT_MSG_COMBAT_HOSTILE_DEATH");

		-- Heals
		this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS");
		this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS");
		this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS");

		this:RegisterEvent("CHAT_MSG_SPELL_SELF_BUFF");
		this:RegisterEvent("CHAT_MSG_SPELL_PARTY_BUFF");
		this:RegisterEvent("CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF");
			
		CombatStatsText:SetText("Overall DPS :: ");
		CombatStats_UpdateVisibility();
end

function CombatStatsAttack_OnClick()
		
	local attackID = this:GetID();
			
	UIDropDownMenu_SetSelectedID(CombatStatsAttackDropDown, attackID);	
	--print2("GetID :: ".. UIDropDownMenu_GetSelectedID(CombatStatsAttackDropDown));
	local attackName =  UIDropDownMenu_GetText(CombatStatsAttackDropDown);
	UIDropDownMenu_SetSelectedValue(CombatStatsAttackDropDown, attackName);
	--print2("GetValue :: ".. UIDropDownMenu_GetSelectedValue(CombatStatsAttackDropDown));
	UIDropDownMenu_SetText(attackName,CombatStatsAttackDropDown);
	--this:SetText(CombatStatsDetailTypes[detailID].value);
	--this.text = CombatStatsDetailTypes[detailID].value;
	
	CombatStats_UpdateDetails(attackName);
	
end

function CombatStatsAttackDropDown_OnLoad()
	UIDropDownMenu_Initialize(this, CombatStatsAttackDropDown_Initialize);
end


function CombatStatsAttackDropDown_Initialize()
	CombatStats_LoadAttackNames();
end

function CombatStats_LoadAttackNames()

	local info;
	
	if(table.getn(attackNames) ~= 0) then	
		if(bHasDefault == 1) then
			info = {};
			info.text = "Default";
			info.func = CombatStatsAttack_OnClick;
			UIDropDownMenu_AddButton(info);
		end
	end
	
	for i=1, table.getn(attackNames), 1 do
		
		if(attackNames[i] ~= "Default") then	
			info = {};
			info.text = attackNames[i];
			info.func = CombatStatsAttack_OnClick;
			UIDropDownMenu_AddButton(info);
		end
		
	end
	
	if(table.getn(attackNames) ~= 0) then		
		info = {};
		info.text = "Total";
		info.func = CombatStatsAttack_OnClick;
		UIDropDownMenu_AddButton(info);
	end
			
end

--
--	Add the damage to the DPS table
--

function CombatStats_AddDPSEntry(p, d)
	
	
	table.insert(timestamps, GetTime());
	table.insert(players, p);
	table.insert(dmg, d);

	-- Keep running totals on group members to shorten calculation times
	-- We'll subtract off the expired entries during OnUpdate				
	if (dpstotals[p] == nil) then
	--	print2("dpstotals[p] == nil");
		dpstotals[p] = d;
	else
	--	print2("dpstotals[p] == " ..dpstotals[p] );
		dpstotals[p] = dpstotals[p] + d;
	--	print2("AFTER : dpstotals[p] == " ..dpstotals[p] );
	end
	
	--print2("Total : " ..dpstotals[p]);
end


--
--	Add damage taken to the DPS table
--

function CombatStats_AddDefDPSEntry(p, d)

	--print2("Adding Entry[" .. p .. "] = " .. d);	-- debug
	table.insert(takenTimestamps, GetTime());
	table.insert(playersTaken, p);
	table.insert(dmgTaken, d);

	-- Keep running totals on group members to shorten calculation times
	-- We'll subtract off the expired entries during OnUpdate				
	if (dpsTakenTotals[p] == nil) then
	--	print2("dpstotals[p] == nil");
		dpsTakenTotals[p] = d;
	else
	--	print2("dpstotals[p] == " ..dpstotals[p] );
		dpsTakenTotals[p] = dpsTakenTotals[p] + d;
	--	print2("AFTER : dpstotals[p] == " ..dpstotals[p] );
	end
	
	--print2("Total : " ..dpstotals[p]);
end

--	Show the stats collected

function CombatStatsText_OnClick()
   if (CombatStatsDataFrame:IsVisible()) then 
   	CombatStatsDataFrame:Hide();
   else
		if (CombatStats_Config.CombatStats_UseMouseOver == 0) then
			CombatStatsText_ShowFrame();
		end
	end
end

function CombatStatsText_OnEnter()
	if (CombatStats_Config.CombatStats_UseMouseOver == 1) then
		CombatStatsText_ShowFrame();
	end
end

function CombatStatsText_ShowFrame()

	
	if(bFirstTime == 1) then
		
		--
		--	Set all the default values
		--
		
		CombatStatsGeneralNameLabel:SetText(TEXT(CS_FRAME_GEN_ATTACK_NAME));	
		CombatStatsGeneralHitsTextLabel:SetText(CS_FRAME_HITS_TEXT);
		CombatStatsGeneralSwingsTextLabel:SetText(CS_FRAME_SWINGS_TEXT);
		CombatStatsGeneralMissesLabel:SetText(CS_FRAME_MISSES_TEXT);
		CombatStatsGeneralDodgesLabel:SetText(CS_FRAME_DODGES_TEXT);
		CombatStatsGeneralParriedLabel:SetText(CS_FRAME_PARRIES_TEXT);
		CombatStatsGeneralBlockedLabel:SetText(CS_FRAME_BLOCKS_TEXT);
		CombatStatsGeneralResistedLabel:SetText(CS_FRAME_RESISTS_TEXT);
		CombatStatsGeneralImmunedLabel:SetText(CS_FRAME_IMMUNE_TEXT);
		CombatStatsGeneralEvadedLabel:SetText(CS_FRAME_EVADES_TEXT );
		CombatStatsGeneralDeflectedLabel:SetText(CS_FRAME_DEFLECTS_TEXT);
		CombatStatsGeneralPercentDmgLabel:SetText(CS_FRAME_PERCENT_OVERALL_TEXT);
		CombatStatsGeneralTimeLastCritLabel:SetText(CS_FRAME_TIME_LASTCRIT_TEXT);
		
		CombatStatsNonCritHitsLabel:SetText(CS_FRAME_TOTAL_TEXT);
		CombatStatsNonCritDamageLabel:SetText(CS_FRAME_DAMAGE_TEXT);
		CombatStatsNonCritMinMaxLabel:SetText(CS_FRAME_MINMAX_TEXT);
		CombatStatsNonCritAvgLabel:SetText(CS_FRAME_AVGDMG_TEXT);
		CombatStatsNonCritPercentDamageLabel:SetText(CS_FRAME_PERCENTDMG_TEXT);
		
		CombatStatsCritHitsLabel:SetText(CS_FRAME_TOTAL_TEXT);
		CombatStatsCritDamageLabel:SetText(CS_FRAME_DAMAGE_TEXT);
		CombatStatsCritMinMaxLabel:SetText(CS_FRAME_MINMAX_TEXT);
		CombatStatsCritAvgLabel:SetText(CS_FRAME_AVGDMG_TEXT);
		CombatStatsCritPercentDamageLabel:SetText(CS_FRAME_PERCENTDMG_TEXT);
		
		CombatStatsGeneralNameTextLabel:SetText("N/A");
		
		CombatStatsNonCritHitsStatText:SetText("0");	
		CombatStatsNonCritDamageStatText:SetText("0");		
		CombatStatsNonCritMinMaxStatText:SetText("0 / 0");	
		CombatStatsNonCritAvgStatText:SetText("0.0");	
		CombatStatsNonCritPercentDamageStatText:SetText("0.0 %");	
	
		CombatStatsCritHitsStatText:SetText("0");
		CombatStatsCritDamageStatText:SetText("0");
		CombatStatsCritMinMaxStatText:SetText("0 / 0");
		CombatStatsCritAvgStatText:SetText("0.0");
		CombatStatsCritPercentDamageStatText:SetText("0.0 %");
	
		CombatStatsGeneralTotalHitsHits:SetText("0");	
		CombatStatsGeneralSwingsLabel:SetText("0");
			
		CombatStatsGeneralMissesTextLabel:SetText("0");	
		CombatStatsGeneralMissesPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
		
		CombatStatsGeneralDodgesTextLabel:SetText("0");	
		CombatStatsGeneralDodgesPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
		
		CombatStatsGeneralParriedTextLabel:SetText("0");	
		CombatStatsGeneralParriedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
		
		CombatStatsGeneralBlockedTextLabel:SetText("0");	
		CombatStatsGeneralBlockedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
		
		CombatStatsGeneralResistedTextLabel:SetText("0");	
		CombatStatsGeneralResistedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
		
		CombatStatsGeneralImmunedTextLabel:SetText("0");	
		CombatStatsGeneralImmunedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
		
		CombatStatsGeneralEvadedTextLabel:SetText("0");	
		CombatStatsGeneralEvadedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
		
		CombatStatsGeneralDeflectedTextLabel:SetText("0");
		CombatStatsGeneralDeflectedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
		
		CombatStatsGeneralPercentDmgPctLabel:SetText("0.0%");
		
		CombatStatsGeneralTimeLastCritTimeLabel:SetText(GREEN_FONT_COLOR_CODE.."N/A");
	
		CombatStatsOverallCritPctLabel:SetText(RED_FONT_COLOR_CODE.."0.0 %");		
		
		CombatStatsAttackNonCritPctLabel:SetText(GREEN_FONT_COLOR_CODE.."0.0 %");		
		CombatStatsAttackCritPctLabel:SetText(RED_FONT_COLOR_CODE.."0.0 %");
		
		UIDropDownMenu_SetText(CS_DROPDOWN_SELECT_TEXT,CombatStatsAttackDropDown);
		
		bFirstTime = 0;
		
	end
	
	if( UIDropDownMenu_GetText(CombatStatsAttackDropDown) ~= CS_DROPDOWN_SELECT_TEXT) then
		
		CombatStats_UpdateDetails( UIDropDownMenu_GetText(CombatStatsAttackDropDown));
		
	end
	
	CombatStatsDataFrame:Show();
	
end

function CS_ToggleGameMenu(clicked)
	if ( clicked ) then
		if ( OptionsFrame:IsVisible() ) then
			OptionsFrameCancel:Click();
		end
		if ( GameMenuFrame:IsVisible() ) then
			PlaySound("igMainMenuQuit");
			HideUIPanel(GameMenuFrame);
		else
			CloseMenus();
			CloseAllWindows()
			PlaySound("igMainMenuOpen");
			ShowUIPanel(GameMenuFrame);
		end
		return;
	end
	if ( StaticPopup_EscapePressed() ) then
	elseif ( OptionsFrame:IsVisible() ) then
		OptionsFrameCancel:Click();
	elseif ( GameMenuFrame:IsVisible() ) then
		PlaySound("igMainMenuQuit");
		HideUIPanel(GameMenuFrame);
	elseif ( CloseMenus() ) then
	elseif ( SpellStopCasting() ) then
	elseif ( SpellStopTargeting() ) then
	elseif ( CloseAllWindows() ) then
		CombatStatsDataFrame:Hide();
	elseif ( ClearTarget() ) then
	else
		if ( CombatStatsDataFrame:IsVisible() ) then
			CombatStatsDataFrame:Hide();
			return;
		end
		PlaySound("igMainMenuOpen");
		ShowUIPanel(GameMenuFrame);
	end
end

ToggleGameMenu = CS_ToggleGameMenu;

function CombatStats_UpdateDetails(attackName)
	CombatStatsDataFrame.currAttack = attackName;
	if ( strsub(attackName, 0, 6) == "[Heal]" ) then
	
		CS_TT_NONCRIT_HITSPCT_TEXT = CS_TT_NONCRIT_HITSPCT_TEXT_HEAL;
		CS_TT_CRIT_HITSPCT_TEXT = CS_TT_CRIT_HITSPCT_TEXT_HEAL;
		CS_TT_OVERALLDMGPCT_TEXT = CS_TT_OVERALLDMGPCT_TEXT_HEAL;
		CS_TT_CRIT_DMGPCT_TEXT = CS_TT_CRIT_DMGPCT_TEXT_HEAL;
		CS_TT_NONCRIT_DMGPCT_TEXT = CS_TT_NONCRIT_DMGPCT_TEXT_HEAL;

		CombatStatsGeneralHitsTextLabel:SetText(CS_FRAME_HITS_TEXT_HEAL);
		CombatStatsGeneralPercentDmgLabel:SetText(CS_FRAME_PERCENT_OVERALL_TEXT_HEAL);
		CombatStatsNonCritDamageLabel:SetText(CS_FRAME_DAMAGE_TEXT_HEAL);
		CombatStatsNonCritAvgLabel:SetText(CS_FRAME_AVGDMG_TEXT_HEAL);
		CombatStatsNonCritPercentDamageLabel:SetText(CS_FRAME_PERCENTDMG_TEXT_HEAL);
		CombatStatsCritDamageLabel:SetText(CS_FRAME_DAMAGE_TEXT_HEAL);
		CombatStatsCritAvgLabel:SetText(CS_FRAME_AVGDMG_TEXT_HEAL);
		CombatStatsCritPercentDamageLabel:SetText(CS_FRAME_PERCENTDMG_TEXT_HEAL);

		CombatStatsGeneralSwingsTextLabel:Hide();
	else
		CS_TT_NONCRIT_HITSPCT_TEXT = CS_TT_NONCRIT_HITSPCT_TEXT_NONHEAL;
		CS_TT_CRIT_HITSPCT_TEXT = CS_TT_CRIT_HITSPCT_TEXT_NONHEAL;
		CS_TT_OVERALLDMGPCT_TEXT = CS_TT_OVERALLDMGPCT_TEXT_NONHEAL;
		CS_TT_CRIT_DMGPCT_TEXT = CS_TT_CRIT_DMGPCT_TEXT_NONHEAL;
		CS_TT_NONCRIT_DMGPCT_TEXT = CS_TT_NONCRIT_DMGPCT_TEXT_NONHEAL;

		CombatStatsGeneralHitsTextLabel:SetText(CS_FRAME_HITS_TEXT);
		CombatStatsGeneralPercentDmgLabel:SetText(CS_FRAME_PERCENT_OVERALL_TEXT);
		CombatStatsNonCritDamageLabel:SetText(CS_FRAME_DAMAGE_TEXT);
		CombatStatsNonCritAvgLabel:SetText(CS_FRAME_AVGDMG_TEXT);
		CombatStatsNonCritPercentDamageLabel:SetText(CS_FRAME_PERCENTDMG_TEXT);
		CombatStatsCritDamageLabel:SetText(CS_FRAME_DAMAGE_TEXT);
		CombatStatsCritAvgLabel:SetText(CS_FRAME_AVGDMG_TEXT);
		CombatStatsCritPercentDamageLabel:SetText(CS_FRAME_PERCENTDMG_TEXT);

		CombatStatsGeneralSwingsTextLabel:Show();
	end

	local x,y,info;
	
	--
	--	Draw the text for the hits/swings 
	--
	
	if(attackName ~= "Total") then
			
	--
	-- Calculate % of hits that are crits
	-- 		
	
	if( (totalCrits) ~= 0) then		
		CombatStatsOverallCritPctLabel:SetText( format(RED_FONT_COLOR_CODE.."%.2f %%", ( totalCrits / totalHits) * 100.0));			
	end
	
	CombatStatsGeneralNameTextLabel:SetText(attackName);
	CombatStatsGeneralTotalHitsHits:SetText(specialAttacks[attackName].totalHits);
	if ( strsub(attackName, 0, 6) ~= "[Heal]" ) then
		CombatStatsGeneralSwingsLabel:SetText(specialAttacks[attackName].totalSwings);
		CombatStatsGeneralSwingsLabel:Show();
	else
		CombatStatsGeneralSwingsLabel:Hide();
	end
	
	CombatStatsGeneralMissesTextLabel:SetText(specialAttacks[attackName].totalMisses);
	
	if(specialAttacks[attackName].totalMisses ~= 0) then
		CombatStatsGeneralMissesPercentLabel:SetText( format(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.. "%.1f%%" .. NORMAL_FONT_COLOR_CODE.." ]", (specialAttacks[attackName].totalMisses / (specialAttacks[attackName].totalSwings) * 100)));
	else
		CombatStatsGeneralMissesPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
	end
	
	CombatStatsGeneralDodgesTextLabel:SetText(specialAttacks[attackName].totalDodged);
	
	if(specialAttacks[attackName].totalDodged ~= 0) then
		CombatStatsGeneralDodgesPercentLabel:SetText( format(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.. "%.1f%%" .. NORMAL_FONT_COLOR_CODE.." ]", (specialAttacks[attackName].totalDodged / (specialAttacks[attackName].totalSwings) * 100)));
	else
		CombatStatsGeneralDodgesPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
	end
	
	CombatStatsGeneralBlockedTextLabel:SetText(specialAttacks[attackName].totalBlocked);
	
	if(attackName == "Defensive") then
	
		if(specialAttacks[attackName].totalBlocked ~= 0) then
			CombatStatsGeneralBlockedPercentLabel:SetText( format(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.. "%.1f%%" .. NORMAL_FONT_COLOR_CODE.." ]", (specialAttacks[attackName].totalBlocked / (specialAttacks[attackName].totalHits) * 100)));
		else
			CombatStatsGeneralBlockedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
		end
		
	else
	
		if(specialAttacks[attackName].totalBlocked ~= 0) then
			CombatStatsGeneralBlockedPercentLabel:SetText( format(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.. "%.1f%%" .. NORMAL_FONT_COLOR_CODE.." ]", (specialAttacks[attackName].totalBlocked / (specialAttacks[attackName].totalSwings) * 100)));
		else
			CombatStatsGeneralBlockedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
		end
	
	end
	
	CombatStatsGeneralParriedTextLabel:SetText(specialAttacks[attackName].totalParried);
	
	if(specialAttacks[attackName].totalParried ~= 0) then
		CombatStatsGeneralParriedPercentLabel:SetText( format(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.. "%.1f%%" .. NORMAL_FONT_COLOR_CODE.." ]", (specialAttacks[attackName].totalParried / (specialAttacks[attackName].totalSwings) * 100)));
	else
		CombatStatsGeneralParriedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
	end
	
	CombatStatsGeneralResistedTextLabel:SetText(specialAttacks[attackName].totalResisted);
	
	if(specialAttacks[attackName].totalResisted ~= 0) then
		CombatStatsGeneralResistedPercentLabel:SetText( format(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.. "%.1f%%" .. NORMAL_FONT_COLOR_CODE.." ]", (specialAttacks[attackName].totalResisted / (specialAttacks[attackName].totalSwings) * 100)));
	else
		CombatStatsGeneralResistedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
	end
	
	CombatStatsGeneralImmunedTextLabel:SetText(specialAttacks[attackName].totalImmuned);
	
	if(specialAttacks[attackName].totalImmuned ~= 0) then
		CombatStatsGeneralImmunedPercentLabel:SetText( format(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.. "%.1f%%" .. NORMAL_FONT_COLOR_CODE.." ]", (specialAttacks[attackName].totalImmuned / (specialAttacks[attackName].totalSwings) * 100)));
	else
		CombatStatsGeneralImmunedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
	end
	
	CombatStatsGeneralEvadedTextLabel:SetText(specialAttacks[attackName].totalEvaded);
	
	if(specialAttacks[attackName].totalEvaded ~= 0) then
		CombatStatsGeneralEvadedPercentLabel:SetText( format(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.. "%.1f%%" .. NORMAL_FONT_COLOR_CODE.." ]", (specialAttacks[attackName].totalEvaded / (specialAttacks[attackName].totalSwings) * 100)));
	else
		CombatStatsGeneralEvadedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
	end
	
	CombatStatsGeneralDeflectedTextLabel:SetText(specialAttacks[attackName].totalDeflected);
	
	if(specialAttacks[attackName].totalDeflected ~= 0) then
		CombatStatsGeneralDeflectedPercentLabel:SetText( format(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.. "%.1f%%" .. NORMAL_FONT_COLOR_CODE.." ]", (specialAttacks[attackName].totalDeflected / (specialAttacks[attackName].totalSwings) * 100)));
	else
		CombatStatsGeneralDeflectedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
	end
	
	--
	--	Percent of total damage
	--
	
	if(attackName ~= "Defensive") then	
		if ( attackName == "[Heal] Total" ) then
			CombatStatsGeneralPercentDmgPctLabel:SetText("100.0%");
		elseif ( strsub(attackName, 0, 6) == "[Heal]" ) then
			if ( specialAttacks[attackName].totalHits ~= 0 ) then
				CombatStatsGeneralPercentDmgPctLabel:SetText( format("%.2f %%",  ((specialAttacks[attackName].totalRegDmg + specialAttacks[attackName].totalCritDmg + specialAttacks[attackName].dotDmg) / (specialAttacks["[Heal] Total"].totalRegDmg + specialAttacks["[Heal] Total"].totalCritDmg + specialAttacks["[Heal] Total"].dotDmg)) * 100) );
			else
				CombatStatsGeneralPercentDmgPctLabel:SetText("0.0%");
			end
		else
			
			if(specialAttacks[attackName].totalHits ~=0) then
				CombatStatsGeneralPercentDmgPctLabel:SetText( format("%.2f %%",  ((specialAttacks[attackName].totalRegDmg + specialAttacks[attackName].totalCritDmg + specialAttacks[attackName].dotDmg) / totalDamage) * 100) );
			else
				CombatStatsGeneralPercentDmgPctLabel:SetText("0.0%");
			end
		end
	end
	
	--
	--	Time since last crit
	--
	
	local timeNow;
	timeNow = combatTime;
	
	if(specialAttacks[attackName].lastCrit ~= 0) then
		CombatStatsGeneralTimeLastCritTimeLabel:SetText(GREEN_FONT_COLOR_CODE ..Clock_FormatTime( (timeNow - specialAttacks[attackName].lastCrit)));
	else
		CombatStatsGeneralTimeLastCritTimeLabel:SetText(GREEN_FONT_COLOR_CODE.."N/A");	
	end
	
	--
	--	Attack Crit %
	--
	
	if (specialAttacks[attackName].totalHits ~= 0) and (specialAttacks[attackName].totalCrits ~= 0) then
		CombatStatsAttackCritPctLabel:SetText(format(RED_FONT_COLOR_CODE.."%.1f%%", ( (specialAttacks[attackName].totalCrits) / (specialAttacks[attackName].totalHits)) * 100.0 ));			
	else
		CombatStatsAttackCritPctLabel:SetText(RED_FONT_COLOR_CODE.."0.0 %");
	end
	
	--
	--	Attack Non Crit %
	--
	
	if (specialAttacks[attackName].totalHits ~= 0) and (specialAttacks[attackName].totalNonCrits ~= 0) then
		CombatStatsAttackNonCritPctLabel:SetText( format(GREEN_FONT_COLOR_CODE.."%.1f%%", ( (specialAttacks[attackName].totalNonCrits) / (specialAttacks[attackName].totalHits)) * 100.0 ));			
	else
		CombatStatsAttackNonCritPctLabel:SetText(GREEN_FONT_COLOR_CODE.."0.0 %");
	end
	
	--
	--	Non Crit stats
	--
	
	CombatStatsNonCritHitsStatText:SetText(specialAttacks[attackName].totalNonCrits);	
	CombatStatsNonCritDamageStatText:SetText(specialAttacks[attackName].totalRegDmg);	
	CombatStatsNonCritMinMaxStatText:SetText(specialAttacks[attackName].minReg .." / "..specialAttacks[attackName].maxReg);
	
	if( specialAttacks[attackName].totalRegDmg ~= 0) then
												
		if( (specialAttacks[attackName].totalHits - specialAttacks[attackName].totalCrits) < 0) then
			CombatStatsNonCritAvgStatText:SetText(format("%.1f",  specialAttacks[attackName].totalRegDmg / (specialAttacks[attackName].totalCrits - specialAttacks[attackName].totalHits ) ));
		end
						
		if(	(specialAttacks[attackName].totalHits - specialAttacks[attackName].totalCrits) == 0 ) then
			CombatStatsNonCritAvgStatText:SetText(format("%1.f", specialAttacks[attackName].totalRegDmg / (specialAttacks[attackName].totalCrits) ));
		end
						
		if(	(specialAttacks[attackName].totalHits - specialAttacks[attackName].totalCrits) > 0 ) then
			CombatStatsNonCritAvgStatText:SetText(format("%1.f",specialAttacks[attackName].totalRegDmg / (specialAttacks[attackName].totalHits - specialAttacks[attackName].totalCrits) ));
		end
						
	else		
		CombatStatsNonCritAvgStatText:SetText("0.0");
	end
	
	if(specialAttacks[attackName].totalNonCrits ~=0) then
		CombatStatsNonCritPercentDamageStatText:SetText( format("%.2f %%", ( specialAttacks[attackName].totalRegDmg   / (specialAttacks[attackName].totalRegDmg + specialAttacks[attackName].totalCritDmg )) * 100.0));
	else
		CombatStatsNonCritPercentDamageStatText:SetText("0.0 %");
	end
	
	--
	--	Crit stats
	--
	
	CombatStatsCritHitsStatText:SetText(specialAttacks[attackName].totalCrits);	
	CombatStatsCritDamageStatText:SetText(specialAttacks[attackName].totalCritDmg);	
	CombatStatsCritMinMaxStatText:SetText(specialAttacks[attackName].minCrit .." / "..specialAttacks[attackName].maxCrit);
	
	if( specialAttacks[attackName].totalCritDmg ~= 0) then
		CombatStatsCritAvgStatText:SetText(format("%1.f", (specialAttacks[attackName].totalCritDmg / specialAttacks[attackName].totalCrits) ));
	else
		CombatStatsCritAvgStatText:SetText("0.0");
	end
	
	if(specialAttacks[attackName].totalCrits ~=0) then
		CombatStatsCritPercentDamageStatText:SetText(format("%.2f %%", (specialAttacks[attackName].totalCritDmg / ( specialAttacks[attackName].totalRegDmg + specialAttacks[attackName].totalCritDmg )) * 100.10 ));
	else
		CombatStatsCritPercentDamageStatText:SetText("0.0 %");
	end	
				
	--
	--	Show DOT Stats
	--
	
	
			
	if (specialAttacks[attackName].isDOT ==1) then
		
		CombatStatsGeneralHitsTextLabel:SetText(CS_FRAME_TICKS_TEXT);
		CombatStatsGeneralSwingsTextLabel:SetText("");
		CombatStatsGeneralSwingsLabel:SetText("");
		
		CombatStatsGeneralTotalHitsHits:SetText(specialAttacks[attackName].dotTicks);
		CombatStatsNonCritHitsStatText:SetText(specialAttacks[attackName].dotTicks);
		CombatStatsNonCritDamageStatText:SetText(specialAttacks[attackName].dotDmg);
		
		CombatStatsNonCritMinMaxStatText:SetText(specialAttacks[attackName].minReg .." / "..specialAttacks[attackName].maxReg);
		CombatStatsNonCritAvgStatText:SetText(format("%.1f",  specialAttacks[attackName].dotDmg /  specialAttacks[attackName].dotTicks  ));
		CombatStatsNonCritPercentDamageStatText:SetText("100.0 %");
		CombatStatsAttackNonCritPctLabel:SetText(GREEN_FONT_COLOR_CODE.."100.0%");
		
		--
		--	Should never be a 0 tick entry but just in case
		--
--		if(specialAttacks[attackNames[y]].dotTicks ~= 0) then	
--			text = text.."\n"..format(TEXT(DOT_AVERAGE),(specialAttacks[attackNames[y]].dotDmg / specialAttacks[attackNames[y]].dotTicks));
--		end
	elseif ( specialAttacks[attackName].isDOT ==2) then
		CombatStatsGeneralHitsTextLabel:SetText(CS_FRAME_HOT_TEXT);
		CombatStatsGeneralSwingsTextLabel:SetText("");
		CombatStatsGeneralSwingsLabel:SetText("");
		
		CombatStatsGeneralTotalHitsHits:SetText(specialAttacks[attackName].dotTicks);
		CombatStatsNonCritHitsStatText:SetText(specialAttacks[attackName].dotTicks);
		CombatStatsNonCritDamageStatText:SetText(specialAttacks[attackName].dotDmg);
		
		CombatStatsNonCritMinMaxStatText:SetText(specialAttacks[attackName].minReg .." / "..specialAttacks[attackName].maxReg);
		CombatStatsNonCritAvgStatText:SetText(format("%.1f",  specialAttacks[attackName].dotDmg /  specialAttacks[attackName].dotTicks  ));
		CombatStatsNonCritPercentDamageStatText:SetText("100.0 %");
		CombatStatsAttackNonCritPctLabel:SetText(GREEN_FONT_COLOR_CODE.."100.0%");
	end

	
	else
		
	--
	-- Calculate % of hits that are crits
	-- 		
	
	if( (totalCrits) ~= 0) then		
		CombatStatsOverallCritPctLabel:SetText( format(RED_FONT_COLOR_CODE.."%.2f %%", ( totalCrits / totalHits) * 100.0));			
	end
	
	CombatStatsGeneralNameTextLabel:SetText("Total");
	CombatStatsGeneralTotalHitsHits:SetText(totalHits);
	CombatStatsGeneralSwingsLabel:SetText(overallSwings);
	
	CombatStatsGeneralMissesTextLabel:SetText(overallMisses);
	
	if(overallMisses ~= 0) then
		CombatStatsGeneralMissesPercentLabel:SetText( format(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.. "%.1f%%" .. NORMAL_FONT_COLOR_CODE.." ]", (overallMisses / (overallSwings) * 100)));
	else
		CombatStatsGeneralMissesPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
	end
	
	CombatStatsGeneralDodgesTextLabel:SetText(overallDodged);
	
	if(overallDodged ~= 0) then
		CombatStatsGeneralDodgesPercentLabel:SetText( format(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.. "%.1f%%" .. NORMAL_FONT_COLOR_CODE.." ]", (overallDodged / (overallSwings) * 100)));
	else
		CombatStatsGeneralDodgesPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
	end
	
	CombatStatsGeneralParriedTextLabel:SetText(overallParried);
	
	if(overallParried ~= 0) then
		CombatStatsGeneralParriedPercentLabel:SetText( format(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.. "%.1f%%" .. NORMAL_FONT_COLOR_CODE.." ]", (overallParried / (overallSwings) * 100)));
	else
		CombatStatsGeneralParriedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
	end
	
	CombatStatsGeneralResistedTextLabel:SetText(overallResisted);
	
	if(overallResisted ~= 0) then
		CombatStatsGeneralResistedPercentLabel:SetText( format(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.. "%.1f%%" .. NORMAL_FONT_COLOR_CODE.." ]", (overallResisted / (overallSwings) * 100)));
	else
		CombatStatsGeneralResistedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
	end
	
	CombatStatsGeneralImmunedTextLabel:SetText(overallImmuned);
	
	if(overallImmuned ~= 0) then
		CombatStatsGeneralImmunedPercentLabel:SetText( format(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.. "%.1f%%" .. NORMAL_FONT_COLOR_CODE.." ]", (overallImmuned / (overallSwings) * 100)));
	else
		CombatStatsGeneralImmunedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
	end
	
	CombatStatsGeneralEvadedTextLabel:SetText(overallEvaded);
	
	if(overallEvaded ~= 0) then
		CombatStatsGeneralEvadedPercentLabel:SetText( format(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.. "%.1f%%" .. NORMAL_FONT_COLOR_CODE.." ]", (overallEvaded / (overallSwings) * 100)));
	else
		CombatStatsGeneralEvadedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
	end
	
	CombatStatsGeneralDeflectedTextLabel:SetText(overallDeflected);
	
	if(overallDeflected ~= 0) then
		CombatStatsGeneralDeflectedPercentLabel:SetText( format(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.. "%.1f%%" .. NORMAL_FONT_COLOR_CODE.." ]", (overallDeflected / (overallSwings) * 100)));
	else
		CombatStatsGeneralDeflectedPercentLabel:SetText(NORMAL_FONT_COLOR_CODE.."[ "..WHITE_FONT_COLOR_CODE.."0.0%"..NORMAL_FONT_COLOR_CODE.." ]");
	end
	
	--
	--	Percent of total damage
	--
	
	if(totalHits ~=0) then
		CombatStatsGeneralPercentDmgPctLabel:SetText( format("%.2f %%",  ((overallRegDmg + overallCritDmg ) / totalDamage) * 100) );
	else
		CombatStatsGeneralPercentDmgPctLabel:SetText("0.0%");
	end
	
	--
	--	Time since last crit
	--
	
	local timeNow;
	timeNow = GetTime();
	
	if(overallLastcrit ~= 0) then
		CombatStatsGeneralTimeLastCritTimeLabel:SetText(GREEN_FONT_COLOR_CODE ..Clock_FormatTime( (timeNow - overallLastcrit)));
	else
		CombatStatsGeneralTimeLastCritTimeLabel:SetText(GREEN_FONT_COLOR_CODE.."N/A");	
	end
	
	--
	--	Attack Crit %
	--
	
	if (totalHits ~= 0) and (overallCrits ~= 0) then
		CombatStatsAttackCritPctLabel:SetText(format(RED_FONT_COLOR_CODE.."%.1f%%", ( (overallCrits) / (totalHits)) * 100.0 ));			
	else
		CombatStatsAttackCritPctLabel:SetText(RED_FONT_COLOR_CODE.."0.0 %");
	end
	
	--
	--	Attack Non Crit %
	--
	
	if (totalHits ~= 0) and (overallNonCrits ~= 0) then
		CombatStatsAttackNonCritPctLabel:SetText( format(GREEN_FONT_COLOR_CODE.."%.1f%%", ( (overallNonCrits) / (totalHits)) * 100.0 ));			
	else
		CombatStatsAttackNonCritPctLabel:SetText(GREEN_FONT_COLOR_CODE.."0.0 %");
	end
	
	--
	--	Non Crit stats
	--
	
	CombatStatsNonCritHitsStatText:SetText(overallNonCrits);	
	CombatStatsNonCritDamageStatText:SetText(overallRegDmg);	
	CombatStatsNonCritMinMaxStatText:SetText(overallminReg .." / "..overallmaxReg);
	
	if( overallRegDmg ~= 0) then
												
		if( (totalHits - overallCrits) < 0) then
			CombatStatsNonCritAvgStatText:SetText(format("%.1f",  overallRegDmg / (overallCrits - totalHits ) ));
		end
						
		if(	(totalHits - overallCrits) == 0 ) then
			CombatStatsNonCritAvgStatText:SetText(format("%1.f", overallRegDmg / (overallCrits) ));
		end
						
		if(	(totalHits - overallCrits) > 0 ) then
			CombatStatsNonCritAvgStatText:SetText(format("%1.f", overallRegDmg / (totalHits - overallCrits) ));
		end
						
	else		
		CombatStatsNonCritAvgStatText:SetText("0.0");
	end
	
	if(overallNonCrits ~=0) then
		CombatStatsNonCritPercentDamageStatText:SetText( format("%.2f %%", ( overallRegDmg  / (overallRegDmg + overallCritDmg )) * 100.0));
	else
		CombatStatsNonCritPercentDamageStatText:SetText("0.0 %");
	end
	
	--
	--	Crit stats
	--
	
	CombatStatsCritHitsStatText:SetText(overallCrits);	
	CombatStatsCritDamageStatText:SetText(overallCritDmg);	
	CombatStatsCritMinMaxStatText:SetText(overallminCrit .." / "..overallmaxCrit);
	
	if( overallCritDmg ~= 0) then
		CombatStatsCritAvgStatText:SetText(format("%1.f", (overallCritDmg / overallCrits) ));
	else
		CombatStatsCritAvgStatText:SetText("0.0");
	end
	
	if(overallCrits ~=0) then
		CombatStatsCritPercentDamageStatText:SetText(format("%.2f %%", (overallCritDmg / ( overallRegDmg + overallCritDmg )) * 100.10 ));
	else
		CombatStatsCritPercentDamageStatText:SetText("0.0 %");
	end	
	
	end
	
end					


--
--  Time functions
--  from Clock.lua
--

local function Clock_FormatPart(fmt, val)
	local part;

	part = format(TEXT(fmt), val);
	if( val ~= 1 ) then
		part = part.."s";
	end

	return part;
end

function Clock_FormatTime(time)
	local d, h, m, s;
	local text = "";
	local skip = 1;

	if ( time == 0 ) then return Clock_FormatPart(CLOCK_TIME_SECOND, 0); end

	d, h, m, s = ChatFrame_TimeBreakDown(time);
	if( d > 0 ) then
		text = text..Clock_FormatPart(CLOCK_TIME_DAY, d)..", ";
		skip = 0;
	end
	if( (skip == 0) or (h > 0) ) then
		text = text..Clock_FormatPart(CLOCK_TIME_HOUR, h)..", ";
		skip = 0;
	end
	if( (skip == 0) or (m > 0) ) then
		text = text..Clock_FormatPart(CLOCK_TIME_MINUTE, m)..", ";
		skip = 0;
	end
	if( (skip == 0) or (s > 0) ) then
		text = text..Clock_FormatPart(CLOCK_TIME_SECOND, s);
	end

	return text;
end

function CombatStats_TargetFrame_OnShow()
	if (CombatStats_Old_TargetFrame_OnShow) then
		CombatStats_Old_TargetFrame_OnShow();
	end
	CombatStats_UpdateVisibility(1);
end

function CombatStats_TargetFrame_OnHide()
	if (CombatStats_Old_TargetFrame_OnHide) then
		CombatStats_Old_TargetFrame_OnHide();
	end
	CombatStats_UpdateVisibility(0);
end
