--[[
Name: CandyBar-2.0
Revision: $Rev: 15771 $
Author: Ammo (wouter@muze.nl)
Website: http://www.wowace.com/
Documentation: http://www.wowace.com/
SVN: svn://svn.wowace.com/root/trunk/CandyBar/CandyBar-2.0
Description: A timer bars library
Dependencies: AceLibrary, AceOO-2.0, PaintChips-2.0, (optional) Compost-2.0
]]

local vmajor, vminor = "CandyBar-2.0", "$Revision: 15771 $"

if not AceLibrary then error(vmajor .. " requires AceLibrary.") end
if not AceLibrary:IsNewVersion(vmajor, vminor) then return end

if not AceLibrary:HasInstance("AceOO-2.0") then error(vmajor .. " requires AceOO-2.0") end

if not AceLibrary:HasInstance("PaintChips-2.0") then error(vmajor .. " requires PaintChips-2.0") end

local compost = AceLibrary:HasInstance("Compost-2.0") and AceLibrary("Compost-2.0")
local paint = AceLibrary("PaintChips-2.0")

local AceOO = AceLibrary:GetInstance("AceOO-2.0")
local Mixin = AceOO.Mixin
local CandyBar = Mixin {
	"RegisterCandyBar",
	"UnregisterCandyBar",
	"IsCandyBarRegistered",
	"StartCandyBar",
	"StopCandyBar",
	"PauseCandyBar",
	"CandyBarStatus",
	"SetCandyBarTexture",
	"SetCandyBarTime",
	"SetCandyBarColor",
	"SetCandyBarText",
	"SetCandyBarIcon",
	"SetCandyBarWidth",
	"SetCandyBarHeight",
	"SetCandyBarBackgroundColor",
	"SetCandyBarTextColor",
	"SetCandyBarTimerTextColor",
	"SetCandyBarFontSize",
	"SetCandyBarPoint",
	"SetCandyBarGradient",
	"SetCandyBarScale",
	"SetCandyBarTimeFormat",
	"SetCandyBarTimeLeft",
	"SetCandyBarCompletion",
	"SetCandyBarFade",
	"RegisterCandyBarGroup",
	"UnregisterCandyBarGroup",
	"IsCandyBarGroupRegistered",
	"SetCandyBarGroupPoint",
	"SetCandyBarGroupGrowth",
	"UpdateCandyBarGroup",
	"RegisterCandyBarWithGroup",
	"UnregisterCandyBarWithGroup",
	"IsCandyBarRegisteredWithGroup",
	"SetCandyBarReversed",
	"IsCandyBarReversed",
	"SetCandyBarOnClick",
}


local function getnewtable() return compost and compost:Acquire() or {} end
local function reclaimtable(t) if compost then compost:Reclaim(t) end end


-- Registers a new candy bar
-- name - A unique identifier for your bar.
-- time - Time for the bar
-- text - text displayed on the bar [defaults to the name if not set]
-- icon - icon off the bar [optional]
-- c1 - c10 - color of the bar [optional]
-- returns true on a succesful register
function CandyBar:Register(name, time, text, icon, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10)
	CandyBar:argCheck(name, 2, "string")
	CandyBar:argCheck(time, 3, "number")
	if not name or not time then return end
	if CandyBar.var.handlers[name] then self:Unregister(name) end
	local t = getnewtable()
	t.name, t.time, t.text, t.icon = name, time, text or name, icon
	t.texture = CandyBar.var.defaults.texture
	t.color = {}
	if not paint:GetRGBPercent(c1) then c1 = "green" end
	_, t.color[1], t.color[2], t.color[3] = paint:GetRGBPercent(c1)
	t.color[4] = 1
	t.running = nil
	t.endtime = 0
	t.reversed = nil
	CandyBar.var.handlers[name] = t
	CandyBar.var.handlers[name].frame = CandyBar:AcquireBarFrame(name)
	if c1 and c2 then
		CandyBar:SetGradient( name, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10)
	end
	return true
end


-- Removes a candy bar
-- a1 - a10 handlers that you wish to remove
-- returns true upon sucessful removal
function CandyBar:Unregister(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
	CandyBar:argCheck(a1, 2, "string")
	if not CandyBar.var.handlers[a1] then return end
	CandyBar:UnregisterWithGroup(a1)
	CandyBar:ReleaseBarFrame(a1)
	reclaimtable(CandyBar.var.handlers[a1])
	CandyBar.var.handlers[a1] = nil
	if a2 then CandyBar:Unregister(a2,a3,a4,a5,a6,a7,a8,a9,a10)
	elseif not CandyBar:HasHandlers() then CandyBar.var.frame:Hide() end
	return true
end

-- Checks if a candy bar is registered
-- Args: name - name of the candybar
-- returns true if a the candybar is registered
function CandyBar:IsRegistered(name)
	CandyBar:argCheck(name, 2, "string")
	if CandyBar.var.handlers[name] then return true end
	return false
end

-- Start a bar
-- Args:  name - the candybar you want to start
--        fireforget [optional] - pass true if you want the bar to unregister upon completion
-- returns true if succesful
function CandyBar:Start( name, fireforget )
	CandyBar:argCheck(name, 2, "string")
	if not CandyBar.var.handlers[name] then return end
	local t = GetTime()
	if CandyBar.var.handlers[name].paused then
		local pauseoffset = t - CandyBar.var.handlers[name].pausetime
		CandyBar.var.handlers[name].endtime = CandyBar.var.handlers[name].endtime + pauseoffset
		CandyBar.var.handlers[name].starttime = CandyBar.var.handlers[name].starttime + pauseoffset
	else
		-- bar hasn't elapsed a second.
		CandyBar.var.handlers[name].elapsed = 0
		CandyBar.var.handlers[name].endtime = t + CandyBar.var.handlers[name].time
		CandyBar.var.handlers[name].starttime = t
	end
	CandyBar.var.handlers[name].fireforget = fireforget
	CandyBar.var.handlers[name].running = true
	CandyBar.var.handlers[name].paused = nil
	CandyBar.var.handlers[name].fading = nil
	CandyBar:AcquireBarFrame( name ) -- this will reset the barframe incase we were fading out when it was restarted
	CandyBar.var.handlers[name].frame:Show()
	if CandyBar.var.handlers[name].group then CandyBar:UpdateGroup( CandyBar.var.handlers[name].group ) end -- update the group
	CandyBar.var.frame:Show()
	return true

end

-- Stop a bar
-- Args:  name - the candybar you want to stop
-- returns true if succesful
function CandyBar:Stop( name)
	CandyBar:argCheck(name, 2, "string")
	if not CandyBar.var.handlers[name] then return end

	CandyBar.var.handlers[name].running = nil
	CandyBar.var.handlers[name].paused = nil

	if CandyBar.var.handlers[name].fadeout then
		CandyBar.var.handlers[name].frame.spark:Hide()
		CandyBar.var.handlers[name].fading = true
		CandyBar.var.handlers[name].fadeelapsed = 0
		local t = GetTime()
		if CandyBar.var.handlers[name].endtime > t then
			CandyBar.var.handlers[name].endtime = t
		end

		local reversed = CandyBar.var.handlers[name].reversed
	else
		CandyBar.var.handlers[name].frame:Hide()
		CandyBar.var.handlers[name].starttime = nil
		CandyBar.var.handlers[name].endtime = 0
		if CandyBar.var.handlers[name].group then CandyBar:UpdateGroup(CandyBar.var.handlers[name].group) end
		if CandyBar.var.handlers[name].fireforget then
			return CandyBar:Unregister(name)
		end
	end
	if not CandyBar:HasHandlers() then CandyBar.var.frame:Hide() end
	return true
end

-- Pause a bar
-- Name - the candybar you want to pause
-- returns true if succesful
function CandyBar:Pause( name )
	CandyBar:argCheck(name, 2, "string")
	if not CandyBar.var.handlers[name] then return end
	CandyBar.var.handlers[name].pausetime = GetTime()
	CandyBar.var.handlers[name].paused = true
	CandyBar.var.handlers[name].running = nil
end

-- Query a timer's status
-- Args: name - the schedule you wish to look up
-- Returns: registered - true if a schedule exists with this name
--	    time    - time for this bar
--          elapsed - time elapsed for this bar
--          running - true if this schedule is currently running
function CandyBar:Status(name)
	CandyBar:argCheck(name, 2, "string")
	if not CandyBar.var.handlers[name] then return end
	return true, CandyBar.var.handlers[name].time, CandyBar.var.handlers[name].elapsed, CandyBar.var.handlers[name].running, CandyBar.var.handlers[name].paused
end


-- Set the time for a bar.
-- Args: name - the candybar name
--	 time - the new time for this bar
-- returns true if succesful
function CandyBar:SetTime(name, time)
	CandyBar:argCheck(name, 2, "string")
	CandyBar:argCheck(time, 3, "number")
	if not CandyBar.var.handlers[name] then return end
	CandyBar.var.handlers[name].time = time
	if CandyBar.var.handlers[name].starttime and CandyBar.var.handlers[name].endtime then
		CandyBar.var.handlers[name].endtime = CandyBar.var.handlers[name].starttime + time 
	end
	return true
end

-- Set the time left for a bar.
-- Args: name - the candybar name
--       time - time left on the bar
-- returns true if succesful

function CandyBar:SetTimeLeft(name, time)
	CandyBar:argCheck(name, 2, "string")
	CandyBar:argCheck(time, 3, "number")
	if not CandyBar.var.handlers[name] then return end
	if CandyBar.var.handlers[name].time < time or time < 0 then return end

	local e = CandyBar.var.handlers[name].time - time
	local d = CandyBar.var.handlers[name].elapsed - e
	if CandyBar.var.handlers[name].starttime and CandyBar.var.handlers[name].endtime then
		CandyBar.var.handlers[name].starttime = CandyBar.var.handlers[name].starttime + d
		CandyBar.var.handlers[name].endtime = CandyBar.var.handlers[name].endtime + d
	end

	CandyBar.var.handlers[name].elapsed = e

	return true
end

-- Sets smooth coloring of the bar depending on time elapsed
-- Args: name - the candybar name
--       c1 - c10 color order of the gradient
-- returns true when succesful
function CandyBar:SetGradient(name, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10)
	CandyBar:argCheck(name, 2, "string")

	CandyBar:argCheck(c1, 3, "string")
	CandyBar:argCheck(c2, 4, "string")

	if not CandyBar.var.handlers[name] then return end
	if not c1 or not c2 then return end


	local gtable = {}

	gtable[1] = {}
	gtable[2] = {}

	if not paint:GetRGBPercent(c1) then c1 = "green" end
	if not paint:GetRGBPercent(c2) then c2 = "green" end
	if c3 and not paint:GetRGBPercent(c3) then c3 = "green" end
	if c4 and not paint:GetRGBPercent(c4) then c4 = "green" end
	if c5 and not paint:GetRGBPercent(c5) then c5 = "green" end
	if c6 and not paint:GetRGBPercent(c6) then c6 = "green" end
	if c7 and not paint:GetRGBPercent(c7) then c7 = "green" end
	if c8 and not paint:GetRGBPercent(c8) then c8 = "green" end
	if c9 and not paint:GetRGBPercent(c9) then c9 = "green" end
	if c10 and not paint:GetRGBPercent(c10) then c10 = "green" end

	_, gtable[1][1], gtable[1][2], gtable[1][3] = paint:GetRGBPercent(c1)
	_, gtable[2][1], gtable[2][2], gtable[2][3] = paint:GetRGBPercent(c2)
	if c3 then gtable[3] = {} _, gtable[3][1], gtable[3][2], gtable[3][3] = paint:GetRGBPercent(c3) end
	if c4 then gtable[4] = {} _, gtable[4][1], gtable[4][2], gtable[4][3] = paint:GetRGBPercent(c4) end
	if c5 then gtable[5] = {} _, gtable[5][1], gtable[5][2], gtable[5][3] = paint:GetRGBPercent(c5) end
	if c6 then gtable[6] = {} _, gtable[6][1], gtable[6][2], gtable[6][3] = paint:GetRGBPercent(c6) end
	if c7 then gtable[7] = {} _, gtable[7][1], gtable[3][2], gtable[7][3] = paint:GetRGBPercent(c7) end
	if c8 then gtable[8] = {} _, gtable[8][1], gtable[8][2], gtable[8][3] = paint:GetRGBPercent(c8) end
	if c9 then gtable[9] = {} _, gtable[9][1], gtable[9][2], gtable[9][3] = paint:GetRGBPercent(c9) end
	if c10 then gtable[10] = {} _, gtable[10][1], gtable[10][2], gtable[10][3] = paint:GetRGBPercent(c10) end



	local max = table.getn(gtable)

	for i = 1, max do
		if not gtable[i][4] then gtable[i][4] = 1 end
		gtable[i][5] = (i-1) / (max-1)
	end

	self.var.handlers[name].gradienttable = gtable
	self.var.handlers[name].gradient = true

	CandyBar.var.handlers[name].frame.statusbar:SetStatusBarColor( gtable[1][1], gtable[1][2], gtable[1][3], gtable[1][4])

	return true
end

-- Set the color of the bar
-- Args: name - the candybar name
--	 color - new color of the bar
--	 alpha - new alpha of the bar
-- Setting the color will override smooth settings.
function CandyBar:SetColor(name, color, alpha)
	CandyBar:argCheck(name, 2, "string")
	CandyBar:argCheck(color, 3, "string")

	if not CandyBar.var.handlers[name] then return end

	if not paint:GetRGBPercent(color) then return end

	local ctable = {}

	_, ctable[1], ctable[2], ctable[3] = paint:GetRGBPercent(color)

	if alpha then ctable[4] = alpha else ctable[4] = 1 end

	CandyBar.var.handlers[name].color = ctable
	CandyBar.var.handlers[name].gradient = nil

	CandyBar.var.handlers[name].frame.statusbar:SetStatusBarColor( ctable[1], ctable[2], ctable[3], ctable[4] )

	return true
end

-- Set the color of background of the bar
-- Args: name - the candybar name
--	 color - new color of the bar
-- 	 alpha - new alpha of the bar
-- Setting the color will override smooth settings.
function CandyBar:SetBackgroundColor(name, color, alpha)
	CandyBar:argCheck(name, 2, "string")
	CandyBar:argCheck(color, 3, "string")

	if not CandyBar.var.handlers[name] then return end

	if not paint:GetRGBPercent(color) then return end

	local ctable = {}

	_, ctable[1], ctable[2], ctable[3] = paint:GetRGBPercent(color)

	if alpha then ctable[4] = alpha else ctable[4] = 1 end

	CandyBar.var.handlers[name].bgcolor = ctable

	CandyBar.var.handlers[name].frame.statusbarbg:SetStatusBarColor( ctable[1], ctable[2], ctable[3], ctable[4] )

	return true
end

-- Set the color for the bar text
-- Args: name - name of the candybar
--	 color - new color of the text
--	 alpha - new alpha of the text
-- returns true when succesful
function CandyBar:SetTextColor(name, color, alpha)
	CandyBar:argCheck(name, 2, "string")
	CandyBar:argCheck(color, 3, "string")

	if not CandyBar.var.handlers[name] then return end

	if not paint:GetRGBPercent(color) then return end

	local ctable = {}

	_, ctable[1], ctable[2], ctable[3] = paint:GetRGBPercent(color)

	if alpha then ctable[4] = alpha else ctable[4] = 1 end


	CandyBar.var.handlers[name].textcolor = ctable

	CandyBar.var.handlers[name].frame.text:SetTextColor( ctable[1], ctable[2], ctable[3], ctable[4] )

	return true
end

-- Set the color for the timer text
-- Args: name - name of the candybar
--	 color - new color of the text
--	 alpha - new alpha of the text
-- returns true when succesful
function CandyBar:SetTimerTextColor(name, color, alpha)
        CandyBar:argCheck(name, 2, "string")
        CandyBar:argCheck(color, 3, "string")
	if not CandyBar.var.handlers[name] then return end

	if not paint:GetRGBPercent(color) then return end

	local ctable = {}

	_, ctable[1], ctable[2], ctable[3] = paint:GetRGBPercent(color)

	if alpha then ctable[4] = alpha else ctable[4] = 1 end

	CandyBar.var.handlers[name].timertextcolor = ctable

	CandyBar.var.handlers[name].frame.timertext:SetTextColor( ctable[1], ctable[2], ctable[3], ctable[4] )

	return true
end

-- Set the text for the bar
-- Args: name - name of the candybar
--       text - text to set it to
-- returns true when succesful
function CandyBar:SetText(name, text)
	CandyBar:argCheck(name, 2, "string")
	CandyBar:argCheck(text, 2, "string")
	if not CandyBar.var.handlers[name] then return end

	CandyBar.var.handlers[name].text = text
	CandyBar.var.handlers[name].frame.text:SetText(text)

	return true
end

-- Set the fontsize
-- Args: name - name of the candybar
-- 	     fontsize - new fontsize
-- returns true when succesful
function CandyBar:SetFontSize(name, fontsize)
	CandyBar:argCheck(name, 2, "string")
	CandyBar:argCheck(fontsize, 3, "number")

	if not CandyBar.var.handlers[name] then return end

	local font, _, _ = GameFontHighlight:GetFont()
	local timertextwidth = fontsize * 3
	local width = CandyBar.var.handlers[name].width or CandyBar.var.defaults.width
	local f = CandyBar.var.handlers[name].frame

	CandyBar.var.handlers[name].fontsize = fontsize
	f.timertext:SetFont(font, fontsize)
	f.text:SetFont(font, fontsize)
	f.timertext:SetWidth( timertextwidth )
	f.text:SetWidth( ( width - timertextwidth ) * .9 )

	return true
end


-- Set the point where a bar should be anchored
-- Args: name -- name of the bar
-- 	 point -- anchor point
-- 	 rframe -- relative frame
-- 	 rpoint -- relative point
-- 	 xoffset -- x offset
-- 	 yoffset -- y offset
-- returns true when succesful
function CandyBar:SetPoint(name, point, rframe, rpoint, xoffset, yoffset)
        CandyBar:argCheck(name, 2, "string")

	if not CandyBar.var.handlers[name] then return end

	CandyBar.var.handlers[name].point = point
	CandyBar.var.handlers[name].rframe = rframe
	CandyBar.var.handlers[name].rpoint = rpoint
	CandyBar.var.handlers[name].xoffset = xoffset
	CandyBar.var.handlers[name].yoffset = yoffset

	CandyBar.var.handlers[name].frame:ClearAllPoints()
	CandyBar.var.handlers[name].frame:SetPoint(point, rframe,rpoint,xoffset,yoffset)

	return true
end

-- Set the width for a bar
-- Args: name - name of the candybar
--       width - new width of the candybar
-- returns true when succesful
function CandyBar:SetWidth(name, width)
        CandyBar:argCheck(name, 2, "string")
        CandyBar:argCheck(width, 3, "number")

	if not CandyBar.var.handlers[name] then return end

	local height = CandyBar.var.handlers[name].height or CandyBar.var.defaults.height
	local fontsize = CandyBar.var.handlers[name].fontsize or CandyBar.var.defaults.fontsize
	local timertextwidth = fontsize * 3
	local f = CandyBar.var.handlers[name].frame
	f:SetWidth( width + height )
	f.statusbar:SetWidth( width )
	f.statusbarbg:SetWidth( width )

	f.timertext:SetWidth( timertextwidth )
	f.text:SetWidth( ( width - timertextwidth ) * .9 )

	CandyBar.var.handlers[name].width = width

	return true
end

-- Set the height for a bar
-- Args: name - name of the candybar
--       height - new height for the bar
-- returs true when succesful
function CandyBar:SetHeight(name, height)
        CandyBar:argCheck(name, 2, "string")
        CandyBar:argCheck(height, 3, "number")

	if not CandyBar.var.handlers[name] then return end

	local width = CandyBar.var.handlers[name].width or CandyBar.var.defaults.width
	local f = CandyBar.var.handlers[name].frame

	f:SetWidth( width + height )
	f:SetHeight( height )
	f.icon:SetWidth( height )
	f.icon:SetHeight( height )
	f.statusbar:SetHeight( height )
	f.statusbarbg:SetHeight( height )
	f.spark:SetHeight( height + 25 )

	f.statusbarbg:SetPoint( "TOPLEFT", f, "TOPLEFT", height, 0)
	f.statusbar:SetPoint("TOPLEFT", f, "TOPLEFT", height, 0)

	CandyBar.var.handlers[name].height = height


	return true
end

-- Set the scale for a bar
-- Args: name - name of the candybar
-- 	 scale - new scale of the bar
-- returns true when succesful
function CandyBar:SetScale(name, scale)
        CandyBar:argCheck(name, 2, "string")
        CandyBar:argCheck(scale, 3, "number")

	if not CandyBar.var.handlers[name] then return end

	CandyBar.var.handlers[name].scale = scale

	CandyBar.var.handlers[name].frame:SetScale( scale )

	return true
end

-- Set the time formatting function for a bar
-- Args: name - name of the candybar
--       func - function that returns the formatted string
-- 	     a1-a10 - optional arguments to that function
-- returns true when succesful

function CandyBar:SetTimeFormat(name, func, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
	CandyBar:argCheck(name, 2, "string")
	CandyBar:argCheck(func, 3, "function")

	if not CandyBar.var.handlers[name] then return end
	CandyBar.var.handlers[name].timeformat = func
	CandyBar.var.handlers[name].timeformat1 = a1
	CandyBar.var.handlers[name].timeformat2 = a2
	CandyBar.var.handlers[name].timeformat3 = a3
	CandyBar.var.handlers[name].timeformat4 = a4
	CandyBar.var.handlers[name].timeformat5 = a5
	CandyBar.var.handlers[name].timeformat6 = a6
	CandyBar.var.handlers[name].timeformat7 = a7
	CandyBar.var.handlers[name].timeformat8 = a8
	CandyBar.var.handlers[name].timeformat9 = a9
	CandyBar.var.handlers[name].timeformat10 = a10

	return true
end

-- Set the completion function for a bar
-- Args: name - name of the candybar
--		   func - function to call upon ending of the bar
--       a1 - a10 - arguments to pass to the function
-- returns true when succesful
function CandyBar:SetCompletion(name, func, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
	CandyBar:argCheck(name, 2, "string")
	CandyBar:argCheck(func, 3, "function")

	if not CandyBar.var.handlers[name] then return end
	CandyBar.var.handlers[name].completion = func
	CandyBar.var.handlers[name].completion1 = a1
	CandyBar.var.handlers[name].completion2 = a2
	CandyBar.var.handlers[name].completion3 = a3
	CandyBar.var.handlers[name].completion4 = a4
	CandyBar.var.handlers[name].completion5 = a5
	CandyBar.var.handlers[name].completion6 = a6
	CandyBar.var.handlers[name].completion7 = a7
	CandyBar.var.handlers[name].completion8 = a8
	CandyBar.var.handlers[name].completion9 = a9
	CandyBar.var.handlers[name].completion10 = a10

	return true

end

-- Set the on click function for a bar
-- Args: name - name of the candybar
--		   func - function to call when the bar is clicked
--       a1 - a10 - arguments to pass to the function
-- returns true when succesful
function CandyBar:SetOnClick(name, func, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
	CandyBar:argCheck(name, 2, "string")
	if func then CandyBar:argCheck(func, 3, "function") end

	if not CandyBar.var.handlers[name] then return end
	CandyBar.var.handlers[name].onclick = func
	CandyBar.var.handlers[name].onclick1 = a1
	CandyBar.var.handlers[name].onclick2 = a2
	CandyBar.var.handlers[name].onclick3 = a3
	CandyBar.var.handlers[name].onclick4 = a4
	CandyBar.var.handlers[name].onclick5 = a5
	CandyBar.var.handlers[name].onclick6 = a6
	CandyBar.var.handlers[name].onclick7 = a7
	CandyBar.var.handlers[name].onclick8 = a8
	CandyBar.var.handlers[name].onclick9 = a9
	CandyBar.var.handlers[name].onclick10 = a10

	if func then
		-- enable mouse
		CandyBar.var.handlers[name].frame:EnableMouse(true)
		CandyBar.var.handlers[name].frame:RegisterForClicks("LeftButtonUp", "RightButtonUp", "MiddleButtonUp", "Button4Up", "Button5Up")
		CandyBar.var.handlers[name].frame:SetScript("OnClick", function() CandyBar:OnClick() end )
		CandyBar.var.handlers[name].frame.icon:EnableMouse(true)
		CandyBar.var.handlers[name].frame.icon:RegisterForClicks("LeftButtonUp", "RightButtonUp", "MiddleButtonUp", "Button4Up", "Button5Up")
		CandyBar.var.handlers[name].frame.icon:SetScript("OnClick", function() CandyBar:OnClick() end )
	else
		CandyBar.var.handlers[name].frame:EnableMouse(false)
		CandyBar.var.handlers[name].frame:RegisterForClicks()
		CandyBar.var.handlers[name].frame:SetScript("OnClick", nil )
		CandyBar.var.handlers[name].frame.icon:EnableMouse(false)
		CandyBar.var.handlers[name].frame.icon:RegisterForClicks()
		CandyBar.var.handlers[name].frame.icon:SetScript("OnClick", nil )	
	end

	return true

end
-- Set the texture for a bar
-- Args: name - name of the candybar
--	 texture - new texture, if passed nil, the texture is reset to default
-- returns true when succesful
function CandyBar:SetTexture(name, texture)
        CandyBar:argCheck(name, 2, "string")
	if texture then CandyBar:argCheck(texture, 3, "string") end

	if not CandyBar.var.handlers[name] then return end
	if not texture then texture = CandyBar.var.defaults.texture end

	CandyBar.var.handlers[name].texture = texture

	CandyBar.var.handlers[name].frame.statusbar:SetStatusBarTexture(texture)
	CandyBar.var.handlers[name].frame.statusbarbg:SetStatusBarTexture(texture)

	return true
end

-- Set the icon on a bar
-- Args: name - name of the candybar
-- 	 icon - icon path, nil removes the icon
-- returns true when succesful
function CandyBar:SetIcon(name, icon)
	CandyBar:argCheck(name, 2, "string")
        CandyBar:argCheck(icon, 3, "string")

	if not CandyBar.var.handlers[name] then return end
	CandyBar.var.handlers[name].icon = icon

	if not icon then
		CandyBar.var.hanlders[name].frame.icon:Hide()
	else
		CandyBar.var.handlers[name].frame.icon:SetNormalTexture( icon )
		CandyBar.var.handlers[name].frame.icon:Show()
	end

	return true
end

-- Sets the fading style of a candybar
-- args: name - name of the candybar
--			 time - duration of the fade (default .5 seconds), negative to keep the bar on screen
-- returns true when succesful
function CandyBar:SetFade(name, time, fade)
	CandyBar:argCheck(name, 2, "string")
	CandyBar:argCheck(time, 3, "number")
	if not CandyBar.var.handlers[name] then return end

	CandyBar.var.handlers[name].fadetime = time
	CandyBar.var.handlers[name].fadeout = true

	return true
end


function CandyBar:SetReversed(name, reversed)
	CandyBar:argCheck(name, 2, "string")
	CandyBar:argCheck(reversed, 3, "boolean")
	if not CandyBar.var.handlers[name] then return end
	
	CandyBar.var.handlers[name].reversed = reversed
	return true
end

function CandyBar:IsReversed(name)
	CandyBar:argCheck(name, 2, "string")
	if not CandyBar.var.handlers[name] then return end

	return CandyBar.var.handlers[name].reversed
end


-- Registers a candybar with a certain candybar group
-- args: name - name of the candybar
--       group - group to register the bar with
-- returns true when succesful
function CandyBar:RegisterWithGroup( name, group )
	CandyBar:argCheck(name, 2, "string")
	CandyBar:argCheck(group, 3, "string")

	if not CandyBar.var.handlers[name] or not CandyBar.var.groups[group] then return end

	CandyBar:UnregisterWithGroup(name)

	table.insert( CandyBar.var.groups[group].bars, name)
	-- CandyBar.var.groups[group].bars[name] = name
	CandyBar.var.handlers[name].group = group
	CandyBar:UpdateGroup(group)

	return true
end

-- Unregisters a candybar from its group
-- args: name - name of the candybar
-- returns true when succesful

function CandyBar:UnregisterWithGroup( name )
	CandyBar:argCheck(name, 2, "string")
	if not CandyBar.var.handlers[name] then return end
	--if not CandyBar.var.handlers[name].group then return end

	local group = CandyBar.var.handlers[name].group
	if not CandyBar.var.groups[group] then return end

	for k,v in pairs( CandyBar.var.groups[group].bars ) do
		if v == name then
			table.remove( CandyBar.var.groups[group].bars, k)
		end
	end
	-- CandyBar.var.groups[group].bars[name] = nil
	CandyBar.var.handlers[name].group = nil

	CandyBar:UpdateGroup(group)

	return true

end



-- Register a Candybar group
-- Args: name - name of the candybar group
-- returns true when succesful
function CandyBar:RegisterGroup( name )
	CandyBar:argCheck(name, 2, "string")
	if CandyBar.var.groups[name] then return end

	local t = getnewtable()

	t.point = "CENTER"
	t.rframe = UIParent
	t.rpoint = "CENTER"
	t.xoffset = 0
	t.yoffset = 0
	t.bars = {}

	CandyBar.var.groups[name] = t
	return true
end

-- Unregister a candybar group
-- Args: a1-a2 candybar group ids
-- returns true when succesful

function CandyBar:UnregisterGroup( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 )
	CandyBar:argCheck(a1, 2, "string")
	if not CandyBar.var.groups[a1] then return end
	reclaimtable(CandyBar.var.groups[a1])
	CandyBar.var.groups[a1] = nil

	if a2 then CandyBar:UnregisterGroup( a2, a3,a4, a5, a6, a7, a8, a9, a10 )	end

	return true
end

-- Checks if a group is registered
-- Args: name - Candybar group
-- returns true if the candybar group is registered
function CandyBar:IsGroupRegistered( name )
	CandyBar:argCheck(name, 2, "string")
	if not CandyBar.var.groups[name] then return false end
	return true
end

-- Checks if a bar is registered with a group
-- Args: name - Candybar name
--       group - group id [optional]
-- returns true is the candybar is registered with a/the group
function CandyBar:IsRegisteredWithGroup( name, group )
	CandyBar:argCheck(name, 2, "string")
	if not CandyBar.var.handlers[name] then return end

	if group then
		if not CandyBar.var.groups[group] then return false end
		if CandyBar.var.handlers[name].group == group then return true end
	elseif CandyBar.var.handlers[name].group then
		return true
	end
	return false
end


-- Set the point for a CanyBargroup
-- 	 point -- anchor point
-- 	 rframe -- relative frame
-- 	 rpoint -- relative point
-- 	 xoffset [optional] -- x offset
-- 	 yoffset [optional] -- y offset
-- The first bar of the group will be anchored at the anchor.
-- returns true when succesful

function CandyBar:SetGroupPoint(name, point, rframe, rpoint, xoffset, yoffset )
	CandyBar:argCheck(name, 2, "string")
	if not CandyBar.var.groups[name] then return end

	CandyBar.var.groups[name].point = point
	CandyBar.var.groups[name].rframe = rframe
	CandyBar.var.groups[name].rpoint = rpoint
	CandyBar.var.groups[name].xoffset = xoffset
	CandyBar.var.groups[name].yoffset = yoffset
	CandyBar:UpdateGroup(name)
	return true
end


-- SetGroupGrowth - sets the group to grow up or down
-- Args: name - name of the candybar group
--       growup - true if growing up, false for growing down
-- returns true when succesful
function CandyBar:SetGroupGrowth( name, growup )
	CandyBar:argCheck(name, 2, "string")
	CandyBar:argCheck(growup, 3, "boolean")

	if not CandyBar.var.groups[name] then return end

	CandyBar.var.groups[name].growup = growup

	CandyBar:UpdateGroup(name)

	return true
end

function CandyBar:SortGroup( name )
	if not CandyBar.var.groups[name] then return end
	table.sort( CandyBar.var.groups[name].bars,
		function( a, b )
				return CandyBar.var.handlers[a].endtime < CandyBar.var.handlers[b].endtime
		end
	)
end

-- internal method
-- UpdateGroup - updates the location of bars in a group
-- Args: name - name of the candybar group
-- returns true when succesful

function CandyBar:UpdateGroup( name )
	if not CandyBar.var.groups[name] then return end

	local point = CandyBar.var.groups[name].point
	local rframe = CandyBar.var.groups[name].rframe
	local rpoint = CandyBar.var.groups[name].rpoint
	local xoffset = CandyBar.var.groups[name].xoffset
	local yoffset = CandyBar.var.groups[name].yoffset
	local m = -1
	if CandyBar.var.groups[name].growup then m = 1 end

	local bar = 0
	local barh = 0

	CandyBar:SortGroup( name )

	for c,n in pairs(CandyBar.var.groups[name].bars) do
		if CandyBar.var.handlers[n] then
			if CandyBar.var.handlers[n].frame:IsShown() then
				CandyBar:SetPoint(n, point, rframe, rpoint, xoffset, yoffset + (m * bar))
				barh = CandyBar.var.handlers[n].height or CandyBar.var.defaults.height
				bar = bar + barh
			end
		end
	end
	return true
end

-- Internal Method
-- Update a bar on screen
function CandyBar:Update( name )

	if not CandyBar.var.handlers[name] then return end

	local t = CandyBar.var.handlers[name].time - CandyBar.var.handlers[name].elapsed

	local timetext

	local reversed = CandyBar.var.handlers[name].reversed

	if CandyBar.var.handlers[name].timeformat then
		local c = CandyBar.var.handlers[name]
		timetext = CandyBar.var.handlers[name].timeformat(t, c.timeformat1, c.timeformat2, c.timeformat3, c.timeformat4, c.timeformat5, c.timeformat6, c.timeformat7, c.timeformat8, c.timeformat9, c.timeformat10 )
	else
		local h = floor(t/3600)
		local m = t - (h*3600)
		m = floor(m/60)
		local s = t - ((h*3600) + (m*60))
		if h > 0 then
			timetext = string.format("%d:%02d", h, m)
		elseif m > 0 then
			timetext = string.format("%d:%02d", m, s)
		elseif s < 10 then
			timetext = string.format("%1.1f", s)
		else
			timetext = string.format("%d", floor(s))
		end
	end
	CandyBar.var.handlers[name].frame.timertext:SetText(timetext)

	local perc = t / CandyBar.var.handlers[name].time

	CandyBar.var.handlers[name].frame.statusbar:SetValue(reversed and 1-perc or perc)

	local width = CandyBar.var.handlers[name].width or CandyBar.var.defaults.width

	local sp = width * perc
	sp = reversed and -sp or sp
	CandyBar.var.handlers[name].frame.spark:SetPoint("CENTER", CandyBar.var.handlers[name].frame.statusbar, reversed and "RIGHT" or "LEFT", sp, 0)

	if CandyBar.var.handlers[name].gradient then
		local p = CandyBar.var.handlers[name].elapsed / CandyBar.var.handlers[name].time
		local gstart, gend, gp
		-- find the appropriate start/end
		for i = 1, table.getn(CandyBar.var.handlers[name].gradienttable)-1 do
			if CandyBar.var.handlers[name].gradienttable[i][5] < p and p <= CandyBar.var.handlers[name].gradienttable[i+1][5] then
				-- the bounds are to assure no divide by zero error here.

				gstart = self.var.handlers[name].gradienttable[i]
				gend = self.var.handlers[name].gradienttable[i+1]
				gp = (p - gstart[5]) / (gend[5] - gstart[5])
			end
		end
		if gstart and gend then
			local color = getnewtable()
			-- calculate new gradient
			local i
			for i = 1, 4 do
				-- these may be the same.. but I'm lazy to make sure.
				color[i] = gstart[i]*(1-gp) + gend[i]*(gp)
			end
			CandyBar.var.handlers[name].frame.statusbar:SetStatusBarColor( color[1], color[2], color[3], color[4])

			reclaimtable(color)
			color = nil
		end
	end
end

-- Intenal Method
-- Fades the bar out when it's complete.
function CandyBar:UpdateFade( name )
	if not CandyBar.var.handlers[name] then return end
	if not CandyBar.var.handlers[name].fading then return end

	-- if the fade is done go and keel the bar.
	if CandyBar.var.handlers[name].fadeelapsed > CandyBar.var.handlers[name].fadetime then
		CandyBar.var.handlers[name].fading = nil
		CandyBar.var.handlers[name].starttime = nil
		CandyBar.var.handlers[name].endtime = 0
		CandyBar.var.handlers[name].frame:Hide()
		if CandyBar.var.handlers[name].group then CandyBar:UpdateGroup(CandyBar.var.handlers[name].group) end
		if CandyBar.var.handlers[name].fireforget then
			return CandyBar:Unregister(name)
		end
	else -- we're fading, set the alpha for the texts, statusbar and background. fade from default to 0 in the time given.
		local t = CandyBar.var.handlers[name].fadetime - CandyBar.var.handlers[name].fadeelapsed
		local p = t / CandyBar.var.handlers[name].fadetime
		local color = CandyBar.var.handlers[name].color or CandyBar.var.defaults.color
		local bgcolor = CandyBar.var.handlers[name].bgcolor or CandyBar.var.defaults.bgcolor
		local textcolor = CandyBar.var.handlers[name].textcolor or CandyBar.var.defaults.textcolor
		local timertextcolor = CandyBar.var.handlers[name].timertextcolor or CandyBar.var.defaults.timertextcolor
		local colora = color[4] * p
		local bgcolora = bgcolor[4] * p
		local textcolora = textcolor[4] * p
		local timertextcolora = timertextcolor[4] * p

		CandyBar.var.handlers[name].frame.statusbarbg:SetStatusBarColor( bgcolor[1], bgcolor[2], bgcolor[3], bgcolora)
		CandyBar.var.handlers[name].frame.statusbar:SetStatusBarColor( color[1], color[2], color[3], colora)
		CandyBar.var.handlers[name].frame.text:SetTextColor( textcolor[1], textcolor[2], textcolor[3], textcolora )
		CandyBar.var.handlers[name].frame.timertext:SetTextColor( timertextcolor[1], timertextcolor[2], timertextcolor[3], timertextcolora )
		CandyBar.var.handlers[name].frame.icon:SetAlpha(p)
	end
	return true
end

-- Internal Method
-- Create and return a new bar frame, recycles where needed
-- Name - which candybar is this for
-- Returns the frame
function CandyBar:AcquireBarFrame( name )
	if not CandyBar.var.handlers[name] then return end

	local f = CandyBar.var.handlers[name].frame

	local color = CandyBar.var.handlers[name].color or CandyBar.var.defaults.color
	local bgcolor = CandyBar.var.handlers[name].bgcolor or CandyBar.var.defaults.bgcolor
	local icon = CandyBar.var.handlers[name].icon or nil
	local texture = CandyBar.var.handlers[name].texture or CandyBar.var.defaults.texture
	local width = CandyBar.var.handlers[name].width or CandyBar.var.defaults.width
	local height = CandyBar.var.handlers[name].height or CandyBar.var.defaults.height
	local point = CandyBar.var.handlers[name].point or CandyBar.var.defaults.point
	local rframe = CandyBar.var.handlers[name].rframe or CandyBar.var.defaults.rframe
	local rpoint = CandyBar.var.handlers[name].rpoint or CandyBar.var.defaults.rpoint
	local xoffset = CandyBar.var.handlers[name].xoffset or CandyBar.var.defaults.xoffset
	local yoffset = CandyBar.var.handlers[name].yoffset or CandyBar.var.defaults.yoffset
	local text = CandyBar.var.handlers[name].text or CandyBar.var.defaults.text
	local fontsize = CandyBar.var.handlers[name].fontsize or CandyBar.var.defaults.fontsize
	local textcolor = CandyBar.var.handlers[name].textcolor or CandyBar.var.defaults.textcolor
	local timertextcolor = CandyBar.var.handlers[name].timertextcolor or CandyBar.var.defaults.timertextcolor
	local scale = CandyBar.var.handlers[name].scale or CandyBar.var.defaults.scale
	if not scale then scale = 1 end
	local timertextwidth = fontsize * 3
	local font, _, _ = GameFontHighlight:GetFont()


	if not f and table.getn(CandyBar.var.framepool) > 0 then
		f = table.remove(CandyBar.var.framepool)
	end

	if not f then f = CreateFrame("Button", nil, UIParent) end
	f:Hide()
	f.owner = name
	-- yes we add the height to the width for the icon.
	f:SetWidth( width + height )
	f:SetHeight( height )
	f:ClearAllPoints()
	f:SetPoint( point, rframe, rpoint, xoffset, yoffset)
	-- disable mouse
	f:EnableMouse(false)
	f:RegisterForClicks()
	f:SetScript("OnClick", nil)
	f:SetScale( scale )

	if not f.icon then f.icon = CreateFrame("Button", nil, f) end
	f.icon:ClearAllPoints()
	f.icon.owner = name
	f.icon:EnableMouse(false)
	f.icon:RegisterForClicks()
	f.icon:SetScript("OnClick", nil)
	-- an icno is square and the height of the bar, so yes 2x height there
	f.icon:SetHeight( height)
	f.icon:SetWidth( height)
	f.icon:SetPoint("LEFT", f, "LEFT", 0, 0)
	f.icon:SetNormalTexture(icon)
	f.icon:SetAlpha(1)
	f.icon:Show()

	if not f.statusbarbg then
		f.statusbarbg = CreateFrame("StatusBar", nil, f )
		f.statusbarbg:SetFrameLevel(f.statusbarbg:GetFrameLevel() - 1)
	end
	f.statusbarbg:ClearAllPoints()
	f.statusbarbg:SetHeight( height )
	f.statusbarbg:SetWidth( width )
	-- offset the height of the frame on the x-axis for the icon.
	f.statusbarbg:SetPoint( "TOPLEFT", f, "TOPLEFT", height, 0)
	f.statusbarbg:SetStatusBarTexture( texture )
	f.statusbarbg:SetStatusBarColor( bgcolor[1],bgcolor[2],bgcolor[3],bgcolor[4])
	f.statusbarbg:SetMinMaxValues(0,100)
	f.statusbarbg:SetValue(100)

	if not f.statusbar then f.statusbar = CreateFrame("StatusBar", nil, f ) end
	f.statusbar:ClearAllPoints()
	f.statusbar:SetHeight( height )
	f.statusbar:SetWidth( width )
	-- offset the height of the frame on the x-axis for the icon.
	f.statusbar:SetPoint( "TOPLEFT", f, "TOPLEFT", height, 0)
	f.statusbar:SetStatusBarTexture( texture )
	f.statusbar:SetStatusBarColor( color[1], color[2], color[3], color[4] )
	f.statusbar:SetMinMaxValues(0,1)
	f.statusbar:SetValue(1)


	if not f.spark then f.spark = f.statusbar:CreateTexture(nil, "OVERLAY") end
	f.spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark")
	f.spark:SetWidth(16)
	f.spark:SetHeight( height + 25 )
	f.spark:SetBlendMode("ADD")
	f.spark:Show()

	if not f.timertext then f.timertext = f.statusbar:CreateFontString(nil, "OVERLAY") end
	f.timertext:SetFontObject(GameFontHighlight)
	f.timertext:SetFont( font, fontsize )
	f.timertext:SetHeight( height)
	f.timertext:SetWidth( timertextwidth )
	f.timertext:SetPoint( "LEFT", f.statusbar, "LEFT", 0, 0)
	f.timertext:SetJustifyH("RIGHT")
	f.timertext:SetText("0")
	f.timertext:SetTextColor(timertextcolor[1], timertextcolor[2], timertextcolor[3], timertextcolor[4])

	if not f.text then f.text = f.statusbar:CreateFontString(nil, "OVERLAY") end
	f.text:SetFontObject(GameFontHighlight)
	f.text:SetFont( font, fontsize)
	f.text:SetHeight(height)
	f.text:SetWidth( (width - timertextwidth) *.9 )
	f.text:SetPoint( "RIGHT", f.statusbar, "RIGHT", 0, 0)
	f.text:SetJustifyH("LEFT")
	f.text:SetText(text)
	f.text:SetTextColor(textcolor[1], textcolor[2], textcolor[3], textcolor[4])

	if CandyBar.var.handlers[name].onclick then
		f:EnableMouse(true)
		f:RegisterForClicks("LeftButtonUp", "RightButtonUp", "MiddleButtonUp", "Button4Up", "Button5Up")
		f:SetScript("OnClick", function() CandyBar:OnClick() end )
		f.icon:EnableMouse(true)
		f.icon:RegisterForClicks("LeftButtonUp", "RightButtonUp", "MiddleButtonUp", "Button4Up", "Button5Up")
		f.icon:SetScript("OnClick", function() CandyBar:OnClick() end )	
	end


	return f
end


-- Internal Method
-- Releases a bar frame into the pool
-- Name - which candybar's frame are we're releasing
-- Returns true when succesful
function CandyBar:ReleaseBarFrame( name )
	if not CandyBar.var.handlers[name] then return end
	if not CandyBar.var.handlers[name].frame then return end
	CandyBar.var.handlers[name].frame:Hide()
	table.insert(CandyBar.var.framepool, CandyBar.var.handlers[name].frame)
	return true
end


-- Internal Method
-- Executes the OnClick function of a bar

function CandyBar:OnClick()
	if not this.owner then return end
	if not CandyBar.var.handlers[this.owner] then return end
	if not CandyBar.var.handlers[this.owner].onclick then return end
	-- pass the name of the handlers first, and the button clicked as the second argument
	local c = CandyBar.var.handlers[this.owner]
	local button = arg1
	CandyBar.var.handlers[this.owner].onclick( this.owner, button, c.onclick1, c.onclick2, c.onclick3, c.onclick4, c.onclick5, c.onclick6, c.onclick7, c.onclick8, c.onclick9, c.onclick10)
	return true
end


-- Internal Method
-- on update handler
function CandyBar:OnUpdate()
	local t = GetTime()
	for i,v in pairs(this.owner.var.handlers) do
		if v.running then
			v.elapsed = t - v.starttime
			if v.endtime <= t then
				if this.owner.var.handlers[i].completion then
					local c = this.owner.var.handlers[i]
					this.owner.var.handlers[i].completion( c.completion1, c.completion2, c.completion3, c.completion4, c.completion5, c.completion6, c.completion7, c.completion8, c.completion9, c.completion10 )
				end
				this.owner:Stop(i)
			else
				this.owner:Update(i)
			end
		elseif v.fading then
			v.fadeelapsed = (t - v.endtime)
			this.owner:UpdateFade(i)
		end
	end
end

-- Internal Method
-- returns true if we have any handlers
function CandyBar:HasHandlers()
	for i in pairs(CandyBar.var.handlers) do return true end
end


------------------------------
--      Mixins Methods      --
------------------------------

CandyBar.IsCandyBarRegistered = CandyBar.IsRegistered
CandyBar.StartCandyBar = CandyBar.Start
CandyBar.StopCandyBar = CandyBar.Stop
CandyBar.PauseCandyBar = CandyBar.Pause
CandyBar.CandyBarStatus = CandyBar.Status
CandyBar.SetCandyBarTexture = CandyBar.SetTexture
CandyBar.SetCandyBarTime = CandyBar.SetTime
CandyBar.SetCandyBarColor = CandyBar.SetColor
CandyBar.SetCandyBarText = CandyBar.SetText
CandyBar.SetCandyBarIcon = CandyBar.SetIcon
CandyBar.SetCandyBarBackgroundColor = CandyBar.SetBackgroundColor
CandyBar.SetCandyBarTextColor = CandyBar.SetTextColor
CandyBar.SetCandyBarTimerTextColor = CandyBar.SetTimerTextColor
CandyBar.SetCandyBarFontSize = CandyBar.SetFontSize
CandyBar.SetCandyBarPoint = CandyBar.SetPoint
CandyBar.SetCandyBarScale = CandyBar.SetScale
CandyBar.SetCandyBarTimeFormat = CandyBar.SetTimeFormat
CandyBar.SetCandyBarTimeLeft = CandyBar.SetTimeLeft
CandyBar.SetCandyBarCompletion = CandyBar.SetCompletion
CandyBar.RegisterCandyBarGroup = CandyBar.RegisterGroup
CandyBar.UnregisterCandyBarGroup = CandyBar.UnregisterGroup
CandyBar.IsCandyBarGroupRegistered = CandyBar.IsGroupRegistered
CandyBar.SetCandyBarGroupPoint = CandyBar.SetGroupPoint
CandyBar.SetCandyBarGroupGrowth = CandyBar.SetGroupGrowth
CandyBar.UpdateCandyBarGroup = CandyBar.UpdateGroup
CandyBar.SetCandyBarOnClick = CandyBar.SetOnClick
CandyBar.SetCandyBarFade = CandyBar.SetFade
CandyBar.RegisterCandyBarWithGroup = CandyBar.RegisterWithGroup
CandyBar.UnregisterCandyBarWithGroup = CandyBar.UnregisterWithGroup
CandyBar.IsCandyBarRegisteredWithGroup = CandyBar.IsRegisteredWithGroup
CandyBar.SetCandyBarReversed = CandyBar.SetReversed
CandyBar.IsCandyBarReversed = CandyBar.IsReversed
CandyBar.SetCandyBarOnClick = CandyBar.SetOnClick
CandyBar.SetCandyBarHeight = CandyBar.SetHeight
CandyBar.SetCandyBarWidth = CandyBar.SetWidth

function CandyBar:RegisterCandyBar(name, time, text, icon, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10)
	if not CandyBar.var.addons[self] then CandyBar.var.addons[self] = getnewtable() end
	CandyBar.var.addons[self][name] = CandyBar:Register(name, time, text, icon, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10)
end

function CandyBar:UnregisterCandyBar( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
	CandyBar:argCheck(a1, 2, "string")
	if CandyBar.var.addons[self] then CandyBar.var.addons[self][a1] = nil end
	CandyBar:Unregister(a1)
	if a2 then self:UnregisterCandyBar( a2, a3, a4, a5, a6, a7, a8, a9, a10) end
end


function CandyBar:OnEmbedDisable(target)
	if self.var.addons[target] then
		for i in pairs(self.var.addons[target]) do
			self:Unregister(i)
		end
	end
end



--------------------------------
--      Load this bitch!      --
--------------------------------


function CandyBar:activate(oldLib, oldDeactivate)
	CandyBar = self

	if oldLib then self.var = oldLib.var
	else
		local _,_,ourpath = string.find(debugstack(), "\\AddOns\\(.-)CandyBar%-2%.0%.lua")
		ourpath = "Interface\\AddOns\\"..ourpath .. "bar.tga"
		self.var = {  -- "Local" variables go here
			frame = CreateFrame("Frame"),
			handlers = {},
			groups = {},
			framepool = {},
			addons = {},
			defaults = {
				texture = "Interface\\TargetingFrame\\UI-StatusBar",
				width = 200,
				height = 16,
				scale = 1,
				point = "CENTER",
				rframe = UIParent,
				rpoint = "CENTER",
				xoffset = 0,
				yoffset = 0,
				fontsize = 11,
				color = { 1, 0, 1, 1 },
				bgcolor = { 0, .5, .5, .5},
				textcolor = {1, 1, 1, 1},
				timertextcolor = {1, 1, 1, 1},
			}
		}
		self.var.frame:Hide()
		self.var.frame.name = "CandyBar-2.0 Frame"
	end
	self.var.frame:SetScript("OnUpdate", self.OnUpdate)
	self.var.frame.owner = self

	if oldDeactivate then oldDeactivate(oldLib) end
end


local function external(self, major, instance)
	if major == "Compost-2.0" then compost = instance end
end


AceLibrary:Register(CandyBar, vmajor, vminor, CandyBar.activate, nil, external)
