-- 파티/공격대 인원의 힐 거리 및 부활 거리 체크 모듈(비힐 클래스는 28미터 체크)
-- 추가적으로 정신 지배 등으로 적대적이 된 플레이어의 체력바 색상을 붉게 변경
local IRF2 = InvenRaidFrames2

local _G = _G
local pairs = _G.pairs
local type = _G.type
local UnitIsUnit = _G.UnitIsUnit
local UnitIsDead = _G.UnitIsDead
local UnitIsDeadOrGhost = _G.UnitIsDeadOrGhost
local UnitIsVisible = _G.UnitIsVisible
local IsSpellInRange = _G.IsSpellInRange
local CheckInteractDistance = _G.CheckInteractDistance
local GetSpellInfo = _G.GetSpellInfo
local GetSpellTexture = _G.GetSpellTexture
local UnitCanAttack = _G.UnitCanAttack

local rangeSpell = {
	["PRIEST"] = 2050,	-- 하급 치유
	["MAGE"] = 2782,	-- 저주 해제
	["WARLOCK"] = 2972,	-- 투명체 감지
	["DRUID"] = 5185,	-- 치유의 손길
	["SHAMAN"] = 331,	-- 치유의 물결
	["PALADIN"] = 635,	-- 성스러운 빛
}
local reviveSpell = {
	["PRIEST"] = 2006,	-- 부활
	["DRUID"] = 50769,	-- 되살리기
	["SHAMAN"] = 2008,	-- 고대의 영혼
	["PALADIN"] = 7328,	-- 구원
}

local checkRange

local function updateRange(object)
	object.rangeCheckFrame.needUpdate = nil
	if object.unit and object.cutName then
		-- 서정 거리 투명도 적용
		object.rangeCheckFrame.prevRange = object.inRange
		object.inRange = checkRange(object.unit)
		if object.rangeCheckFrame.prevRange ~= object.inRange then
			object.health:SetAlpha(object.inRange and 1 or IRF2.db.layout.outRangeAlpha)
			if IRF2.db.layout.outRangeAlphaMana then
				object.mana:SetAlpha(object.inRange and 1 or IRF2.db.layout.outRangeAlpha)
			end
			if IRF2.db.layout.outRangeAlphaName then
				object.textFrame:SetAlpha(object.inRange and 1 or IRF2.db.layout.outRangeAlpha)
			end
			object.rangeCheckFrame.needUpdate = true
		end
		-- 적대적 유닛 체력 생상 변화
		object.rangeCheckFrame.prevEnemy = object.enemy
		object.enemy = UnitCanAttack(object.unit, "player")
		if object.rangeCheckFrame.prevEnemy ~= object.enemy then
			object:UpdateHealthBarColor()
			object.rangeCheckFrame.needUpdate = true
		end
		if object.rangeCheckFrame.needUpdate then
			object:UpdateText()
		end
	end
end

local function rangeCheckOnUpdate(self, timer)
	self.timer = self.timer + timer
	if self.timer > 0 then
		self.timer = 0
		updateRange(self:GetParent())
	end
end

local function rangeCheckOnShow(self)
	updateRange(self:GetParent())
end

local function rangeMod(object)
	if not checkRange then
		if rangeSpell[IRF2.playerClass] then
			rangeSpell = GetSpellInfo(rangeSpell[IRF2.playerClass])
		else
			rangeSpell = nil
		end
		if reviveSpell[IRF2.playerClass] then
			reviveSpell = GetSpellInfo(reviveSpell[IRF2.playerClass])
		else
			reviveSpell = nil
		end
		if rangeSpell and reviveSpell then
			-- 부활 스킬과 사거리 체크용 스킬이 있을 때
			checkRange = function(unit)
				if not UnitIsVisible(unit) then
					return false
				elseif UnitIsDead(unit) and not UnitIsDeadOrGhost("player") then
					if IsSpellInRange(reviveSpell, unit) == 1 then
						return true
					end
				elseif IsSpellInRange(rangeSpell, unit) == 1 then
					return true
				elseif CheckInteractDistance(unit, 1) == 1 then
					return true
				end
				return false
			end
		elseif rangeSpell then
			-- 사거리 체크용 스킬이 있을 때
			checkRange = function(unit)
				if not UnitIsVisible(unit) then
					return false
				elseif IsSpellInRange(rangeSpell, unit) == 1 then
					return true
				elseif CheckInteractDistance(unit, 1) == 1 then
					return true
				end
				return false
			end
		elseif reviveSpell then
			-- 부활 스킬이 있을 때
			checkRange = function(unit)
				if not UnitIsVisible(unit) then
					return false
				elseif UnitIsDead(unit) and not UnitIsDeadOrGhost("player") then
					if IsSpellInRange(reviveSpell, unit) == 1 then
						return true
					end
				elseif CheckInteractDistance(unit, 1) == 1 then
					return true
				end
				return false
			end
		else
			-- 없을 떄
			checkRange = function(unit)
				return CheckInteractDistance(unit, 1) == 1 and true or false
			end
		end
	end
	object.rangeCheckFrame = CreateFrame("Frame", nil, object)
	object.rangeCheckFrame.timer = 0
	object.rangeCheckFrame:SetScript("OnUpdate", rangeCheckOnUpdate)
	object.rangeCheckFrame:SetScript("OnShow", rangeCheckOnShow)
end

IRF2:RegisterObjectModule("Range", rangeMod)