IRF_Pet = LibStub("AceAddon-3.0"):NewAddon("IRF_Pet", "AceEvent-3.0", "AceTimer-3.0")
local self = IRF_Pet
local mother = InvenRaidFrames
local status = ""
local init = false
self.vars = { eventHandler = {} }

function IRF_Pet:OnInitialize()
	local m = CreateFrame("Frame", "InvenRaidFramesPetMain", UIParent)
	m:SetClampedToScreen(true)
	m:SetMovable(true)
	m:SetScale(mother.db.profile.scale)
	local s = m:GetEffectiveScale()
	m:SetPoint(mother.db.profile.pospet[1], UIParent, mother.db.profile.pospet[1], mother.db.profile.pospet[2] / s, mother.db.profile.pospet[3] / s)
	m:SetHeight(mother.db.profile.unitHeight)
	m:SetWidth(mother.db.profile.unitWidth)
	local b = CreateFrame("Frame", nil, UIParent)
	b:SetPoint("TOPLEFT", m, "TOPLEFT", -4, 4)
	b:SetBackdrop({
		bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
		edgeFile = "Interface\\Addons\\InvenRaidFrames\\Texture\\Border",
		tile = true, tileSize = 16, edgeSize = 16,
		insets = { left = 2, right = 2, top = 2, bottom = 2 }
	})
	b:SetBackdropColor(unpack(mother.db.profile.color.bg))
	b:SetBackdropBorderColor(unpack(mother.db.profile.color.border))
	b:SetAlpha(mother.db.profile.borderAlpha)
	--b:EnableMouse(true)
	b:SetMovable(true)
	b:RegisterForDrag("LeftButton")
	b:SetScript("OnDragStart", self.FrameOnDragStart)
	b:SetScript("OnDragStop", mother.FrameOnDragStop)
	m.border = b
	m.border:SetScale(mother.db.profile.scale)
	--m:SetScript("OnShow", function() m.border:Show() end)
	m:SetScript("OnHide", function() m.border:Hide() end)
	m:Show()
	self.vars.main = m
	local h = CreateFrame("Frame", "InvenRaidFramesPetHeader", self.vars.main, "SecureGroupPetHeaderTemplate")
	h:SetAttribute("template", "InvenRaidFramesSecurePetTemplate")
	h.initialConfigFunction = IRF_GroupInitialConfigFunction
	h:SetAttribute("groupingOrder", "WARLOCK,HUNTER")
	h:SetAttribute("groupFilter", "WARLOCK,HUNTER")
	h:SetPoint("TOPLEFT", self.vars.main, "TOPLEFT")
	h.SetManyAttribute = mother.SetManyAttribute
	self.vars.header = h
	self:RegisterEvent("UNIT_PET", function() mother.FrameOnDragStop() end)
	self:RegisterMessage("InvenRaidFrames_RosterUpdate", "RosterUpdate")
	self:RegisterMessage("InvenRaidFrames_UnitSizeUpdate", "UnitSizeUpdate")
	self:RegisterMessage("InvenRaidFrames_InitUnits", function() mother.FrameOnDragStop() self:UpdateBorder() end)
	self:RegisterMessage("InvenRaidFrames_UpdateScale", "UnitSizeUpdate")
	self:RegisterEvent("UNIT_PET")
	self:SetOffset()
	self:SetOrder()
	self:CheckStatus()
	for i = 1, 20 do
		if not h:GetAttribute("child"..i) then
			local n = h:GetName().."UnitButton"..i
			local f = CreateFrame("Button", n, h, "InvenRaidFramesSecurePetTemplate")
			SetupUnitButtonConfiguration(h, f)
			h:SetAttribute("child"..i, f)
		end
	end
	self:CallbackTimer("UpdateBorder", 0.1)
end

function IRF_Pet:CheckStatus()
	local rm = GetNumRaidMembers()
	local pm = GetNumPartyMembers()
	if mother.db.char.pet then
		if mother.db.char.showIRF and (mother.db.profile.use == "항상" or (mother.db.profile.use == "파티" and (rm > 0 or pm > 0)) or (mother.db.profile.use == "공격대" and rm > 0)) then
			if rm > 0 and status ~= "R" then
				status = "R"
				self.vars.header:SetManyAttribute({
					"showSolo", false,
					"showPlayer", false,
					"showParty", false,
					"showRaid", true,
				})
				self.vars.header:Show()
			elseif rm == 0 and status ~= "P" then
				status = "P"
				self.vars.header:SetManyAttribute({
					"showSolo", true,
					"showPlayer", true,
					"showParty", true,
					"showRaid", false,
				})
				self.vars.header:Show()
			end
		elseif status ~= "N" then
			status = "N"
			self.vars.header:SetManyAttribute({
				"showSolo", false,
				"showPlayer", false,
				"showParty", false,
				"showRaid", false,
			})
			self.vars.header:Show()
		end
	elseif status ~= "N" then
		status = "N"
		self.vars.header:SetManyAttribute({
			"showSolo", false,
			"showPlayer", false,
			"showParty", false,
			"showRaid", false,
		})
		self.vars.header:Show()
	end
end

function IRF_Pet:CreateUnitFrame(f)
	mother:CreateUnit(f)
	f:SetScript("OnDragStart", self.FrameOnDragStart)
end

function IRF_Pet:RosterUpdate()
	mother.FrameOnDragStop()
	if InCombatLockdown() then
		mother:RunLeaveCombat("PetRosterUpdate", self, "RosterUpdate")
	else
		self:CheckStatus()
	end
	self:CallbackTimer("UpdateBorder", 0.1)
end

function IRF_Pet:UNIT_PET(_, unit)
	if UnitInParty(unit) or UnitInRaid(unit) then
		local unitpet = gsub(unit, "party", "partypet")
		unitpet = gsub(unit, "raid", "raidpet")
		unitpet = gsub(unit, "player", "pet")
		if UnitIsPlayer(unitpet) then return end
		if mother.vars.unit[unitpet] then
			mother:UpdateUnit(unitpet)
		end
	end
end

function IRF_Pet:UpdateBorder()
	if mother.db.profile.showbg and mother.vars.showMainFrame then
		if mother.db.char.pet then
			local pp = false
			local x, y = 0, 10000
			local topx, topy = self.vars.main:GetLeft(), self.vars.main:GetTop()
			if topx and topy then
				for unit, frame in pairs(mother.vars.pet) do
					if frame:IsVisible() and frame.unit == unit then
						local r, b = frame:GetRight(), frame:GetBottom()
						if r and b then
							pp = true
							x = max(x, r)
							y = min(y, b)
						end
					end
				end
				if pp then
					self.vars.main.border:Show()
					self.vars.main.border:SetWidth(x - topx + 8)
					self.vars.main.border:SetHeight(topy - y + 8)
				else
					self.vars.main.border:Hide()
				end
			end
		else
			self.vars.main.border:Hide()
		end
	else
		self.vars.main.border:Hide()
	end
end

function IRF_Pet:NameUpdate(unit)
	if UnitExists(unit) and not UnitIsPlayer(unit) then
		local f = mother:GetUnit(unit)
		if f and f.unit == unit then
			mother:UNIT_NAME_UPDATE(_, unit, f)
		end
	end
end

function IRF_Pet:OnAttributeChanged(frame, name, value)
	if name == "unit" and value then
		frame.unit = value
		mother.vars.range[value] = nil
		mother.vars.ata[value] = nil
		mother:RegisterUnitEvent(frame)
		mother:CallbackTimer("InitUnits", 0.1)
	end
end

function IRF_Pet:OnShowUnitFrame(f)
	mother:OnShowUnitFrame(f)
	self:CallbackTimer("UpdateBorder", 0.1)
end

function IRF_Pet:OnHideUnitFrame(f)
	mother:OnHideUnitFrame(f)
	self:CallbackTimer("UpdateBorder", 0.1)
	if mother:IsEnableModule("Buff") then
		IRF_Buff:ClearPet()
	end
	if mother:IsEnableModule("Debuff") then
		IRF_Debuff:ClearPet()
	end
	if mother:IsEnableModule("SpellTimer") then
		IRF_SpellTimer:ClearPet()
	end
end

function IRF_Pet:CallbackTimer(callback, delay, ...)
	self:CancelCallbackTimer(callback)
	self.vars.eventHandler[callback] = self:ScheduleTimer(callback, delay, ...)
end

function IRF_Pet:CancelCallbackTimer(callback)
	if self.vars.eventHandler[callback] then
		self:CancelTimer(self.vars.eventHandler[callback], true)
		self.vars.eventHandler[callback] = nil
	end
end

function IRF_Pet.FrameOnDragStart()
	if not mother.db.profile.lock and not self.vars.main.isMove then
		self.vars.main.isMove = true
		self.vars.main:StartMoving()
	end
end

function IRF_Pet:SetOrder()
	if InCombatLockdown() then
		mother:RunLeaveCombat("UpdatePetOrder", self, "SetOrder")
	else
		self.vars.header:SetAttribute("maxColumns", 25)
		self.vars.header:SetAttribute("unitsPerColumn", mother.db.profile.petline)
		if mother.db.profile.petorder == "가로" then
			self.vars.header:SetAttribute("point", "LEFT")
			self.vars.header:SetAttribute("columnAnchorPoint", "TOP")
		else
			self.vars.header:SetAttribute("point", "TOP")
			self.vars.header:SetAttribute("columnAnchorPoint", "LEFT")
		end
	end
	self:CallbackTimer("UpdateBorder", 0.1)
end

function IRF_Pet:SetOffset()
	if InCombatLockdown() then
		mother:RunLeaveCombat("UpdatePetOffset", self, "SetOffset")
	else
		self.vars.header:SetAttribute("xOffset", mother.db.profile.offset)
		self.vars.header:SetAttribute("yOffset", -mother.db.profile.offset)
		self.vars.header:SetAttribute("columnSpacing", mother.db.profile.offset)
	end
end

function IRF_Pet:UnitSizeUpdate()
	if InCombatLockdown() then
		mother:RunLeaveCombat("UpdatePetSize", self, "UnitSizeUpdate")
	else
		self.vars.main:SetScale(mother.db.profile.scale)
		self.vars.main.border:SetScale(mother.db.profile.scale)
		self.vars.main:SetWidth(mother.db.profile.unitWidth)
		self.vars.main:SetHeight(mother.db.profile.unitHeight)
		self.vars.header:SetAttribute("initial-width", mother.db.profile.unitWidth)
		self.vars.header:SetAttribute("initial-height", mother.db.profile.unitWidth)
		self.vars.header:ClearAllPoints()
		self.vars.header:SetPoint("TOPLEFT", self.vars.main, "TOPLEFT")
	end
end

function IRF_Pet:SetBorder()
	self.vars.main.border:SetAlpha(mother.db.profile.borderAlpha)
	self.vars.main.border:SetBackdropColor(unpack(mother.db.profile.color.bg))
	self.vars.main.border:SetBackdropBorderColor(unpack(mother.db.profile.color.border))
end