param(
    [Parameter(Mandatory = $true)]
    [string]$Job
)

$ErrorActionPreference = "Stop"
[Console]::OutputEncoding = [Text.UTF8Encoding]::new()

if (-not (Test-Path -LiteralPath $Job)) {
    Write-Error "Missing job file"
    exit 2
}

$cfg = Get-Content -LiteralPath $Job -Raw -Encoding UTF8 | ConvertFrom-Json
$file = [string]$cfg.file
$printer = [string]$cfg.printer
$widthMm = [double]$cfg.width_mm
$heightMm = [double]$cfg.height_mm
$copies = [int]($cfg.copies)
$label = [string]$cfg.label
if ($copies -lt 1) { $copies = 1 }

if (-not (Test-Path -LiteralPath $file)) {
    Write-Error "Missing photo"
    exit 3
}

Add-Type -AssemblyName System.Drawing

function ToHundredths([double]$mm) {
    return [int][Math]::Round(($mm / 25.4) * 100)
}

$wantW = ToHundredths $widthMm
$wantH = ToHundredths $heightMm
if ($wantW -lt 80) { $wantW = 400 }
if ($wantH -lt 80) { $wantH = 600 }

$img = [System.Drawing.Image]::FromFile($file)
try {
    $doc = New-Object System.Drawing.Printing.PrintDocument
    $doc.DocumentName = "Panorama Lab"
    $doc.OriginAtMargins = $false
    if ($printer -ne "") {
        $doc.PrinterSettings.PrinterName = $printer
        if (-not $doc.PrinterSettings.IsValid) {
            throw "Ο εκτυπωτής δεν είναι έγκυρος: $printer"
        }
    }
    $doc.PrinterSettings.Copies = [int16]$copies

    $paper = $null
    $needles = @()
    if ($label) { $needles += $label.ToLowerInvariant() }
    $needles += ("{0}x{1}" -f [int][Math]::Round($widthMm / 25.4), [int][Math]::Round($heightMm / 25.4))
    $needles += ("{0}x{1}" -f [int]$widthMm, [int]$heightMm)

    foreach ($size in $doc.PrinterSettings.PaperSizes) {
        $name = ([string]$size.PaperName).ToLowerInvariant()
        foreach ($n in $needles) {
            if ($n -and $name.Contains($n.ToLowerInvariant())) {
                $paper = $size
                break
            }
        }
        if ($paper) { break }
        $dw = [Math]::Abs($size.Width - $wantW)
        $dh = [Math]::Abs($size.Height - $wantH)
        $dwr = [Math]::Abs($size.Width - $wantH)
        $dhr = [Math]::Abs($size.Height - $wantW)
        if (($dw -le 25 -and $dh -le 25) -or ($dwr -le 25 -and $dhr -le 25)) {
            $paper = $size
            break
        }
    }

    if (-not $paper) {
        $paper = New-Object System.Drawing.Printing.PaperSize "LabPrint", $wantW, $wantH
        try { $paper.RawKind = 256 } catch {}
    }

    $landscape = $false
    if ($img.Width -ge $img.Height -and $paper.Width -lt $paper.Height) {
        $landscape = $true
    }
    if ($img.Height -gt $img.Width -and $paper.Width -gt $paper.Height) {
        $landscape = $true
    }

    $doc.DefaultPageSettings.PaperSize = $paper
    $doc.DefaultPageSettings.Landscape = $landscape
    $doc.DefaultPageSettings.Color = $true
    $doc.DefaultPageSettings.Margins = New-Object System.Drawing.Printing.Margins 0, 0, 0, 0

    $script:photo = $img
    $doc.add_PrintPage({
        param($sender, $e)
        $e.Graphics.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
        $e.Graphics.DrawImage($script:photo, $e.PageBounds)
        $e.HasMorePages = $false
    })
    $doc.Print()
    $doc.Dispose()
}
finally {
    $img.Dispose()
}

exit 0
