local AddName, Ns = ...
local L = Ns.L

------------------------------
--		Options Equates		--
------------------------------
local Both, Enhanced, Basic, Damage, DamageTaken, Percentage, Rating, MainHand, OffHand, World, Realm, Modifiers, Base = 3, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2
local SameLevel, BossLevel, Regen, Casting, Critical, CritDamage, Total, Max, Average, Auto, Chance, Reduction, Complete = 1, 2, 1, 2, 1, 2, 1, 1, 2, 3, 1, 2, 1

----------------------------------
--		Text Return Formats		--
----------------------------------
local Double_Rating_Format = { "%.1f", "%.0f", "%.1f (%.0f)", }

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

Ns.armorValue, Ns.armorDebuff, Ns.Resilvalue, Ns.ohID = 0, 0, 0, 0
Ns.dodgeChance, Ns.parryChance, Ns.blockChance, Ns.avoid, Ns.defAdjust, Ns.avoidBase = 0, 0, 0, 0, 0, 0
Ns.bossMiss = 0.956
if (Ns.classFilename == "DRUID") then Ns.bossMiss = 0.972 end

function Ns.DefenseUpdate()

 	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

	-- Armor
	local _, effectiveArmor, _, _, negBuff = UnitArmor("player")
	Ns.armorValue = effectiveArmor
	Ns.armorDebuff = negBuff

	-- Resilience
	Ns.Resilvalue = GetCombatRatingBonus(15)

	-- Block, Parry, Dodge
	Ns.blockChance = GetBlockChance()
	Ns.parryChance = GetParryChance()
	Ns.dodgeChance = GetDodgeChance()

	-- Avoidance / Crushing
	local ohID = GetInventoryItemID("player", 17)
	local classId, subId = 0, 0

	local miss = 5
	local parryBonus = GetCombatRatingBonus(CR_PARRY)

	if ohID == nil then  Ns.blockChance = 0 end

		Ns.avoid = (miss + Ns.dodgeChance + Ns.parryChance + Ns.blockChance + parryBonus) + Ns.quickness
		Ns.avoidBase = (miss + Ns.dodgeChance + Ns.parryChance + Ns.blockChance + parryBonus)
end
------------------------------------------------

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

	local EB = options.Enhanced_Base
	local returnText, decimals
	local debuffColor, endColor = "", ""

	if options.Dec_Def_Armor == 0 then decimals = "%.0f"
	elseif options.Dec_Def_Armor == 1 then decimals = "%.1f"
	elseif options.Dec_Def_Armor == 2 then decimals = "%.2f"
	else decimals = "%.3f" end

	if Ns.armorDebuff < 0 then debuffColor = Ns.redText end
	if Ns.armorValue > options.Cap_Def_Armor then debuffColor = Ns.greenText end
	if debuffColor ~= "" then endColor = "|r" end

	if Ns.Band(EB, Enhanced) then returnText = debuffColor .. (decimals):format(Ns.armorValue) end
	if Ns.Band(EB, Basic) then returnText = (decimals):format(Ns.armorValue) end
	if Ns.Band(EB, Both) then returnText = debuffColor .. (decimals):format(Ns.armorValue) .. endColor .. "/" .. Ns.armorValue end

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

-- Effective HP
function Ns.FunctionList.EHP(HUD, data, options, ...)

	local maxHP = UnitHealthMax("player")
    local ehp = maxHP / (1 - (Ns.armorReduction))

	HUD:UpdateText(data, ("%.0f"):format(ehp))
end
------------------------------------------------

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

	local npcMiss = 0
	local decimals
	local baseMiss = 5 - (UnitLevel("player") * 5 - 400) * 0.04

	if Ns.gearDefense > 0 then npcMiss = baseMiss + 1 / (0.0625 + Ns.bossMiss / (Ns.gearDefense * 0.04))
	else npcMiss = baseMiss end

	if options.Dec_Def_Miss == 0 then decimals = "%.0f%%"
	elseif options.Dec_Def_Miss == 1 then decimals = "%.1f%%"
	elseif options.Dec_Def_Miss == 2 then decimals = "%.2f%%"
	else decimals = "%.3f%%" end

	npcMiss = npcMiss * 100 / 100
	npcMiss = (decimals):format(npcMiss)

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

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

	--local EB = options.Crit_Damage_Taken
	local returnText, decimals, dualdec

	local Resilience = GetCombatRatingBonus(15)
	local resiDamage = GetCombatRatingBonus(16)
	resiDamage = resiDamage + Resilience

	if options.Dec_Def_Res == 0 then decimals = "%.0f%%" ; dualdec = "%.0f"
	elseif options.Dec_Def_Res == 1 then decimals = "%.1f%%" ; dualdec = "%.1f"
	elseif options.Dec_Def_Res == 2 then decimals = "%.2f%%" ; dualdec = "%.2f"
	else decimals = "%.3f%%"; dualdec = "%.3f" end

	resiDamage = (decimals):format(resiDamage)

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

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

	local EB = options.Total_Modifiers
	local returnText, decimals
	local debuffColor = ""
	Ns.armorReduction = (Ns.armorValue/((88 * 2167.5) + Ns.armorValue - 158167.5))
	local defStance, battleStance = 0, 0

	local modifiers, bonus = 0, 0

	if Ns.targetLevel < 80 then Ns.armorReduction = (Ns.armorValue/(Ns.armorValue+400+85*((5.5 * Ns.targetLevel)-265.5))) * 100
	elseif Ns.targetLevel == 80 then Ns.armorReduction = Ns.armorValue/(Ns.armorValue + 15232.5) * 100 end

	local mitBase = Ns.armorReduction

	if GetShapeshiftForm() == 2 and (Ns.classFilename == "WARRIOR") then defStance = 10
	elseif GetShapeshiftForm() == 1 and (Ns.classFilename == "WARRIOR") then battleStance = 5 end

	-- modifiers = (Ns.armorReduction - (Ns.armorReduction * (Ns.divineProt/100)) - (Ns.armorReduction * (Ns.stoneForm/100)) - (Ns.armorReduction * (Ns.rockBiter/100)) -
	-- 			(Ns.armorReduction * (Ns.BladeBarrier/100)) -
	-- 			(Ns.armorReduction * (Ns.inspiration/100)) - (Ns.armorReduction * (defStance/100)) - (Ns.armorReduction * (Ns.safeGuard/100)) -
	-- 			(Ns.armorReduction * (Ns.painSuppress/100)) - (Ns.armorReduction * (Ns.PrismaticCloak/100)) - (Ns.armorReduction * (Ns.bloodPresence/100)) -
	-- 			(Ns.armorReduction * (Ns.armyDead/100)) - (Ns.armorReduction * (Ns.iceFortitude/100)) - (Ns.armorReduction * (Ns.scarletFever/100)) -
	-- 			(Ns.armorReduction * (Ns.naturalReaction/100)) - (Ns.armorReduction * (Ns.focusWill/100)) -
	-- 			(Ns.armorReduction * (Ns.powerBarrier/100)) - (Ns.armorReduction * (Ns.shadowForm/100)) - (Ns.armorReduction * (Ns.dispDmg/100)) -
	-- 			(Ns.armorReduction * (Ns.DeadNerves/100)) - (Ns.armorReduction * (Ns.curseWeak/100)) - (Ns.armorReduction * (Ns.sancDmg/100)) -
	-- 			(Ns.armorReduction * (Ns.vindication/100)) - (Ns.armorReduction * (Ns.ardentDef/100)) - (Ns.armorReduction * (Ns.ancientKings/100)) -
	-- 			(Ns.armorReduction * (Ns.masteryDmg/100)) - (Ns.armorReduction * (Ns.shamRage/100)) - (Ns.armorReduction * (Ns.ancResolve/100)) -
	-- 			(Ns.armorReduction * (Ns.ancFort/100)) - (Ns.armorReduction * (Ns.shieldWall/100)) - (Ns.armorReduction * (battleStance/100)) +
	-- 			(Ns.armorReduction * (Ns.deathWish/100)) + (Ns.armorReduction * (Ns.reckless/100)) - (Ns.armorReduction * (Ns.moonDmg/100)) -
	-- 			(Ns.armorReduction * (Ns.survInstinct/100)) - (Ns.armorReduction * (Ns.barkskin/100)) - (Ns.armorReduction * (Ns.boneShield/100)) -
	-- 			(Ns.armorReduction * (Ns.willNecro/100)))

	-- Ns.armorReduction = modifiers + Ns.divineProt +
	-- 				Ns.BladeBarrier + Ns.inspiration + battleStance +
	-- 				Ns.PrismaticCloak + Ns.bloodPresence + Ns.armyDead + Ns.painSuppress + Ns.shieldWall +
	-- 				Ns.iceFortitude + Ns.scarletFever + Ns.boneShield + Ns.willNecro +
	-- 				Ns.focusWill + Ns.powerBarrier + Ns.shadowForm + Ns.dispDmg + Ns.DeadNerves + Ns.curseWeak +
	-- 				Ns.sancDmg + Ns.vindication + Ns.ardentDef + Ns.ancientKings + Ns.stoneForm + Ns.rockBiter +
	-- 				Ns.masteryDmg + Ns.shamRage + Ns.ancResolve + Ns.ancFort + defStance + Ns.safeGuard -
	-- 				Ns.deathWish - Ns.reckless + Ns.moonDmg + Ns.naturalReaction + Ns.survInstinct + Ns.barkskin

	Ns.armorReduction = 1-(1-Ns.armorReduction) * (1-(Ns.divineProt/100)) * (1-(Ns.stoneForm/100)) * (1-(Ns.rockBiter/100)) * (1-(Ns.BladeBarrier/100))
						* (1-(Ns.inspiration/100)) * (1-(defStance/100)) * (1-(Ns.safeGuard/100)) * (1-(Ns.sancDmg/100)) * (1-(Ns.boneShield/100))
						* (1-(Ns.painSuppress/100)) * (1-(Ns.PrismaticCloak/100)) * (1-(Ns.bloodPresence/100)) * (1-(Ns.armyDead/100)) * (1-(Ns.iceFortitude/100))
						* (1-(Ns.scarletFever/100)) * (1-(Ns.naturalReaction/100)) * (1-(Ns.focusWill/100)) * (1-(Ns.powerBarrier/100)) * (1-(Ns.shadowForm/100))
						* (1-(Ns.dispDmg/100)) * (1-(Ns.DeadNerves/100)) * (1-(Ns.curseWeak/100)) * (1-(Ns.barkskin/100)) * (1-(Ns.vindication/100))
						* (1-(Ns.ardentDef/100)) * (1-(Ns.ancientKings/100)) * (1-(Ns.masteryDmg/100)) * (1-(Ns.shamRage/100)) * (1-(Ns.ancResolve/100))
						* (1-(Ns.ancFort/100)) * (1-(Ns.shieldWall/100)) * (1-(battleStance/100)) * (1-(Ns.moonDmg/100)) * (1-(Ns.survInstinct/100))
						* (1-(Ns.willNecro/100))

	Ns.fullDR = Ns.armorReduction * 100

	bonus = Ns.divineProt + Ns.BladeBarrier + Ns.inspiration + battleStance +
	Ns.PrismaticCloak + Ns.bloodPresence + Ns.armyDead + Ns.painSuppress + Ns.shieldWall + Ns.iceFortitude +
	Ns.focusWill + Ns.powerBarrier + Ns.shadowForm + Ns.dispDmg + Ns.scarletFever +
	Ns.DeadNerves + Ns.curseWeak + Ns.sancDmg + Ns.vindication + Ns.ardentDef + Ns.ancientKings + Ns.stoneForm +
	Ns.rockBiter + Ns.masteryDmg + Ns.shamRage + Ns.ancResolve + Ns.ancFort + defStance + Ns.safeGuard -
	Ns.deathWish - Ns.reckless + Ns.moonDmg + Ns.naturalReaction + Ns.survInstinct + Ns.barkskin + Ns.boneShield +
	Ns.willNecro

	if Ns.armorDebuff < 0 then debuffColor = Ns.redText end

	if Ns.armorReduction >= options.Cap_Def_Mit then debuffColor = Ns.greenText
	elseif Ns.armorReduction < 0 then Ns.armorReduction = 0; debuffColor = Ns.redText end

	if options.Dec_Def_Mit == 0 then decimals = "%.0f%%"
	elseif options.Dec_Def_Mit == 1 then decimals = "%.1f%%"
	elseif options.Dec_Def_Mit == 2 then decimals = "%.2f%%"
	else decimals = "%.3f%%" end

	if Ns.Band(EB, Complete) then returnText = debuffColor ..  (decimals):format(Ns.fullDR) end
	if Ns.Band(EB, Basic) then returnText = (decimals):format(mitBase) end
	if Ns.Band(EB, Modifiers) then returnText = (decimals):format(bonus) end

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

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

	local hitReduction = Ns.quickness + Ns.Resilvalue
	local decimals

	if options.Dec_Def_Hit == 0 then decimals = "%.0f%%"
	elseif options.Dec_Def_Hit == 1 then decimals = "%.1f%%"
	elseif options.Dec_Def_Hit == 2 then decimals = "%.2f%%"
	else decimals = "%.3f%%" end

	HUD:UpdateText(data, (decimals):format(hitReduction))
end
------------------------------------------------

-- Crit Immunity
function Ns.FunctionList.CritReceived(HUD, data, options, ...)

	local EB = options.Chance_Reduction
	local chanceGetCrit = 19
	local getCritLevel = (Ns.targetLevel - Ns.playerLevel) * 0.2
	local uncritCap = 5
	local critTakenCap = 5.6
	local debuffColor = ""
	local returnText, decimals, liveImmunity
	local warStance = 0
	if GetShapeshiftForm() == 2 and (Ns.classFilename == "WARRIOR") then warStance = Ns.BastionDefense end

	chanceGetCrit = (uncritCap + getCritLevel) - Ns.Resilvalue - Ns.moltenArmor - Ns.metaCrit - Ns.sancCrit -
					warStance - Ns.ThickHide - Ns.barkCrit - Ns.impBlood

	if chanceGetCrit < 0 then chanceGetCrit = 0; debuffColor = Ns.greenText
	elseif chanceGetCrit <= 1.5 then debuffColor = Ns.orangeText
	else debuffColor = Ns.redText end

	critTakenCap = Ns.Resilvalue + Ns.moltenArmor + Ns.metaCrit + Ns.sancCrit + warStance + Ns.ThickHide + Ns.barkCrit + Ns.impBlood

	if options.Dec_Def_Crit == 0 then decimals = "%.0f%%"
	elseif options.Dec_Def_Crit == 1 then decimals = "%.1f%%"
	elseif options.Dec_Def_Crit == 2 then decimals = "%.2f%%"
	else decimals = "%.3f%%" end

	if options.Display_Simulate then liveImmunity = " > " .. (decimals):format(Ns.critReceived)
	else liveImmunity = "" end

	if Ns.Band(EB, Chance) then returnText = debuffColor .. (decimals):format(chanceGetCrit) .. "|r" .. liveImmunity end
	if Ns.Band(EB, Reduction) then returnText = (decimals):format(critTakenCap) .. liveImmunity end
	if Ns.Band(EB, Both) then returnText = debuffColor .. (decimals):format(chanceGetCrit) .. " |r(" .. (decimals):format(critTakenCap) .. ")" .. liveImmunity end

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

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

	local EB = options.Percent_Rating
	local dodgeRating =	GetCombatRating(CR_DODGE)
	local returnText, decimals, liveDodge

	if options.Dec_Def_Dodge == 0 then decimals = "%.0f%%"
	elseif options.Dec_Def_Dodge == 1 then decimals = "%.1f%%"
	elseif options.Dec_Def_Dodge == 2 then decimals = "%.2f%%"
	else decimals = "%.3f%%" end

	if options.Display_Simulate then liveDodge = " > " .. (decimals):format(Ns.totalDodge)
	else liveDodge = "" end

	if Ns.Band(EB, Percentage) then returnText = (decimals):format(Ns.dodgeChance) .. liveDodge end
	if Ns.Band(EB, Rating) then returnText = dodgeRating .. liveDodge end
	if Ns.Band(EB, Both) then returnText = (decimals):format(Ns.dodgeChance) .. " (" .. dodgeRating .. ")" .. liveDodge end

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

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

	local EB = options.Percent_Rating
	local parryBonus = GetCombatRatingBonus(CR_PARRY)
	local parry = GetParryChance() + parryBonus
	local parryRating =	GetCombatRating(CR_PARRY)
	local returnText, decimals, liveParry

	if options.Dec_Def_Parry == 0 then decimals = "%.0f%%"
	elseif options.Dec_Def_Parry == 1 then decimals = "%.1f%%"
	elseif options.Dec_Def_Parry == 2 then decimals = "%.2f%%"
	else decimals = "%.3f%%" end

	if options.Display_Simulate then liveParry = " > " .. (decimals):format(Ns.totalParry)
	else liveParry = "" end

	if Ns.Band(EB, Percentage) then returnText = (decimals):format(parry) .. liveParry end
	if Ns.Band(EB, Rating) then returnText = parryRating .. liveParry end
	if Ns.Band(EB, Both) then returnText = (decimals):format(parry) .. " (" .. parryRating .. ")" .. liveParry end

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

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

	local EB = options.Percent_Rating
	local block = GetBlockChance()
	local blockRating =	GetCombatRating(CR_BLOCK)
	local blockDamage = GetShieldBlock()
	local returnText, decimals, liveBlock

	if options.Dec_Def_Block == 0 then decimals = "%.0f%%"
	elseif options.Dec_Def_Block == 1 then decimals = "%.1f%%"
	elseif options.Dec_Def_Block == 2 then decimals = "%.2f%%"
	else decimals = "%.3f%%" end

	if options.Block_Damage then block = blockDamage end

	if options.Display_Simulate then liveBlock = " > " .. (decimals):format(Ns.totalBlock)
	else liveBlock = "" end

	if Ns.Band(EB, Percentage) then returnText = (decimals):format(block) .. liveBlock end
	if Ns.Band(EB, Rating) then returnText = blockRating .. liveBlock end
	if Ns.Band(EB, Both) then returnText = (decimals):format(block) .. " (" .. blockRating .. ")" .. liveBlock end

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

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

	local EB = options.Enhanced_Base
	local returnText, decimals
	local avoidColor, endColor = "", ""

	if Ns.avoid >= options.Cap_Def_Avo then avoidColor = Ns.greenText end
	if avoidColor ~= "" then endColor = "|r" end

	if options.Add_Block then
		Ns.avoid = Ns.avoid - Ns.blockChance
		Ns.avoidBase = Ns.avoidBase - Ns.blockChance
	end

	if options.Dec_Def_Avoidance == 0 then decimals = "%.0f%%"
	elseif options.Dec_Def_Avoidance == 1 then decimals = "%.1f%%"
	elseif options.Dec_Def_Avoidance == 2 then decimals = "%.2f%%"
	else decimals = "%.3f%%" end

	if Ns.Band(EB, Enhanced) then returnText = avoidColor .. (decimals):format(Ns.avoid) end
	if Ns.Band(EB, Basic) then returnText = avoidColor .. (decimals):format(Ns.avoidBase) end
	if Ns.Band(EB, Both) then returnText = avoidColor .. (decimals):format(Ns.avoid) .. endColor .. " (" .. avoidColor .. (decimals):format(Ns.avoidBase) .. ")" end

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

