Quantcast
-- Big thanks goes out to all the guys in #wowi-lounge.  Couldn't have done this without them.
local version = '0.57-20000'
local targets = {}
local locked = false
-- constant
local HW_MIN_CAST_TIME = 0.5
local HW_MAX_CAST_TIME = 3.5
local HW_HOLD_TIME = 0.2
local HW_MAX_SHOW_TIME = 3.5
-- to debug or not?
local debugging = nil
local debugEvents = nil
local debugUpdates = nil
local debugTarget = nil
local _playerName = nil
-- debug frame
local dframe = ChatFrame4
-- heals (don't get saved between sessions)
local _Heals = {}
-- labelButtons is for local reference to the button frames
local frameTable = nil
local maxLabels = 40
local maxStatusBars = 40
-- see if we are a raid group
local isRaid = nil
local groupSetup = nil
local raidGroups = nil
-- for casting things
local curSpell = nil
local compTime = nil
local HW_LAG_FACTOR=0.25

local babbleSpells
local babbleClass

local colorTbl = {}
local color

local _targets = {}

-- globally accessible table
if (not HealWatch) then HealWatch = {} end
if (not HealWatchSave) then HealWatchSave = {} end
--if (not HealWatch.Options) then HealWatch.Options = {} end
if (not HealWatch.Health) then HealWatch.Health = {} end
HealWatch.version = version
HealWatch.dframe = ChatFrame1
HealWatch.hasComs = {}

-- if timeRemain exists, then it means that it was a messaged heal, which means we know the time remaining
function HealWatch.UpdateTarget(unit,target,targetUnit,custom)
	if (unit == 'player') then
		if (not custom) then
			HealWatch.prevTarget = HealWatch.target
		end
		if (not target and not custom) then
			if (HealWatch.target) then
				--if (HealWatch.Options.stickTarget) then HealWatch.SetStickyTarget(nil) end
				--local frame = HealWatch.GetLabelFrame(HealWatch.target)
				--if (frame and not frame.locked) then HealWatch.RemLabelFrame(frame) end
				HealWatch.RemoveLabelFrame(HealWatch.target,true)
			end
			HealWatch.target = nil
			return
		end
		if (SpellIsTargeting() or target ~= HealWatch.prevTarget) then
			if (not custom) then
				HealWatch.RemoveLabelFrame(HealWatch.target,true)
			end
		end
		if (not custom) then
			HealWatch.target = target
		end
		HealWatch.InsertLabelFrame(target)
		if (targetUnit) then HealWatch.UNIT_HEALTH(targetUnit) end
	else
		if (targetUnit and UnitCanAssist("player",targetUnit)) then
			_targets[unit] = UnitName(targetUnit)
		else
			_targets[unit] = target or nil
		end
	end
end

local _prefix = 'party'
function HealWatch.GetUnitFromName(name)
	if (HealWatch.isRaid) then _prefix = 'raid' else _prefix = 'party' end
	if (name == UnitName('player')) then
		return 'player'
	elseif (HealWatch.groupSetup and HealWatch.groupSetup[name]) then
		return _prefix..HealWatch.groupSetup[name]['index']
	elseif (name == UnitName('target')) then
		return 'target'
	elseif (name == UnitName('mouseover')) then
		return 'mouseover'
	elseif (name == UnitName('focus')) then
		return 'focus'
	end
end

function HealWatch.LabelCheckOnClick(arg1)
	if (this.GetChecked and this:GetChecked() == 1) then
		this:GetParent().locked = true
		HealWatch.AddLockedTarget(this:GetParent().text:GetText())
	else
		this:GetParent().locked = nil
		HealWatch.RemLockedTarget(this:GetParent().text:GetText())
	end
end

function HealWatch.Init()
	if (not HealWatch) then HealWatch = {} end
	if (not HealWatch._Heals) then HealWatch._Heals = {} end
	_Heals = HealWatch._Heals
	if (not HealWatch.History) then HealWatch.History = {} end
	if (not _Heals.Casting) then _Heals.Casting = {} end
end

function HealWatch.OnLoad()
	HealWatch.Init()
	HealWatch.frame = this
	HealWatch.Enable()
	local _,class = UnitClass('player')
	-- do the slash command stuff
	SLASH_HEALWATCH1 = "/healwatch"
	SLASH_HEALWATCH2 = "/hw"
	SlashCmdList["HEALWATCH"] = HealWatch.CommandHandler
	-- setup babble
	babbleSpells = BabbleLib:GetInstance('Spell 1.1')
	babbleClass = BabbleLib:GetInstance('Class 1.1')
	local spells = HealWatch.spells
	local colors = spells.spellColors
	for spell,class in pairs(colors) do
		if (type(class) == 'string') then
			colors[spell] = { babbleClass:GetColor(class) }
			colors[babbleSpells:GetLocalized(spell)] = colors[spell]
		end
	end
	local uniques = spells.unique
	for spell,value in pairs(uniques) do
		uniques[babbleSpells:GetLocalized(spell)] = value
	end
	local watchs = spells.watch
	for spell,value in pairs(watchs) do
		watchs[babbleSpells:GetLocalized(spell)] = value
	end
	-- DON'T notify we loaded
	--DEFAULT_CHAT_FRAME:AddMessage("HealWatch loaded")
end

function HealWatch.EnableDebug(state)
	if (state == 'debugComs') then
		HealWatch.debugComs = true
		HealWatch.dframe = dframe
		HealWatch.enableComs = true
		HealWatch.comChannel = getglobal('CT_RA_Channel') or 'ihatewc'
	elseif (state == 'self_Heals') then
		HealWatch.playerName = _playerName
		HealWatch.Casting = _Heals.Casting
		HealWatch.debugSelf_Heals = true
	elseif (state == 'TestHealWatch') then
		if (not groupSetup) then groupSetup = {} end
		HealWatch.groupSetup = groupSetup
		if (not isRaid) then isRaid = true end
		HealWatch.isRaid = isRaid
		HealWatch.Casting = _Heals.Casting
	elseif (state) then
		debugging = true
		HealWatch.Casting = _Heals.Casting
		HealWatch.debugEvents = debugEvents
		HealWatch.isRaid = isRaid
		HealWatch.groupSetup = groupSetup
		HealWatch.targets = targets
	else
		debugging = nil
		HealWatch.Casting = nil
		HealWatch.target = nil
		HealWatch.debugEvents = nil
		HealWatch.isRaid = nil
		HealWatch.groupSetup = nil
	end
end

function HealWatch.Disable()
	local frame = HealWatch.frame
	if (debugging or not frame) then return end
	HealWatch.DisableEvents()
	frame:UnregisterEvent("PARTY_MEMBERS_CHANGED")
	frame:UnregisterEvent("RAID_ROSTER_UPDATE")
end

function HealWatch.Enable()
	-- make sure we have access to the frame, in case we ever need it
	local frame = HealWatch.frame
	if (not frame) then
		frame = getglobal("HealWatchFrame")
		if (not frame) then HealWatch.DisableEvents() return end
		HealWatch.frame = frame
	end
	frame:RegisterEvent("PLAYER_ENTERING_WORLD")
	frame:RegisterEvent("VARIABLES_LOADED")
	frame:RegisterEvent("PARTY_MEMBERS_CHANGED")
	frame:RegisterEvent("PLAYER_LOGOUT")
	frame:RegisterEvent("PLAYER_LOGIN")
	frame:RegisterEvent("RAID_ROSTER_UPDATE")
	HealWatch.Options.enabled = true
	if (not _playerName) then _playerName = UnitName('player') end

end

function HealWatch.EnableEvents()
	local frame = HealWatch.frame
	if (not frame) then
		frame = getglobal("HealWatchFrame")
		if (not frame) then HealWatch.Disable() return end
		HealWatch.frame = frame
	end
	frame = HealWatch.frame
	frame:RegisterEvent("UNIT_HEALTH")
	frame:RegisterEvent("UNIT_MAXHEALTH")
	HealWatch.HW2Toggle(true)
end

function HealWatch.DisableEvents()
	local frame = HealWatch.frame
	if (debugging or not frame) then return end
	frame:UnregisterEvent("VARIABLES_LOADED")
	frame:UnregisterEvent("UNIT_HEALTH")
	frame:UnregisterEvent("UNIT_MAXHEALTH")
	HealWatch.Options.enabled = false
	HealWatch.HW2Toggle(false)
end

function HealWatch.PlayerInGroup(caster)
	if (HealWatch.UpdateRaidSetup) then HealWatch.UpdateRaidInfo() end
	if (not groupSetup) then groupSetup = HealWatch.groupSetup end
	return (groupSetup and groupSetup[caster] and groupSetup[caster]['inGroup'])
end

function HealWatch.GetTarget(unit)
	if (unit == "player") then return HealWatch.customTarget or HealWatch.target end
	return _targets[unit]
end

function HealWatch.CommandHandler(cmd)
	cmd = string.lower(cmd)
	if (cmd == 'show') then
		HealWatchCastFrame:Show()
	elseif (cmd == 'hide') then
		HealWatchCastFrame:Hide()
	elseif (cmd == 'coms') then
		if (HealWatch.enableComs) then
			HealWatch.enableComs = nil
			DEFAULT_CHAT_FRAME:AddMessage("Healwatch communications: |cFFFF0000disabled|r")
			if (HealWatch.DisableComs) then HealWatch.DisableComs() end
		else
			HealWatch.enableComs = true
			if (HealWatch.EnableComs) then HealWatch.EnableComs() end
			DEFAULT_CHAT_FRAME:AddMessage("Healwatch communications: |cFF00FF00enabled|r")
		end
	elseif (cmd == 'status') then
		DEFAULT_CHAT_FRAME:AddMessage("Healwatch version:"..version)
		if (HealWatch.Options.enabled) then
			DEFAULT_CHAT_FRAME:AddMessage("Healwatch is: |cFF00FF00enabled|r")
		else
			DEFAULT_CHAT_FRAME:AddMessage("Healwatch is: |cFFFF0000disabled|r")
		end
		if (HealWatch.Options.showHealth) then
			DEFAULT_CHAT_FRAME:AddMessage("Healwatch showing health deficit is: |cFF00FF00enabled|r")
		else
			DEFAULT_CHAT_FRAME:AddMessage("Healwatch showing health deficit is: |cFFFF0000disabled|r")
		end
		if (HealWatch.Options.showAllHeals) then
			DEFAULT_CHAT_FRAME:AddMessage("Healwatch showing all heals is: |cFF00FF00enabled|r")
		else
			DEFAULT_CHAT_FRAME:AddMessage("Healwatch showing all heals is: |cFFFF0000disabled|r")
		end
		DEFAULT_CHAT_FRAME:AddMessage('Healwatch max cast bars: |cFF00FF00'..HealWatch.Options.maxCastBars..'|r')
		if (HealWatch.Options.FrameAttachPoint == 'BOTTOM') then
			DEFAULT_CHAT_FRAME:AddMessage('Healwatch is now growing: |cFF00FF00up|r')
		else
			DEFAULT_CHAT_FRAME:AddMessage('Healwatch is now growing: |cFF00FF00down|r')
		end
		if (HealWatch.enableComs) then
			DEFAULT_CHAT_FRAME:AddMessage("Healwatch communications: |cFF00FF00enabled|r")
		else
			DEFAULT_CHAT_FRAME:AddMessage("Healwatch communications: |cFFFF0000disabled|r")
		end
	elseif (cmd == 'version') then
		DEFAULT_CHAT_FRAME:AddMessage("Healwatch version: "..version)
	elseif (cmd == 'debugcoms') then
		HealWatch.dframe = ChatFrame2
		HealWatch.debugComs = true
	elseif (cmd == 'debugaddheal') then
		HealWatch.dframe = ChatFrame2
		HealWatch.debugAddHeal = true
	elseif (cmd == 'allheals') then
		if (HealWatch.Options.showAllHeals) then
			HealWatch.Options.showAllHeals = nil
			DEFAULT_CHAT_FRAME:AddMessage("Healwatch showing all heals is now: |cFFFF0000disabled|r")
		else
			HealWatch.Options.showAllHeals = true
			DEFAULT_CHAT_FRAME:AddMessage("Healwatch showing all heals is now: |cFF00FF00enabled|r")
		end
	elseif (cmd == 'showhealth') then
		if (HealWatch.Options.showHealth) then
			HealWatch.Options.showHealth = nil
			DEFAULT_CHAT_FRAME:AddMessage("Healwatch showing health deficit is now: |cFFFF0000disabled|r")
		else
			HealWatch.Options.showHealth = true
			DEFAULT_CHAT_FRAME:AddMessage("Healwatch showing health deficit is now: |cFF00FF00enabled|r")
		end
	elseif (cmd == 'off') then
		HealWatch.Disable(true)
		HealWatch.HW2Toggle(false)
		DEFAULT_CHAT_FRAME:AddMessage('Healwatch is now: |cFFFF0000disabled|r')
	elseif (cmd == 'on') then
		HealWatch.Enable()
		HealWatch.EnableEvents()
		HealWatch.HW2Toggle(true)
		DEFAULT_CHAT_FRAME:AddMessage('Healwatch is now: |cFF00FF00enabled|r')
	elseif (cmd == 'up') then
		HealWatch.Options.FrameAttachPoint = 'BOTTOM'
		HealWatch.Options.ParentAttachPoint = 'TOP'
		DEFAULT_CHAT_FRAME:AddMessage('Healwatch is now growing: |cFF00FF00up|r')
	elseif (cmd == 'down') then
		HealWatch.Options.FrameAttachPoint = 'TOP'
		HealWatch.Options.ParentAttachPoint = 'BOTTOM'
		DEFAULT_CHAT_FRAME:AddMessage('Healwatch is now growing: |cFF00FF00down|r')
	elseif (cmd == 'resetgui' or cmd == 'reset') then
		HealWatch.ResetFrames()
	elseif (cmd == 'resetpos') then
		HealWatchCastFrame:ClearAllPoints()
		HealWatchCastFrame:SetPoint('CENTER',HealWatchAnchorFrame,'CENTER',0,0)
		HealWatchAnchorFrame:ClearAllPoints()
		HealWatchAnchorFrame:SetPoint('CENTER',UIParent,'CENTER',0,0)
	elseif (cmd == 'reattach') then
		local top1 = math.floor(HealWatchCastFrame:GetTop() + 0.5)
		local left2 = math.floor(HealWatchCastFrame:GetLeft() + 0.5)
		local top2 = math.floor(HealWatchAnchorFrame:GetTop() + 0.5)
		local left2 = math.floor(HealWatchAnchorFrame:GetLeft() + 0.5)
		local top = math.min(top1 or 0,top2 or 0)
		local left = math.min(left1 or 0,left2 or 0)
		HealWatchCastFrame:ClearAllPoints()
		HealWatchCastFrame:SetPoint('TOP',HealWatchAnchorFrame,'TOP',0,0)
		HealWatchAnchorFrame:ClearAllPoints()
		HealWatchAnchorFrame:SetPoint('TOPLEFT',UIParent,'TOPLEFT',left,-(UIParent:GetHeight() - top))
	elseif (cmd == 'resetupdate') then
		HealWatchCastFrame:ClearAllPoints()
		HealWatchCastFrame:SetPoint('CENTER',HealWatchAnchorFrame,'CENTER',0,0)
		HealWatchAnchorFrame:ClearAllPoints()
		HealWatchAnchorFrame:SetPoint('CENTER',UIParent,'CENTER',0,0)
	elseif (cmd == 'getversions') then
--function HealWatch.SendHWMessage(target,spell,status,time,rank)
		HealWatch.SendHWMessage('none','HOLY_LIGHT',5,0,0)
	elseif (cmd == 'hw2on') then
		DEFAULT_CHAT_FRAME:AddMessage(string.format("HW2 Status: %s",tostring(HealWatch.HW2Toggle(true))))
	elseif (cmd == 'hw2off') then
		DEFAULT_CHAT_FRAME:AddMessage(string.format("HW2 Status: %s",tostring(HealWatch.HW2Toggle(false))))
	elseif (cmd == 'hw2toggle') then
		DEFAULT_CHAT_FRAME:AddMessage(string.format("HW2 Status: %s",tostring(HealWatch.HW2Toggle())))
	elseif (cmd == 'hw2status') then
		DEFAULT_CHAT_FRAME:AddMessage(string.format("HW2 Status: %s",tostring(HealWatch.DumpHW2Status())))
	else
		local _,_,msg,param = string.find(cmd,'(%S-)[= ](.+)')
		if (msg and param) then
			if (msg == 'debug') then
				HealWatch['debug'][param] = not HealWatch['debug'][param]
				if (not HealWatch.dframe) then HealWatch.dframe = ChatFrame1 end
			elseif (msg == 'scale') then
				HealWatchCastFrame:SetScale(param)
				HealWatch.Options.scale = param
			elseif (msg == 'maxcastbars') then
				HealWatch.Options.maxCastBars = tonumber(param)
				DEFAULT_CHAT_FRAME:AddMessage('Healwatch max cast bars: |cFF00FF00'..HealWatch.Options.maxCastBars..'|r')
			end
		else
			DEFAULT_CHAT_FRAME:AddMessage("Command: "..cmd.." not valid, please use show/hide/on/off/status/version/coms/up/down/showHealth/allHeals/maxbars <number>")
		end
	end
end

HealWatch.debug = {}
function HealWatch.Debug(debugLvl,msg)
	if (HealWatch.debug[debugLvl]) then
		HealWatch.dframe:AddMessage(string.format('HW: %s',msg))
	end
end