local _, Ns = ...

local SameLevel, BossLevel, Both = 1, 2, 3
local Regen, Casting = 1, 2

------------------------------
--		Global Updater		--
------------------------------

Ns.critSpellChance, Ns.hitSpell, Ns.hitSpellRating, Ns.regenBase, Ns.regenCasting, Ns.critSpellBase, Ns.regenBaseBasic, Ns.regenCastingBasic  = 0, 0, 0, 0, 0, 0, 0, 0
Ns.unitStat, Ns.masterDemonologist = 0, 0

function Ns.SpellUpdate()

 	Ns.targetLevel = Ns.playerLevel + 3
	if UnitCanAttack("player", "target") then
		Ns.targetLevel = UnitLevel("target")
		if Ns.targetLevel <= 0 then
			Ns.targetLevel = Ns.playerLevel + 3
		end
	end

	local _, stat, _, _ = UnitStat("player", 4)
	Ns.unitStat = stat

	Ns.masterDemonologist = 0

	local _, petStamina, _, _ = UnitStat("pet", 4)
	local _, petIntellect, _, _ = UnitStat("pet", 3)

	petStamina = petStamina + petIntellect

	Ns.masterDemonologist = Ns.masterDemo
	if petStamina <= 0 then
		Ns.masterDemonologist = 0
	end

	-- Critical
	Ns.critSpellChance = 0
	local holySchool = GetSpellCritChance(2) or 0
	local fireSchool = GetSpellCritChance(3) or 0
	local natureSchool = GetSpellCritChance(4) or 0
	local frostSchool = GetSpellCritChance(5) or 0
	local shadowSchool = GetSpellCritChance(6) or 0
	local arcaneSchool = GetSpellCritChance(7) or 0

	Ns.critSpellChance = max(holySchool, fireSchool, natureSchool, frostSchool, shadowSchool, arcaneSchool)

	-- Hit
	Ns.hitSpell = GetCombatRatingBonus(CR_HIT_SPELL)

	if Ns.hitSpell == nil then
		Ns.hitSpell = 0
	end

	Ns.hitSpell = Ns.hitSpell + Ns.hitMod + Ns.elePrecision + Ns.natGuidance + Ns.balancePower + Ns.totemWrath + Ns.inspiSpellHit + Ns.inspiringPresence

	-- Regen
	local notcasting = notcasting
	local tempRegen = 0
	Ns.regenBase, Ns.regenCasting = GetManaRegen()
	local tierBonus = 0
	local zgBonus = 0

	Ns.regenBase = Ns.regenBase * 2
	Ns.regenCasting = (Ns.regenCasting * 2)

	if Ns.regenBase == Ns.regenCasting then
		if notcasting then
			Ns.regenBase = notcasting
		end
	else
		notcasting = Ns.regenBase
	end

	if Ns.tierPieces >= 3 then
		tierBonus = 8
	end
	if Ns.zgPieces >= 2 then
		zgBonus = 1.6
	end

	tempRegen = ((stat * Ns.DreamState) * 0.4) + Ns.felEnergy + Ns.springTotem + (Ns.epiphany * 0.4) + Ns.aspectViper + Ns.secondWind + Ns.manaTide + tierBonus + zgBonus + Ns.warchief

	if Ns.innervate then
		Ns.regenCasting = Ns.regenBase
		Ns.regenBase = (Ns.regenBase * 4)
	end

	Ns.regenCasting = Ns.regenCasting + tempRegen + (stat * (Ns.unrStorm/100) * 0.4)
	Ns.regenBase = Ns.regenBase + (stat * (Ns.unrStorm/100) * 0.4) + Ns.springTotem + Ns.felEnergy + ((stat * Ns.DreamState) * 0.4) + Ns.evoc + (Ns.epiphany * 0.4) + Ns.aspectViper + Ns.secondWind + Ns.manaTide + Ns.tierPieces + zgBonus + Ns.warchief

end
-------------------------------------------------

-- Healing
function Ns.FunctionList.Healing(HUD, data, options, ...)

	local heal = GetSpellBonusHealing()
	local returnText

	Ns.unitStat = Ns.unitStat * Ns.natBlessing
	heal = (heal + (heal * Ns.spiritualHealing) + (heal * Ns.giftNature) + (heal * Ns.purification) + Ns.unitStat)

	returnText = ("%.0f"):format(heal)

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- Holy
function Ns.FunctionList.Holy(HUD, data, options, ...)

	local holy = GetSpellBonusDamage(2)
	local returnText

	holy = (holy + (holy * Ns.sancAura) + (holy * Ns.vengBuff) + (holy * Ns.avenWrath) + (holy * Ns.zoneBuff))
	holy = holy + (holy * Ns.misery) + Ns.judgeCrusader

	returnText = ("%.0f"):format(holy)

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- Nature
function Ns.FunctionList.Nature(HUD, data, options, ...)

	local spell = GetSpellBonusDamage(4)
	local returnText

	spell =  (spell + Ns.unitStat) + (spell * Ns.zoneBuff)
	spell = spell + (spell * Ns.misery) + (spell * Ns.stormStrike)

	returnText = ("%.0f"):format(spell)

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- Shadow
function Ns.FunctionList.Shadow(HUD, data, options, ...)

	local spell = GetSpellBonusDamage(6)
	local returnText

	spell = (spell + (spell * Ns.shadowMastery) + (spell * Ns.DarkNessTalent) + (spell * Ns.dsSuc) + (spell * Ns.zoneBuff))
	spell = (spell + (spell * Ns.shadowFormDmg))
	spell = spell + (spell * Ns.misery) + (spell * Ns.shadowVuln) + (spell * Ns.shadowDmg) + (spell * Ns.curseElements) + (spell * Ns.masterDemonologist)

	returnText = ("%.0f"):format(spell)

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- Fire
function Ns.FunctionList.Fire(HUD, data, options, ...)

	local spell = GetSpellBonusDamage(3)
	local returnText

	spell = (spell + (spell * Ns.firepowerMod) + (spell * Ns.aiMod) + (spell * Ns.zoneBuff) + (spell * Ns.emberstorm) + (spell * Ns.dsImp) + (spell * Ns.playFire) + Ns.unitStat)
	spell = spell + (spell * Ns.arcanePower)
	spell = spell + (spell * Ns.misery) + (spell * Ns.curseElements) + (spell * Ns.impSorch) + (spell * Ns.masterDemonologist)

	returnText = ("%.0f"):format(spell)

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- Frost
function Ns.FunctionList.Frost(HUD, data, options, ...)

	local spell = GetSpellBonusDamage(5)
	local returnText

	spell = (spell + (spell * Ns.pierceMod) + (spell * Ns.aiMod) + (spell * Ns.zoneBuff) + (spell * Ns.playFire) + (spell * Ns.impFbDmg) + (spell * Ns.arcticWind) + Ns.unitStat)
	spell = (spell + (spell * Ns.arcanePower))
	spell = spell + (spell * Ns.misery) + (spell * Ns.curseElements)

	returnText = ("%.0f"):format(spell)

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- Arcane
function Ns.FunctionList.Arcane(HUD, data, options, ...)

	local spell = GetSpellBonusDamage(7)
	local returnText

	spell = (spell + (spell * Ns.aiMod) + (spell * Ns.arcanePower) + (spell * Ns.playFire) + (spell * Ns.zoneBuff))
	spell = spell + (spell * Ns.misery) + (spell * Ns.curseElements)

	returnText = ("%.0f"):format(spell)

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- Critical
function Ns.FunctionList.SpellCrit(HUD, data, options, ...)

	local crit = 0
	local wintersChillEffect = ""
	local returnText

	crit = Ns.critSpellChance + Ns.combustionCount + Ns.arcaneMod + Ns.eleMastery + Ns.tidalMastery + Ns.devastation + Ns.arcanePotency + Ns.starlight + Ns.impFrostbolt

	if (Ns.wintersChill > 0) then
		if Ns.wintersChill ~= 0 then
			wintersChillEffect = "|cff3FC7EB +" .. Ns.wintersChill .. "|r"
		end
	end
	if Ns.crusader then
		crit = Ns.critSpellChance + Ns.crusaderTalent
	end
	returnText = ("%.2f"):format(crit) .. "%" .. Ns.callofThunder .. wintersChillEffect

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- Critical vs Boss
function Ns.FunctionList.SpellCritBoss(HUD, data, options, ...)

	local crit = 0
	local wintersChillEffect = ""
	local returnText

	crit = Ns.critSpellChance + Ns.combustionCount + Ns.arcaneMod + Ns.eleMastery + Ns.tidalMastery + Ns.devastation + Ns.arcanePotency + Ns.starlight + Ns.impFrostbolt
	if (Ns.wintersChill > 0) then
		if Ns.wintersChill ~= 0 then
			wintersChillEffect = "|cff3FC7EB +" .. Ns.wintersChill .. "|r"
		end
	end
	if Ns.crusader then
		crit = Ns.critSpellChance + Ns.crusaderTalent
	end

	local levelDifference = 0
	local critAura = 1.84

	levelDifference = Ns.targetLevel - Ns.playerLevel
	if levelDifference <= 0 then
		levelDifference = 0
		critAura = 0
	end
	crit = Ns.critSpellChance - levelDifference - critAura
	if crit < 0 then
		crit = 0
	end
	returnText = ("%.2f"):format(crit) .. "%" .. Ns.callofThunder .. wintersChillEffect

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- Haste
function Ns.FunctionList.HasteCaster(HUD, data, options, ...)

	local haste = GetCombatRatingBonus(CR_HASTE_SPELL)
	local returnText

	returnText = Ns.castHaste + ("%.1f"):format(haste) .. "%"

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- Hit
function Ns.FunctionList.SpellHit(HUD, data, options, ...)

	local returnText
	local hit =	Ns.hitSpell

	if hit == nil then
		hit = 0
	end

	returnText = ("%.2f"):format(hit) .. "%" .. Ns.Suppression .. Ns.arcaneFocus

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- Miss
function Ns.FunctionList.SpellMiss(HUD, data, options, ...)

	local EB = options.Level_Same_Boss
	local returnText
	local hit =	Ns.hitSpell

	local spellSameLevel = 3
	local spellBossLevel = 16
	spellSameLevel = (spellSameLevel - hit)
	spellBossLevel = (spellBossLevel - hit)
	if spellSameLevel < 0 then
		spellSameLevel = 0
	elseif spellSameLevel > 100 then
		spellSameLevel = 100
	end
	if spellBossLevel < 0 then
		spellBossLevel = 0
	elseif spellBossLevel > 100 then
		spellBossLevel = 100
	end

	if Ns.Band(EB, SameLevel) then returnText = ("%.1f"):format(spellSameLevel) .. "%" end
	if Ns.Band(EB, BossLevel) then returnText = ("%.1f"):format(spellBossLevel) .. "%" end
	if Ns.Band(EB, Both) then returnText = ("%.1f"):format(spellSameLevel) .. "%" .. " (" .. ("%.1f"):format(spellBossLevel) .. "%" end

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- MP2
function Ns.FunctionList.ManaRegen(HUD, data, options, ...)

	local EB = options.Regen_Normal_Casting
	local returnText

	if Ns.Band(EB, Regen) then returnText = ("%.1f"):format(Ns.regenBase) end
	if Ns.Band(EB, Casting) then returnText = ("%.1f"):format(Ns.regenCasting) end
	if Ns.Band(EB, Both) then returnText = ("%.1f"):format(Ns.regenBase) .. " (" .. ("%.1f"):format(Ns.regenCasting) .. ")" end

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- MP5
function Ns.FunctionList.MP5(HUD, data, options, ...)

	local EB = options.Regen_Normal_Casting
	local returnText
	local mp5, mpcast = 0, 0

	mp5 = format("%.1f", (Ns.regenBase / 2) * 5)
	mpcast = format("%.1f", (Ns.regenCasting / 2) * 5)

	if Ns.Band(EB, Regen) then returnText = mp5 end
	if Ns.Band(EB, Casting) then returnText = mpcast end
	if Ns.Band(EB, Both) then returnText = mp5 .. " (" .. mpcast .. ")" end

	HUD:UpdateText(data, returnText)
end
------------------------------------------------

-- Spell Penetration
function Ns.FunctionList.SpellPenetration(HUD, data, options, ...)

	local spellPenetration = GetSpellPenetration()
	local returnText

	returnText = ("%.0f"):format(spellPenetration)

	HUD:UpdateText(data, returnText)
end
------------------------------------------------
