-------------------------
-- AiB Animation System
-------------------------
-- Fade, Slide, Scale, Pulse Animationen

AiB = AiB or {}
AiB.Animations = {}

-- Animation Queue
AiB.Animations.queue = {}
AiB.Animations.activeAnimations = {}

-------------------------
-- FADE ANIMATIONS
-------------------------
function AiB.Animations:FadeIn(frame, duration, callback)
    duration = duration or AiB.Config:GetAnimationDuration("FADE_DURATION")
    
    if not frame.fadeGroup then
        frame.fadeGroup = frame:CreateAnimationGroup()
        frame.fadeAnim = frame.fadeGroup:CreateAnimation("Alpha")
    end
    
    frame:SetAlpha(0)
    frame:Show()
    
    frame.fadeAnim:SetFromAlpha(0)
    frame.fadeAnim:SetToAlpha(1)
    frame.fadeAnim:SetDuration(duration)
    frame.fadeAnim:SetSmoothing("IN_OUT")
    
    if callback then
        frame.fadeGroup:SetScript("OnFinished", function()
            callback()
            frame.fadeGroup:SetScript("OnFinished", nil)
        end)
    end
    
    frame.fadeGroup:Play()
end

function AiB.Animations:FadeOut(frame, duration, callback)
    duration = duration or AiB.Config:GetAnimationDuration("FADE_DURATION")
    
    if not frame.fadeGroup then
        frame.fadeGroup = frame:CreateAnimationGroup()
        frame.fadeAnim = frame.fadeGroup:CreateAnimation("Alpha")
    end
    
    frame.fadeAnim:SetFromAlpha(1)
    frame.fadeAnim:SetToAlpha(0)
    frame.fadeAnim:SetDuration(duration)
    frame.fadeAnim:SetSmoothing("IN_OUT")
    
    frame.fadeGroup:SetScript("OnFinished", function()
        frame:Hide()
        if callback then callback() end
        frame.fadeGroup:SetScript("OnFinished", nil)
    end)
    
    frame.fadeGroup:Play()
end

-------------------------
-- SLIDE ANIMATIONS
-------------------------
function AiB.Animations:SlideIn(frame, direction, duration, callback)
    direction = direction or "LEFT" -- LEFT, RIGHT, TOP, BOTTOM
    duration = duration or AiB.Config:GetAnimationDuration("SLIDE_DURATION")
    
    if not frame.slideGroup then
        frame.slideGroup = frame:CreateAnimationGroup()
        frame.slideAnim = frame.slideGroup:CreateAnimation("Translation")
    end
    
    local width = frame:GetWidth() or 100
    local height = frame:GetHeight() or 100
    
    local offsetX, offsetY = 0, 0
    if direction == "LEFT" then
        offsetX = -width
    elseif direction == "RIGHT" then
        offsetX = width
    elseif direction == "TOP" then
        offsetY = height
    elseif direction == "BOTTOM" then
        offsetY = -height
    end
    
    frame:SetAlpha(0)
    frame:Show()
    
    frame.slideAnim:SetOffset(offsetX, offsetY)
    frame.slideAnim:SetDuration(duration)
    frame.slideAnim:SetSmoothing("OUT")
    
    -- Fade in während slide
    self:FadeIn(frame, duration)
    
    if callback then
        frame.slideGroup:SetScript("OnFinished", function()
            callback()
            frame.slideGroup:SetScript("OnFinished", nil)
        end)
    end
    
    frame.slideGroup:Play()
end

function AiB.Animations:SlideOut(frame, direction, duration, callback)
    direction = direction or "LEFT"
    duration = duration or AiB.Config:GetAnimationDuration("SLIDE_DURATION")
    
    if not frame.slideGroup then
        frame.slideGroup = frame:CreateAnimationGroup()
        frame.slideAnim = frame.slideGroup:CreateAnimation("Translation")
    end
    
    local width = frame:GetWidth() or 100
    local height = frame:GetHeight() or 100
    
    local offsetX, offsetY = 0, 0
    if direction == "LEFT" then
        offsetX = -width
    elseif direction == "RIGHT" then
        offsetX = width
    elseif direction == "TOP" then
        offsetY = height
    elseif direction == "BOTTOM" then
        offsetY = -height
    end
    
    frame.slideAnim:SetOffset(offsetX, offsetY)
    frame.slideAnim:SetDuration(duration)
    frame.slideAnim:SetSmoothing("IN")
    
    -- Fade out während slide
    self:FadeOut(frame, duration)
    
    frame.slideGroup:SetScript("OnFinished", function()
        frame:Hide()
        if callback then callback() end
        frame.slideGroup:SetScript("OnFinished", nil)
    end)
    
    frame.slideGroup:Play()
end

-------------------------
-- SCALE ANIMATIONS
-------------------------
function AiB.Animations:ScalePulse(frame, scale, duration)
    scale = scale or 1.1
    duration = duration or 0.15
    
    if not frame.scaleGroup then
        frame.scaleGroup = frame:CreateAnimationGroup()
        frame.scaleUp = frame.scaleGroup:CreateAnimation("Scale")
        frame.scaleDown = frame.scaleGroup:CreateAnimation("Scale")
        
        frame.scaleUp:SetOrder(1)
        frame.scaleDown:SetOrder(2)
    end
    
    frame.scaleUp:SetScale(scale, scale)
    frame.scaleUp:SetDuration(duration)
    frame.scaleUp:SetSmoothing("OUT")
    
    frame.scaleDown:SetScale(1/scale, 1/scale)
    frame.scaleDown:SetDuration(duration)
    frame.scaleDown:SetSmoothing("IN")
    
    frame.scaleGroup:Play()
end

function AiB.Animations:ScaleUp(frame, fromScale, toScale, duration, callback)
    fromScale = fromScale or 0.8
    toScale = toScale or 1.0
    duration = duration or 0.2
    
    if not frame.scaleUpGroup then
        frame.scaleUpGroup = frame:CreateAnimationGroup()
        frame.scaleUpAnim = frame.scaleUpGroup:CreateAnimation("Scale")
    end
    
    frame:SetScale(fromScale)
    frame:Show()
    
    frame.scaleUpAnim:SetScale(toScale/fromScale, toScale/fromScale)
    frame.scaleUpAnim:SetDuration(duration)
    frame.scaleUpAnim:SetSmoothing("OUT")
    
    if callback then
        frame.scaleUpGroup:SetScript("OnFinished", function()
            callback()
            frame.scaleUpGroup:SetScript("OnFinished", nil)
        end)
    end
    
    frame.scaleUpGroup:Play()
end

-------------------------
-- GLOW ANIMATIONS
-------------------------
function AiB.Animations:CreateGlow(frame, color)
    if frame.glowTexture then return end
    
    color = color or {AiB.Themes:GetColor("glow_color")}
    
    frame.glowTexture = frame:CreateTexture(nil, "BACKGROUND", nil, -8)
    frame.glowTexture:SetPoint("TOPLEFT", frame, "TOPLEFT", -4, 4)
    frame.glowTexture:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 4, -4)
    frame.glowTexture:SetColorTexture(unpack(color))
    frame.glowTexture:SetBlendMode("ADD")
    frame.glowTexture:SetAlpha(0)
    
    frame.glowGroup = frame:CreateAnimationGroup()
    frame.glowGroup:SetLooping("BOUNCE")
    
    frame.glowFade = frame.glowGroup:CreateAnimation("Alpha")
    frame.glowFade:SetChildKey("glowTexture")
    frame.glowFade:SetFromAlpha(0)
    frame.glowFade:SetToAlpha(0.6)
    frame.glowFade:SetDuration(0.6)
    frame.glowFade:SetSmoothing("IN_OUT")
end

function AiB.Animations:StartGlow(frame)
    if frame.glowGroup then
        frame.glowGroup:Play()
    end
end

function AiB.Animations:StopGlow(frame)
    if frame.glowGroup then
        frame.glowGroup:Stop()
        if frame.glowTexture then
            frame.glowTexture:SetAlpha(0)
        end
    end
end

-------------------------
-- HOVER EFFECTS
-------------------------
function AiB.Animations:AddHoverEffect(button, scaleAmount)
    scaleAmount = scaleAmount or AiB.Config:GetAnimationDuration("TAB_HOVER_SCALE")
    
    button:HookScript("OnEnter", function(self)
        if AiB_Settings and AiB_Settings.animations_enabled then
            AiB.Animations:ScalePulse(self, scaleAmount, 0.1)
            
            -- Optional: Glow effect
            if self.enableGlow then
                AiB.Animations:StartGlow(self)
            end
        end
    end)
    
    button:HookScript("OnLeave", function(self)
        if self.glowGroup then
            AiB.Animations:StopGlow(self)
        end
    end)
end

-------------------------
-- TAB TRANSITION
-------------------------
function AiB.Animations:TransitionTab(oldContent, newContent, direction)
    if not AiB_Settings or not AiB_Settings.animations_enabled then
        if oldContent then oldContent:Hide() end
        if newContent then newContent:Show() end
        return
    end
    
    direction = direction or "LEFT"
    
    if oldContent then
        self:SlideOut(oldContent, direction, 0.2)
    end
    
    if newContent then
        C_Timer.After(0.1, function()
            local oppositeDir = direction == "LEFT" and "RIGHT" or "LEFT"
            AiB.Animations:SlideIn(newContent, oppositeDir, 0.25)
        end)
    end
end

-------------------------
-- SHAKE ANIMATION
-------------------------
function AiB.Animations:Shake(frame, intensity, duration)
    intensity = intensity or 5
    duration = duration or 0.3
    
    local originalPoint = {frame:GetPoint()}
    local shakes = 10
    local interval = duration / shakes
    
    local count = 0
    local ticker = C_Timer.NewTicker(interval, function()
        count = count + 1
        
        if count >= shakes then
            frame:ClearAllPoints()
            frame:SetPoint(unpack(originalPoint))
            return
        end
        
        local offsetX = math.random(-intensity, intensity)
        local offsetY = math.random(-intensity, intensity)
        
        frame:ClearAllPoints()
        frame:SetPoint(originalPoint[1], originalPoint[2], originalPoint[3], 
                      originalPoint[4] + offsetX, originalPoint[5] + offsetY)
    end)
    
    C_Timer.After(duration, function()
        if ticker then ticker:Cancel() end
        frame:ClearAllPoints()
        frame:SetPoint(unpack(originalPoint))
    end)
end

-------------------------
-- ROTATION ANIMATION
-------------------------
function AiB.Animations:RotateTexture(texture, duration, degrees)
    duration = duration or 2
    degrees = degrees or 360
    
    if not texture.rotationGroup then
        texture.rotationGroup = texture:CreateAnimationGroup()
        texture.rotationAnim = texture.rotationGroup:CreateAnimation("Rotation")
        texture.rotationGroup:SetLooping("REPEAT")
    end
    
    texture.rotationAnim:SetDegrees(degrees)
    texture.rotationAnim:SetDuration(duration)
    texture.rotationGroup:Play()
end

function AiB.Animations:StopRotation(texture)
    if texture.rotationGroup then
        texture.rotationGroup:Stop()
    end
end

-------------------------
-- UTILITY FUNCTIONS
-------------------------
function AiB.Animations:IsAnimating(frame)
    if frame.fadeGroup and frame.fadeGroup:IsPlaying() then return true end
    if frame.slideGroup and frame.slideGroup:IsPlaying() then return true end
    if frame.scaleGroup and frame.scaleGroup:IsPlaying() then return true end
    return false
end

function AiB.Animations:StopAll(frame)
    if frame.fadeGroup then frame.fadeGroup:Stop() end
    if frame.slideGroup then frame.slideGroup:Stop() end
    if frame.scaleGroup then frame.scaleGroup:Stop() end
    if frame.glowGroup then frame.glowGroup:Stop() end
end

-- Enable/Disable Animations
function AiB.Animations:SetEnabled(enabled)
    AiB_Settings = AiB_Settings or {}
    AiB_Settings.animations_enabled = enabled
end

function AiB.Animations:IsEnabled()
    return AiB_Settings and AiB_Settings.animations_enabled ~= false
end


