Quantcast
local addonname, addon = ...
local L = addon.L

function addon:Initialize()
	local events = CreateFrame'Frame'
	events:SetScript('OnEvent', function(frame, e, ...)
		if type(self[e]) == 'function' then
			self[e](self, ...)
		end
	end)

	function self:RegisterEvent(...) events:RegisterEvent(...) end
	function self:UnregisterEvent(...) events:UnregisterEvent(...) end

	self:RegisterEvent'ADDON_LOADED'
	self:RegisterEvent'PLAYER_ROLES_ASSIGNED'
end

function addon:ADDON_LOADED(name)
	if addonname ~= name then return end

	-- DB
	local defaults = {
		profile = {
			minthreat = 5000,
			dynamic_minthreat = true,
			enabled_in = { dungeon = true, raid = false },
			raid_icons = { 8, 7, 1, 2 },
		}
	}
	self.db = LibStub('AceDB-3.0'):New('KungalooshDB', defaults, true)

	self:CreateConfig()

	self:UnregisterEvent'ADDON_LOADED'
end

function addon:Print(...)
	print('|cFF33FF99Kungaloosh|r '..string.format(...))
end

function addon:PLAYER_ROLES_ASSIGNED()
	self:EnableIfTank()
end

function addon:PLAYER_REGEN_ENABLED()
	self:ResetState()
end

function addon:UNIT_THREAT_LIST_UPDATE(unit)
	if not unit then return end

	local icon = self:GetNextIcon()
	local guid = UnitGUID(unit)

	for i,v in pairs(self.iconstate) do
		if v == guid then
			icon = i
			break
		end
	end

	if icon and GetRaidTargetIndex(unit) == nil then
		local istanking, status, threatpct, rawthreatpct, threat = UnitDetailedThreatSituation('player', unit)

		if threat and threat > (self:GetMinThreat() * 100) then
			SetRaidTarget(unit, icon)
		end
	end
end

function addon:COMBAT_LOG_EVENT(timestamp, event, sguid, sname, sflags, dguid, dname, dflags)
	if event == 'UNIT_DIED' then
		for icon, guid in pairs(self.iconstate) do
			if dguid == guid then
				self.iconstate[icon] = nil
			end
		end
	end
end

function addon:RAID_TARGET_UPDATE()
	local function check(unit)
		if UnitExists(unit) then
			local icon = GetRaidTargetIndex(unit)
			if icon then
				self.iconstate[icon] = UnitGUID(unit)
			end
		end
	end

	check('target')
	check('pettarget')
	for i=1,5 do
		check('party'..i..'target')
	end

	for i=1,40 do
		check('raid'..i..'target')
	end
end

function addon:ResetState()
	self.iconstate = self.iconstate or {}
	table.wipe(self.iconstate)
end

function addon:GetNextIcon()
	for i, icon in ipairs(self.db.profile.raid_icons) do
		if not self.iconstate[icon] then
			return icon
		end
	end
end

function addon:GetMinThreat()
	if self.db.profile.dynamic_minthreat then
		local level = UnitLevel'player'

		return (level * level) * 1.2
	else
		return self.db.profile.minthreat
	end
end

function addon:EnableIfTank()
	if self.db.profile.enabled_in.dungeon then
		local istank, ishealer, isdamage = UnitGroupRolesAssigned'player'
		if istank then
			return self:Enable(L['is now enabled since you are assigned as a tank'])
		end
	end

	if self.db.profile.enabled_in.raid then
		if GetPartyAssignment('MAINTANK', 'player') then
			return self:Enable(L['is now enabled since you are assigned as a tank'])
		end
	end

	return self:Disable()
end

function addon:Enable(msg)
	if self.enabled then return end

	self:RegisterEvent'PLAYER_REGEN_ENABLED'
	self:RegisterEvent'UNIT_THREAT_LIST_UPDATE'
	self:RegisterEvent'RAID_TARGET_UPDATE'
	self:RegisterEvent'COMBAT_LOG_EVENT'
	self.enabled = true

	self:ResetState()

	if msg then self:Print(msg) end
end

function addon:Disable(msg)
	if not self.enabled then return end

	self:UnregisterEvent'PLAYER_REGEN_ENABLED'
	self:UnregisterEvent'UNIT_THREAT_LIST_UPDATE'
	self:UnregisterEvent'RAID_TARGET_UPDATE'
	self:UnregisterEvent'COMBAT_LOG_EVENT'
	self.enabled = false

	if msg then self:Print(msg) end
end

function addon:Toggle()
	if not self.enabled then
		self:Enable(L['is now enabled'])
	else
		self:Disable(L['is now disabled'])
	end
end

function SlashCmdList.KUNGALOOSH()
	addon:Toggle()
end

addon:Initialize()

_G['SLASH_KUNGALOOSH1'] = '/kungaloosh'
_G['SLASH_KUNGALOOSH2'] = '/kl'