PSTerminalAnimations.psm1

#region ASCII Terminal Animations - Fun & Creative Edition
# Purpose: Create various ASCII animations for different execution scenarios
# Author: Jaya Surya Pennada
# Date: 2026

#region Color Configuration
$script:AnimationColors = @{
    Loop        = "Cyan"
    APIWait     = "Yellow"
    Conditional = "Magenta"
    Processing  = "Green"
    Sync        = "Blue"
    Error       = "Red"
    Success     = "Green"
}
#endregion

#region Animation Database - Creative Shapes
$script:Animations = @{
    # ╔═══════════════════════════════════════════════════════════════╗
    # ║ LOOP ANIMATION - "Dancing Robot" / Rotating DJ
    # ║ Perfect for: loops, iterations, rotating operations
    # ╚═══════════════════════════════════════════════════════════════╝
    Loop = @{
        Frames = @(
            "♪ ♫ ♪",
            " ♫ ♪",
            "♫ ♪ ♫",
            "♪ ♫"
        )
        Description = "Dancing Robot Loop"
        Color = "Cyan"
        Speed = 100
    }

    # ╔═══════════════════════════════════════════════════════════════╗
    # ║ API WAITING - "Bouncing Ball Fetch"
    # ║ Perfect for: API calls, HTTP requests, network operations
    # ╚═══════════════════════════════════════════════════════════════╝
    APIWait = @{
        Frames = @(
            " ● ",
            " ●●● ",
            " ● ● ",
            " ● ● ",
            " ● ● ",
            " ●●● "
        )
        Description = "Bouncing Ball Fetching Data"
        Color = "Yellow"
        Speed = 80
    }

    # ╔═══════════════════════════════════════════════════════════════╗
    # ║ LOADING VARIATION - "Satellite Orbital"
    # ║ Perfect for: long-running async operations
    # ╚═══════════════════════════════════════════════════════════════╝
    LoadingOrbital = @{
        Frames = @(
            "◐ Orbiting...",
            "◓ Orbiting...",
            "◑ Orbiting...",
            "◒ Orbiting..."
        )
        Description = "Satellite in Orbit"
        Color = "Yellow"
        Speed = 120
    }

    # ╔═══════════════════════════════════════════════════════════════╗
    # ║ CONDITIONAL CHECK - "Thinking Brain"
    # ║ Perfect for: if/else conditions, decision logic
    # ╚═══════════════════════════════════════════════════════════════╝
    Conditional = @{
        Frames = @(
            " ◯◯◯ ⚡",
            " ◯◯◯◯◯ ⚡⚡",
            "◯◯◯◯◯◯◯ ⚡⚡⚡",
            " ◯◯◯◯◯ ⚡⚡",
            " ◯◯◯ ⚡"
        )
        Description = "Thinking Brain Evaluating"
        Color = "Magenta"
        Speed = 100
    }

    # ╔═══════════════════════════════════════════════════════════════╗
    # ║ PROCESSING - "Hungry Pac-Man"
    # ║ Perfect for: data processing, calculations, crunching
    # ╚═══════════════════════════════════════════════════════════════╝
    Processing = @{
        Frames = @(
            "◉ ◙ ◎ ◍",
            "◎ ◉ ◙ ◍",
            "◍ ◎ ◉ ◙",
            "◙ ◍ ◎ ◉"
        )
        Description = "Pac-Man Processing Data"
        Color = "Green"
        Speed = 90
    }

    # ╔═══════════════════════════════════════════════════════════════╗
    # ║ PROCESSING VARIATION - "Building Blocks"
    # ║ Perfect for: step-by-step operations, building sequences
    # ╚═══════════════════════════════════════════════════════════════╝
    ProcessingBlocks = @{
        Frames = @(
            "▁▂▃▄▅▆▇█",
            "█▁▂▃▄▅▆▇",
            "▇█▁▂▃▄▅▆",
            "▆▇█▁▂▃▄▅",
            "▅▆▇█▁▂▃▄",
            "▄▅▆▇█▁▂▃",
            "▃▄▅▆▇█▁▂",
            "▂▃▄▅▆▇█▁"
        )
        Description = "Building Blocks Rotating"
        Color = "Green"
        Speed = 70
    }

    # ╔═══════════════════════════════════════════════════════════════╗
    # ║ SYNCHRONIZATION - "Breathing Heartbeat"
    # ║ Perfect for: waiting for sync, multi-process coordination
    # ╚═══════════════════════════════════════════════════════════════╝
    Sync = @{
        Frames = @(
            "♥ ",
            "♥♥ ",
            "♥♥♥ ",
            "♥♥♥♥",
            "♥♥♥ ",
            "♥♥ "
        )
        Description = "Heartbeat Synchronizing"
        Color = "Blue"
        Speed = 110
    }

    # ╔═══════════════════════════════════════════════════════════════╗
    # ║ SYNC VARIATION - "Pulsing Gear"
    # ║ Perfect for: mechanical operations, gear-like coordination
    # ╚═══════════════════════════════════════════════════════════════╝
    SyncGear = @{
        Frames = @(
            "⚙",
            "⚙",
            "⚙",
            "⚙"
        )
        Description = "Spinning Gear Syncing"
        Color = "Blue"
        Speed = 120
    }

    # ╔═══════════════════════════════════════════════════════════════╗
    # ║ ERROR/ALERT - "Angry Warning Eye"
    # ║ Perfect for: errors, retries, critical warnings
    # ╚═══════════════════════════════════════════════════════════════╝
    Error = @{
        Frames = @(
            "✗✗✗",
            " ✗ ",
            "✗✗✗"
        )
        Description = "Angry Warning Blinking"
        Color = "Red"
        Speed = 150
    }

    # ╔═══════════════════════════════════════════════════════════════╗
    # ║ ERROR VARIATION - "Skull Warning"
    # ║ Perfect for: critical failures, dangerous operations
    # ╚═══════════════════════════════════════════════════════════════╝
    ErrorSkull = @{
        Frames = @(
            "☠ DANGER",
            "✕ DANGER",
            "☠ DANGER",
            "✕ DANGER"
        )
        Description = "Skull Warning Critical"
        Color = "Red"
        Speed = 140
    }

    # ╔═══════════════════════════════════════════════════════════════╗
    # ║ SUCCESS - "Dancing Celebration"
    # ║ Perfect for: successful completions, wins, achievements
    # ╚═══════════════════════════════════════════════════════════════╝
    Success = @{
        Frames = @(
            "\\o/",
            "\\O/",
            "/o\\",
            "/O\\"
        )
        Description = "Victory Dance Celebration"
        Color = "Green"
        Speed = 130
    }

    # ╔═══════════════════════════════════════════════════════════════╗
    # ║ RETRY - "Phoenix Rising"
    # ║ Perfect for: retries, recovery, bouncing back
    # ╚═══════════════════════════════════════════════════════════════╝
    Retry = @{
        Frames = @(
            "🜨 ",
            " 🜨",
            "🜨 ",
            " 🜨"
        )
        Description = "Phoenix Rising Retry"
        Color = "Yellow"
        Speed = 100
    }

    # ╔═══════════════════════════════════════════════════════════════╗
    # ║ DOWNLOADING - "Falling Raindrops"
    # ║ Perfect for: downloads, data streaming, flow operations
    # ╚═══════════════════════════════════════════════════════════════╝
    Download = @{
        Frames = @(
            "↓ ",
            " ↓ ",
            " ↓ ",
            " ↓",
            " ",
            "↓ ",
            " ↓ "
        )
        Description = "Raindrops Falling Download"
        Color = "Cyan"
        Speed = 80
    }

    # ╔═══════════════════════════════════════════════════════════════╗
    # ║ UPLOADING - "Rising Bubbles"
    # ║ Perfect for: uploads, data sending, rising operations
    # ╚═══════════════════════════════════════════════════════════════╝
    Upload = @{
        Frames = @(
            " ",
            " ◉",
            " ◉ ",
            " ◉ ",
            "◉ ",
            " ",
            " ◉"
        )
        Description = "Bubbles Rising Upload"
        Color = "Cyan"
        Speed = 80
    }

    # ╔═══════════════════════════════════════════════════════════════╗
    # ║ SEARCHING - "Detective Magnifying Glass"
    # ║ Perfect for: search operations, lookup, scanning
    # ╚═══════════════════════════════════════════════════════════════╝
    Search = @{
        Frames = @(
            "◯/ ",
            "/◯ ",
            "◯/ ",
            "/◯ "
        )
        Description = "Detective Searching"
        Color = "White"
        Speed = 100
    }

    # ╔═══════════════════════════════════════════════════════════════╗
    # ║ CONNECTING - "Growing Network"
    # ║ Perfect for: connections, networking, linking resources
    # ╚═══════════════════════════════════════════════════════════════╝
    Connecting = @{
        Frames = @(
            "●",
            "●─●",
            "●─●─●",
            "●─●─●─●",
            "●─●─●",
            "●─●"
        )
        Description = "Growing Network Connection"
        Color = "Green"
        Speed = 90
    }
}
#endregion

#region Core Animation Functions

<#
.SYNOPSIS
    Displays a looping ASCII animation with customizable speed and message
.DESCRIPTION
    Shows animated ASCII frames in a loop for specified duration or iteration count
.PARAMETER AnimationType
    Type of animation to display (Loop, APIWait, Conditional, etc.)
.PARAMETER Duration
    How long to show animation in seconds (default: 5)
.PARAMETER Message
    Optional message to display alongside animation
.PARAMETER Iterations
    Alternative to Duration - run for specific number of iterations
.EXAMPLE
    Show-Animation -AnimationType "APIWait" -Duration 3 -Message "Fetching data..."
#>

function Show-Animation {
    param(
        [Parameter(Mandatory=$true)]
        [ValidateSet("Loop","APIWait","LoadingOrbital","Conditional","Processing","ProcessingBlocks","Sync","SyncGear","Error","ErrorSkull","Success","Retry","Download","Upload","Search","Connecting")]
        [string]$AnimationType,
        
        [int]$Duration = 5,
        [string]$Message = "",
        [int]$Iterations = 0
    )

    if (-not $script:Animations.ContainsKey($AnimationType)) {
        Write-Host "Animation type '$AnimationType' not found!" -ForegroundColor Red
        return
    }

    $animation = $script:Animations[$AnimationType]
    $frames = $animation.Frames
    $speed = $animation.Speed
    $color = $animation.Color
    $frameCount = 0

    # Calculate iterations if duration is specified
    if ($Iterations -eq 0) {
        $Iterations = [math]::Ceiling(($Duration * 1000) / $speed)
    }

    $startTime = Get-Date
    
    for ($i = 0; $i -lt $Iterations; $i++) {
        $frameIndex = $i % $frames.Count
        $frame = $frames[$frameIndex]
        
        # Clear and display frame
        Write-Host "`r$frame $Message" -ForegroundColor $color -NoNewline
        
        Start-Sleep -Milliseconds $speed
        $frameCount++
    }
    
    Write-Host "`r" + (" " * ($frames[0].Length + $Message.Length + 5)) + "`r" -NoNewline  # Clear line
}

<#
.SYNOPSIS
    Shows animation for a specified duration with a label
.DESCRIPTION
    Display animation with automatic clearing after completion
.PARAMETER AnimationType
    Type of animation to display
.PARAMETER Duration
    Duration in seconds
.PARAMETER Label
    Label to show with animation
.EXAMPLE
    Show-AnimatedWait -AnimationType "APIWait" -Duration 3 -Label "Connecting to API"
#>

function Show-AnimatedWait {
    param(
        [Parameter(Mandatory=$true)]
        [ValidateSet("Loop","APIWait","LoadingOrbital","Conditional","Processing","ProcessingBlocks","Sync","SyncGear","Error","ErrorSkull","Success","Retry","Download","Upload","Search","Connecting")]
        [string]$AnimationType,
        
        [int]$Duration = 5,
        [string]$Label = "Processing"
    )
    
    Show-Animation -AnimationType $AnimationType -Duration $Duration -Message "[$Label]"
    Write-Host "✓ Complete!" -ForegroundColor Green
}

<#
.SYNOPSIS
    Gets list of all available animations
.DESCRIPTION
    Returns information about all registered animations
.EXAMPLE
    Get-AvailableAnimations
#>

function Get-AvailableAnimations {
    Write-Host "`n" -ForegroundColor Cyan
    Write-Host "╔════════════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
    Write-Host "║ AVAILABLE ASCII ANIMATIONS - CREATIVE EDITION ║" -ForegroundColor Cyan
    Write-Host "╚════════════════════════════════════════════════════════════════╝" -ForegroundColor Cyan
    Write-Host ""
    
    $script:Animations.GetEnumerator() | ForEach-Object {
        $name = $_.Key
        $desc = $_.Value.Description
        $color = $_.Value.Color
        
        Write-Host " ► " -ForegroundColor $color -NoNewline
        Write-Host "$name".PadRight(20) -NoNewline
        Write-Host " : $desc" -ForegroundColor White
    }
    
    Write-Host "`n"
}

<#
.SYNOPSIS
    Demonstrates all available animations
.DESCRIPTION
    Shows a quick preview of each animation type
.EXAMPLE
    Show-AllAnimations
#>

function Show-AllAnimations {
    Write-Host "`nDemonstrating ALL Animations (2 seconds each):`n" -ForegroundColor Cyan
    
    $script:Animations.GetEnumerator() | ForEach-Object {
        $name = $_.Key
        $desc = $_.Value.Description
        
        Write-Host "$name ($desc):" -ForegroundColor Yellow
        Show-Animation -AnimationType $name -Duration 2
        Write-Host ""
    }
}

<#
.SYNOPSIS
    Quick animation test - useful for testing
.DESCRIPTION
    Shows a specific animation with custom parameters
.PARAMETER AnimationType
    Animation type to test
.PARAMETER Seconds
    Duration in seconds
.EXAMPLE
    Test-Animation -AnimationType "APIWait" -Seconds 3
#>

function Test-Animation {
    param(
        [Parameter(Mandatory=$true)]
        [ValidateSet("Loop","APIWait","LoadingOrbital","Conditional","Processing","ProcessingBlocks","Sync","SyncGear","Error","ErrorSkull","Success","Retry","Download","Upload","Search","Connecting")]
        [string]$AnimationType,
        [int]$Seconds = 3
    )
    
    Write-Host "Animating: " -NoNewline -ForegroundColor Cyan
    Write-Host $script:Animations[$AnimationType].Description -ForegroundColor Yellow
    Write-Host ""
    
    Show-Animation -AnimationType $AnimationType -Duration $Seconds -Message "[Test]"
    
    Write-Host "`n" -ForegroundColor Green
    Write-Host "✓ Animation Complete!" -ForegroundColor Green
}

#endregion

#region Practical Usage Examples (Export-able scenarios)

<#
.SYNOPSIS
    Runs a script block with animation displayed while it executes
.DESCRIPTION
    Shows animation while running a script block in the current scope. Optionally displays performance statistics and custom messages. Returns the output from the script block.
.PARAMETER AnimationType
    Type of animation to display
.PARAMETER ScriptBlock
    The code block to execute
.PARAMETER Label
    Label to show with animation
.PARAMETER ShowStats
    Switch to display elapsed time and performance statistics
.PARAMETER StartMessage
    Optional message to display before animation starts
.PARAMETER EndMessage
    Optional message to display after animation completes
.OUTPUTS
    Returns the output from the script block
.EXAMPLE
    Invoke-WithAnimation -AnimationType "APIWait" -ScriptBlock { Start-Sleep -Seconds 2 } -Label "API Call"
.EXAMPLE
    Invoke-WithAnimation -AnimationType "Processing" -ScriptBlock { Start-Sleep -Seconds 5 } -Label "Task" -ShowStats
.EXAMPLE
    $result = Invoke-WithAnimation -AnimationType "Download" -ScriptBlock { Get-ChildItem } -Label "Download" -StartMessage "Starting..." -EndMessage "Done!"
#>

function Invoke-WithAnimation {
    param(
        [Parameter(Mandatory=$true)]
        [ValidateSet("Loop","APIWait","LoadingOrbital","Conditional","Processing","ProcessingBlocks","Sync","SyncGear","Error","ErrorSkull","Success","Retry","Download","Upload","Search","Connecting")]
        [string]$AnimationType,
        
        [Parameter(Mandatory=$true)]
        [scriptblock]$ScriptBlock,
        
        [string]$Label = "Processing",
        
        [switch]$ShowStats,
        
        [string]$StartMessage = "",
        
        [string]$EndMessage = ""
    )
    
    # Display start message if provided
    if ($StartMessage) {
        Write-Host $StartMessage -ForegroundColor Cyan
    }
    
    $animation = $script:Animations[$AnimationType]
    $frames = $animation.Frames
    $speed = $animation.Speed
    $color = $animation.Color
    
    # Record start time
    $startTime = [DateTime]::UtcNow
    
    # Run the script block asynchronously
    $job = Start-Job -ScriptBlock $ScriptBlock
    
    # Show animation while job is running
    while ($job.State -eq "Running") {
        $elapsed = [int]([DateTime]::UtcNow - $startTime).TotalSeconds
        $frameIndex = [math]::Floor([DateTime]::UtcNow.Ticks / ($speed * 10000)) % $frames.Count
        $frame = $frames[$frameIndex]
        
        if ($ShowStats) {
            Write-Host "`r$frame [$Label] ${elapsed}s" -ForegroundColor $color -NoNewline
        } else {
            Write-Host "`r$frame [$Label]" -ForegroundColor $color -NoNewline
        }
        
        Start-Sleep -Milliseconds $speed
    }
    
    # Calculate total elapsed time
    $totalElapsed = [DateTime]::UtcNow - $startTime
    
    # Clear the animation line
    $clearLength = if ($ShowStats) { $frames[0].Length + $Label.Length + 15 } else { $frames[0].Length + $Label.Length + 5 }
    Write-Host "`r" + (" " * $clearLength) + "`r" -NoNewline
    
    # Receive job output
    $output = Receive-Job -Job $job
    
    # Display output to console if present
    if ($output) {
        Write-Host $output
    }
    
    Remove-Job -Job $job
    
    # Display performance stats if requested
    if ($ShowStats) {
        Write-Host "✓ Done! " -ForegroundColor Green -NoNewline
        Write-Host "Completed in " -NoNewline
        Write-Host "$($totalElapsed.TotalSeconds.ToString('F2'))s" -ForegroundColor Cyan
    } else {
        Write-Host "✓ Done!" -ForegroundColor Green
    }
    
    # Display end message if provided
    if ($EndMessage) {
        Write-Host $EndMessage -ForegroundColor Green
    }
    
    # Return the script block output
    return $output
}

# Export the functions to make them available when the module is imported
Export-ModuleMember -Function Show-Animation, Show-AnimatedWait, Get-AvailableAnimations, Show-AllAnimations, Test-Animation, Invoke-WithAnimation