Quantcast
local L = Elementarist.Locals;

Elementarist:RegisterModule("elemental");

Elementarist.elemental = {
	["Configuration"] = {
		["trackAuraBuffs"] = {
			["type"]	=	"CheckBox",
			["vposition"] =  -100,
			["hposition"] =  10,
			["label"]	=	L.CONFIG_DEBUFF_TRACKER_SHOW_BUFFS
		},
		["enableEQ"] = {
			["type"]	=	"CheckBox",
			["vposition"] =  -170,
			["hposition"] =  10,
			["label"]	=	L.CONFIG_ENABLE_EQ_SPELL
		},
		["showHealingStream"] = {
			["type"]	=	"CheckBox",
			["vposition"] =  -200,
			["hposition"] =  10,
			["label"]	=	L.CONFIG_ENABLE_HS_TOTEM
		},
		["disableLM"] = {
			["type"]	=	"CheckBox",
			["vposition"] =  -140,
			["hposition"] =  10,
			["label"]	=	L.CONFIG_DISABLE_LM_SPELL
		},
		["maximizeFS"] = {
			["type"]	=	"CheckBox",
			["vposition"] =  -60,
			["hposition"] =  10,
			["label"]	=	L.CONFIG_DOFS
		},
		["doFSThreshold"] = {
			["type"]	=	"Slider",
			["vposition"] =  -85,
			["hposition"] =  350,
			["label"]	=	L.CONFIG_DOFS_THRESHOLD,
			["low"]		=	1,
			["high"]	=	30,
			["step"]	=	1
		},
	};
	Initialize = function(self)
		Elementarist:LoadSpells({
			["Unleash Flame"] = GetSpellInfo(165462),
			["Elemental Fusion"] = GetSpellInfo(157174),
			["Glyph of Flame Shock"] = GetSpellInfo(55447),
			["Healing Stream Totem"] = GetSpellInfo(5394),
			["Liquid Magma"] = GetSpellInfo(152255),
			["Enhanced Chain Lightning"]  = GetSpellInfo(157766),
			["Storm Elemental Totem"] = GetSpellInfo(152256)
		});

		Elementarist.role = "DPS";
		Elementarist.trackAura = Elementarist.SpellList["Flame Shock"]  -- Spell used in Aura Tracking window
		Elementarist.trackAuraBuffSpell1 = Elementarist.SpellList["Unleash Flame"]  -- buff charge count to display in Aura Tracking Window
		Elementarist.trackAuraBuffSpell2 = Elementarist.SpellList["Elemental Fusion"] -- buff charge count to display in Aura Tracking Window
		Elementarist.trackFilter = "PLAYER|HARMFUL";
		Elementarist.trackDuration = 39;
	end;

-----------------------------------------------------
-- Determine next spell to display
-----------------------------------------------------

	NextSpell = function(self,timeshift,exspell1,exspell2)
		local guid = UnitGUID("target")
		local currentTime = GetTime()
		local s,d,e
		local haveFireTotem,fireTotemName,fireTotemStart,fireTotemDuration
		local lastSpell
		local doFS = false
		local _
		local EBTalent = (Elementarist.tier6Talent == 19267)
		local UFTalent = (Elementarist.tier6Talent == 21773)
		local EFTalent = (Elementarist.tier7Talent == 21198)
		local LMTalent = (Elementarist.tier7Talent == 21200)
		local fsRefreshPercentage=0.3
		if Elementarist.hasT18_Class_Trinket then
			fsRefreshPercentage=fsRefreshPercentage + 0.48
			if UFTalent then fsRefreshPercentage=fsRefreshPercentage + 0.22 end
		end
		if (exspell1) then
			if (exspell2) then
				lastSpell = exspell2
			else
				lastSpell = exspell1
			end
		else
			lastSpell = Elementarist.lastSpell
		end

		-- get current spell and target information
		tguid = UnitGUID("target")
		local spellInCast, _, _, _, sICstartTime, sICendTime = UnitCastingInfo("player")


		-----------------------------------------------------
		-- Timing calulatutions
		-----------------------------------------------------

		-- check Shock CD
		s, d = GetSpellCooldown(Elementarist.SpellList["Flame Shock"])
		if (d) and (d>0) and (s == 0) then
			Elementarist.lastShockCD = d
		end
		s, d = GetSpellCooldown(Elementarist.SpellList["Earth Shock"])
		if (d) and (d>0) and (s == 0) then
			Elementarist.lastShockCD = d
		end

		-- set minimuim amount of flameshock remaining for a lava burst
		local LvBct = 2 - (2 * Elementarist.spellHaste * .01)

		--  Set Global Coolodown
		Elementarist.lastBaseGCD = 1.5 - (1.5 * Elementarist.spellHaste * .01)

		if (not timeshift) then	timeshift = 0 end

		-- Adjust current spell to deal with timming issue
		if (spellInCast) then
			if ( (sICendTime - sICstartTime) / 1000 ) < Elementarist.lastBaseGCD then
				sICendTime = sICstartTime + (Elementarist.lastBaseGCD * 1000)
			end
			Elementarist.lastCastTime = sICendTime;
			timeshift = timeshift + (sICendTime / 1000) - GetTime()
		else
			-- to prevent tick in current spell, check if last one finished in short time
			if (Elementarist.lastCastTime) and ((Elementarist.lastCastTime / 1000) + Elementarist.lastBaseGCD >= GetTime() ) then
				spellInCast = Elementarist.lastSpell
			end

			-- no spell in cast, check global cd via Ghost Wolf
			if (Elementarist.SpellList["Ghost Wolf"]) then
				local ftcd = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Ghost Wolf"])
				if (ftcd) then
					timeshift = timeshift + Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Ghost Wolf"])
				else
					timeshift = timeshift + Elementarist.lastBaseGCD
				end
			else
				timeshift = timeshift + Elementarist.lastBaseGCD
			end
		end

		-----------------------------------------------------
		-- buffs and debuff status
		-----------------------------------------------------

		-- set lightning shield count
		local _, _, _, lscount = Elementarist:hasBuff("player",Elementarist.SpellList["Lightning Shield"])

		-- get targets flame shock debuff information
		name, _, _, _, _, fsDuration,fsExpiration, unitCaster = Elementarist:hasDeBuff("target", Elementarist.SpellList["Flame Shock"], "player");
		if (not fsExpiration) then fsExpiration = 0 fsDuration = 0 end

		-- get lava burst charges and adjust Charges based on timeshift
		local lvbCharges, maxLvbCharges, cdStart, cdLength  = GetSpellCharges(Elementarist.SpellList["Lava Burst"]);
		lvbCharges = lvbCharges - Elementarist:Count(Elementarist.SpellList["Lava Burst"], spellInCast,exspell1,exspell2);
		if (((cdStart + cdLength)- GetTime()) - timeshift <= 0) then lvbCharges = lvbCharges + 1 end

		-- check if assendance active
		local ascendance, _, _, _, _, _, ascendanceExp = Elementarist:hasBuff("player",Elementarist.SpellList["AscendanceElementalBuff"]);
		if (ascendance == nil) then
			ascendanceExp = 0
		end

		-- Set elemental fussion buff count
		local _, _, _, efCount = Elementarist:hasBuff("player",Elementarist.SpellList["Elemental Fusion"])
		if (efCount == nil) then efCount = 0 end
		if (efCount < 2)and (EFTalent) then efCount = efCount +(Elementarist:Count(Elementarist.SpellList["Lava Burst"],spellInCast,exspell1,exspell2) ) end
		if (efCount > 2) then efCount = 2 end

		-- get Unleashed Flame buff Status
		local ufCount=0
		if (Elementarist:hasBuff("player",Elementarist.SpellList["Unleash Flame"]) or  (spellInCast == Elementarist.SpellList["Unleash Flame"])) and
		    (Elementarist:Count(Elementarist.SpellList["Lava Burst"],spellInCast,exspell1,exspell2) == 0)
			then ufCount =1
		elseif exspell1 == Elementarist.SpellList["Unleash Flame"] and exspell1 ~= Elementarist.SpellList["Lava Burst"]  then
				ufCount=1
		end
		Elementarist.ufCount= ufCount

		-- Determine if  Flameshock is to be boosted in Priority
		-- which occurs if the Boosting checking based on configuration and if they have the relevant talent to boost the DOT,
		-- boost if any available boost is missing or if the  time remaining is less than the configured threshold
		if (ElementaristDB.maximizeFS) and (UFTalent) and (Elementarist.auraCooldowns[tguid] and Elementarist.auraCooldowns[tguid]["BuffCount1"] ~= 1 ) then doFS = true end
		if (ElementaristDB.maximizeFS) and (EFTalent) and (Elementarist.auraCooldowns[tguid] and Elementarist.auraCooldowns[tguid]["BuffCount2"] ~= 2 ) then doFS = true end
		if ElementaristDB.doFSThreshold > (fsExpiration - currentTime - timeshift) then doFS = true end
		if doFS then Elementarist:Debug("doFS    ufCount:" .. ufCount, " efCount"..efCount)	else Elementarist:Debug("-----    ufCount:" .. ufCount, " efCount"..efCount)	end


		-----------------------------------------------------
		-- Spell Priorities for Next Spell to be recommeneded
		-----------------------------------------------------

		-- if target is dead, return ""
		if (UnitHealth("target")<=0) then
			return ""
		end

		-- if not in combat Recommend Pre-combat and spells

		if 	Elementarist.inCombat == false then
		    -- confirm out of combat
			if UnitAffectingCombat ("player") then Elementarist.inCombat = true end
				if 	Elementarist.inCombat == false then

				-- Searing Totem
				if (Elementarist:Count(Elementarist.SpellList["Searing Totem"],spellInCast,exspell1,exspell2) == 0) and
					Elementarist:SpellAvailable(Elementarist.SpellList["Searing Totem"])then
					local haveFireTotem,fireTotemName,fireTotemStart,fireTotemDuration = GetTotemInfo(1);
					if (fireTotemName == "") or (fireTotemDuration and (fireTotemStart + fireTotemDuration - GetTime() ) <= timeshift) then
						return Elementarist.SpellList["Searing Totem"];
					end
				end

				-- Opening Uleash flame  prior to combat
				if (Elementarist:Count(Elementarist.SpellList["Unleash Flame"],spellInCast,exspell1,exspell2) == 0) and
					Elementarist:SpellAvailable(Elementarist.SpellList["Unleash Flame"]) then
					d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Unleash Flame"])
					if (d-timeshift <= 0) then
						return Elementarist.SpellList["Unleash Flame"];
					end
				end
			end
		end


		-- Priority 1
		-- if Tier7 talent is Liquid Magma and fire totem has 10 sec or more, use it
		if (LMTalent) and (not ElementaristDB.disableLM) then
			if (Elementarist:Count(Elementarist.SpellList["Liquid Magma"],spellInCast,exspell1,exspell2) == 0) and
				Elementarist:SpellAvailable(Elementarist.SpellList["Liquid Magma"])then
				haveFireTotem,fireTotemName,fireTotemStart,fireTotemDuration = GetTotemInfo(1);
				if ((fireTotemName ~= "") and (fireTotemDuration and (fireTotemStart + fireTotemDuration - GetTime() ) >= timeshift + 15)) or
					(Elementarist:Count(Elementarist.SpellList["Searing Totem"],spellInCast,exspell1,exspell2) ~= 0) then
					d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Liquid Magma"])
					if (d-timeshift <= 0) then
						return Elementarist.SpellList["Liquid Magma"]
					end
				else
					if (Elementarist:Count(Elementarist.SpellList["Searing Totem"],spellInCast,exspell1,exspell2) == 0) and
						Elementarist:SpellAvailable(Elementarist.SpellList["Searing Totem"])and
						((fireTotemName == "") or (fireTotemDuration and (fireTotemStart + fireTotemDuration - GetTime() ) <= timeshift))
					then
						return Elementarist.SpellList["Searing Totem"];
					end
				end
			end
		end

		-- Priority 2
		-- Earth shock if Lightning Shield count >=20
		-- earth_shock,if=buff.lightning_shield.react=buff.lightning_shield.max_stack
		if (Elementarist:Count(Elementarist.SpellList["Flame Shock"],spellInCast,exspell1,exspell2) == 0 and
			Elementarist:Count(Elementarist.SpellList["Earth Shock"],spellInCast,exspell1,exspell2) == 0 and
			Elementarist:SpellAvailable(Elementarist.SpellList["Earth Shock"])) then
			d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Earth Shock"])
			if ( (d) and ((d-timeshift) <= 0) and (lscount) and (lscount>=20)) then
				return Elementarist.SpellList["Earth Shock"]
			end
		end

		-- Priority 3
		-- Flame shock if 2 stacks Elemental Fussion and Unleashed Flame buff active
		-- flame_shock,cycle_targets=1,if=(talent.elemental_fusion.enabled&buff.elemental_fusion.stack=2&buff.unleash_flame.up&dot.flame_shock.remains<(dot.flame_shock.duration*(0.3+t18_class_trinket*(0.48+talent.unleashed_fury.enabled*0.22))))
		if (Elementarist:Count(Elementarist.SpellList["Flame Shock"],spellInCast,exspell1,exspell2) == 0 and
			Elementarist:Count(Elementarist.SpellList["Earth Shock"],spellInCast,exspell1,exspell2) == 0 and
			Elementarist:SpellAvailable(Elementarist.SpellList["Flame Shock"])) then
			d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Flame Shock"])
			if ((d - timeshift) <= 0) then
				if (efCount==2) and (ufCount==1)then
						if (fsExpiration - currentTime - timeshift) < (fsDuration * fsRefreshPercentage ) then
							return Elementarist.SpellList["Flame Shock"]
					end
				end
			end
		end

		-- Priority 4
		-- Lava Burst if not on Cooldown
		-- lava_burst,if=dot.flame_shock.remains>cast_time
		if ( (lvbCharges > 0) or((ascendanceExp-GetTime()-timeshift) > 0)  ) and
			Elementarist:SpellAvailable(Elementarist.SpellList["Lava Burst"])
		then
			if (IsSpellInRange(Elementarist.SpellList["Flame Shock"], "target") == 1) and
			(
				((fsExpiration~=0) and ((fsExpiration-GetTime()-timeshift) > LvBct)) or
				(Elementarist:Count(Elementarist.SpellList["Flame Shock"],spellInCast,exspell1,exspell2) > 0)
			) then
				d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Lava Burst"])
				if ((d-timeshift) <= 0) or ((ascendanceExp-GetTime()-timeshift) > 0) then
					return Elementarist.SpellList["Lava Burst"]
				end
			end
		end

		-- Priority 5
		-- Earth shock if Lightning Shield count >=15 and not on cd, and FS debuff remaining > FS cooldown, or FS debuff remaining between FS and FS cd + 2sec and LS count>=13, or has T17 4pcs and LS Count >= 12
		-- Earth_shock,if=(set_bonus.tier17_4pc&buff.lightning_shield.react>=12&!buff.lava_surge.up)|(!set_bonus.tier17_4pc&buff.lightning_shield.react>15)
		-- Only allow this if we are not boosting Flameshock priority
		if (Elementarist:Count(Elementarist.SpellList["Flame Shock"],spellInCast,exspell1,exspell2) == 0 and
			Elementarist:Count(Elementarist.SpellList["Earth Shock"],spellInCast,exspell1,exspell2) == 0)and
			Elementarist:SpellAvailable(Elementarist.SpellList["Earth Shock"]) and
			not (doFS) then
			if ( (fsExpiration - GetTime() - timeshift) > Elementarist.lastShockCD ) then
				d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Earth Shock"])
				if (
					( (d) and ((d-timeshift) <= 0) and (lscount) ) and (	-- Earth Shock is available, and has lightning shield
						(lscount>=15) or 														-- Lightning shield has 17 charge
						( (lscount>=13) and ( (fsExpiration - GetTime() - timeshift) < Elementarist.lastShockCD + 2 ) ) or	-- or, has 13 or more charges but FS expiration within 2 secs to FS CD
						( (lscount>=12) and Elementarist.hasT17_4pcs) -- or has T17 4pcs bonus, and 12 or more charges on LS
					)
				) then
					return Elementarist.SpellList["Earth Shock"]
				end
			end
		end

		-- Priority 6
		-- Flameshock if not present or at less than 30% duration
		-- lame_shock,cycle_targets=1,if=dot.flame_shock.remains<=(dot.flame_shock.duration*0.3)
		if 	(Elementarist:Count(Elementarist.SpellList["Flame Shock"],spellInCast,exspell1,exspell2) == 0) and
			(Elementarist:Count(Elementarist.SpellList["Earth Shock"],spellInCast,exspell1,exspell2) == 0) and
			Elementarist:SpellAvailable(Elementarist.SpellList["Flame Shock"]) then
			d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Flame Shock"])
			if ((d - timeshift) <= 0) then
				if ((fsExpiration - GetTime() - timeshift) < (9) ) then
					return Elementarist.SpellList["Flame Shock"]
				end
			end
		end

		-- Priority 6b
		-- Lava Burst if Ascendance but not able to flame shock..you should never get here!!.. Flameshock before you Assend!
		if ( (ascendanceExp-GetTime()-timeshift) > 0)  and
			Elementarist:SpellAvailable(Elementarist.SpellList["Lava Burst"])then
			return Elementarist.SpellList["Lava Burst"]
		end

		-- Priority 7
		-- if Tier6 talent is Elemental Blast use it
		-- elemental_blast
		if (EBTalent) then
			if ((Elementarist:Count(Elementarist.SpellList["Elemental Blast"],spellInCast,exspell1,exspell2) == 0) and
				(IsSpellInRange(Elementarist.SpellList["Elemental Blast"], "target") == 1) and
				Elementarist:SpellAvailable(Elementarist.SpellList["Elemental Blast"])	) then
				d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Elemental Blast"])
				if ((d - timeshift) <= 0) then
					return Elementarist.SpellList["Elemental Blast"]
				end
			end
		end

		-- Priority 8
		-- If Tier6 talent is Unleashed Fury cast Unleash Flame or (buffs & cooldowns & reamaining time are correct)
		-- Unleash_flame,if=talent.unleashed_fury.enabled&!buff.ascendance.up|(talent.elemental_fusion.enabled&buff.elemental_fusion.stack=2&(dot.flame_shock.remains)<(dot.flame_shock.duration*(0.3+t18_class_trinket*(0.48+talent.unleashed_fury.enabled*0.22)))&cooldown.flame_shock.remains<gcd)
		if ((UFTalent) and not (doFS))or
		   (efCount==2 and ( (fsExpiration - currentTime - timeshift) < (fsDuration * fsRefreshPercentage )  and (fsExpiration - currentTime - timeshift) > Elementarist.lastShockCD)    ) then
			if (Elementarist:Count(Elementarist.SpellList["Unleash Flame"],spellInCast,exspell1,exspell2) == 0) and
				Elementarist:SpellAvailable(Elementarist.SpellList["Unleash Flame"])then
				d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Unleash Flame"])
				if (d-timeshift <= 0) then
					return Elementarist.SpellList["Unleash Flame"];
				end
			end
		end

		-- Priority 9
		-- Searing Totem
		if  (Elementarist:Count(Elementarist.SpellList["Searing Totem"],spellInCast,exspell1,exspell2) == 0) and
			Elementarist:SpellAvailable(Elementarist.SpellList["Searing Totem"]) then
			local haveFireTotem,fireTotemName,fireTotemStart,fireTotemDuration = GetTotemInfo(1);
			if (fireTotemName == "") or (fireTotemDuration and (fireTotemStart + fireTotemDuration - GetTime() ) <= timeshift) then
				return Elementarist.SpellList["Searing Totem"];
			end
		end

		-- Priority 9b (optional)
		-- if item level >575 and Earthquake is enabled
		if (ElementaristDB.enableEQ) and Elementarist:SpellAvailable(Elementarist.SpellList["Earthquake"])then
			if (Elementarist.iLvl>=575) or (Elementarist.person["foeCount"]>1) then
				local eqCharges, maxEqCharges, cdStart, cdLength  = GetSpellCharges(Elementarist.SpellList["Earthquake"]);
				if (eqCharges<maxEqCharges) and (((cdStart + cdLength)- GetTime()) - timeshift <= 0) then
					eqCharges = eqCharges + 1;
				end
				eqCharges = eqCharges - Elementarist:Count(Elementarist.SpellList["Earthquake"],spellInCast,exspell1,exspell2);
				eclBuff, _, _, _, _, _, eclExp = Elementarist:hasBuff("player",Elementarist.SpellList["Enhanced Chain Lightning"]);
						if (eqCharges > 0) and (eclBuff) then
					d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Earthquake"])
					if (d) and (d<0.5) then
						return Elementarist.SpellList["Earthquake"]
					end
				end
			end
		end

		-- Priority 10
		-- otherwise lightning bolt
		if IsSpellInRange(Elementarist.SpellList["Lightning Bolt"], "target") == 1 and
			Elementarist:SpellAvailable(Elementarist.SpellList["Lightning Bolt"])then
			return Elementarist.SpellList["Lightning Bolt"]
		end

		return ""
	end;
	MiscSpell = function(self)
		-- Miscelaneous spell order:
		-- Lightning Shield
		-- Searing Totem
		-- Elemental Mastery
		-- Berserking troll racial (if available)
		-- Blood Fury orc racial

		local d, e
		local name, expirationTime, _, name2, expirationTime2, name3, expirationTime3

		------  Augment Rune
		if (
			(
				((Elementarist.faction == "Horde") and (GetItemCount(Elementarist.CustomIDs["Empowered Augment Rune Horde"]) ~= 0)) or
				((Elementarist.faction == "Alliance") and (GetItemCount(Elementarist.CustomIDs["Empowered Augment Rune Alliance"]) ~= 0))
			) and ( not  Elementarist:hasBuff("player", Elementarist.SpellList["Focus Augmentation"]))
		) then
        	if (
        		((Elementarist.faction == "Horde") and (Elementarist:GetItemCooldownRemaining(Elementarist.CustomIDs["Empowered Augment Rune Horde"]) < 2)) or
        		((Elementarist.faction == "Alliance") and (Elementarist:GetItemCooldownRemaining(Elementarist.CustomIDs["Empowered Augment Rune Alliance"]) < 2))
        	) then
				return nil,GetItemIcon(Elementarist.CustomIDs["Empowered Augment Rune Horde"])
			end
       	end

		-- Alchemy Flask of Enhancement
		if	(
			((GetItemCount(Elementarist.CustomIDs["Whispers of Insanity Item"]) ~= 0) and (Elementarist.playerLevel >= 90)  ) or
			((GetItemCount(Elementarist.CustomIDs["Crystal of Insanity Item"]) ~= 0)and (Elementarist.playerLevel >= 85)  ) or
			((GetItemCount(Elementarist.CustomIDs["Alchemist's Flask Item"]) ~= 0)  and (Elementarist.playerLevel <= 91)  )
		) then
			name = Elementarist:hasBuff("player", Elementarist.SpellList["Greater Draenic Intellect Flask"]);
			if (name == nil) then
				name = Elementarist:hasBuff("player", Elementarist.SpellList["Draenic Intellect Flask"]);
			end
			if (name == nil) then
				name = Elementarist:hasBuff("player", Elementarist.SpellList["Flask of the Warm Sun"]);
			end
			if (name == nil) then
				name = Elementarist:hasBuff("player", Elementarist.SpellList["Flask of the Draconic Mind"]);
			end
			if (name == nil) then
				name,  _, _, _, _, _, expirationTime = Elementarist:hasBuff("player", Elementarist.SpellList["Whispers of Insanity"], false, Elementarist.CustomIDs["Whispers of Insanity Spell"]);
				name2, _, _, _, _, _, expirationTime2 = Elementarist:hasBuff("player", Elementarist.SpellList["Crystal of Insanity"], false, Elementarist.CustomIDs["Crystal of Insanity Spell"]);
				name3, _, _, _, _, _, expirationTime3 = Elementarist:hasBuff("player", Elementarist.SpellList["Alchemist's Flask"], false, Elementarist.CustomIDs["Alchemist's Flask Spell"]);

				if ((name == nil) and (name2 == nil) and (name3 == nil)) or (((name ~= nil) and (expirationTime<2)) or ((name2 ~= nil) and (expirationTime2<2)) or ((name3 ~= nil) and (expirationTime3<2))) then
					if (GetItemCount(Elementarist.CustomIDs["Whispers of Insanity Item"]) ~= 0) then
						local itemCooldown = Elementarist:GetItemCooldownRemaining(Elementarist.CustomIDs["Whispers of Insanity Item"]);
						if ((name == nil) or (expirationTime < 2)) and (itemCooldown < 1) then
							return nil,GetItemIcon(Elementarist.CustomIDs["Whispers of Insanity Item"])
						end
					elseif (GetItemCount(Elementarist.CustomIDs["Crystal of Insanity Item"]) ~= 0) then
						local itemCooldown = Elementarist:GetItemCooldownRemaining(Elementarist.CustomIDs["Crystal of Insanity Item"]);
						if ((name == nil) or (expirationTime < 2)) and (itemCooldown < 1) then
							return nil,GetItemIcon(Elementarist.CustomIDs["Crystal of Insanity Item"])
						end
					elseif (GetItemCount(Elementarist.CustomIDs["Alchemist's Flask Item"]) ~= 0) then
						local itemCooldown = Elementarist:GetItemCooldownRemaining(Elementarist.CustomIDs["Alchemist's Flask Item"]);
						if ((name == nil) or (expirationTime < 2)) and (itemCooldown < 1) then
							return nil,GetItemIcon(Elementarist.CustomIDs["Alchemist's Flask Item"])
						end
					end
				end
			end
		end

		-- Lightning Shield
		if Elementarist:SpellAvailable(Elementarist.SpellList["Lightning Shield"]) then
			name, _, _, _, _, _, expirationTime = Elementarist:hasBuff("player", Elementarist.SpellList["Lightning Shield"]);
			if (name == nil) or (expirationTime < 1) then
				return Elementarist.SpellList["Lightning Shield"]
			end
		end

		-- Fire Elemental Totem
		if Elementarist:SpellAvailable(Elementarist.SpellList["Fire Elemental Totem"]) then
			d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Fire Elemental Totem"])
			if d <= 0.5 then
				return Elementarist.SpellList["Fire Elemental Totem"]
			end
		end

		-- Storm Elemental Totem
		if (Elementarist.tier7Talent == 21199) then
			if Elementarist:SpellAvailable(Elementarist.SpellList["Storm Elemental Totem"]) then
				d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Storm Elemental Totem"])
				if d <= 0.5 then
					return Elementarist.SpellList["Storm Elemental Totem"]
				end
			end
		end

		-- Liquid Magma if not in rotation and Tier7 talent is Liquid Magma and fire totem has 10 sec or more
		if (Elementarist.tier7Talent == 21200) and (ElementaristDB.disableLM) then
			local haveFireTotem,fireTotemName,fireTotemStart,fireTotemDuration = GetTotemInfo(1);
			if (fireTotemName ~= "") and (fireTotemDuration and (fireTotemStart + fireTotemDuration - GetTime() ) >= 10) then
				d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Liquid Magma"])
				if (d<=0.5) then
					return Elementarist.SpellList["Liquid Magma"]
				end
			end
		end

		-- Healing Stream Totem
		if (ElementaristDB.showHealingStream) and (Elementarist:SpellAvailable(Elementarist.SpellList["Healing Stream Totem"])) then
			local haveWaterTotem,waterTotemName,_,_ = GetTotemInfo(3)
			if (waterTotemName == "") then
				e = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Healing Stream Totem"]);
				if (e < 1) then
					return Elementarist.SpellList["Healing Stream Totem"];
				end;
			end
		end

		-- Elemental Mastery
		if Elementarist:SpellAvailable(Elementarist.SpellList["Elemental Mastery"]) then
			d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Elemental Mastery"])
			if d <= 0.5 then
				return Elementarist.SpellList["Elemental Mastery"]
			end
		end

		-- Ascendance
		if Elementarist:SpellAvailable(Elementarist.SpellList["Ascendance"]) then
			name = Elementarist:hasBuff("player",Elementarist.SpellList["AscendanceElementalBuff"])
			if (name == nil) then
				d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Ascendance"])
				if d <= 0.5 then
					return Elementarist.SpellList["Ascendance"]
				end
			end
		end

		-- Berserking
		if Elementarist:SpellAvailable(Elementarist.SpellList["Berserking"]) then
			d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Berserking"])
			if d <= 0.5 then
				return Elementarist.SpellList["Berserking"]
			end
		end

		-- Blood Fury
		if Elementarist:SpellAvailable(Elementarist.SpellList["Blood Fury"]) then
			d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Blood Fury"])
			if d <= 0.5 then
				return Elementarist.SpellList["Blood Fury"]
			end
		end

		return ""
	end;
	IntSpell = function(self)
		-- interruptions, purge, and AoE on target
		local d
		local eclBuff, _, _, _, _, _, eclExp = Elementarist:hasBuff("player",Elementarist.SpellList["Enhanced Chain Lightning"])

		---- Earthquake with Enhanced chain lightning buff
		if Elementarist:SpellAvailable(Elementarist.SpellList["Earthquake"]) then
			if (eclBuff) then
				d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Earthquake"])
				if (d) and (d<0.5) then
					return Elementarist.SpellList["Earthquake"]
				end
			end
		end

		if Elementarist:SpellAvailable(Elementarist.SpellList["Wind Shear"]) then
			d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Wind Shear"])
			if ( (IsSpellInRange(Elementarist.SpellList["Wind Shear"], "target") == 1) and (d) and (d<0.5)  ) then
				local _, status, threatpct, _, _ = UnitDetailedThreatSituation("player", "target")


				--- windshear to drop threat
				if ( (status) and (threatpct>80) and (Elementarist.person["friendCount"]>1) and (Elementarist.inParty>0)) then
					return Elementarist.SpellList["Wind Shear"]
				end

				--- windshear to interupt channel spell
				_, _, _, _, _, _, _, notInterruptible = UnitChannelInfo("target")
				if (notInterruptible==false) then
					return Elementarist.SpellList["Wind Shear"]
				end

				--- windshear to interupt cast spell
				_, _, _, _, _, _, _, _, notInterruptible = UnitCastingInfo("target")
				if (notInterruptible==false)  then
					return Elementarist.SpellList["Wind Shear"]
				end
			end
		end



		if (Elementarist.person["foeCount"]>2) then
			----  Lava beam if available
			if Elementarist:SpellAvailable(Elementarist.SpellList["Lava Beam"]) then
				if IsSpellInRange(Elementarist.SpellList["Lava Beam"], "target") == 1 then
					d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Lava Beam"])
					return Elementarist.SpellList["Lava Beam"]
				end
			end

			---- Earth shock if Lightning Shield count >=17 and not on cd
			if Elementarist:SpellAvailable(Elementarist.SpellList["Earth Shock"]) then
				d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Earth Shock"])
				if (d) and (d<0.5) then
					local _, _, _, lscount = Elementarist:hasBuff("player",Elementarist.SpellList["Lightning Shield"])
					if (lscount) then
						lscount= lscount + (Elementarist:Count(Elementarist.SpellList["Lightning Bolt"],spellInCast,exspell1,exspell2));
						lscount= lscount + (Elementarist:Count(Elementarist.SpellList["Lava Burst"],spellInCast,exspell1,exspell2));
					else
						lscount=0;
					end
					if (lscount>=17) then
						return Elementarist.SpellList["Earth Shock"]
					end
				end
			end

			---- Chain Lightning as filler
			if Elementarist:SpellAvailable(Elementarist.SpellList["Chain Lightning"]) then
				return Elementarist.SpellList["Chain Lightning"]
			end
		end

		-- check if purgeable buff is on target (not sure if this is ok)
		if Elementarist:SpellAvailable(Elementarist.SpellList["Purge"]) then
			if IsSpellInRange(Elementarist.SpellList["Purge"], "target") == 1 then
				if (Elementarist:hasBuff("target", ".", 1)) then
					d = Elementarist:GetSpellCooldownRemaining(Elementarist.SpellList["Purge"])
					if (d) and (d<0.5) then
						return Elementarist.SpellList["Purge"]
					end
				end
			end
		end

		return ""
	end;
	ShieldName = function(self)
		return "Lightning Shield";
	end;

};