local XPerl_RaidPets_Events = {}
local FrameArray = {}
local conf
XPerl_RequestConfig(function(new) conf = new end)

-- GetPetFrame
local function GetPetFrame(unit)
	for i = 1,GetNumRaidMembers() do
		local child = XPerl_Raid_GrpPets:GetAttribute("child"..i)
		if (not child) then
			break
		end

		if (SecureButton_GetUnit(child) == unit) then
			return child
		end
	end
end

-- XPerl_RaidPets_OnEvent
local function XPerl_RaidPets_OnEvent(self, event, unit)
	local func = XPerl_RaidPets_Events[event]
	if (func) then
		if (strmatch(event, "^UNIT_")) then
			if (strmatch(unit, "^raidpet")) then
				local f = GetPetFrame(unit)
				if (f) then
					func(f)
				end
			end
		else
			func(self)
		end
	else
XPerl_ShowMessage("EXTRA EVENT")
	end
end

-- XPerl_RaidPets_OnUpdate
local function XPerl_RaidPets_OnUpdate(self, elapsed)
	self.time = self.time + elapsed
	if (self.time > 0.3) then
		for i = 1,GetNumRaidMembers() do
			local child = XPerl_Raid_GrpPets:GetAttribute("child"..i)
			if (not child) then
				break
			end
			XPerl_UpdateSpellRange(child, SecureButton_GetUnit(child))
		end
	end
end

-- XPerl_RaidPets_HighlightCallback
local function XPerl_RaidPets_HighlightCallback(updateName)
	for k,v in pairs(FrameArray) do
		if (v:IsShown()) then
			local partyid = SecureButton_GetUnit(self)
			if (partyid) then
				local name = UnitName(partyid)
				if (name) then
					XPerl_Highlight:SetHighlight(v, updateName)
				end
			end
		end
	end
end

-- XPerl_RaidPets_OnLoad
function XPerl_RaidPets_OnLoad(self)
	self.time = 0
	self.Array = {}

	local events = {"PLAYER_ENTERING_WORLD", "VARIABLES_LOADED", "RAID_ROSTER_UPDATE"}
	for i,event in pairs(events) do
		self:RegisterEvent(event)
	end

        self:SetScript("OnEvent", XPerl_RaidPets_OnEvent)
	self:SetScript("OnUpdate", XPerl_RaidPets_OnUpdate)

	XPerl_Highlight:Register(XPerl_RaidPets_HighlightCallback)
end

-- XPerl_RaidPet_UpdateName
local function XPerl_RaidPet_UpdateName(self)
	local partyid = SecureButton_GetUnit(self)
	local name
	if (partyid) then
		name = UnitName(partyid)
	end
	--local color

	if (not name or name == UNKNOWNOBJECT) then
		name = "no pet"
		--color = conf.ColourTapped
		self:SetAlpha(0.1)
		self.healthBar:SetValue(0)
		XPerl_SetSmoothBarColor(self.healthBar, 0)
	else
		--color = conf.ColourReactionNone
		self:SetAlpha(conf.Transparency)
	end

	self.text:SetText(name)

	local partyid = self:GetAttribute("unit")
	if (partyid) then
		local _, class = UnitClass(partyid)
		local c = XPerl_GetClassColour(class)

		self.text:SetTextColor(c.r, c.g, c.b)
	else
		self.text:SetTextColor(1, 1, 1)
	end
end

-- XPerl_RaidPet_UpdateHealth
local function XPerl_RaidPet_UpdateHealth(self)
	local partyid = SecureButton_GetUnit(self)
	if (not partyid) then
		self.healthBar:SetValue(0)
		XPerl_SetSmoothBarColor(self.healthBar, 0)
		return
	end

	local health = UnitHealth(partyid)
	local healthmax = UnitHealthMax(partyid)

	if (health > healthmax) then
		-- New glitch with 1.12.1
		if (UnitIsDeadOrGhost(partyid)) then
			health = 0
		else
			health = healthmax
		end
	end

	self.healthBar:SetMinMaxValues(0, healthmax)
	if (conf.InverseBars == 1) then
		self.healthBar:SetValue(healthmax - health)
	else
		self.healthBar:SetValue(health)
	end
	XPerl_SetSmoothBarColor(self.healthBar, health / healthmax)

	if (UnitIsDead(partyid)) then
		self.healthBar.text:SetText(XPERL_LOC_DEAD)
	elseif (UnitIsGhost(partyid)) then
		self.healthBar.text:SetText(XPERL_LOC_GHOST)
	else
		self.healthBar.text:SetText(format("%d"..PERCENT_SYMBOL, health / healthmax * 100))
	end
end

-- XPerl_RaidPets_UpdateDisplay
local function XPerl_RaidPets_UpdateDisplay(self)
	XPerl_RaidPet_UpdateName(self)
	XPerl_RaidPet_UpdateHealth(self)
end

-- VARIABLES_LOADED
function XPerl_RaidPets_Events:VARIABLES_LOADED()
	self:UnregisterEvent("VARIABLES_LOADED")

	XPerl_Raid_TitlePets:SetScale(conf.Scale_Raid)

	XPerl_RaidPets_ChangeAttributes()
end

-- PLAYER_ENTERING_WORLD
function XPerl_RaidPets_Events:PLAYER_ENTERING_WORLD()
	XPerl_RaidPets_Titles()
end

-- RAID_ROSTER_UPDATE
function XPerl_RaidPets_Events:RAID_ROSTER_UPDATE()
	XPerl_RaidPets_Titles()
end

-- UNIT_HEALTH
function XPerl_RaidPets_Events:UNIT_HEALTH()
	XPerl_RaidPet_UpdateHealth(self)
end

-- UNIT_HEALTHMAX
XPerl_RaidPets_Events.UNIT_MAXHEALTH = XPerl_RaidPets_Events.UNIT_HEALTH

-- UNIT_NAME_UPDATE
function XPerl_RaidPets_Events:UNIT_NAME_UPDATE()
	XPerl_RaidPet_UpdateName(self)
end

function XPerl_RaidPets_Events:UNIT_AURA()
	XPerl_CheckDebuffs(self, SecureButton_GetUnit(self))
end

-- onAttrChanged
local function onAttrChanged(self, name, value)
	if (name == "unit") then
		if (value) then
			XPerl_RaidPets_UpdateDisplay(self)
		end
	end
end

-- XPerl_RaidPet_Single_OnLoad
function XPerl_RaidPet_Single_OnLoad(self)
	XPerl_SetChildMembers(self)
	XPerl_RegisterPerlFrames(self)
	self:SetScript("OnAttributeChanged", onAttrChanged)
	XPerl_RegisterClickCastFrame(self)
	XPerl_RegisterHighlight(self.highlight, 2)

	self.FlashFrames = {self}
end

-- SetMainHeaderAttributes
local function SetMainHeaderAttributes(self)

	local classes = {}
	if (conf.ShowRaidPetsHunter == 1) then
		tinsert(classes, "HUNTER")
	end
	if (conf.ShowRaidPetsWarlock == 1) then
		tinsert(classes, "WARLOCK")
	end

	self:SetAttribute("groupFilter", table.concat(classes, ","))

	self:SetAttribute("point", conf.RaidAnchor)
	self:SetAttribute("minWidth", 80)
	self:SetAttribute("minHeight", 30)
	local titleFrame = self:GetParent()
	self:ClearAllPoints()
	if (conf.RaidAnchor == "TOP") then
		self:SetPoint("TOP", titleFrame, "BOTTOM", 0, 0)
		self:SetAttribute("xOffset", 0)
		self:SetAttribute("yOffset", -conf.RaidVerticalSpacing)
	elseif (conf.RaidAnchor == "LEFT") then
		self:SetPoint("TOPLEFT", titleFrame, "BOTTOMLEFT", 0, 0)
		self:SetAttribute("xOffset", conf.RaidVerticalSpacing)
		self:SetAttribute("yOffset", 0)
	elseif (conf.RaidAnchor == "BOTTOM") then
		self:SetPoint("BOTTOM", titleFrame, "TOP", 0, 0)
		self:SetAttribute("xOffset", 0)
		self:SetAttribute("yOffset", conf.RaidVerticalSpacing)
	elseif (conf.RaidAnchor == "RIGHT") then
		self:SetPoint("TOPRIGHT", titleFrame, "BOTTOMRIGHT", 0, 0)
		self:SetAttribute("xOffset", -conf.RaidVerticalSpacing)
		self:SetAttribute("yOffset", 0)
	end
	self:SetAttribute("template", "XPerl_RaidPet_FrameTemplate")
	self:SetAttribute("templateType", "Button")

	self.initialConfigFunction = function(self)
		-- This is the only place we're allowed to set attributes whilst in combat
		self:SetAttribute("unitsuffix", "pet")
		self:SetAttribute("*type1", "target")
		XPerl_RaidPets_UpdateDisplay(self)
	end
end

-- XPerl_RaidPets_ChangeAttributes
function XPerl_RaidPets_ChangeAttributes()
	XPerl_ProtectedCall(SetMainHeaderAttributes, XPerl_Raid_GrpPets)
end

-- XPerl_RaidPets_HideShow
function XPerl_RaidPets_HideShow()

	local on = (GetNumRaidMembers() > 0 and conf.ShowRaidPets == 1)

	local events = {"UNIT_HEALTH", "UNIT_MAXHEALTH", "UNIT_NAME_UPDATE", "UNIT_AURA"}
	for i,event in pairs(events) do
		if (on) then
			XPerl_RaidPets_Frame:RegisterEvent(event)
		else
			XPerl_RaidPets_Frame:UnregisterEvent(event)
		end
	end

	if (conf.ShowRaidPets == 1 and GetNumRaidMembers() > 0) then
		XPerl_RaidPets_Frame:Show()
		XPerl_Raid_TitlePets:Show()
		XPerl_Raid_GrpPets:Show()
	else
		XPerl_RaidPets_Frame:Hide()
		XPerl_Raid_TitlePets:Hide()
		XPerl_Raid_GrpPets:Hide()
	end
end

-- XPerl_RaidPets_Titles
function XPerl_RaidPets_Titles()
	if (conf.ShowRaidPetsHunter == 1) then
		if (conf.ShowRaidPetsWarlock == 1) then
			XPerl_Raid_TitlePets.text:SetText(XPERL_LOC_CLASS_PETS)
		else
			XPerl_Raid_TitlePets.text:SetText(XPERL_LOC_CLASS_PETSHUNTER)
		end
	elseif (conf.ShowRaidPetsWarlock == 1) then
		XPerl_Raid_TitlePets.text:SetText(XPERL_LOC_CLASS_PETSWARLOCK)
	end

	if (XPerlLocked == 0 or (conf.ShowRaidPets == 1 and GetNumRaidMembers() > 0 and conf.ShowRaidTitles == 1)) then
		XPerl_Raid_TitlePets.text:Show()
	else
		XPerl_Raid_TitlePets.text:Hide()
	end

	XPerl_ProtectedCall(XPerl_RaidPets_HideShow)
end

-- XPerl_RaidPets_OptionActions
function XPerl_RaidPets_OptionActions()
	XPerl_RaidPets_Titles()

	SetMainHeaderAttributes(XPerl_Raid_GrpPets)

	if (conf.ShowRaidPets == 1) then
		XPerl_Raid_TitlePets:Show()
	else
		XPerl_Raid_TitlePets:Hide()
	end
end

XPerl_RegisterOptionChanger(XPerl_RaidPets_OptionActions, "RaidPets")
