if not oUF then return end

local playerClass = select(2,UnitClass("player"))
local CanDispel = {
  PRIEST = { Magic = true, Disease = true, },
  SHAMAN = { Poison = true, Disease = true, },
  PALADIN = { Magic = true, Poison = true, Disease = true, },
  MAGE = { Curse = true, },
  DRUID = { Curse = true, Poison = true, }
}
local dispellist = CanDispel[playerClass] or {}
local origColors = {}
local origBorderColors = {}
local origPostUpdateAura = {}

local function GetDebuffType(unit, filter)
  if not UnitCanAssist("player", unit) then return nil end
  local i = 1
  while true do
    local _, _, texture, _, debufftype = UnitDebuff(unit, i)
    if not texture then break end
    if texture and not filter or (filter and dispellist[debufftype]) then
      return debufftype, texture
    end
    i = i + 1
  end
end

local function PostUpdateAura(object, event, unit)
  local debuffType, texture  = GetDebuffType(unit, object.DebuffHighlightFilter)
  if texture then
    local color
    if debuffType then
      color = DebuffTypeColor[debuffType]
    else
      color = { r = 0, g = 1, b = 1, a = 1 }
    end
    if object.DebuffHighlightBackdrop then
      object:SetBackdropColor(color.r, color.g, color.b, object.DebuffHighlightAlpha or 1)
    elseif object.DebuffHighlightUseTexture then
      object.DebuffHighlight:SetTexture(texture)
    else
      object.DebuffHighlight:SetVertexColor(color.r, color.g, color.b, object.DebuffHighlightAlpha or .5)
    end
  else
    if object.DebuffHighlightBackdrop then
      local color = origColors[object]
      object:SetBackdropColor(color.r, color.g, color.b, color.a)
      color = origBorderColors[object]
      object:SetBackdropBorderColor(color.r, color.g, color.b, color.a)
    elseif object.DebuffHighlightUseTexture then
      object.DebuffHighlight:SetTexture(nil)
    else
      local color = origColors[object]
      object.DebuffHighlight:SetVertexColor(color.r, color.g, color.b, color.a)
    end
  end
end

local function HookedPostUpdateAura(object, event, unit)
  origPostUpdateAura[object](object, event, unit)
  PostUpdateAura(object, event, unit)
end

local function addHighlight(object)
  -- if we're not highlighting this unit return
  if not object.DebuffHighlightBackdrop and not object.DebuffHighlight then
    return
  end
  -- if we're filtering highlights and we're not of the dispelling type, return
  if object.DebuffHighlightFilter and not CanDispel[playerClass] then
    return
  end
  
  -- make sure aura scanning is active for this object
  object:RegisterEvent("UNIT_AURA")
  
  if object.DebuffHighlightBackdrop then
    local r, g, b, a = object:GetBackdropColor()
    origColors[object] = { r = r, g = g, b = b, a = a}
    r, g, b, a = object:GetBackdropBorderColor()
    origBorderColors[object] = { r = r, g = g, b = b, a = a}
  elseif not object.DebuffHighlightUseTexture then -- color debuffs
    -- object.DebuffHighlight
    local r, g, b, a = object.DebuffHighlight:GetVertexColor()
    origColors[object] = { r = r, g = g, b = b, a = a}
  end
  
  -- there's already a PostUpdateAura active, hook it
  if object.PostUpdateAura then
    origPostUpdateAura[object] = object.PostUpdateAura
    object.PostUpdateAura = HookedPostUpdateAura
  else
    object.PostUpdateAura = PostUpdateAura
  end
end

for k, object in ipairs(oUF.objects) do addHighlight(object) end
oUF:RegisterInitCallback(addHighlight)
