Quantcast
--[[
##############################################################################
_____/\\\\\\\\\\\____/\\\________/\\\__/\\\________/\\\__/\\\\\\\\\\\_       #
 ___/\\\/////////\\\_\/\\\_______\/\\\_\/\\\_______\/\\\_\/////\\\///__      #
  __\//\\\______\///__\//\\\______/\\\__\/\\\_______\/\\\_____\/\\\_____     #
   ___\////\\\__________\//\\\____/\\\___\/\\\_______\/\\\_____\/\\\_____    #
    ______\////\\\________\//\\\__/\\\____\/\\\_______\/\\\_____\/\\\_____   #
     _________\////\\\______\//\\\/\\\_____\/\\\_______\/\\\_____\/\\\_____  #
      __/\\\______\//\\\______\//\\\\\______\//\\\______/\\\______\/\\\_____ #
       _\///\\\\\\\\\\\/________\//\\\________\///\\\\\\\\\/____/\\\\\\\\\\\_#
        ___\///////////___________\///___________\/////////_____\///////////_#
##############################################################################
S U P E R - V I L L A I N - U I   By: Munglunch                              #
##############################################################################
--]]
local SuperVillain, L = unpack(select(2, ...));
local MOD = SuperVillain.Registry:Expose('SVUnit');
local _, ns = ...
local oUF_SuperVillain = ns.oUF
--[[ MUNGLUNCH's FASTER ASSERT FUNCTION ]]--
local assert = enforce;
assert(oUF_SuperVillain, "SVUI was unable to locate oUF.")
local ceil,tinsert = math.ceil,table.insert

local VisibilityUpdate = function(self, event)
    local db = MOD.db[self.___key]
    if (not db or (db and not db.enable) or (MOD.db and not MOD.db.smartRaidFilter) or self.isForced) then return end
    local instance, group = IsInInstance()
    local _, _, _, _, info, _, _ = GetInstanceInfo()
    if event == "PLAYER_REGEN_ENABLED"then
        self:UnregisterEvent("PLAYER_REGEN_ENABLED")
    end
    if not InCombatLockdown()then
        if(instance and (group == "raid") and (info == i)) then
            UnregisterStateDriver(self, "visibility")
            self:Show()
        elseif(instance and (group == "raid")) then
            UnregisterStateDriver(self, "visibility")
            self:Hide()
        elseif db.visibility then
            RegisterStateDriver(self, "visibility", db.visibility)
        end
    else
        self:RegisterEvent("PLAYER_REGEN_ENABLED")
        return
    end
end

local RaidPetVisibility = function(self, event)
    local db = MOD.db["raidpet"]
    if (not db or (db and not db.enable) or (MOD.db and not MOD.db.smartRaidFilter) or self.isForced) then return end
    local inInstance, instanceType = IsInInstance()
    if event == "PLAYER_REGEN_ENABLED" then self:UnregisterEvent("PLAYER_REGEN_ENABLED") end

    if not InCombatLockdown() then
        if inInstance and instanceType == "raid" then
            UnregisterStateDriver(self, "visibility")
            self:Show()
        elseif self.db.visibility then
            RegisterStateDriver(self, "visibility", self.db.visibility)
        end
    else
        self:RegisterEvent("PLAYER_REGEN_ENABLED")
        return
    end
end

local UpdateTargetGlow = function(self)
    if not self.unit then return end
    local unit = self.unit;
    if(UnitIsUnit(unit, "target")) then
        self.TargetGlow:Show()
        local reaction = UnitReaction(unit, "player")
        if(UnitIsPlayer(unit)) then
            local _, class = UnitClass(unit)
            if class then
                local colors = SVUI_CLASS_COLORS[class]
                self.TargetGlow:SetBackdropBorderColor(colors.r, colors.g, colors.b)
            else
                self.TargetGlow:SetBackdropBorderColor(1, 1, 1)
            end
        elseif(reaction) then
            local colors = FACTION_BAR_COLORS[reaction]
            self.TargetGlow:SetBackdropBorderColor(colors.r, colors.g, colors.b)
        else
            self.TargetGlow:SetBackdropBorderColor(1, 1, 1)
        end
    else
        self.TargetGlow:Hide()
    end
end
--[[
##########################################################
BUILD FUNCTION & UPDATE
##########################################################
]]--
local ConstructRaidFrame = function(self, unit)
    self:SetScript("OnEnter", UnitFrame_OnEnter)
    self:SetScript("OnLeave", UnitFrame_OnLeave)
    MOD:SetActionPanel(self, unit)
    self.Health = MOD:CreateHealthBar(self, true)
    self.Power = MOD:CreatePowerBar(self, true)
    self.Power.frequentUpdates = false
    self.Buffs = MOD:CreateBuffs(self, unit)
    self.Debuffs = MOD:CreateDebuffs(self, unit)
    self.AuraWatch = MOD:CreateAuraWatch(self, unit)
    self.RaidDebuffs = MOD:CreateRaidDebuffs(self)
    self.Afflicted = MOD:CreateAfflicted(self)
    self.ResurrectIcon = MOD:CreateResurectionIcon(self)
    self.LFDRole = MOD:CreateRoleIcon(self)
    self.RaidRoleFramesAnchor = MOD:CreateRaidRoleFrames(self)
    self.RaidIcon = MOD:CreateRaidIcon(self)
    self.ReadyCheck = MOD:CreateReadyCheckIcon(self)
    self.HealPrediction = MOD:CreateHealPrediction(self)
    self.Range = { insideAlpha = 1, outsideAlpha = 1 }

    local shadow = CreateFrame("Frame", nil, self)
    shadow:SetFrameLevel(1)
    shadow:SetFrameStrata(self:GetFrameStrata())
    shadow:WrapOuter(self, 3, 3)
    shadow:SetBackdrop({
        edgeFile = [[Interface\AddOns\SVUI\assets\artwork\Template\GLOW]],
        edgeSize = SuperVillain:Scale(3),
        insets = {
            left = SuperVillain:Scale(5),
            right = SuperVillain:Scale(5),
            top = SuperVillain:Scale(5),
            bottom = SuperVillain:Scale(5)
        }
    })
    shadow:SetBackdropColor(0, 0, 0, 0)
    shadow:SetBackdropBorderColor(0, 0, 0, 0.9)
    shadow:Hide()
    self.TargetGlow = shadow
    tinsert(self.__elements, UpdateTargetGlow)
    self:RegisterEvent("PLAYER_TARGET_CHANGED", UpdateTargetGlow)
    self:RegisterEvent("PLAYER_ENTERING_WORLD", UpdateTargetGlow)

    return frame
end

local UpdateRaidFrame = function(self, header)
    local db = MOD.db[header]
    self.colors = oUF_SuperVillain.colors;
    self:RegisterForClicks(MOD.db.fastClickTarget and"AnyDown"or"AnyUp")
    if not InCombatLockdown() then self:Size(db.width, db.height)end
    MOD:RefreshUnitLayout(self, header)
    do
        local rdBuffs = self.RaidDebuffs;
        if db.rdebuffs.enable then
            self:EnableElement("RaidDebuffs")
            rdBuffs:Size(db.rdebuffs.size)
            rdBuffs:Point("CENTER", self, "CENTER", db.rdebuffs.xOffset, db.rdebuffs.yOffset)
        else
            self:DisableElement("RaidDebuffs")
            rdBuffs:Hide()
        end
    end
    MOD:UpdateAuraWatch(self)
    self:EnableElement("ReadyCheck")
    self:UpdateAllElements()
end

for i = 10, 40, 15 do
    local raidGroupName = "raid"..i
    MOD.Construct[raidGroupName] = ConstructRaidFrame
    MOD.HeaderUpdate[raidGroupName] = function(self)
        local frame = self:GetParent()
        if not frame.positioned then
            frame:ClearAllPoints()
            frame:Point("LEFT", SuperVillain.UIParent, "LEFT", 4, 0)
            SuperVillain:SetSVMovable(frame, frame:GetName().."_MOVE", L["Raid 1-"]..i..L[" Frames"], nil, nil, nil, "ALL, RAID"..i)
            frame:RegisterEvent("PLAYER_ENTERING_WORLD")
            frame:RegisterEvent("ZONE_CHANGED_NEW_AREA")
            frame:SetScript("OnEvent", VisibilityUpdate)
            frame.positioned = true
        end
        VisibilityUpdate(frame)
        local index = 1;
        local childFrame = self:GetAttribute("child"..index)
        while childFrame do
            UpdateRaidFrame(childFrame, raidGroupName)
            if(_G[childFrame:GetName().."Pet"]) then
                UpdateRaidFrame(_G[childFrame:GetName().."Pet"], raidGroupName)
            end
            if(_G[childFrame:GetName().."Target"]) then
                UpdateRaidFrame(_G[childFrame:GetName().."Target"], raidGroupName)
            end
            index = index + 1;
            childFrame = self:GetAttribute("child"..index)
        end
    end
end
--[[
##########################################################
BUILD AND UPDATE RAID PETS
##########################################################
]]--
local UpdateRaidpetFrame = function(self)
    local db = MOD.db["raidpet"]
    self.colors = oUF_SuperVillain.colors;
    self:RegisterForClicks(MOD.db.fastClickTarget and "AnyDown" or "AnyUp")
    if not InCombatLockdown() then self:Size(db.width, db.height)end
    MOD:RefreshUnitLayout(self, "raidpet")
    do
        local rdBuffs = self.RaidDebuffs;
        if db.rdebuffs.enable then
            self:EnableElement("RaidDebuffs")
            rdBuffs:Size(db.rdebuffs.size)
            rdBuffs:Point("CENTER", self, "CENTER", db.rdebuffs.xOffset, db.rdebuffs.yOffset)
        else
            self:DisableElement("RaidDebuffs")
            rdBuffs:Hide()
        end
    end
    MOD:UpdateAuraWatch(self, true)
    self:UpdateAllElements()
end

function MOD.Construct:raidpet()
    self:SetScript("OnEnter", UnitFrame_OnEnter)
    self:SetScript("OnLeave", UnitFrame_OnLeave)
    MOD:SetActionPanel(self, "raidpet")
    self.Health = MOD:CreateHealthBar(self, true)
    self.Debuffs = MOD:CreateDebuffs(self, "raidpet")
    self.AuraWatch = MOD:CreateAuraWatch(self, "raidpet")
    self.RaidDebuffs = MOD:CreateRaidDebuffs(self)
    self.Afflicted = MOD:CreateAfflicted(self)
    self.RaidIcon = MOD:CreateRaidIcon(self)
    self.Range = { insideAlpha = 1, outsideAlpha = 1 }

    local shadow = CreateFrame("Frame", nil, self)
    shadow:SetFrameLevel(1)
    shadow:SetFrameStrata(self:GetFrameStrata())
    shadow:WrapOuter(self, 3, 3)
    shadow:SetBackdrop({
        edgeFile = [[Interface\AddOns\SVUI\assets\artwork\Template\GLOW]],
        edgeSize = SuperVillain:Scale(3),
        insets = {
            left = SuperVillain:Scale(5),
            right = SuperVillain:Scale(5),
            top = SuperVillain:Scale(5),
            bottom = SuperVillain:Scale(5)
        }
    })
    shadow:SetBackdropColor(0, 0, 0, 0)
    shadow:SetBackdropBorderColor(0, 0, 0, 0.9)
    shadow:Hide()
    self.TargetGlow = shadow
    tinsert(self.__elements, UpdateTargetGlow)
    self:RegisterEvent("PLAYER_TARGET_CHANGED", UpdateTargetGlow)
    self:RegisterEvent("PLAYER_ENTERING_WORLD", UpdateTargetGlow)

    return self
end

function MOD.HeaderUpdate:raidpet()
    local raidPets = self:GetParent()
    if not raidPets.positioned then
        raidPets:ClearAllPoints()
        raidPets:Point("BOTTOMLEFT", SuperVillain.UIParent, "BOTTOMLEFT", 4, 433)
        SuperVillain:SetSVMovable(raidPets, raidPets:GetName().."_MOVE", L["Raid Pet Frames"], nil, nil, nil, "ALL, RAID10, RAID25, RAID40")
        raidPets.positioned = true;
        raidPets:RegisterEvent("PLAYER_ENTERING_WORLD")
        raidPets:RegisterEvent("ZONE_CHANGED_NEW_AREA")
        raidPets:SetScript("OnEvent", RaidPetVisibility)
    end
    RaidPetVisibility(raidPets)
    local index = 1;
    local childFrame = self:GetAttribute("child"..index)
    while childFrame do
        UpdateRaidpetFrame(childFrame)
        if(_G[childFrame:GetName().."Pet"]) then
            UpdateRaidpetFrame(_G[childFrame:GetName().."Pet"])
        end
        if(_G[childFrame:GetName().."Target"]) then
            UpdateRaidpetFrame(_G[childFrame:GetName().."Target"])
        end
        index = index + 1;
        childFrame = self:GetAttribute("child"..index)
    end
end