#requires -Version 5
# One-shot helper: produces a multi-resolution icon.ico from icon.png.
# Run only when the source icon changes; commit the resulting icon.ico.

Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName PresentationCore
Add-Type -AssemblyName WindowsBase

$here    = Split-Path -Parent $MyInvocation.MyCommand.Path
$srcPath = Join-Path $here 'icon.png'
$icoPath = Join-Path $here 'icon.ico'

if (-not (Test-Path $srcPath)) { throw "icon.png not found at $srcPath" }

# Detect if the file is actually a different format renamed to .png (e.g. WebP from AI tools).
# If so, transcode via WPF's WIC pipeline to a real PNG before feeding GDI+.
$head = [System.IO.File]::ReadAllBytes($srcPath)[0..3]
$isPng = $head[0] -eq 0x89 -and $head[1] -eq 0x50 -and $head[2] -eq 0x4E -and $head[3] -eq 0x47
if (-not $isPng) {
    Write-Host "Source file is not a PNG (likely WebP from AI tool). Transcoding via WIC..."
    $bytes  = [System.IO.File]::ReadAllBytes($srcPath)
    $stream = New-Object System.IO.MemoryStream(,$bytes)
    $decoder = [System.Windows.Media.Imaging.BitmapDecoder]::Create(
        $stream,
        [System.Windows.Media.Imaging.BitmapCreateOptions]::PreservePixelFormat,
        [System.Windows.Media.Imaging.BitmapCacheOption]::OnLoad)
    $frame = $decoder.Frames[0]
    # Force BGRA32 so GDI+ can later handle it cleanly with alpha
    $converted = New-Object System.Windows.Media.Imaging.FormatConvertedBitmap(
        $frame,
        [System.Windows.Media.PixelFormats]::Bgra32,
        $null,
        0)
    $encoder = New-Object System.Windows.Media.Imaging.PngBitmapEncoder
    $encoder.Frames.Add([System.Windows.Media.Imaging.BitmapFrame]::Create($converted))
    $outStream = New-Object System.IO.MemoryStream
    $encoder.Save($outStream)
    [System.IO.File]::WriteAllBytes($srcPath, $outStream.ToArray())
    $outStream.Dispose()
    $stream.Dispose()
    Write-Host "Transcoded to real PNG ($($outStream.Length) bytes)."
}

$sizes = 16, 32, 48, 64, 128, 256
$src   = [System.Drawing.Image]::FromFile($srcPath)
$frames = @{}

foreach ($size in $sizes) {
    $bmp = New-Object System.Drawing.Bitmap $size, $size, ([System.Drawing.Imaging.PixelFormat]::Format32bppArgb)
    $g   = [System.Drawing.Graphics]::FromImage($bmp)
    $g.InterpolationMode  = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
    $g.SmoothingMode      = [System.Drawing.Drawing2D.SmoothingMode]::HighQuality
    $g.PixelOffsetMode    = [System.Drawing.Drawing2D.PixelOffsetMode]::HighQuality
    $g.CompositingQuality = [System.Drawing.Drawing2D.CompositingQuality]::HighQuality
    $g.DrawImage($src, 0, 0, $size, $size)
    $g.Dispose()

    $ms = New-Object System.IO.MemoryStream
    $bmp.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png)
    $frames[$size] = $ms.ToArray()
    $bmp.Dispose()
    $ms.Dispose()
}

$out = New-Object System.IO.MemoryStream
$bw  = New-Object System.IO.BinaryWriter($out)

# ICONDIR header
$bw.Write([UInt16]0)
$bw.Write([UInt16]1)
$bw.Write([UInt16]$sizes.Count)

$dataOffset = 6 + (16 * $sizes.Count)
foreach ($size in $sizes) {
    $bytes = $frames[$size]
    $w = if ($size -ge 256) { [byte]0 } else { [byte]$size }
    $h = if ($size -ge 256) { [byte]0 } else { [byte]$size }
    $bw.Write([byte]$w)
    $bw.Write([byte]$h)
    $bw.Write([byte]0)
    $bw.Write([byte]0)
    $bw.Write([UInt16]1)
    $bw.Write([UInt16]32)
    $bw.Write([UInt32]$bytes.Length)
    $bw.Write([UInt32]$dataOffset)
    $dataOffset += $bytes.Length
}

foreach ($size in $sizes) {
    $bw.Write($frames[$size])
}

[System.IO.File]::WriteAllBytes($icoPath, $out.ToArray())
$bw.Dispose()
$out.Dispose()
$src.Dispose()

"Wrote: $icoPath ($((Get-Item $icoPath).Length) bytes, $($sizes.Count) sizes)"
