DYKey = nil;
local pre_UseAction;
DYVar = { init, attack, once, combat, hate, shot = true, crazy = true, cast = true, target, dead, friend, yellow, class, mount, buff, debuff, use = true, aiminit, dk = true, invul = true, panic, usetimer = 0; };
function DefendYourself_OnLoad()
	SlashCmdList["DEFENDSLASH"] = DefendYourself_Main_ChatCommandHandler;
	SLASH_DEFENDSLASH1 = "/defendyourself";
	SLASH_DEFENDSLASH2 = "/dy";
	this:RegisterEvent("VARIABLES_LOADED");
	this:RegisterEvent("PLAYER_ENTER_COMBAT");
	this:RegisterEvent("PLAYER_LEAVE_COMBAT");
	this:RegisterEvent("PLAYER_REGEN_ENABLED");
	this:RegisterEvent("PLAYER_REGEN_DISABLED");
	this:RegisterEvent("PLAYER_TARGET_CHANGED");
	this:RegisterEvent("START_AUTOREPEAT_SPELL");
	this:RegisterEvent("STOP_AUTOREPEAT_SPELL");
	this:RegisterEvent("PLAYER_CONTROL_LOST");
	this:RegisterEvent("PLAYER_CONTROL_GAINED");
	this:RegisterEvent("PLAYER_AURAS_CHANGED");
	this:RegisterEvent("UNIT_AURA");
	this:RegisterEvent("UNIT_AURASTATE");
	this:RegisterEvent("SPELLCAST_START");
	this:RegisterEvent("SPELLCAST_STOP");
	this:RegisterEvent("PLAYER_ENTERING_WORLD");
	this:RegisterEvent("PLAYER_LEAVING_WORLD");
	this:RegisterEvent("UI_ERROR_MESSAGE");
	this:RegisterEvent("CHAT_MSG_COMBAT_PARTY_HITS");
	this:RegisterEvent("CHAT_MSG_COMBAT_PARTY_MISSES");
	this:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS");
	this:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES");
	this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS");
	this:RegisterEvent("CHAT_MSG_SPELL_AURA_GONE_SELF");
	DefendYourselfTip:SetOwner(DefendYourselfFrame, "ANCHOR_NONE"); 
end

function DefendYourself_OnEvent(event, arg1, arg2, arg3)
	if (not DYVar.class and UnitClass("player")) then 
		local _, tempclassname = UnitClass("player");
		DYVar.class = strlower(tempclassname);
	end
	if event == "VARIABLES_LOADED" then
		DYVar.init = true;
		DefendYourselfTip:SetOwner(DefendYourselfFrame, "ANCHOR_NONE"); 
		DefendYourself_UnitSave();
		if(myAddOnsList) then
			myAddOnsList.DefendYourself = {name = DEFEND_CONFIG_HEADER, description = DEFEND_CONFIG_HEADER_INFO, version = DEFEND_CONFIG_VERSION, category = MYADDONS_CATEGORY_COMBAT, frame = "DefendYourselfFrame", optionsframe = "DYmenu"};
		end
		if not DYKey.On and DYKey.ReOn then DYKey.On = true; DYKey.ReOn = nil; elseif DYKey.ReOn then DYKey.ReOn = nil; end
	elseif DYKey and DYKey.On then
		if DYturn_Event then DYturn_Event(event, arg1, arg2, arg3); end
		if event == "PLAYER_TARGET_CHANGED" then
			DYVar.once = true;
			if DYKey.Debuff and UnitExists("target") and UnitCanAttack("player","target") then DefendYourself_debuff(); elseif DYVar.debuff == nil then DYVar.debuff = true; end
		elseif (event == "UNIT_AURA" or event == "UNIT_AURASTATE") and arg1 == "target" then
			if DYKey.Debuff and UnitExists("target") and UnitCanAttack("player", "target") then DefendYourself_debuff(); elseif DYVar.debuff == nil then DYVar.debuff = true; end
		elseif event == "PLAYER_ENTER_COMBAT" then
			DYVar.combat = true;
		elseif event == "PLAYER_LEAVE_COMBAT" then
			DYVar.combat = nil;
			if DYVar.attack then DYVar.once = true; end
		elseif event == "PLAYER_REGEN_ENABLED" then
			if not DYKey.Safe then DYVar.hate = nil; end
		elseif event == "PLAYER_REGEN_DISABLED" then
			DYVar.hate = true;
		elseif event == "START_AUTOREPEAT_SPELL" then
			DYVar.shot = nil;
		elseif event == "STOP_AUTOREPEAT_SPELL" then
			DYVar.shot = true;
		elseif event == "PLAYER_CONTROL_LOST" then
			DYVar.crazy = nil;
		elseif event == "PLAYER_CONTROL_GAINED" then
			if not DYVar.crazy then
				if not UnitExists("target") then TargetLastEnemy(); end
			end
			DYVar.crazy = true;
		elseif event == "PLAYER_AURAS_CHANGED" then
			DefendYourself_buff();
		elseif event == "SPELLCAST_START" then
			DYVar.spell = nil;
		elseif event == "SPELLCAST_STOP" then
			DYVar.spell = true;
			if not DYVar.aiminit then
				if DYVar.class and strfind(DYVar.class, "hunter") or strfind(DYVar.class, "rogue") then
					pre_UseAction = UseAction;
					UseAction = DefendYourself_checkUse;
				end
				DYVar.aiminit = true;
			end
			if not DYVar.combat and not DYVar.once then DYVar.once = true; end
		elseif event == "UI_ERROR_MESSAGE" then
			if (arg1 == ERR_NO_ATTACK_TARGET or arg1 == ERR_INVALID_ATTACK_TARGET) then
				DYVar.target = nil;
				DYVar.once = nil;
			elseif (arg1 == ERR_WRONG_DIRECTION_FOR_ATTACK or arg1 == ERR_BADATTACKFACING) then
				DYVar.once = nil;
			elseif (arg1 == SPELL_FAILED_TOO_CLOSE) then
				DYVar.use = true;
				DYVar.shot = true;
			end
		elseif event == "PLAYER_ENTERING_WORLD" or event == "PLAYER_LEAVING_WORLD" then
			DYVar.hate = nil;
			DYVar.combat = nil;
			DYVar.once = true;
		end
		if UnitCanAttack("player","target") then
			DefendYourself_Check();
			DefendYourself_Trip();
		end
	end
end

function DefendYourself_checkUse(arg1, arg2, arg3)
	if (GetActionText(arg1)) then
		local a, b, c = GetMacroInfo(GetMacroIndexByName(GetActionText(arg1)));
		if c and (strfind(strlower(c), "aimed shot")) then
			DYVar.use = nil;
		elseif c and strfind(strlower(c), "intercept") then
			DYVar.use = nil;
		elseif c and ((strfind(strlower(c), strlower(DefendYourself_noattack[1])) or strfind(strlower(c), strlower(DefendYourself_noattack[2])) or strfind(strlower(c), strlower(DefendYourself_noattack[13])))) then
			DYVar.use = nil;
		end
	end
	local tex = GetActionTexture(arg1);
	if tex == "Interface\\Icons\\INV_Spear_07" or tex == "Interface\\Icons\\Ability_Gouge" or tex == "Interface\\Icons\\Ability_Sap" or tex == "Interface\\Icons\\Ability_Rogue_Feint" or  tex == "Interface\\Icons\\Spell_Shadow_MindSteal" then
		DYVar.use = nil;
	end
	if not DYVar.use then
		DYVar.attack = nil;
		DYVar.once = nil;
		DYVar.usetimer = 5
	end
	pre_UseAction(arg1,arg2,arg3);
end

function DefendYourself_OnUpdate(elapsed)
	if not DYKey or not DYKey.On then DYStuff:Hide(); DefendYourselfFrame:EnableMouse(0); DefendYourselfFrame:SetBackdropColor(0,0,0,0); DefendYourselfFrame:SetBackdropBorderColor(0,0,0,0); return end
	if DYKey.On then
		if DefendYourself_Panic and DefendYourself_Panic(elapsed) then return; end
		if DYVar.usetimer > 1 then DYVar.usetimer = DYVar.usetimer - elapsed; return; elseif DYVar.usetimer > 0 and not DYVar.use then DYVar.use = true; DYVar.usetimer = 0 return; end
		DefendYourself_Check();
		if UnitCanAttack("player", "target") then 
			DefendYourself_DK();
			if not DYVar.crazy then if HasFullControl() == 1 then DYVar.crazy = true; end end
			DefendYourself_Trip();
			DefendYourself_Attack();
			
		end
		DefendYourself_Stuff();
	end
end

function DefendYourself_Check()
	if UnitExists("target") then DYVar.target = true; else DYVar.target = nil; end
	if UnitIsDead("target") then DYVar.dead = nil; else DYVar.dead = true; end
	if UnitCanAttack("player", "target") then DYVar.friend = true; else DYVar.friend = nil; end
	if DYKey.Yellow then DefendYourself_Yellow(); else DYVar.yellow = true; end
	--if DYKey.Faction then DefendYourself_Faction(); else DYVar.faction = true; end
end

function DefendYourself_Yellow()
	if UnitIsEnemy("target", "player") then 
		DYVar.yellow = true; 
	elseif not UnitIsFriend("target", "player") and UnitExists("target") then 
		DYVar.yellow = nil; 
	else 
		DYVar.yellow = true; 
	end
end

function DefendYourself_Stuff()
	if DYKey.Debug then 
		DYStuff:Show();
		DefendYourselfFrame:EnableMouse(1);
		DefendYourselfFrame:SetBackdropColor(0,0,0,0.5);
		DefendYourselfFrame:SetBackdropBorderColor(1,1,1,1);
		DYStuff:SetText("Attacking:"..dycol(DYVar.attack).."\nNeed to attack:"..dycol(DYVar.once).."\nIn Combat:"..dycol(DYVar.combat).."\nOn Hate List:"..dycol(DYVar.hate)
		.."\nNot Shooting:"..dycol(DYVar.shot).."\nNot Crazy:"..dycol(DYVar.crazy).."\nNot Casting:"..dycol(DYVar.cast).."\nHave a Target?:"..dycol(DYVar.target)
		.."\nIt's not Dead?:"..dycol(DYVar.dead).."\nNot a Friend?:"..dycol(DYVar.friend).."\nNot Unhostile/Yellow?:"..dycol(DYVar.yellow).."\nOn a Mount?:"..dycol(DYVar.mount)
		.."\nNo special Buffs?:"..dycol(DYVar.buff).."\nNo Debuffs on it?:"..dycol(DYVar.debuff).."\nNot using a certain skill?:"..dycol(DYVar.use));
	else
		if DYStuff:IsVisible() then
			DYStuff:Hide();
			DefendYourselfFrame:EnableMouse(0);
			DefendYourselfFrame:SetBackdropColor(0,0,0,0);
			DefendYourselfFrame:SetBackdropBorderColor(0,0,0,0);
		end
	end
end

function DefendYourself_Faction()
	local CurrentZone = GetRealZoneText();
	if UnitExists("target") and UnitIsPlayer("target") then 
		if UnitFactionGroup("player") == "Alliance" then
			if UnitFactionGroup("target") == "Horde" then
				DYVar.faction = nil;
			else
				DYVar.faction = true; 
			end
		elseif UnitFactionGroup("player") == "Horde" then
			if UnitFactionGroup("target") == "Alliance" then
				DYVar.faction = nil; 
			else
				DYVar.faction = true; 
			end
		end
		--[[if UnitIsPVP("player") and UnitIsPVP("target") then 
			DYVar.faction = true;
		else 
			DYVar.faction = nil; 
		end]]
	else 
		DYVar.faction = true; 
	end
end

function DefendYourself_Trip()
	if DYVar.hate and DYVar.target then
		if DYVar.shot and DYVar.crazy and DYVar.dead and DYVar.friend and DYVar.yellow and DYVar.buff and DYVar.debuff and DYVar.dk and not DYVar.mount and DYVar.use then
			DYVar.attack = true;
		else
			DYVar.attack = nil;
		end
	else
		DYVar.attack = nil;
	end
end

--Handles all the lovely person-related saves. Yeah, saved by player name and server. T.T thx rowne!
function DefendYourself_UnitSave(x)
	if (DYVar.init) then
		local info = UnitName("player").." of "..GetCVar("realmName"); 
	--[[	if (x == 1) then 
			info = Fetch_PlayerInfo; 
		end]]
		local _, tempclassname = UnitClass("player");
		DYVar.class = strlower(tempclassname);
		if not DefendYourselfKey or not DefendYourselfKey.Version then
			DefendYourselfKey = {};
			DefendYourselfKey.Version = DEFEND_CONFIG_VERSION;
		elseif DefendYourselfKey.Version ~= DEFEND_CONFIG_VERSION then
			DefendYourselfKey.Version = DEFEND_CONFIG_VERSION;
		end
		if DefendYourselfKey.default then
			info = "Default Class";
		end
		if (not DefendYourselfKey[info]) then
			DefendYourselfKey[info] = {
			["On"] = true,
			["ReOn"] = nil,
			["Yellow"] = true,
			["Faction"] = true,
			["Debuff"] = true,
			["HP"] = nil,
			["Safe"] = nil,
			["Assist"] = true,
			["Civilian"] = true,
			["Debug"] = nil,
			["PanicTimer"] = 30,
			["PanicTime"] = 0,
			["Bar"] = 1,
			["blvl"] = 1
			};
		end
		DYKey = DefendYourselfKey[info];
		--DefendYourself_Fetch_Frame:Hide();
		DefendYourself_Print("Defend Yourself! v."..DEFEND_CONFIG_VERSION.." is Loaded and "..dycol(DYKey.On));
	end
end

function DefendYourself_Print(msg,r,g,b,frame,id)
	if ( Print ) then
		Print(msg, r, g, b, frame, id);
		return;
	end
				
	if (not r) then r = 1.0; end
	if (not g) then g = 1.0; end
	if (not b) then b = 0.0; end
	if ( frame ) then 
		frame:AddMessage(msg,r,g,b,id);
	else
		if ( DEFAULT_CHAT_FRAME ) then 
			DEFAULT_CHAT_FRAME:AddMessage(msg, r, g, b,id);
		end
	end
end

function DefendYourself_Toggle(tog, str)
		if tog then
			DefendYourself_Print(str.." |CFFFF0000Off|r");
			return nil;
		else
			DefendYourself_Print(str.." |CFF00FF00On|r");
			return true;
		end
end

function DefendYourself_Main_ChatCommandHandler(msg)
	local msg = TextParse(msg);
	msg[1] = strlower(msg[1])
	if strfind(msg[1], "toggle") then
		DYKey.On = DefendYourself_Toggle(DYKey.On, "DefendYourself! is");
	elseif strfind(msg[1], "defaultprofile") then
		DefendYourselfKey.default = DefendYourself_Toggle(DefendYourselfKey.default, "Using an overall profile is");
	elseif strfind(msg[1], "yellow") then
		DYKey.Yellow = DefendYourself_Toggle(DYKey.Yellow, "Ignoring Yellow Creatures is");
	elseif strfind(msg[1], "faction") then
		DYKey.Faction = DefendYourself_Toggle(DYKey.Faction, "Ignoring Faction Members is");
	elseif strfind(msg[1], "debuff") then
		DYKey.Debuff = DefendYourself_Toggle(DYKey.Debuff, "Ignoring debuffed creatures is");
	elseif strfind(msg[1], "tlhp") then
		DefendYourself_tlhp();
		DefendYourself_Print("Aquiring target with lowest hp...",1,1,1);
	elseif strfind(msg[1], "assist") then
		DYKey.Assist = DefendYourself_Toggle(DYKey.Assist, "Smart Assist is");
	elseif strfind(msg[1], "debug") then
		DYKey.Debug = DefendYourself_Toggle(DYKey.Debug, "Debug options are");
	elseif strfind(msg[1], "dk") then
		DYKey.Civilian = DefendYourself_Toggle(DYKey.Civilian, "Dishonorable Kill Prevention is");
	elseif strfind(msg[1], "help") then
		DefendYourself_Help();
	elseif strfind(msg[1], "menu") and DYmenu then
		DYmenu:Show();
	elseif strfind(msg[1], "button") then
		if DefendYourselfPanicButtonClick then 
			if msg[2] == "off" then DYKey.PanicState = 5 else DefendYourselfPanicButtonClick("MiddleButton"); end
		end
	elseif strfind(msg[1], "bar") then
		if DefendYourselfBar then
			if msg[2] == "off" then DYKey.Bar = nil; elseif not DYKey.Bar then DYKey.Bar = 1; elseif DYKey.Bar == 1 then DYKey.Bar = 2; elseif DYKey.Bar == 2 then DYKey.Bar = nil; end
		end
	elseif strfind(msg[1], "defaultpanic") then
		DYKey.PanicTimer = tonumber(msg[2]);
	elseif strfind(msg[1], "panic") then
		if DefendYourself_StartPanic then DefendYourself_StartPanic(tonumber(msg[2])); end
	elseif strfind(msg[1], "turn") then
		if DefendYourself_Turn then DYKey.Turn = DefendYourself_Toggle(DYKey.Turn, "Turn functionability is"); end
	elseif strfind(msg[1], "on") then
		DefendYourself_Print("DefendYourself! is on"); DYKey.On = true; DYKey.ReOn = nil;
	elseif strfind(msg[1], "off") then
		local output = "DefendYourself! is off"
		if msg[2] and strfind(msg[2], "s") then
			output = output.." and will be restarted on your next reload";
			DYKey.ReOn = true;
		end
		DefendYourself_Print(output); 
		DYKey.On = nil;
	else
		if DYmenu then DYmenu:Show(); else
		DefendYourself_Print(DEFEND_CHAT_COMMAND_USAGE,1,1,0);
		DefendYourself_Help();
		end
	end
	msg = nil;
end

function DefendYourself_Help()
		DefendYourself_Print("Defend Yourself! v."..DEFEND_CONFIG_VERSION.." Parameters and their states");
		DefendYourself_Print("Toggle is:"..dycol(DYKey.On));
		DefendYourself_Print("Yellow is:"..dycol(DYKey.Yellow));
		DefendYourself_Print("Faction is:"..dycol(DYKey.Faction));
		DefendYourself_Print("Debuff is:"..dycol(DYKey.Debuff));
		DefendYourself_Print("Bloodlust is:"..dycol(DYKey.Safe));
		DefendYourself_Print("DK Prevention is:"..dycol(DYKey.Civilian));
		DefendYourself_Print("Assist is:"..dycol(DYKey.Assist));
		DefendYourself_Print("Using Default profiles is:"..dycol(DefendYourselfKey.default));
		DefendYourself_Print("Use /dy help to see this, /dy on turns it on, /dy off turns it off, and /dy toggle turns it between the two. /dy menu handles the menu! /dy defaultprofile toggles using an overall profile or a per-character-per-server profile.");
end

function dycol(tog)
	if tog then
		return "|CFF00FF00Yes|r";
	else
		return "|CFFFF0000No|r";
	end
end

function TextParse(InputString)
--[[ By FERNANDO!
	This function should take a string and return a table with each word from the string in
	each entry. IE, "Linoleum is teh awesome" returns {"Linoleum", "is", "teh", "awesome"}
	Some good should come of this, I've been avoiding writing a text parser for a while, and
	I need one I understand completely. ^_^

	If you want to gank this function and use it for whatever, feel free. Just give me props
	somewhere. This function, as far as I can tell, is fairly foolproof. It's hard to get it
	to screw up. It's also completely self-contained. Just cut and paste.]]
   local Text = InputString;
   local TextLength = 1;
   local OutputTable = {};
   local OTIndex = 1;
   local StartAt = 1;
   local StopAt = 1;
   local TextStart = 1;
   local TextStop = 1;
   local TextRemaining = 1;
   local NextSpace = 1;
   local Chunk = "";
   local Iterations = 1;
   local EarlyError = false;

   if ((Text ~= nil) and (Text ~= "")) then
   -- ... Yeah. I'm not even going to begin without checking to make sure Im not getting
   -- invalid data. The big ol crashes I got with my color functions taught me that. ^_^

      -- First, it's time to strip out any extra spaces, ie any more than ONE space at a time.
      while (string.find(Text, "  ") ~= nil) do
         Text = string.gsub(Text, "  ", " ");
      end

      -- Now, what if text consisted of only spaces, for some ungodly reason? Well...
      if (string.len(Text) <= 1) then
         EarlyError = true;
      end

      -- Now, if there is a leading or trailing space, we nix them.
      if EarlyError ~= true then
        TextStart = 1;
        TextStop = string.len(Text);

        if (string.sub(Text, TextStart, TextStart) == " ") then
           TextStart = TextStart+1;
        end

        if (string.sub(Text, TextStop, TextStop) == " ") then
           TextStop = TextStop-1;
        end

        Text = string.sub(Text, TextStart, TextStop);
      end

      -- Finally, on to breaking up the goddamn string.

      OTIndex = 1;
      TextRemaining = string.len(Text);

      while (StartAt <= TextRemaining) and (EarlyError ~= true) do

         -- NextSpace is the index of the next space in the string...
         NextSpace = string.find(Text, " ",StartAt);
         -- if there isn't another space, then StopAt is the length of the rest of the
         -- string, otherwise it's just before the next space...
         if (NextSpace ~= nil) then
            StopAt = (NextSpace - 1);
         else
            StopAt = string.len(Text);
            LetsEnd = true;
         end

         Chunk = string.sub(Text, StartAt, StopAt);
         OutputTable[OTIndex] = Chunk;
         OTIndex = OTIndex + 1;

         StartAt = StopAt + 2;

      end
   else
      OutputTable[1] = "Error: Bad value passed to TextParse!";
   end

   if (EarlyError ~= true) then
      return OutputTable;
   else
      return {"Error: Bad value passed to TextParse!"};
   end
end

--[[This is similar to the above, but it checks your current buffs.
(List:DefendYourself_selfbuff)
returns true if it finds a buff that will get removed if you attack something(like stealth)
For reference, this one is run all the time, the previous one only runs if you have
debuff support toggled on.]]
function DefendYourself_buff()
	local pow = 0;
	DYVar.mount = nil;
	--Hanging onto this code currently in case i need it. will be removed when the new way is confirmed.
	--[[for i = 1, getn(DefendYourself_selfbuff), 1 do
		if pow == 1 then break; end
		local j = 1;
		while UnitBuff("player", j) do
			DefendYourselfTip:SetUnitBuff("player", j);
			local msg = DefendYourselfTipTextLeft1:GetText();
			local texture = UnitBuff("player", j);
			if (string.find(texture,"Spell_Nature_Swiftness") or -- Summon Felsteed, Summon Warhorse
				string.find(texture,"Ability_Mount") or string.find(texture,"INV_Misc_Foot_Kodo")) then
					local _, cls = UnitClass("player");
					if cls == "DRUID" and UnitPowerType("player") ~= 0 then 
						DYVar.mount = nil; 
					else
						DYVar.mount = true;
					end
			end
			if (msg == DefendYourself_selfbuff[i]) then
				pow = 1;
				break;
			end
			j = j + 1;
		end
	end]]
	
	local j = 1;
	while UnitBuff("player", j) do
		if pow == 1 then break; end
		DefendYourselfTip:SetUnitBuff("player", j);
		local msg = DefendYourselfTipTextLeft1:GetText();
		local texture = UnitBuff("player", j);
		if (string.find(texture,"Spell_Nature_Swiftness") or -- Summon Felsteed, Summon Warhorse
			string.find(texture,"Ability_Mount") or string.find(texture,"INV_Misc_Foot_Kodo")) then
			local _, cls = UnitClass("player");
			if cls == "DRUID" and UnitPowerType("player") ~= 0 then 
				DYVar.mount = nil; 
			else
				DYVar.mount = true;
			end
		end
		for i = 1, getn(DefendYourself_selfbuff), 1 do
			if (msg == DefendYourself_selfbuff[i]) then
				pow = 1;
				break;
			end
		end
		j = j + 1;
	end
	
	
	if pow == 0 then
		if (not DYVar.buff) then
			DYVar.buff = true;
			DYVar.once = true;
		end
	elseif pow == 1 then
		if DYVar.buff then
			DYVar.buff = nil;
			DYVar.once = nil;
		end
	end
end

function DefendYourself_debuff()
	local pow = 0;
	--read above for this code still existing.
	--[[for i = 1, getn(DefendYourself_noattack), 1 do
		if pow == 1 then break; end
		local j = 1;
		while UnitDebuff("target", j) do
			DefendYourselfTip:SetUnitDebuff("target", j);
			local msg = DefendYourselfTipTextLeft1:GetText();
			if (msg == DefendYourself_noattack[i]) then
				pow = 1;
				break;
			end
			j = j + 1;
		end
	end]]
	local j = 1;
	while UnitDebuff("target", j) do
		if pow == 1 then break; end
		DefendYourselfTip:SetUnitDebuff("target", j);
		local msg = DefendYourselfTipTextLeft1:GetText();
		for i = 1, getn(DefendYourself_noattack), 1 do
			if (msg == DefendYourself_noattack[i]) then
				pow = 1;
				break;
			end
		end
		j = j + 1;
	end
	if pow == 0 then
		if (not DYVar.debuff) then
			DYVar.debuff = true;
			DYVar.once = true;
			DYVar.use = true;
		end
	elseif pow == 1 then
		if DYVar.debuff then
			DYVar.debuff = nil;
			DYVar.once = nil;
		end
	end
end

function DefendYourself_DK()
	DefendYourselfTip:ClearLines();
	DefendYourselfTip:SetUnit("target");
	DYVar.dk = true;
	for i = 1, 6 do
		local msg = tostring(getglobal("DefendYourselfTipTextLeft"..i):GetText());
		if strfind(msg, "Civilian") then
			DYVar.dk = nil;
			break;
		end
	end
end

local escapetlhp = nil;
function DefendYourself_tlhp()
	if escapetlhp and escapetlhp > GetTime() then return; end
	escapetlhp = GetTime()+5;
	local maxHP, curHP, retry;
	maxHP = 101;
	retry = 0;
	if UnitExists("target") then maxHP = UnitHealth("target"); end
	TargetNearestEnemy();
	curHP = UnitHealth("target");
	while (curHP ~= maxHP and UnitExists("target") and retry <= 10) do
		if (curHP < maxHP) then
				maxHP = curHP;
				retry = 0;
		else
			retry = retry + 1;
		end
		TargetNearestEnemy();
		if UnitExists("target") then curHP = UnitHealth("target"); end
	end
	DefendYourself_debuff();
	DefendYourself_Check();
	DefendYourself_Trip();
	if not DYVar.attack or (UnitIsTapped("target") and not UnitIsTappedByPlayer("target")) then ClearTarget(); end
	escapetlhp = nil;
end

function DefendYourself_Attack()
	if DYKey.On then
		if DYVar.attack then 
			DYBattle();
		else
			DYEscape();
		end
	end
end

function DYBattle()
	if DYVar.once then
		if DYVar.combat then
			DYVar.once = nil;
		else
			AttackTarget();
			DYVar.once = nil;
		end
	end
end

function DYEscape()
	if not DYVar.crazy and not UnitOnTaxi("player") then return; end
	if DYVar.combat and (not DYVar.buff or not DYVar.debuff) then AttackTarget(); DYVar.once = nil; return; end
end