-- This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
-- To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/
-- or send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.

local MereHealingFrames, privateVars = ...

local CleansableBuff = MereHealingFrames.BuffManager.CleansableBuff

function CleansableBuff:new(playerBuffs, buffSlots)
	local this = {}
	setmetatable(this, self)
	self.__index = self

	this.playerBuffs = playerBuffs
	this.buffSlots = buffSlots
	this.totalStacks = 0
	this.BuffStacks = {}

	this.buffName = nil

	this:HookPlayerBuffs()

	return this
end

function CleansableBuff:HookPlayerBuffs()
	self.playerBuffs.CleanseTracking[self] = self
end

function CleansableBuff:UnHookPlayerBuffs()
	self.playerBuffs.CleanseTracking[self] = nil
end

function CleansableBuff:BuffAdd(buffId, buffDetail)
	local stacks = buffDetail.stack or 1

	if not buffDetail.debuff then
		MereHealingFrames.Debug(1, "BuffAdd: %s is not a debuff, probably friendly", buffDetail.name)
		MereHealingFrames.DebugDump(1, buffDetail)
		return
	end

	MereHealingFrames.Debug(1, "BuffAdd: %s, new: %d", buffDetail.name, stacks)

	local details = {
		stacks = stacks,
		buffName = buffDetail.name,
		expiryTime = nil
		}

	if (buffDetail.begin and buffDetail.duration) then
		details.expiryTime = buffDetail.begin + buffDetail.duration
	end

	self.BuffStacks[buffId] = details

	self.totalStacks = self.totalStacks + stacks
	MereHealingFrames.Debug(1, "BuffAdd total stacks: %d", self.totalStacks)

	if self.buffName == nil then
		self.buffName = buffDetail.name
		self.expiryTime = buffDetail.expiryTime
	end

	self:UpdateIcons(self.totalStacks)

	self.playerBuffs:RegisterBuffId(buffId, self)
end

function CleansableBuff:BuffChange(buffId, buffDetail)
	local currentStacks = self.BuffStacks[buffId].stacks
	local newStacks = buffDetail.stack or 1

	MereHealingFrames.Debug(1, "BuffChange: %s, old: %d, new: %d", buffDetail.name, currentStacks, newStacks)

	if currentStacks == newStacks then
		return
	end

	local details = self.BuffStacks[buffId]
	details.stacks = newStacks
	details.expiryTime = buffDetail.begin + buffDetail.duration

	self.totalStacks = (self.totalStacks - currentStacks) + newStacks

	MereHealingFrames.Debug(1, "BuffChange total stacks: %d", self.totalStacks)
	self:UpdateStacks()
end

function CleansableBuff:BuffRemove(buffId)
	local details = self.BuffStacks[buffId]

	MereHealingFrames.Debug(1, "BuffRemove: %s, old: %d", details.buffName, details.stacks)

	self.BuffStacks[buffId] = nil

	self.totalStacks = (self.totalStacks - details.stacks)
	MereHealingFrames.Debug(1, "BuffRemove total stacks: %d", self.totalStacks)

	-- TODO this should use the cast sequence to get the timer from
	if (self.totalStacks > 0) then
		if self.buffName == details.buffName then
			for i, details in pairs(self.BuffStacks) do
				self.buffName = details.buffName
				self.expiryTime = details.expiryTime
				break
			end
		end
	else
		self.buffName = nil
	end

	self:UpdateIcons()
end

function CleansableBuff:UpdateIcons()
	if self.totalStacks == 0 then
		self:UpdateAllIcons(function (buffIcon) buffIcon:Clear() end)
	else
		self:UpdateAllIcons(function (buffIcon)
			buffIcon:UpdateIcon(self.buffName, self.totalStacks, nil, "cleansable")
			end
			)
	end
end

function CleansableBuff:UpdateStacks()
	self:UpdateAllIcons(function (buffIcon) buffIcon:UpdateCounter(self.totalStacks) end)
end

function CleansableBuff:UpdateAllIcons(updateFunc)
	for i, value in pairs(self.buffSlots or {}) do
		if value then
			local Handlers = self.playerBuffs.UIHandlers[i] or {}
			for _, BuffIcon in pairs(Handlers) do
				updateFunc(BuffIcon)
			end
		end
	end
end