--- ============================ HEADER ============================
-- HeroLib
local HL      = HeroLib
local Cache   = HeroCache
local Unit    = HL.Unit
local Player  = Unit.Player
local Pet     = Unit.Pet
local Target  = Unit.Target
local Spell   = HL.Spell
local Item    = HL.Item
-- HeroRotation
local HR      = HeroRotation
local num     = HR.Commons.Everyone.num
-- Spells
local SpellShadow  = Spell.Priest.Shadow
-- Lua
-- WoW API
local UnitPower         = UnitPower
local InsanityPowerType = Enum.PowerType.Insanity

--- ============================ CONTENT ============================
-- Shadow, ID: 258
HL.AddCoreOverride ("Player.Insanity",
  function ()
    local Insanity = UnitPower("Player", InsanityPowerType)
    if not Player:IsCasting() then
      return Insanity
    else
      if Player:IsCasting(SpellShadow.MindBlast) then
        return Insanity + 6
      elseif Player:IsCasting(SpellShadow.VampiricTouch) then
        return Insanity + 4
      elseif Player:IsCasting(SpellShadow.MindSpike) or Player:IsCasting(SpellShadow.MindSpikeInsanity) then
        return Insanity + 6
      elseif Player:IsCasting(SpellShadow.MindFlay) then
        return Insanity + (18 / SpellShadow.MindFlay:BaseDuration()) * Player:CastRemains()
      elseif Player:IsCasting(SpellShadow.MindFlayInsanity) then
        return Insanity + (8 / SpellShadow.MindFlayInsanity:BaseDuration()) * Player:CastRemains()
      elseif Player:IsCasting(SpellShadow.DarkAscension) then
        return Insanity + 30
      elseif Player:IsCasting(SpellShadow.VoidTorrent) then
        return Insanity + (24 / SpellShadow.VoidTorrent:BaseDuration()) * Player:CastRemains()
      else
        return Insanity
      end
    end 
  end
, 258)

local OldShadowIsReady
OldShadowIsReady = HL.AddCoreOverride("Spell.IsReady",
  function (self, BypassRecovery, Range, AoESpell, ThisUnit, Offset)
    local BaseCheck = OldShadowIsReady(self, BypassRecovery, Range, AoESpell, ThisUnit, Offset)
    if self == SpellShadow.MindSpikeInsanity then
      return BaseCheck and (Player:BuffStack(SpellShadow.MindSpikeInsanityBuff) - num(Player:IsCasting(SpellShadow.MindSpikeInsanity)) > 0)
    elseif self == SpellShadow.Halo then
      return BaseCheck and not Player:IsCasting(self)
    elseif self == SpellShadow.VoidBlastAbility then
      return BaseCheck and not Player:IsCasting(self)
    else
      return BaseCheck
    end
  end
, 258)

local OldShadowIsCastable
OldShadowIsCastable = HL.AddCoreOverride("Spell.IsCastable",
  function (self, BypassRecovery, Range, AoESpell, ThisUnit, Offset)
    local BaseCheck = OldShadowIsCastable(self, BypassRecovery, Range, AoESpell, ThisUnit, Offset)
    if self == SpellShadow.VampiricTouch then
      return BaseCheck and not SpellShadow.ShadowCrash:InFlight() and not SpellShadow.ShadowCrashTarget:InFlight() and (Player:BuffUp(SpellShadow.UnfurlingDarknessBuff) or not Player:IsCasting(self))
    elseif self == SpellShadow.MindBlast then
      return BaseCheck and not (self:Charges() == 1 and Player:IsCasting(self))
    elseif self == SpellShadow.VoidEruption or self == SpellShadow.DarkAscension then
      return BaseCheck and not Player:IsCasting(self)
    elseif self == SpellShadow.VoidBolt then
      return BaseCheck or Player:IsCasting(SpellShadow.VoidEruption)
    elseif self == SpellShadow.ShadowCrash or self == SpellShadow.ShadowCrashTarget then
      return BaseCheck and not self:InFlight()
    else
      return BaseCheck
    end
  end
, 258)

local OldShadowBuffUp
OldShadowBuffUp = HL.AddCoreOverride("Player.BuffUp",
  function (self, Spell, AnyCaster, Offset)
    local BaseCheck = OldShadowBuffUp(self, Spell, AnyCaster, Offset)
    if Spell == SpellShadow.VoidformBuff then
      return BaseCheck or Player:IsCasting(SpellShadow.VoidEruption)
    elseif Spell == SpellShadow.DarkAscensionBuff then
      return BaseCheck or Player:IsCasting(SpellShadow.DarkAscension)
    else
      return BaseCheck
    end
  end
, 258)

local OldShadowInFlight
OldShadowInFlight = HL.AddCoreOverride("Spell.InFlight",
  function(self)
    if self == SpellShadow.ShadowCrash or self == SpellShadow.ShadowCrashTarget then
      return self:TimeSinceLastCast() < 1.5
    else
      return OldShadowInFlight(self)
    end
  end
, 258)
