if select(2, UnitClass("player")) ~= "PALADIN" then return end

local SpellName, _, SpellIcon = GetSpellInfo(86273) -- Озаряющее исцеление

local extraOptions = {
 {
  [0] = "Additional",
  { type = "Check", var = "colGradientTime", default = true, label = "Use Gradient Color for Time", tip = "", y = 12 },
  { type = "Check", var = "colGradient", default = true, label = "Use Gradient Color for Bar", tip = "", y = 8 },
  { type = "Color", var = "colNormal", default = { 0.4, 0.6, 0.8, 1.0 }, label = "Bar Color", y = 8 },
  { type = "Check", var = "colClassColor", default = true, label = "Use Class Color", tip = "", y = 12 },
  { type = "Check", var = "LastTarget", default = false, label = "Last Target", tip = "", y = 14 },
 },
}
local bcr, bcg, bcb = 0.4, 0.6, 0.8
local tcr, tcg, tcb = 0, 1, 0
local useGradient, useGradientTime, useLastTarget, useClassColor = true, true, false, true

local select = select
-- http://www.wowwiki.com/ColorGradient
local function ColorGradient(perc, ...)
 if perc >= 1 then
  local r, g, b = select(select('#', ...) - 2, ...)
  return r, g, b
 elseif perc <= 0 then
  local r, g, b = ...
  return r, g, b
 end
 local num = select('#', ...) / 3
 local segment, relperc = math.modf(perc*(num-1))
 local r1, g1, b1, r2, g2, b2 = select((segment*3)+1, ...)
 return r1 + (r2-r1)*relperc, g1 + (g2-g1)*relperc, b1 + (b2-b1)*relperc
end

local RAID_CLASS_COLORS = CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS
local sformat = string.format
local function ColorClass(unit)
 local c = RAID_CLASS_COLORS[select(2, UnitClass(unit)) or "PRIEST"]
 return sformat("|c%s%s|r", c.colorStr, UnitName(unit))
end

-- Plugin
local plugin = AzCastBar.CreateMainBar("Frame", "Absorb", extraOptions)

-- Init Bar
plugin.icon:SetTexture(SpellIcon)
plugin.name:SetText(SpellName)
plugin.name:SetJustifyV("CENTER")
plugin:SetPoint("CENTER", -50)
plugin.status:SetMinMaxValues(0, 15)
plugin.status:SetValue(0)
plugin.timeleft = 0
plugin.duration = 15
plugin.guid = nil
plugin.unit = nil
plugin.beacon = nil

-------------------------------------------------------------------------------
-- Code
-------------------------------------------------------------------------------
local function IsBeaconed(unit)
 local caster, spellid
 local index = 1
 while true do
  caster, _, _, spellid = select(8, UnitBuff(unit, index, "PLAYER"))
  if not spellid then
   break
  elseif spellid == 53563 and caster then
   return true
  end
  index = index + 1
 end
 return false
end

local function CheckBeacon(self)
 local i, unit, tempunit
 if IsInRaid() then
  for i = 1, GetNumGroupMembers() do
   tempunit = "raid"..i
   if IsBeaconed(tempunit) then
    unit = tempunit
    break
   end
  end
 else
  if IsInGroup() then
   for i = 1, GetNumSubgroupMembers() do
    tempunit = "party"..i
    if IsBeaconed(tempunit) then
     unit = tempunit
     break
    end
   end
  end
  if not unit and IsBeaconed("player") then
   unit = "player"
  end
 end
 self.beacon = unit and UnitGUID(unit) or nil
end

function plugin:OnConfigChanged(cfg)
 bcr, bcg, bcb = unpack(cfg.colNormal)
 tcr, tcg, tcb = unpack(cfg.colTimeLabel)
 useGradient = cfg.colGradient
 if not useGradient then
  self.status:SetStatusBarColor(bcr, bcg, bcb, 1)
 end
 useGradientTime = cfg.colGradientTime
 if not useGradientTime then
  self.time:SetTextColor(tcr, tcg, tcb, 1)
 end
 useLastTarget = cfg.LastTarget
 useClassColor = cfg.colClassColor
 if cfg.enabled then
  self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
  self:RegisterEvent("UNIT_AURA")
  self:RegisterEvent("GROUP_ROSTER_UPDATE")
  self:RegisterEvent("PLAYER_ENTERING_WORLD")
  CheckBeacon(self)
 else
  self:UnregisterAllEvents()
  self:Hide()
 end
end

plugin:SetScript("OnUpdate", function(self, elapsed)
 self.timeleft = self.timeleft - elapsed
 if self.timeleft > 0 then
  self.status:SetValue(self.timeleft)
  self.time:SetFormattedText("%d", ceil(self.timeleft))
  local percent = self.timeleft/self.duration
  local cr, cg, cb
  if useGradient then
   cr, cg, cb = ColorGradient(percent, 1, 0, 0, bcr, bcg, bcb)
   self.status:SetStatusBarColor(cr, cg, cb, 1)
  end
  if useGradientTime then
   cr, cg, cb = ColorGradient(percent, 1, 0, 0, tcr, tcg, tcb)
   self.time:SetTextColor(cr, cg, cb, 1)
  end
 else
  self:Hide()
 end
end)

----- Функция сокращения значений
local siValue = function(value)
 if value < 1e4 then return value -- 1e4 = 10000, 1e5 = 100000
 elseif value < 1e6 then return ('%.1fk'):format(value / 1e3):gsub('%.?0+([km])$', '%1')
 elseif value < 1e7 then return ('%.2fm'):format(value / 1e6):gsub('%.?0+([km])$', '%1')
 else return ('%.1fm'):format(value / 1e6):gsub('%.?0+([km])$', '%1')
 end
end

local function CheckAbsorb(self, dstGUID, unitid)
 local unit = unitid
 if dstGUID and not unit then
  local tempunit
  if IsInRaid() then
   for i = 1, GetNumGroupMembers() do
    tempunit = "raid"..i
    if dstGUID == UnitGUID(tempunit) then
     unit = tempunit
     break
    end
   end
  else
   if IsInGroup() then
    for i = 1, GetNumSubgroupMembers() do
     tempunit = "party"..i
     if dstGUID == UnitGUID(tempunit) then
      unit = tempunit
      break
     end
    end
   end
   if not unit and dstGUID == UnitGUID("player") then
    unit = "player"
   end
  end
 end
 if unit then
  local duration, timeleft, caster, spellid, absorb
  local index = 1
  while true do
   duration, timeleft, caster, _, _, spellid, _, _, absorb = select(6, UnitBuff(unit, index, "PLAYER"))
   if not spellid then
    break
   elseif spellid == 86273 and caster then
    if self.duration ~= duration then
     self.status:SetMinMaxValues(0, duration)
     self.duration = duration
    end
    self.timeleft = timeleft - GetTime()
    self.name:SetFormattedText("%s (%s)", siValue(absorb), useClassColor and ColorClass(unit) or UnitName(unit))
    return unit
   end
   index = index + 1
  end
 end
 return nil
end

local RaidFilter = COMBATLOG_OBJECT_AFFILIATION_RAID + COMBATLOG_OBJECT_AFFILIATION_PARTY + COMBATLOG_OBJECT_AFFILIATION_MINE
local band = bit.band

plugin:SetScript("OnEvent", function(self, event, unit, ...)
 if event == "COMBAT_LOG_EVENT_UNFILTERED" then
  local eventType, _, srcGUID, _, _, _, dstGUID, _, dstFlags, _, spellID = ...
  if band(dstFlags, RaidFilter) ~= 0 and srcGUID == UnitGUID("player") then
   if eventType == "SPELL_AURA_APPLIED" or eventType == "SPELL_AURA_REFRESH" then
    if spellID == 86273 and (useLastTarget or dstGUID == self.beacon) then
     local unit = CheckAbsorb(self, dstGUID, nil)
     if unit then
      self.guid = dstGUID
      self.unit = unit
      if not self:IsShown() then
       self:Show()
      end
     end
    elseif spellID == 53563 then
     self.beacon = dstGUID
    end
   elseif eventType == "SPELL_AURA_REMOVED" then
    if spellID == 86273 and (useLastTarget or dstGUID == self.beacon) and dstGUID == self.guid then
     self.timeleft = 0
     self.guid = nil
     self.unit = nil
    elseif spellID == 53563 and dstGUID == self.beacon then
     self.beacon = nil
    end
   end
  end
 elseif event == "UNIT_AURA" and unit == self.unit then
  CheckAbsorb(self, self.guid, unit)
 elseif (event == "GROUP_ROSTER_UPDATE" and self.beacon) or event == "PLAYER_ENTERING_WORLD" then
  CheckBeacon(self)
 end
end)
