assert( WarlockTimerFu, "WarlockTimerFu not found!")
local parser = ParserLib:GetInstance("1.1")
local L = AceLibrary("AceLocale-2.2"):new("WarlockTimerFu")
local candy = AceLibrary("CandyBar-2.0")
local PaintChips = AceLibrary("PaintChips-2.0")

local surface = AceLibrary("Surface-1.0")

WarlockTimerFu.defaults.bars = {
	growup = false,
	scale = 1.0,
	texture = "BantoBar",
	darken = true,
	Reversed = false,
	Size = 11,
	name = true,
	safe = false,
	colors = {}
}
WarlockTimerFu.Menu.args[L["Bar Options"]] = {
	type = "group",
	name = L["Bar Options"],
	desc = L["Bar Options"],
	order = 11,
	args = { 
		[L["Show Anchor"]] = {
			type = "execute",
			order = 1,
			name = L["Show Anchor"],
			desc = L["Show the bar anchor frame."],
			func = function() WarlockTimerFu:ShowAnchors() end,
		},
		[L["Visuals"]] = {
			type = "group",
			desc = L["Visual options for bars"],
			order = 2,
			name = L["Visuals"],
			args = {
				[L["Grow upwards"]] = {
					type = "toggle",
					order = 1,
					name = L["Grow upwards"],
					desc = L["Toggle bars grow upwards/downwards from anchor."],
					get = function() return WarlockTimerFu.db.profile.bars.growup end,
					set = function(v) WarlockTimerFu.db.profile.bars.growup = v end,
					message = "Bars now grow %2$s",
					current = "Bars now grow %2$s",
					map = {[true] = "Up", [false] = "Down"},
				},
				[L["Fill Bars"]] = {
					type = "toggle",
					order = 2,
					name = L["Fill Bars"],
					desc = L["Set the bars to fill."],
					get = function() return WarlockTimerFu.db.profile.bars.Reversed end,
					set = function() WarlockTimerFu.db.profile.bars.Reversed = not WarlockTimerFu.db.profile.bars.Reversed end,
				},
				[L["Text"]] = {
					type = "group",
					order = 3,
					name = L["Text"],
					desc = L["Options for text."],
					args = {	
						[L["Font Size"]] = {
							type = "range",
							name = L["Font Size"],
							desc = L["Set the bar font size."],
							min = 5,
							max = 20,
							step = 0.5,
							get = function() return WarlockTimerFu.db.profile.bars.Size end,
							set = function(v) WarlockTimerFu.db.profile.bars.Size = v end,
						},
						[L["Target"]] = {
							type = "toggle",
							name = L["Target"],
							desc = L["Toggle showing the target of the stun"],
							get = function() return WarlockTimerFu.db.profile.bars.name end,
							set = function() WarlockTimerFu.db.profile.bars.name = not WarlockTimerFu.db.profile.bars.name end,
						},
					},
				},
				[L["Scale"]] = {
					type = "range",
					order = 4,
					name = L["Scale"],
					desc = L["Set the bar scale."],
					min = 0.2,
					max = 2.0,
					step = 0.1,
					get = function() return WarlockTimerFu.db.profile.bars.scale end,
					set = function(v) WarlockTimerFu.db.profile.bars.scale = v end,
				},
				[L["Texture"]] = {
					type = "text",
					order = 5,
					name = L["Texture"],
					desc = L["Set the texture for the timer bars."],
					get = function() return WarlockTimerFu.db.profile.bars.texture end,
					set = function(v) WarlockTimerFu.db.profile.bars.texture = v end,
					validate = surface:List(),
				},
				[L["Colors"]] = {
					type = "group",
					order = 6,
					name = L["Colors"],
					desc = L["Colors of messages and bars."],
					args = {
						[L["Background"]] = {
							name = L["Background"],
							type = "color",
							desc = L["Change the bar background color."],
							hasAlpha = true,
							get = function() if WarlockTimerFu.db.profile.bars.colors.bgc then local _, r, g, b = PaintChips:GetRGBPercent(WarlockTimerFu.db.profile.bars.colors.bgc); return r, g, b, WarlockTimerFu.db.profile.bars.colors.bga else return  0, .5, .5, .5 end end,
							set = function(r, g, b, a) local hex = WarlockTimerFu:RGBToHex(r, g, b); PaintChips:RegisterHex(hex); WarlockTimerFu.db.profile.bars.colors.bgc = hex; WarlockTimerFu.db.profile.bars.colors.bga = a end,
						},
						[L["Text"]] = {
							name = L["Text"],
							type = "color",
							desc = L["Change the bar text color."],
							get = function() if WarlockTimerFu.db.profile.bars.colors.txtc then local _, r, g, b = PaintChips:GetRGBPercent(WarlockTimerFu.db.profile.bars.colors.txtc); return r, g, b else return  1, 1, 1 end end,
							set = function(r, g, b, a) local hex = WarlockTimerFu:RGBToHex(r, g, b); PaintChips:RegisterHex(hex); WarlockTimerFu.db.profile.bars.colors.txtc = hex end,
						},
						[L["Darken"]] = {
							name = L["Darken"],
							desc = L["Darken the bars as the time left decreases"],
							order = 1,
							type = 'toggle',
							get = function()
							        return WarlockTimerFu.db.profile.bars.darken
							    end,
							set = function(v)
								WarlockTimerFu.db.profile.bars.darken = not WarlockTimerFu.db.profile.bars.darken
							end,
							map = { [false] = "Disabled", [true] = "Enabled" },
							},
						[L["Main Color"]] = {
						name = L["Main Color"],
						desc = L["Main color of bar if static color is set"],
						order = 2,
						type = "color",
						get = function() if WarlockTimerFu.db.profile.bars.colors.mainc then local _, r, g, b = PaintChips:GetRGBPercent(WarlockTimerFu.db.profile.bars.colors.mainc); return r, g, b else return  1, 1, 0 end end,
						set = function(r, g, b, a) local hex = WarlockTimerFu:RGBToHex(r, g, b); PaintChips:RegisterHex(hex); WarlockTimerFu.db.profile.bars.colors.mainc = hex end,
						disabled = function() return WarlockTimerFu.db.profile.bars.darken end, 
						}
					}
				}
			}
		}
	}
}

function WarlockTimerFu:RegHex(hex)
	if type(hex) == "string" then
		PaintChips:RegisterHex(hex)
	elseif type(hex) == "table" then
		for _,hexx in pairs(hex) do
			self:RegHex(hexx)
		end
	end
end

function WarlockTimerFu:BarSetup()
	if not surface:Fetch(self.db.profile.bars.texture) then self.db.profile.bars.texture = "BantoBar" end
	self:SetupFrames()
	if not self:IsEventRegistered("Surface_Registered") then
		self:RegisterEvent("Surface_Registered", function()
			WarlockTimerFu.Menu.args[L["Bar Options"]][L["Visuals"]].args[L["Texture"]].validate = surface:List()
		end)
	end
self:RegisterEvent("PLAYER_DEAD", "Death")
parser:RegisterEvent("WarlockTimerFu", "CHAT_MSG_COMBAT_HOSTILE_DEATH", self.DeathOther)
self:RegHex(self.db.profile.bars.colors)
end

function WarlockTimerFu:BarDisable()
parser:UnregisterAllEvents("WarlockTimerFu")
end

function WarlockTimerFu:Safe()
self.db.profile.bars.Safe = not self.db.profile.bars.Safe
if not self.db.profile.bars.Safe then
parser:RegisterEvent("self", "CHAT_MSG_COMBAT_HOSTILE_DEATH", self.DeathOther)
else
parser:UnregisterEvent("self", "CHAT_MSG_COMBAT_HOSTILE_DEATH")
end
end

function WarlockTimerFu:Death()
if candy.groups["WarlockTimerFuGroup"]==nil then return end
for _,v in ipairs(candy.groups["WarlockTimerFuGroup"].bars) do
	candy:StopCandyBar(v)
	end
end

function WarlockTimerFu:DeathOther(info)
for k,v in pairs(candy.handlers) do
   if string.find(v.text, info.victim) then candy:StopCandyBar(k) end
end
end

function WarlockTimerFu:RGBToHex(r, g, b)
	return format("%02x%02x%02x", r*255, g*255, b*255)
end

function WarlockTimerFu:ShowAnchors()
	self.frames.anchor:Show()
end

function WarlockTimerFu:HideAnchors()
	self.frames.anchor:Hide()
end

function WarlockTimerFu:StartBar(text, target, applications, time, icon)
	if not text or not time then return end
	local id = "WarlockTimerFu "..text
	
	local u = self.db.profile.bars.growup
	local d = self.db.profile.bars.darken
	if applications and applications >= 2 then text = text.."("..applications..")" end
	if self.db.profile.bars.name and target and target ~= "" and target ~= ParserLib_SELF then text = text.." ("..target..")" end
	-- yes we try and register every time, we also set the point every time since people can change their mind session.
	self:RegisterCandyBarGroup("WarlockTimerFuGroup")
	self:SetCandyBarGroupPoint("WarlockTimerFuGroup", u and "BOTTOM" or "TOP", self.frames.anchor, u and "TOP" or "BOTTOM", 0, 0)
	self:SetCandyBarGroupGrowth("WarlockTimerFuGroup", u)
	
	if d then 
		self:RegisterCandyBar(id, time, text, icon, "Green", "Red")
	else
		self:RegisterCandyBar(id, time, text, icon, self.db.profile.bars.colors.mainc)
	end
	self:SetCandyBarFontSize(id, self.db.profile.bars.Size)
	self:SetCandyBarReversed(id, self.db.profile.bars.Reversed)
	self:RegisterCandyBarWithGroup(id, "WarlockTimerFuGroup")
	self:SetCandyBarTexture( id, surface:Fetch( self.db.profile.bars.texture) )
	
	bc, balpha, txtc = self.db.profile.bars.colors.bgc, self.db.profile.bars.colors.bga, self.db.profile.bars.colors.txtc
	if bc then self:SetCandyBarBackgroundColor(id, bc, balpha) end
	if txtc then self:SetCandyBarTextColor(id, txtc) end
	
	self:SetCandyBarOnClick(id, function(id, button) WarlockTimerFu:OnClick(id, button) end)
	self:SetCandyBarScale(id, self.db.profile.bars.scale)
	self:SetCandyBarFade(id, .5)
	self:StartCandyBar(id, true)
end

local function time(t)
	local m = floor(t/60)
	local s = t - (m*60)
	if m > 0 then
		timetext = string.format("%d:%02d mins", m, floor(s))
	elseif s < 10 then
		timetext = string.format("%1.1f secs", s)
	else
		timetext = string.format("%.0f secs", floor(s))
	end
return timetext
end

function WarlockTimerFu:OnClick(id, button)
local msg = candy.handlers[id].text.." has "..time(candy.handlers[id].time-candy.handlers[id].elapsed).." remaining"
if button == "LeftButton" then
	if UnitInRaid("player") then
		SendChatMessage(msg, "RAID")
		return
	elseif UnitInParty("player") then
		SendChatMessage(msg, "PARTY")
	end
end
end

function WarlockTimerFu:StopBar(text, text2)
	if (not text or self.db.profile.bars.Safe) and text2 ~= ParserLib_SELF then return end
	self:UnregisterCandyBar("WarlockTimerFuBar "..text)
	if not text2 then return end
	self:UnregisterCandyBar("WarlockTimerFuBar "..text.." ("..text2..")")
end

function WarlockTimerFu:SetupFrames()
	local f, t

	f, _, _ = GameFontNormal:GetFont()

	self.frames = {}
	self.frames.anchor = CreateFrame("Frame", "WarlockTimerFuAnchor", UIParent)
	self.frames.anchor.owner = self
	self.frames.anchor:Hide()

	self.frames.anchor:SetWidth(175)
	self.frames.anchor:SetHeight(75)
	self.frames.anchor:SetBackdrop({
		bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background", tile = true, tileSize = 16,
		edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", edgeSize = 16,
		insets = {left = 4, right = 4, top = 4, bottom = 4},
		})
	self.frames.anchor:SetBackdropBorderColor(.5, .5, .5)
	self.frames.anchor:SetBackdropColor(0,0,0)
	self.frames.anchor:ClearAllPoints()
	self.frames.anchor:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
	self.frames.anchor:EnableMouse(true)
	self.frames.anchor:RegisterForDrag("LeftButton")
	self.frames.anchor:SetMovable(true)
	self.frames.anchor:SetScript("OnDragStart", function() this:StartMoving() end)
	self.frames.anchor:SetScript("OnDragStop", function() this:StopMovingOrSizing() this.owner:SavePosition() end)

	self.frames.cfade = self.frames.anchor:CreateTexture(nil, "BORDER")
	self.frames.cfade:SetWidth(169)
	self.frames.cfade:SetHeight(25)
	self.frames.cfade:SetTexture("Interface\\ChatFrame\\ChatFrameBackground")
	self.frames.cfade:SetPoint("TOP", self.frames.anchor, "TOP", 0, -4)
	self.frames.cfade:SetBlendMode("ADD")
	self.frames.cfade:SetGradientAlpha("VERTICAL", .1, .1, .1, 0, .25, .25, .25, 1)
	self.frames.anchor.Fade = self.frames.fade

	self.frames.cheader = self.frames.anchor:CreateFontString(nil,"OVERLAY")
	self.frames.cheader:SetFont(f, 14)
	self.frames.cheader:SetWidth(150)
	self.frames.cheader:SetText("Bars")
	self.frames.cheader:SetTextColor(1, .8, 0)
	self.frames.cheader:ClearAllPoints()
	self.frames.cheader:SetPoint("TOP", self.frames.anchor, "TOP", 0, -10)

	self.frames.leftbutton = CreateFrame("Button", nil, self.frames.anchor)
	self.frames.leftbutton.owner = self
	self.frames.leftbutton:SetWidth(40)
	self.frames.leftbutton:SetHeight(25)
	self.frames.leftbutton:SetPoint("RIGHT", self.frames.anchor, "CENTER", -10, -15)
	self.frames.leftbutton:SetScript( "OnClick", function()  self:Test() end )

	t = self.frames.leftbutton:CreateTexture()
	t:SetWidth(50)
	t:SetHeight(32)
	t:SetPoint("CENTER", self.frames.leftbutton, "CENTER")
	t:SetTexture("Interface\\Buttons\\UI-Panel-Button-Up")
	t:SetTexCoord(0, 0.625, 0, 0.6875)
	self.frames.leftbutton:SetNormalTexture(t)

	t = self.frames.leftbutton:CreateTexture(nil, "BACKGROUND")
	t:SetTexture("Interface\\Buttons\\UI-Panel-Button-Down")
	t:SetTexCoord(0, 0.625, 0, 0.6875)
	t:SetAllPoints(self.frames.leftbutton)
	self.frames.leftbutton:SetPushedTexture(t)

	t = self.frames.leftbutton:CreateTexture()
	t:SetTexture("Interface\\Buttons\\UI-Panel-Button-Highlight")
	t:SetTexCoord(0, 0.625, 0, 0.6875)
	t:SetAllPoints(self.frames.leftbutton)
	t:SetBlendMode("ADD")
	self.frames.leftbutton:SetHighlightTexture(t)
	self.frames.leftbuttontext = self.frames.leftbutton:CreateFontString(nil,"OVERLAY")
	self.frames.leftbuttontext:SetFontObject(GameFontHighlight)
	self.frames.leftbuttontext:SetText("Test")
	self.frames.leftbuttontext:SetAllPoints(self.frames.leftbutton)

	self.frames.rightbutton = CreateFrame("Button", nil, self.frames.anchor)
	self.frames.rightbutton.owner = self
	self.frames.rightbutton:SetWidth(40)
	self.frames.rightbutton:SetHeight(25)
	self.frames.rightbutton:SetPoint("LEFT", self.frames.anchor, "CENTER", 10, -15)
	self.frames.rightbutton:SetScript( "OnClick", function() self:HideAnchors() end )

	t = self.frames.rightbutton:CreateTexture()
	t:SetWidth(50)
	t:SetHeight(32)
	t:SetPoint("CENTER", self.frames.rightbutton, "CENTER")
	t:SetTexture("Interface\\Buttons\\UI-Panel-Button-Up")
	t:SetTexCoord(0, 0.625, 0, 0.6875)
	self.frames.rightbutton:SetNormalTexture(t)

	t = self.frames.rightbutton:CreateTexture(nil, "BACKGROUND")
	t:SetTexture("Interface\\Buttons\\UI-Panel-Button-Down")
	t:SetTexCoord(0, 0.625, 0, 0.6875)
	t:SetAllPoints(self.frames.rightbutton)
	self.frames.rightbutton:SetPushedTexture(t)

	t = self.frames.rightbutton:CreateTexture()
	t:SetTexture("Interface\\Buttons\\UI-Panel-Button-Highlight")
	t:SetTexCoord(0, 0.625, 0, 0.6875)
	t:SetAllPoints(self.frames.rightbutton)
	t:SetBlendMode("ADD")
	self.frames.rightbutton:SetHighlightTexture(t)
	self.frames.rightbuttontext = self.frames.rightbutton:CreateFontString(nil,"OVERLAY")
	self.frames.rightbuttontext:SetFontObject(GameFontHighlight)
	self.frames.rightbuttontext:SetText("Close")
	self.frames.rightbuttontext:SetAllPoints(self.frames.rightbutton)

	self:RestorePosition()
end

function WarlockTimerFu:SavePosition()
	local f = self.frames.anchor
	local s = f:GetEffectiveScale()

	self.db.profile.bars.posx = f:GetLeft() * s
	self.db.profile.bars.posy = f:GetTop() * s
end

function WarlockTimerFu:RestorePosition()
	local x = self.db.profile.bars.posx
	local y = self.db.profile.bars.posy

	if not x or not y then return end

	local f = self.frames.anchor
	local s = f:GetEffectiveScale()

	f:ClearAllPoints()
	f:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", x / s, y / s)
end


function WarlockTimerFu:Test()
self:StartBar(L["Testing..."], nil, nil,15)
self:StartBar(L["Wait! a Test!"], nil, nil, 5)
end 