IRF_ReadyCheck = LibStub("AceAddon-3.0"):NewAddon("IRF_ReadyCheck", "AceEvent-3.0", "AceTimer-3.0")
local mother = InvenRaidFrames
local IsReadyCheck = false
local initEvents = false
local initMessages = false
local icons = {}
local main

function IRF_ReadyCheck:OnInitialize()
	main = CreateFrame("Frame", nil, UIParent)
	main:SetScript("OnShow", function()
		main:SetAlpha(1)
	end)
	main:SetScript("OnHide", function()
		IsReadyCheck = false
		main:SetScript("OnUpdate", nil)
		for u in pairs(icons) do
			icons[u]:Hide()
			icons[u].state = nil
		end
	end)
	main:SetScale(mother.db.profile.scale)
	main:Hide()
	self:RegisterMessage("InvenRaidFrames_UpdateScale", "SetScale")
	self:RegisterMessage("InvenRaidFrames_InitUnits", function() self:Update() end)
	self:RegisterMessage("InvenRaidFrames_HideAll", function()
		main:SetScript("OnUpdate", self.OnUpdate)
		main:Hide()
	end)
end

function IRF_ReadyCheck:OnEnable()
	if mother.db.profile.readycheck then
		if not initEvents then
			initEvents = true
			self:RegisterEvent("READY_CHECK")
			self:RegisterEvent("READY_CHECK_CONFIRM")
			self:RegisterEvent("READY_CHECK_FINISHED")
		end
	end
end

function IRF_ReadyCheck:OnDisable()
	if initEvents and not mother.db.profile.readycheck then
		initEvents = false
		self:UnregisterEvent("READY_CHECK")
		self:UnregisterEvent("READY_CHECK_CONFIRM")
		self:UnregisterEvent("READY_CHECK_FINISHED")
		if IsReadyCheck then
			self:READY_CHECK_FINISHED()
		end
	end
end

function IRF_ReadyCheck:CreateIcons(unit)
	if not unit then return end
	local name = UnitName(unit)
	if not icons[name] then
		c = main:CreateTexture(nil, "BACKGROUND")
		c:SetTexture("")
		c:Hide()
		icons[name] = c
	end
	return icons[name]
end

function IRF_ReadyCheck:READY_CHECK(_, name)
	if mother:IsReadyCheckable() then
		IsReadyCheck = true
		main:SetScript("OnUpdate", nil)
		main:SetAlpha(1)
		main:Show()
		for u in pairs(mother.vars.unit) do
			if UnitIsPlayer(u) then
				self:Start(u)
			end
		end
		if mother.vars.member.raid == 0 and UnitName("player") == name then
			self:READY_CHECK_CONFIRM(_, 0, 1)
		else
			self:READY_CHECK_CONFIRM(_, tonumber(strmatch(mother.vars.name[name], "(%d+)") or ""), 1)
		end
	else
		IsReadyCheck = false
	end
end

function IRF_ReadyCheck:READY_CHECK_CONFIRM(_, id, confirm)
	if not id then return end
	main:SetScript("OnUpdate", nil)
	main:SetAlpha(1)
	main:Show()
	local unit
	if mother.vars.member.raid > 0 then
		unit = "raid"..id
	elseif mother.vars.member.party > 0 then
		if id == 0 then
			unit = "player"
		else
			unit = "party"..id
		end
	end
	local f = self:CreateIcons(unit)
	if f then
		if confirm == 1 then
			f:SetTexture(READY_CHECK_READY_TEXTURE)
			f.state = "ready"
		else
			f:SetTexture(READY_CHECK_NOT_READY_TEXTURE)
			f.state = "notready"
		end
		f:Show()
	end
end

function IRF_ReadyCheck:READY_CHECK_FINISHED()
	if mother:IsReadyCheckable() then
		for u in pairs(mother.vars.unit) do
			if UnitIsPlayer(u) then
				self:End(u)
			end
		end
		main.finishedTimer = mother.db.profile.readycheckft1
		main.fadeTimer = mother.db.profile.readycheckft2
		main:SetScript("OnUpdate", self.OnUpdate)
	end
end

function IRF_ReadyCheck:Start(unit)
	local f = self:CreateIcons(unit)
	f:SetTexture(READY_CHECK_WAITING_TEXTURE)
	f.state = "waiting"
	f:Show()
	self:SetIcon(unit)
end

function IRF_ReadyCheck:End(unit)
	local f = self:CreateIcons(unit)
	if f.state == "waiting" then
		f:SetTexture(READY_CHECK_AFK_TEXTURE)
		f.state = "afk"
	end
end

function IRF_ReadyCheck.OnUpdate(f, elapsed)
	if initEvents then
		if f.finishedTimer then
			f.finishedTimer = f.finishedTimer - elapsed
			if f.finishedTimer <= 0 or InCombatLockdown() then
				f.finishedTimer = nil
			end
		elseif f.fadeTimer then
			f.fadeTimer = f.fadeTimer - elapsed
			f:SetAlpha(f.fadeTimer / mother.db.profile.readycheckft2)
			if f.fadeTimer <= 0 then
				f.fadeTimer = nil
				f:Hide()
			end
		end
	else
		f.finishedTimer = nil
		f.fadeTimer = nil
		f:Hide()
	end
end

function IRF_ReadyCheck:SetScale()
	if main then
		main:SetScale(mother.db.profile.scale)
	end
end

function IRF_ReadyCheck:SetIcon(unit)
	local parent = mother:GetUnit(unit)
	local f = self:CreateIcons(unit)
	if not (f and parent) then return end
	main:SetFrameStrata(parent:GetFrameStrata())
	main:SetFrameLevel(parent.topparent:GetFrameLevel() + 5)
	f:ClearAllPoints()
	if mother.db.profile.readycheckloc == "좌측" then
		f:SetPoint("LEFT", parent, "LEFT", 2, 0)
	elseif mother.db.profile.readycheckloc == "우측" then
		f:SetPoint("RIGHT", parent, "RIGHT", -2, 0)
	elseif mother.db.profile.readycheckloc == "상단" then
		f:SetPoint("TOP", parent, "TOP", 0, -2)
	elseif mother.db.profile.readycheckloc == "하단" then
		f:SetPoint("BOTTOM", parent, "BOTTOM", 0, 2)
	elseif mother.db.profile.readycheckloc == "좌측 상단" then
		f:SetPoint("TOPLEFT", parent, "TOPLEFT", 2, -2)
	elseif mother.db.profile.readycheckloc == "좌측 하단" then
		f:SetPoint("BOTTOMLEFT", parent, "BOTTOMLEFT", 2, 2)
	elseif mother.db.profile.readycheckloc == "우측 상단" then
		f:SetPoint("TOPRIGHT", parent, "TOPRIGHT", -2, -2)
	elseif mother.db.profile.readycheckloc == "우측 하단" then
		f:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT", -2, 2)
	else
		f:SetPoint("CENTER", parent, "CENTER")
	end
	f:SetWidth(mother.db.profile.readychecksize)
	f:SetHeight(mother.db.profile.readychecksize)
end

function IRF_ReadyCheck:Update(unit)
	if unit then
		if mother.vars.member.raid > 0 then
			if strfind(unit, "raid") then
				self:SetIcon(unit)
			end
		elseif mother.vars.membar.party > 0 then
			if strfind(unit, "party") then
				self:SetIcon(unit)
			end
		end
	else
		for u in pairs(mother.vars.unit) do
			if UnitIsPlayer(u) then
				self:SetIcon(u)
			end
		end
	end
end