----------------------------------------------------------------------------------------
--  API of DarkUI
----------------------------------------------------------------------------------------
local T, C, L, _ = unpack(select(2, ...))

----------------------------------------------------------------------------------------
--  Frame Fader Functions
----------------------------------------------------------------------------------------

local defaultFadeIn   = {time = 0.4, alpha = 1}
local defaultFadeOut  = {time = 0.3, alpha = 0}

local frameFadeManager = CreateFrame("FRAME")

-- Generic fade function
local function UIFrameFade(frame, fadeInfo)
    if (not frame) then return end

    if ( not fadeInfo.mode ) then
        fadeInfo.mode = "IN"
    end

    local alpha
    if ( fadeInfo.mode == "IN" ) then
        if ( not fadeInfo.startAlpha ) then
            fadeInfo.startAlpha = 0
        end
        if ( not fadeInfo.endAlpha ) then
            fadeInfo.endAlpha = 1.0
        end

        alpha = 0
    elseif ( fadeInfo.mode == "OUT" ) then
        if ( not fadeInfo.startAlpha ) then
            fadeInfo.startAlpha = 1.0
        end
        if ( not fadeInfo.endAlpha ) then
            fadeInfo.endAlpha = 0
        end

        alpha = 1.0
    end

    frame:SetAlpha(fadeInfo.startAlpha)
    frame.fadeInfo = fadeInfo

    local index = 1
    while FADEFRAMES[index] do
        -- If frame is already set to fade then return
        if ( FADEFRAMES[index] == frame ) then
            return
        end

        index = index + 1
    end

    tinsert(FADEFRAMES, frame)
    frameFadeManager:SetScript("OnUpdate", UIFrameFade_OnUpdate)
end

-- Convenience function to do a simple fade in
T.UIFrameFadeIn = function(frame, timeToFade, startAlpha, endAlpha)
    local fadeInfo = {};

    fadeInfo.mode = "IN";
    fadeInfo.timeToFade = timeToFade
    fadeInfo.startAlpha = startAlpha
    fadeInfo.endAlpha = endAlpha
    UIFrameFade(frame, fadeInfo)
end

-- Convenience function to do a simple fade out
T.UIFrameFadeOut = function(frame, timeToFade, startAlpha, endAlpha)
    local fadeInfo = {};

    fadeInfo.mode = "OUT"
    fadeInfo.timeToFade = timeToFade
    fadeInfo.startAlpha = startAlpha
    fadeInfo.endAlpha = endAlpha
    UIFrameFade(frame, fadeInfo)
end

--ButtonBarFader func
T.ButtonBarFader = function(frame, buttonList, fadeIn, fadeOut)
    if not frame or not buttonList then return end
    if not fadeIn then fadeIn = defaultFadeIn end
    if not fadeOut then fadeOut = defaultFadeOut end

    frame:EnableMouse(true)
    frame:HookScript("OnEnter", function() T.UIFrameFadeIn( frame, fadeIn.time, frame:GetAlpha(), fadeIn.alpha) end)
    frame:HookScript("OnLeave", function() T.UIFrameFadeOut(frame, fadeOut.time, frame:GetAlpha(), fadeOut.alpha) end)
    T.UIFrameFadeOut(frame, fadeOut.time, frame:GetAlpha(), fadeOut.alpha)

    for _, button in pairs(buttonList) do
        if button then
            button:HookScript("OnEnter", function() T.UIFrameFadeIn(frame, fadeIn.time, frame:GetAlpha(), fadeIn.alpha) end)
            button:HookScript("OnLeave", function() T.UIFrameFadeOut(frame, fadeOut.time, frame:GetAlpha(), fadeOut.alpha) end)
        end
    end
end

--SpellFlyoutFader func
--the flyout is special, when hovering the flyout the parented bar must not fade out
T.SpellFlyoutFader = function(frame, buttonList, fadeIn, fadeOut)
    if not frame or not buttonList then return end
    if not fadeIn then fadeIn = defaultFadeIn end
    if not fadeOut then fadeOut = defaultFadeOut end

    SpellFlyout:HookScript("OnEnter", function() T.UIFrameFadeIn( frame, fadeIn.time, frame:GetAlpha(), fadeIn.alpha) end)
    SpellFlyout:HookScript("OnLeave", function() T.UIFrameFadeOut(frame, fadeOut.time, frame:GetAlpha(), fadeOut.alpha) end)

    for _, button in pairs(buttonList) do
        if button then
            button:HookScript("OnEnter", function() T.UIFrameFadeIn( frame, fadeIn.time, frame:GetAlpha(), fadeIn.alpha) end)
            button:HookScript("OnLeave", function() T.UIFrameFadeOut(frame, fadeOut.time, frame:GetAlpha(), fadeOut.alpha) end)
        end
    end
end

--FrameFader func
T.FrameFader = function(frame, fadeIn, fadeOut)
    if not frame then return end
    if not fadeIn then fadeIn = defaultFadeIn end
    if not fadeOut then fadeOut = defaultFadeOut end

    frame:EnableMouse(true)
    frame:HookScript("OnEnter", function(self) T.UIFrameFadeIn( frame, fadeIn.time, frame:GetAlpha(), fadeIn.alpha) end)
    frame:HookScript("OnLeave", function(self) T.UIFrameFadeOut(frame, fadeOut.time, frame:GetAlpha(), fadeOut.alpha) end)
    T.UIFrameFadeOut(frame, fadeOut.time, frame:GetAlpha(), fadeOut.alpha)
end

--CombatFrameFader func
T.CombatFrameFader = function(frame, fadeIn, fadeOut)
    if not frame then return end
    if not fadeIn then fadeIn = defaultFadeIn end
    if not fadeOut then fadeOut = defaultFadeOut end

    frame:RegisterEvent("PLAYER_REGEN_ENABLED")
    frame:RegisterEvent("PLAYER_REGEN_DISABLED")
    frame:RegisterEvent("PLAYER_ENTERING_WORLD")

    frame:HookScript("OnEvent", function(self, event, ...)
        if event == "PLAYER_REGEN_DISABLED" then
            T.UIFrameFadeIn(frame, fadeIn.time, frame:GetAlpha(), fadeIn.alpha)
        elseif event == "PLAYER_REGEN_ENABLED" or event == "PLAYER_ENTERING_WORLD" then
            T.UIFrameFadeOut(frame, fadeOut.time, frame:GetAlpha(), fadeOut.alpha)
        end
    end)
end
