WoWInterface SVN vCast

[/] [trunk/] [vCast/] [embeds/] [LibCandyBar/] [LibCandyBar.lua] - Rev 2

Compare with Previous | Blame | View Log

local major, minor = "LibCandyBar-2.1", "$Revision: 67072 $"

local lib, oldMinor = LibStub:NewLibrary(major, minor)
if not lib then return end

if not lib.frame then
        lib.frame = CreateFrame("Frame")
        lib.frame.name = "CandyBar-2.1 Frame"
        lib.frame:Hide()
end

lib.handlers = lib.handlers or {}
lib.groups = lib.groups or {}
lib.framepool = lib.framepool or {}
lib.addons = lib.addons or {}
lib.embeds = lib.embeds or {}

local function print(text)
        ChatFrame1:AddMessage(text)
end

local paint

local mixins = {
        "RegisterCandyBar",
        "UnregisterCandyBar",
        "IsCandyBarRegistered",
        "StartCandyBar",
        "StopCandyBar",
        "PauseCandyBar",
        "CandyBarStatus",
        "SetCandyBarTexture",
        "SetCandyBarTime",
        "SetCandyBarColor",
        "SetCandyBarText",
        "SetCandyBarIcon",
        "SetCandyBarIconPosition",
        "SetCandyBarWidth",
        "SetCandyBarHeight",
        "SetCandyBarBackgroundColor",
        "SetCandyBarTextColor",
        "SetCandyBarTimerTextColor",
        "SetCandyBarFontSize",
        "SetCandyBarPoint",
        "GetCandyBarPoint",
        "GetCandyBarCenter",
        "GetCandyBarOffsets",
        "GetCandyBarEffectiveScale",
        "SetCandyBarGradient",
        "SetCandyBarScale",
        "SetCandyBarTimeFormat",
        "SetCandyBarTimeLeft",
        "SetCandyBarCompletion",
        "SetCandyBarFade",
        "RegisterCandyBarGroup",
        "UnregisterCandyBarGroup",
        "IsCandyBarGroupRegistered",
        "SetCandyBarGroupPoint",
        "SetCandyBarGroupGrowth",
        "SetCandyBarGroupVerticalSpacing",
        "UpdateCandyBarGroup",
        "GetCandyBarNextBarPointInGroup",
        "RegisterCandyBarWithGroup",
        "UnregisterCandyBarWithGroup",
        "IsCandyBarRegisteredWithGroup",
        "SetCandyBarReversed",
        "IsCandyBarReversed",
        "SetCandyBarOnClick",
        "SetCandyBarOnSizeGroup",
}

local defaults = {
        texture = "Interface\\TargetingFrame\\UI-StatusBar",
        width = 200,
        height = 16,
        scale = 1,
        point = "CENTER",
        rframe = UIParent,
        rpoint = "CENTER",
        iconpos = "LEFT",
        xoffset = 0,
        yoffset = 0,
        fontsize = 11,
        color = {1, 0, 1, 1},
        bgcolor = {0, 0.5, 0.5, 0.5},
        textcolor = {1, 1, 1, 1},
        timertextcolor = {1, 1, 1, 1},
    stayonscreen = false,
}

local getArgs
do
        local numargs
        local function _get(t, str, i, ...)
                if i<=numargs then
                        return t[format("%s%d", str, i)],  _get(t, str, i+1, ...)
                end
                return ...
        end

        function getArgs(t, str, ...)
                numargs = t[str.."#" or 0]
                return _get(t,str,1, ...)
        end
end

local function setArgs(t, str, ...)
        local n = select("#", ...)
        for i=1,n do
          t[format("%s%d",str,i)]=select(i,...)
        end
        for i=n+1, (t[str.."#"] or 0) do
                t[format("%s%d",str,i)]=nil
        end
        t[str.."#"] = n
end

local new, del
do
        local cache = setmetatable({},{__mode='k'})
        function new()
                local t = next(cache)
                if t then
                        cache[t] = nil
                        return t
                else
                        return {}
                end
        end
        function del(t)
                for k in pairs(t) do
                        t[k] = nil
                end
                cache[t] = true
                return nil
        end
end


function lib:argCheck(var, nr, ...)
        local total = select("#", ...)
        local ok = false
        for i=1,total do
                if type(var) == select(i,...) then
                        ok = true
                end
        end
        if not ok then
                error("Wrong type for argument "..nr, 2)
        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 lib:Register(name, time, text, icon, c1, c2, c3, c4, ...)
        lib:argCheck(name, 2, "string")
        lib:argCheck(time, 3, "number")
        lib:argCheck(text, 4, "string", "nil")
        lib:argCheck(icon, 5, "string", "nil")
        lib:argCheck(c1, 6, "string", "number", "nil")
        lib:argCheck(c2, 7, "string", "number", "nil")
        lib:argCheck(c3, 8, "string", "number", "nil")
        lib:argCheck(c4, 9, "string", "number", "nil")
        if not text then text = name end
        if lib.handlers[name] then
                self:Unregister(name)
        end
        local handler = new()
        handler.name, handler.time, handler.text, handler.icon = name, time, text or name, icon
        handler.texture = defaults.texture
        local c1Type = type(c1)
        if c1Type ~= "number" and not paint then
                error("You need the PaintChips-2.0 library if you don't pass in RGB pairs as colors.")
        end
        if c1Type == "nil" or (c1Type ~= "number" and paint and not paint:GetRGBPercent(c1)) then
                c1 = "green"
        end
        handler.color = new()
        if c1Type == "number" then
                handler.color[1] = c1
                handler.color[2] = c2
                handler.color[3] = c3
        else
                handler.color[1], handler.color[2], handler.color[3] = select(2, paint:GetRGBPercent(c1))
        end
        handler.color[4] = 1
        handler.running = nil
        handler.endtime = 0
        handler.reversed = nil
        lib.handlers[name] = handler
        handler.frame = lib:AcquireBarFrame(name)
        if (c1Type == "number" and c4) or (c1Type == "string" and c2) then
                lib:SetGradient(name, c1, c2, c3, c4, ...)
        end
        handler.stayonscreen = defaults.stayonscreen
        return true
end


-- Removes a candy bar
-- a1 - a10 handlers that you wish to remove
-- returns true upon sucessful removal
function lib:Unregister(a1, ...)
        lib:argCheck(a1, 2, "string")
        if not lib.handlers[a1] then
                return
        end
        lib:UnregisterWithGroup(a1)
        lib:ReleaseBarFrame(a1)
        local handler = lib.handlers[a1]
        lib.handlers[a1] = nil
        if handler.color then
                handler.color = del(handler.color)
        end
        if handler.bgcolor then
                handler.bgcolor = del(handler.bgcolor)
        end
        if handler.textcolor then
                handler.textcolor = del(handler.textcolor)
        end
        if handler.timertextcolor then
                handler.timertextcolor = del(handler.timertextcolor)
        end
        if handler.gradienttable then
                for i,v in ipairs(handler.gradienttable) do
                        v = del(v)
                end
                handler.gradienttable = del(handler.gradienttable)
        end
        handler = del(handler)
        if ... then
                lib:Unregister(...)
        elseif not lib:HasHandlers() then
                lib.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 lib:IsRegistered(name)
        lib:argCheck(name, 2, "string")
        if lib.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 lib:Start(name, fireforget)
        lib:argCheck(name, 2, "string")
        lib:argCheck(fireforget, 3, "boolean", "nil")
        local handler = lib.handlers[name]
        if not handler then
                return
        end
        local t = GetTime()
        if handler.paused then
                local pauseoffset = t - handler.pausetime
                handler.endtime = handler.endtime + pauseoffset
                handler.starttime = handler.starttime + pauseoffset
        elseif handler.elapsed and not handler.running then
                handler.endtime = t + handler.time - handler.elapsed
                handler.starttime = t - handler.elapsed
        else
                -- bar hasn't elapsed a second.
                handler.elapsed = 0
                handler.endtime = t + handler.time
                handler.starttime = t
        end
        handler.fireforget = fireforget
        handler.running = true
        handler.paused = nil
        handler.fading = nil
        lib:AcquireBarFrame(name) -- this will reset the barframe incase we were fading out when it was restarted
        handler.frame:Show()
        if handler.group then
                lib:UpdateGroup(handler.group) -- update the group
        end
        lib.frame:Show()
        return true
end

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

        handler.running = nil
        handler.paused = nil
        handler.elapsed = 0

        if handler.fadeout then
                handler.frame.spark:Hide()
                if not handler.stayonscreen then
                        handler.fading = true
                        handler.fadeelapsed = 0
                        local t = GetTime()
                        if handler.endtime > t then
                                handler.endtime = t
                        end
                end
        else
                handler.frame:Hide()
                handler.starttime = nil
                handler.endtime = 0
                if handler.group then
                        lib:UpdateGroup(handler.group)
                end
                if handler.fireforget then
                        return lib:Unregister(name)
                end
        end
        if not lib:HasHandlers() then
                lib.frame:Hide()
        end
        return true
end

-- Pause a bar
-- Name - the candybar you want to pause
-- returns true if succesful
function lib:Pause(name)
        lib:argCheck(name, 2, "string")
        local handler = lib.handlers[name]
        if not handler then
                return
        end
        handler.pausetime = GetTime()
        handler.paused = true
        handler.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 lib:Status(name)
        lib:argCheck(name, 2, "string")
        local handler = lib.handlers[name]
        if not handler then
                return
        end
        return true, handler.time, handler.elapsed, handler.running, handler.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 lib:SetTime(name, time)
        lib:argCheck(name, 2, "string")
        lib:argCheck(time, 3, "number")
        
        local handler = lib.handlers[name]
        if not handler then
                return
        end
        handler.time = time
        if handler.starttime and handler.endtime then
                handler.endtime = handler.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 lib:SetTimeLeft(name, time)
        lib:argCheck(name, 2, "string")
        lib:argCheck(time, 3, "number")
        
        local handler = lib.handlers[name]
        if not handler then
                return
        end
        if handler.time < time or time < 0 then
                return
        end

        local e = handler.time - time
        if handler.starttime and handler.endtime then
                local d = handler.elapsed - e
                handler.starttime = handler.starttime + d
                handler.endtime = handler.endtime + d
        end

        handler.elapsed = e

        if handler.group then
                lib:UpdateGroup(handler.group)
        end

        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
local cachedgradient = {}
function lib:SetGradient(name, c1, c2, ...)
        lib:argCheck(name, 2, "string")
        lib:argCheck(c1, 3, "string", "number", "nil")
        lib:argCheck(c2, 4, "string", "number", "nil")

        local handler = lib.handlers[name]

        if not handler then
                return
        end

        local gtable = new()
        local gradientid = nil

        -- We got string values passed in, which means they're not rgb values
        -- directly, but a color most likely registered with paintchips
        if type(c1) == "string" then
                if not paint then
                        error("You need the PaintChips-2.0 library if you don't pass in RGB pairs as colors.")
                end
                if not paint:GetRGBPercent(c1) then c1 = "green" end
                if not paint:GetRGBPercent(c2) then c2 = "red" end

                gtable[1] = new()
                gtable[2] = new()

                gradientid = c1 .. "_" .. c2

                gtable[1][1], gtable[1][2], gtable[1][3] = select(2, paint:GetRGBPercent(c1))
                gtable[2][1], gtable[2][2], gtable[2][3] = select(2, paint:GetRGBPercent(c2))
                for i = 1, select('#', ...) do
                        local c = select(i, ...)
                        if not c or not paint:GetRGBPercent(c) then
                                break
                        end
                        local t = new()
                        t[1], t[2], t[3] = select(2, paint:GetRGBPercent(c))
                        table.insert(gtable, t)
                        gradientid = gradientid .. "_" .. c
                end
        elseif type(c1) == "number" then
                -- It's a number, which means we should expect r,g,b values
                local n = select("#", ...)
                if n < 4 then error("Not enough extra arguments to :SetGradient, need at least 2 RGB pairs.") end
                gtable[1] = new()
                gtable[1][1] = c1
                gtable[1][2] = c2
                gtable[1][3] = select(1, ...)
                gradientid = string.format("%d%d%d", c1, c2, gtable[1][3])

                for i = 2, n, 3 do
                        local r, g, b = select(i, ...)
                        if r and g and b then
                                local t = new()
                                t[1], t[2], t[3] = r, g, b
                                table.insert(gtable, t)
                                gradientid = string.format("%s_%d%d%d", gradientid, r, g, b)
                        else
                                break
                        end
                end
        end

        local max = #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
        if handler.gradienttable then
                for i,v in ipairs(handler.gradienttable) do
                        v = del(v)
                end
                handler.gradienttable = del(handler.gradienttable)
        end
        handler.gradienttable = gtable
        handler.gradient = true
        handler.gradientid = gradientid
        if not cachedgradient[gradientid] then
                cachedgradient[gradientid] = {}
        end

        handler.frame.statusbar:SetStatusBarColor(unpack(gtable[1], 1, 4))
        return true
end

local function setColor(color, alpha, b, a)
        lib:argCheck(color, 3, "string", "number")
        local ctable = nil
        if type(color) == "string" then
                if not paint then
                        error("You need the PaintChips-2.0 library if you don't pass in RGB pairs as colors.")
                end
                if not paint:GetRGBPercent(color) then
                        return
                end
                lib:argCheck(alpha, 4, "number", "nil")
                ctable = new()
                ctable[1], ctable[2], ctable[3] = select(2, paint:GetRGBPercent(color))
                if alpha then
                        ctable[4] = alpha
                else
                        ctable[4] = 1
                end
        else
                lib:argCheck(alpha, 4, "number")
                lib:argCheck(b, 5, "number")
                lib:argCheck(a, 6, "number", "nil")
                ctable = new()
                ctable[1], ctable[2], ctable[3] = color, alpha, b
                if a then
                        ctable[4] = a
                else
                        ctable[4] = 1
                end
        end
        return ctable
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 lib:SetColor(name, color, alpha, b, a)
        lib:argCheck(name, 2, "string")
        local handler = lib.handlers[name]
        if not handler then
                return
        end
        local t = setColor(color, alpha, b, a)
        if not t then return end

        if handler.color then
                handler.color = del(handler.color)
        end
        handler.color = t
        handler.gradient = nil

        handler.frame.statusbar:SetStatusBarColor(unpack(t, 1, 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 lib:SetBackgroundColor(name, color, alpha, b, a)
        lib:argCheck(name, 2, "string")
        local handler = lib.handlers[name]
        if not handler then
                return
        end

        local t = setColor(color, alpha, b, a)
        if not t then return end

        if handler.bgcolor then
                handler.bgcolor = del(handler.bgcolor)
        end
        handler.bgcolor = t
        handler.frame.statusbarbg:SetStatusBarColor(unpack(t, 1, 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 lib:SetTextColor(name, color, alpha, b, a)
        lib:argCheck(name, 2, "string")
        local handler = lib.handlers[name]
        if not handler then
                return
        end

        local t = setColor(color, alpha, b, a)
        if not t then return end

        if handler.textcolor then
                handler.textcolor = del(handler.textcolor)
        end
        handler.textcolor = t
        handler.frame.text:SetTextColor(unpack(t, 1, 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 lib:SetTimerTextColor(name, color, alpha, b, a)
        lib:argCheck(name, 2, "string")
        local handler = lib.handlers[name]
        if not handler then
                return
        end

        local t = setColor(color, alpha, b, a)
        if not t then return end

        if handler.timertextcolor then
                handler.timertextcolor = del(handler.timertextcolor)
        end
        handler.timertextcolor = t
        handler.frame.timertext:SetTextColor(unpack(t, 1, 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 lib:SetText(name, text)
        lib:argCheck(name, 2, "string")
        lib:argCheck(text, 3, "string")
        
        local handler = lib.handlers[name]
        if not handler then
                return
        end

        handler.text = text
        handler.frame.text:SetText(text)

        return true
end

-- Set the fontsize
-- Args: name - name of the candybar
--               fontsize - new fontsize
-- returns true when succesful
function lib:SetFontSize(name, fontsize)
        lib:argCheck(name, 2, "string")
        lib:argCheck(fontsize, 3, "number")
        
        local handler = lib.handlers[name]
        if not handler then
                return
        end
        
        local font, _, style = GameFontHighlight:GetFont()
        local timertextwidth = fontsize * 3.6
        local width = handler.width or defaults.width
        local f = handler.frame
        
        handler.fontsize = fontsize
        f.timertext:SetFont(font, fontsize, style)
        f.text:SetFont(font, fontsize, style)
        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 lib:SetPoint(name, point, rframe, rpoint, xoffset, yoffset)
        lib:argCheck(name, 2, "string")
        lib:argCheck(point, 3, "string")
        lib:argCheck(rframe, 4, "table", "string", "nil")
        lib:argCheck(rpoint, 5, "string", "nil")
        lib:argCheck(xoffset, 6, "number", "nil")
        lib:argCheck(yoffset, 7, "number", "nil")
        
        local handler = lib.handlers[name]
        if not handler then
                return
        end

        handler.point = point
        handler.rframe = rframe
        handler.rpoint = rpoint
        handler.xoffset = xoffset
        handler.yoffset = yoffset

        handler.frame:ClearAllPoints()
        handler.frame:SetPoint(point, rframe, rpoint, xoffset, yoffset)

        return true
end

function lib:GetPoint(name)
        lib:argCheck(name, 2, "string")
        
        local handler = lib.handlers[name]
        if not handler then
                return
        end
        
        return handler.point, handler.rframe, handler.rpoint, handler.xoffset, handler.yoffset
end

function lib:GetCenter(name)
        lib:argCheck(name, 2, "string")
        
        local handler = lib.handlers[name]
        if not handler then
                return
        end

        return handler.frame:GetCenter()
end

function lib:GetOffsets(name)
        lib:argCheck(name, 2, "string")
        
        local handler = lib.handlers[name]
        if not handler then
                return
        end
        
        local bottom = handler.frame:GetBottom()
        local top = handler.frame:GetTop()
        local left = handler.frame:GetLeft()
        local right = handler.frame:GetRight()
        
        return left, top, bottom, right
end

function lib:GetEffectiveScale(name)
        lib:argCheck(name, 2, "string")
        
        local handler = lib.handlers[name]
        if not handler then
                return
        end

        return handler.frame:GetEffectiveScale()
end

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

        local handler = lib.handlers[name]
        if not lib.handlers[name] then
                return
        end

        local height = handler.height or defaults.height
        local fontsize = handler.fontsize or defaults.fontsize
        local timertextwidth = fontsize * 3.6
        local f = handler.frame
        f:SetWidth(width + height)
        f.statusbar:SetWidth(width)
        f.statusbarbg:SetWidth(width)

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

        handler.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 lib:SetHeight(name, height)
        lib:argCheck(name, 2, "string")
        lib:argCheck(height, 3, "number")

        local handler = lib.handlers[name]
        if not handler then
                return
        end
        
        local width = handler.width or defaults.width
        local f = handler.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)

        handler.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 lib:SetScale(name, scale)
        lib:argCheck(name, 2, "string")
        lib:argCheck(scale, 3, "number")

        local handler = lib.handlers[name]
        if not handler then
                return
        end

        handler.scale = scale

        handler.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 lib:SetTimeFormat(name, func, ...)
        lib:argCheck(name, 2, "string")
        lib:argCheck(func, 3, "function")

        local handler = lib.handlers[name]

        if not handler then
                return
        end
        handler.timeformat = func
        setArgs(handler, "timeformat", ...)

        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 lib:SetCompletion(name, func, ...)
        lib:argCheck(name, 2, "string")
        lib:argCheck(func, 3, "function")
        
        local handler = lib.handlers[name]
        
        if not handler then
                return
        end
        handler.completion = func
        setArgs(handler, "completion", ...)
        
        return true
end

local function onClick()
        lib:OnClick()
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 lib:SetOnClick(name, func, ...)
        lib:argCheck(name, 2, "string")
        lib:argCheck(func, 3, "function", "nil")

        local handler = lib.handlers[name]
        
        if not handler then
                return
        end
        handler.onclick = func
        setArgs(handler, "onclick", ...)
        
        local frame = handler.frame
        if func then
                -- enable mouse
                frame:EnableMouse(true)
                frame:RegisterForClicks("LeftButtonUp", "RightButtonUp", "MiddleButtonUp", "Button4Up", "Button5Up")
                frame:SetScript("OnClick", onClick)
                frame.icon:EnableMouse(true)
                frame.icon:RegisterForClicks("LeftButtonUp", "RightButtonUp", "MiddleButtonUp", "Button4Up", "Button5Up")
                frame.icon:SetScript("OnClick", onClick)
        else
                frame:EnableMouse(false)
                frame:RegisterForClicks()
                frame:SetScript("OnClick", nil)
                frame.icon:EnableMouse(false)
                frame.icon:RegisterForClicks()
                frame.icon:SetScript("OnClick", nil)
        end

        return true

end

-- Set the "on size" function for a group
-- Args: name - name of the candybar
--                 func - function to call when a group changes size
--           ...  - arguments to pass to the function
--              (the new size of the bar, in pixels, will be appended last)
-- returns true when succesful
function lib:SetOnSizeGroup(name, func, ...)
        lib:argCheck(name, 2, "string")
        lib:argCheck(func, 3, "function", "nil")

        local group = assert(lib.groups[name])

        group.onsize = func
        setArgs(group, "onsize", ...)
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 lib:SetTexture(name, texture)
        lib:argCheck(name, 2, "string")
        lib:argCheck(texture, 3, "string", "nil")
        
        local handler = lib.handlers[name]
        if not handler then
                return
        end
        if not texture then
                texture = defaults.texture
        end

        handler.texture = texture

        handler.frame.statusbar:SetStatusBarTexture(texture)
        handler.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
--   left, right, top, bottom - optional texture coordinates
-- returns true when succesful
function lib:SetIcon(name, icon, left, right, top, bottom)
        lib:argCheck(name, 2, "string")
        lib:argCheck(icon, 3, "string", "nil")
        lib:argCheck(left, 4, "number", "nil")
        lib:argCheck(right, 5, "number", "nil")
        lib:argCheck(top, 6, "number", "nil")
        lib:argCheck(bottom, 7, "number", "nil")
        
        local handler = lib.handlers[name]
        if not handler then
                return
        end
        handler.icon = icon

        if not icon then
                handler.frame.icon:Hide()
        else
                left = left or 0.07
                right = right or 0.93
                top = top or 0.07
                bottom = bottom or 0.93
                handler.frame.icon:SetNormalTexture(icon)
                handler.frame.icon:GetNormalTexture():SetTexCoord(left, right, top, bottom)
                handler.frame.icon:Show()
        end

        return true
end

-- Set the icon position on bar
-- Args: name - name of the candybar
--       position  - icon position, "LEFT" or "RIGHT"
-- returns true when succesful
function lib:SetIconPosition(name, position)
        lib:argCheck(name, 2, "string")
        lib:argCheck(position, 3, "string", "LEFT", "RIGHT")

        local handler = lib.handlers[name]
        if not handler then
                return
        end

        handler.iconpos = position
        if handler.running then
                handler.frame.icon:SetPoint("LEFT", handler.frame, position, 0, 0)
        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 lib:SetFade(name, time)
        lib:argCheck(name, 2, "string")
        lib:argCheck(time, 3, "number")
        
        local handler = lib.handlers[name]
        if not handler then
                return
        end

        handler.fadetime = time
        handler.fadeout = true
        handler.stayonscreen = (handler.fadetime < 0)
    
        return true
end

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

function lib:IsReversed(name)
        lib:argCheck(name, 2, "string")
        
        local handler = lib.handlers[name]
        if not handler then
                return
        end

        return handler.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 lib:RegisterWithGroup(name, group)
        lib:argCheck(name, 2, "string")
        lib:argCheck(group, 3, "string")
        
        local handler = lib.handlers[name]
        local gtable = lib.groups[group]
        if not handler or not gtable then
                return
        end

        lib:UnregisterWithGroup(name)

        table.insert(gtable.bars, name)
        -- lib.groups[group].bars[name] = name
        handler.group = group
        lib:UpdateGroup(group)

        return true
end

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

function lib:UnregisterWithGroup(name)
        lib:argCheck(name, 2, "string")
        
        local handler = lib.handlers[name]
        if not handler then
                return
        end
        --if not lib.handlers[name].group then return end

        local group = handler.group
        local gtable = lib.groups[group]
        if not gtable then
                return
        end

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

        lib:UpdateGroup(group)

        return true
end

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

        local t = new()

        t.point = "CENTER"
        t.rframe = UIParent
        t.rpoint = "CENTER"
        t.xoffset = 0
        t.yoffset = 0
        t.bars = new()
        t.height = -1

        lib.groups[name] = t
        return true
end

-- Unregister a candybar group
-- Args: a1-a2 candybar group ids
-- returns true when succesful
function lib:UnregisterGroup(a1, ...)
        lib:argCheck(a1, 2, "string")
        if not lib.groups[a1] then
                return
        end
        lib.groups[a1].bars = del(lib.groups[a1].bars)
        lib.groups[a1] = del(lib.groups[a1])

        if ... then
                lib:UnregisterGroup(...)
        end

        return true
end

-- Checks if a group is registered
-- Args: name - Candybar group
-- returns true if the candybar group is registered
function lib:IsGroupRegistered(name)
        lib:argCheck(name, 2, "string")
        return lib.groups[name] and true or false
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 lib:IsRegisteredWithGroup(name, group)
        lib:argCheck(name, 2, "string")
        lib:argCheck(group, 3, "string", "nil")
        local handler = lib.handlers[name]
        if not handler then
                return
        end

        if group then
                if not lib.groups[group] then
                        return false
                end
                if handler.group == group then
                        return true
                end
        elseif handler.group then
                return true
        end
        return false
end


-- Set the point for a CandyBargroup
--       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 lib:SetGroupPoint(name, point, rframe, rpoint, xoffset, yoffset)
        lib:argCheck(name, 2, "string")
        lib:argCheck(point, 3, "string")
        lib:argCheck(rframe, 4, "string", "table", "nil")
        lib:argCheck(rpoint, 5, "string", "nil")
        lib:argCheck(xoffset, 6, "number", "nil")
        lib:argCheck(yoffset, 6, "number", "nil")
        
        local group = lib.groups[name]
        if not group then
                return
        end

        group.point = point
        group.rframe = rframe
        group.rpoint = rpoint
        group.xoffset = xoffset
        group.yoffset = yoffset
        lib: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 lib:SetGroupGrowth(name, growup)
        lib:argCheck(name, 2, "string")
        lib:argCheck(growup, 3, "boolean")
        
        local group = lib.groups[name]
        if not group then
                return
        end

        group.growup = growup

        lib:UpdateGroup(name)

        return true
end

-- SetGroupVerticalSpacing - sets a vertical spacing between the bars of the group
-- Args: name - name of the candybar group
--         spacing - y offset for the bars
-- returns true when succesful
function lib:SetGroupVerticalSpacing(name, spacing)
        lib:argCheck(name, 2, "string");
        lib:argCheck(spacing, 3, "number");
        
        local group = lib.groups[name]
        if not group then
                return
        end

        group.vertspacing = spacing;

        lib:UpdateGroup(name)

        return true
end

local mysort = function(a, b)
        return lib.handlers[a].endtime < lib.handlers[b].endtime
end
function lib:SortGroup(name)
        local group = lib.groups[name]
        if not group then
                return
        end
        table.sort(group.bars, mysort)
end

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

function lib:UpdateGroup(name)
        local group = lib.groups[name]
        if not lib.groups[name] then
                return
        end

        local point = group.point
        local rframe = group.rframe
        local rpoint = group.rpoint
        local xoffset = group.xoffset
        local yoffset = group.yoffset
        local m = -1
        if group.growup then
                m = 1
        end
        local vertspacing = group.vertspacing or 0

        local bar = 0
        local barh = 0

        lib:SortGroup(name)

        for c,n in pairs(group.bars) do
                local handler = lib.handlers[n]
                if handler then
                        if handler.frame:IsShown() then
                                lib:SetPoint(n, point, rframe, rpoint, xoffset, yoffset + (m * bar))
                                barh = handler.height or defaults.height
                                bar = bar + barh + vertspacing
                        end
                end
        end
        
        if group.height ~= bar then
                group.height = bar
                if group.onsize then
                        group.onsize(getArgs(group, "onsize", bar))
                end
        end
        
        return true
end

function lib:GetNextBarPointInGroup(name)
        lib:argCheck(name, 2, "string")
        
        local group = lib.groups[name]
        if not lib.groups[name] then
                return
        end
        
        local xoffset = group.xoffset
        local yoffset = group.yoffset
        local m = -1
        if group.growup then
                m = 1
        end
        
        local bar = 0
        local barh = 0
        
        local vertspacing = group.vertspacing or 0
        
        for c,n in pairs(group.bars) do
                local handler = lib.handlers[n]
                if handler then
                        if handler.frame:IsShown() then
                                barh = handler.height or defaults.height
                                bar = bar + barh + vertspacing
                        end
                end
        end
        
        return xoffset, yoffset + (m * bar)
end

-- Internal Method
-- Update a bar on screen
function lib:Update(name)
        local handler = lib.handlers[name]
        if not handler then
                return
        end

        local t = handler.time - handler.elapsed
        handler.slow = t>11

        local timetext
        if handler.timeformat then
                timetext = handler.timeformat(t, getArgs(handler, "timeformat"))
        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 = ("%d:%02d"):format(h, m)
                elseif m > 0 then
                        timetext = string.format("%d:%02d", m, floor(s))
                elseif s < 10 then
                        timetext = string.format("%1.1f", s)
                else
                        timetext = string.format("%.0f", floor(s))
                end
        end
        handler.frame.timertext:SetText(timetext)

        local perc = t / handler.time

        local reversed = handler.reversed
        handler.frame.statusbar:SetValue(reversed and 1-perc or perc)

        local width = handler.width or defaults.width

        local sp = width * perc
        sp = reversed and -sp or sp
        handler.frame.spark:SetPoint("CENTER", handler.frame.statusbar, reversed and "RIGHT" or "LEFT", sp, 0)

        if handler.gradient then
                local p = floor( (handler.elapsed / handler.time) * 100 ) / 100
                if not cachedgradient[handler.gradientid][p] then
                        -- find the appropriate start/end
                        local gstart, gend, gp
                        for i = 1, #handler.gradienttable - 1 do
                                if handler.gradienttable[i][5] < p and p <= handler.gradienttable[i+1][5] then
                                        -- the bounds are to assure no divide by zero error here.
        
                                        gstart = handler.gradienttable[i]
                                        gend = handler.gradienttable[i+1]
                                        gp = (p - gstart[5]) / (gend[5] - gstart[5])
                                end
                        end
                        if gstart and gend then
                                -- calculate new gradient
                                cachedgradient[handler.gradientid][p] = new()
                                local i
                                for i = 1, 4 do
                                        -- these may be the same.. but I'm lazy to make sure.
                                        cachedgradient[handler.gradientid][p][i] = gstart[i]*(1-gp) + gend[i]*(gp)
                                end
                        end
                end
                if cachedgradient[handler.gradientid][p] then
                        handler.frame.statusbar:SetStatusBarColor(unpack(cachedgradient[handler.gradientid][p], 1, 4))
                end
        end
end

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

        -- if the fade is done go and keel the bar.
        if handler.fadeelapsed > handler.fadetime then
                handler.fading = nil
                handler.starttime = nil
                handler.endtime = 0
                handler.frame:Hide()
                if handler.group then
                        lib:UpdateGroup(handler.group)
                end
                if handler.fireforget then
                        return lib: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 = handler.fadetime - lib.handlers[name].fadeelapsed
                local p = t / handler.fadetime
                local color = handler.color or defaults.color
                local bgcolor = handler.bgcolor or defaults.bgcolor
                local textcolor = handler.textcolor or defaults.textcolor
                local timertextcolor = handler.timertextcolor or defaults.timertextcolor
                local colora = color[4] * p
                local bgcolora = bgcolor[4] * p
                local textcolora = textcolor[4] * p
                local timertextcolora = timertextcolor[4] * p

                handler.frame.statusbarbg:SetStatusBarColor(bgcolor[1], bgcolor[2], bgcolor[3], bgcolora)
                handler.frame.statusbar:SetStatusBarColor(color[1], color[2], color[3], colora)
                handler.frame.text:SetTextColor(textcolor[1], textcolor[2], textcolor[3], textcolora)
                handler.frame.timertext:SetTextColor(timertextcolor[1], timertextcolor[2], timertextcolor[3], timertextcolora)
                handler.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 lib:AcquireBarFrame(name)
        local handler = lib.handlers[name]
        if not handler then
                return
        end

        local f = handler.frame

        local color = handler.color or defaults.color
        local bgcolor = handler.bgcolor or defaults.bgcolor
        local icon = handler.icon or nil
        local iconpos = handler.iconpos or defaults.iconpos
        local texture = handler.texture or defaults.texture
        local width = handler.width or defaults.width
        local height = handler.height or defaults.height
        local point = handler.point or defaults.point
        local rframe = handler.rframe or defaults.rframe
        local rpoint = handler.rpoint or defaults.rpoint
        local xoffset = handler.xoffset or defaults.xoffset
        local yoffset = handler.yoffset or defaults.yoffset
        local text = handler.text or defaults.text
        local fontsize = handler.fontsize or defaults.fontsize
        local textcolor = handler.textcolor or defaults.textcolor
        local timertextcolor = handler.timertextcolor or defaults.timertextcolor
        local scale = handler.scale or defaults.scale
        if not scale then
                scale = 1
        end
        local timertextwidth = fontsize * 3.6
        local font, _, style = GameFontHighlight:GetFont()

        if not f and #lib.framepool > 0 then
                f = table.remove(lib.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, iconpos, 0, 0)
        f.icon:SetNormalTexture(icon)
        if f.icon:GetNormalTexture() then 
                f.icon:GetNormalTexture():SetTexCoord( 0.07, 0.93, 0.07, 0.93)
        end 
        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, style)
        f.timertext:SetHeight(height)
        f.timertext:SetWidth(timertextwidth)
        f.timertext:SetPoint("RIGHT", f.statusbar, "RIGHT", 0, 0)
        f.timertext:SetJustifyH("RIGHT")
        f.timertext:SetText("")
        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, style)
        f.text:SetHeight(height)
        f.text:SetWidth((width - timertextwidth) *.9)
        f.text:SetPoint("LEFT", f.statusbar, "LEFT", 0, 0)
        f.text:SetJustifyH("LEFT")
        f.text:SetText(text)
        f.text:SetTextColor(textcolor[1], textcolor[2], textcolor[3], textcolor[4])

        if handler.onclick then
                f:EnableMouse(true)
                f:RegisterForClicks("LeftButtonUp", "RightButtonUp", "MiddleButtonUp", "Button4Up", "Button5Up")
                f:SetScript("OnClick", onClick)
                f.icon:EnableMouse(true)
                f.icon:RegisterForClicks("LeftButtonUp", "RightButtonUp", "MiddleButtonUp", "Button4Up", "Button5Up")
                f.icon:SetScript("OnClick", onClick)
        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 lib:ReleaseBarFrame(name)
        local handler = lib.handlers[name]
        if not handler then
                return
        end
        if not handler.frame then
                return
        end
        handler.frame:Hide()
        table.insert(lib.framepool, handler.frame)
        return true
end

-- Internal Method
-- Executes the OnClick function of a bar
function lib:OnClick()
        if not this.owner then
                return
        end
        local handler = lib.handlers[this.owner]
        if not handler then
                return
        end
        if not handler.onclick then
                return
        end
        -- pass the name of the handlers first, and the button clicked as the second argument
        local button = arg1
        handler.onclick(this.owner, button, getArgs(handler, "onclick"))
        return true
end

-- Internal Method
-- on update handler
local lastSlow = 0
function lib.OnUpdate(self, elapsed)
        local doslow
        lastSlow = lastSlow + elapsed
        if lastSlow > 0.04 then
                doslow = true
                lastSlow = 0
        end

        local t
        for i,v in pairs(lib.handlers) do
                if not t then t = GetTime() end
                if (not doslow) and v.slow then
                        -- nada
                elseif v.running then
                        v.elapsed = t - v.starttime
                        if v.endtime <= t then
                                local c = lib.handlers[i]
                                if c.completion then
                                        if not c.completion(getArgs(c, "completion")) then
                                                lib:Stop(i)
                                        end
                                else
                                        lib:Stop(i)
                                end
                        else
                                lib:Update(i)
                        end
                elseif v.fading and not v.stayonscreen then
                        v.fadeelapsed = (t - v.endtime)
                        lib:UpdateFade(i)
                end
        end
end

-- Internal Method
-- returns true if we have any handlers
function lib:HasHandlers()
        return next(lib.handlers) and true
end

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

lib.IsCandyBarRegistered = lib.IsRegistered
lib.StartCandyBar = lib.Start
lib.StopCandyBar = lib.Stop
lib.PauseCandyBar = lib.Pause
lib.CandyBarStatus = lib.Status
lib.SetCandyBarTexture = lib.SetTexture
lib.SetCandyBarTime = lib.SetTime
lib.SetCandyBarColor = lib.SetColor
lib.SetCandyBarText = lib.SetText
lib.SetCandyBarIcon = lib.SetIcon
lib.SetCandyBarIconPosition = lib.SetIconPosition
lib.SetCandyBarBackgroundColor = lib.SetBackgroundColor
lib.SetCandyBarTextColor = lib.SetTextColor
lib.SetCandyBarTimerTextColor = lib.SetTimerTextColor
lib.SetCandyBarFontSize = lib.SetFontSize
lib.SetCandyBarPoint = lib.SetPoint
lib.GetCandyBarPoint = lib.GetPoint
lib.GetCandyBarCenter = lib.GetCenter
lib.GetCandyBarOffsets = lib.GetOffsets
lib.GetCandyBarEffectiveScale = lib.GetEffectiveScale
lib.SetCandyBarScale = lib.SetScale
lib.SetCandyBarTimeFormat = lib.SetTimeFormat
lib.SetCandyBarTimeLeft = lib.SetTimeLeft
lib.SetCandyBarCompletion = lib.SetCompletion
lib.RegisterCandyBarGroup = lib.RegisterGroup
lib.UnregisterCandyBarGroup = lib.UnregisterGroup
lib.IsCandyBarGroupRegistered = lib.IsGroupRegistered
lib.SetCandyBarGroupPoint = lib.SetGroupPoint
lib.SetCandyBarGroupGrowth = lib.SetGroupGrowth
lib.SetCandyBarGroupVerticalSpacing = lib.SetGroupVerticalSpacing
lib.UpdateCandyBarGroup = lib.UpdateGroup
lib.GetCandyBarNextBarPointInGroup = lib.GetNextBarPointInGroup
lib.SetCandyBarOnClick = lib.SetOnClick
lib.SetCandyBarFade = lib.SetFade
lib.RegisterCandyBarWithGroup = lib.RegisterWithGroup
lib.UnregisterCandyBarWithGroup = lib.UnregisterWithGroup
lib.IsCandyBarRegisteredWithGroup = lib.IsRegisteredWithGroup
lib.SetCandyBarReversed = lib.SetReversed
lib.IsCandyBarReversed = lib.IsReversed
lib.SetCandyBarOnClick = lib.SetOnClick
lib.SetCandyBarHeight = lib.SetHeight
lib.SetCandyBarWidth = lib.SetWidth
lib.SetCandyBarOnSizeGroup = lib.SetOnSizeGroup

function lib:RegisterCandyBar(name, time, text, icon, ...)
        if not lib.addons[self] then
                lib.addons[self] = new()
        end
        lib.addons[self][name] = lib:Register(name, time, text, icon, ...)
end

function lib:UnregisterCandyBar(a1, ...)
        lib:argCheck(a1, 2, "string")
        if lib.addons[self] then
                lib.addons[self][a1] = nil
        end
        lib:Unregister(a1)
        if ... then
                self:UnregisterCandyBar(...)
        end
end

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

function lib:Embed(target)
        for k, v in pairs(mixins) do
                target[v] = lib[v]
        end
        self.embeds[target] = true
        return target   
end

-- last step of upgrading

lib.frame:SetScript("OnUpdate", lib.OnUpdate)

for target, v in pairs(lib.embeds) do
        lib:Embed(target)
end


Compare with Previous | Blame