#!/usr/bin/env bash
# By Maciej Dworak
# Version 2021-06-04
# Compatible with Inkscape 1.0
# This script generates PNG icons from SVG files using Inkscape.
# If pngquant is installed, it will automatically use it to compress the PNGs.
#
# PNG files are written to /tmp/rt-icons-XXXX
#
# USAGE EXAMPLES
#   ./tools/generatePngIcons rtdata/images/themed/svg/*
#   ./tools/generatePngIcons rtdata/images/themed/svg/circle* rtdata/images/themed/svg/square-toggle-*

# No touching below this line
# -----------------------------------------------------------------------------

#tmpDir="$(mktemp -d /tmp/rt-icons-XXXX)" || exit
tmpDir="/tmp/rt-icons"
rm -r "$tmpDir"
mkdir "$tmpDir" || exit 1
outDir="$tmpDir"

# Abort if Inkscape is not installed:
if [[ ${OSTYPE^^} = "MSYS" ]]; then
    if ! command -v "/c/Program Files/Inkscape/inkscape.exe" >/dev/null; then
        printf '%s\n' "Inkscape does not appear to be installed. Aborting."
        exit 1
    fi
else
    if ! command -v inkscape >/dev/null; then
        printf '%s\n' "Inkscape does not appear to be installed. Aborting."
        exit 1
    fi
fi

# Command-line arguments:
if [[ $# -eq 0 ]]; then
    printf '%s\n' "This script generates PNG icons from SVG files using Inkscape." \
    "" \
    "USAGE" \
    "   Generate PNG icons from many SVG icons and output to /tmp/rt-icons-XXXX" \
    "       ./generatePngIcons some-icons-*.svg" \
    "" \
    "If pngquant is installed, it will automatically use it to compress the PNGs." \
    ""
    exit 0
fi

printf '%s\n' "Converting SVG icons to PNG." "${#} files passed as arguments."

# This color will be replaced by each theme's color:
colRef="#2a7fff"

# Define theme names, and for each theme the color which will replace colorRef:
declare -A themes
themes=( ["dark"]="#CCCCCC" ["light"]="#252525" )

# Optionally use pngquant to compress resulting PNGs:
doCompress="false"
if command -v pngquant >/dev/null; then
    doCompress="true"
    printf '%s\n' "pngquant found, will compress PNG files." ""
fi

# Ask for confirmation if folders already present:
folderExists="false"
doDelete="true"
for theme in "${!themes[@]}"; do
    if [[ -d "${outDir}/${theme}" ]]; then
        folderExists="true"
        doDelete="false"
    fi
done
if [[ $folderExists = "true" ]]; then
    printf '%s\n' "One or more output folders already exist in \"${outDir}\". If you proceed, they will be deleted."
    read -r -p "Proceed? [y/n]: "
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        doDelete="true"
    else
        printf '%s\n' "Aborting."
        exit 0
    fi
fi

# Create output folders:
for theme in "${!themes[@]}"; do
    if [[ -d "${outDir}/${theme}" && $doDelete = "true" ]]; then
        rm -rf "${outDir:?}/${theme}"
    fi
    mkdir -p "${outDir:?}/${theme}" || exit 1
done
printf '%s\n' "Output folder: ${outDir}" ""

# Platform-dependent SVG to PNG conversion using Inkscape
# $1 = output PNG absolute path
# $2 = input SVG absolute path
convertSvg() {
    if [[ ${OSTYPE^^} = "MSYS" ]]; then
        "/c/Program Files/Inkscape/inkscape.exe" \
            --export-area-page \
            --export-background-opacity="0" \
            --export-type=png \
            --export-filename="$1" \
            "$2"
    else
        inkscape \
            --export-area-page \
            --export-background-opacity="0" \
            --export-type=png \
            --export-filename="$1" \
            "$2"
    fi

    if [[ $doCompress = "true" ]]; then
        sizeBefore=$(wc -c < "$1")
        pngquant \
            --quality=70-80 \
            --ext .png \
            --force \
            --skip-if-larger \
            "$1"
        sizeAfter=$(wc -c < "$1")
        printf 'Filesize before: %s    After: %s    Difference: %s\n' "$sizeBefore" "$sizeAfter" "$((sizeBefore - sizeAfter))"
    fi
}

# Iterate over each SVG, saving PNGs for each theme.
# Files passed as arguments can have absolute paths or just filenames depending on how the user calls the script,
# so svgFilename and svgAbsolute are explicitly handled.
for f in "${@}"; do
    if [[ $f = *.svg || $f = *.svgz ]]; then
        svgAbsolute="$(readlink -m -n "$f")"
        svgFilename="$(basename "$svgAbsolute")"
        printf '%s\n' "Processing: ${svgAbsolute}"

        for theme in "${!themes[@]}"; do
            printf '%s\n' "Theme: ${theme}"
            sed -e "s/fill:${colRef};/fill:${themes[$theme]};/" -e "s/stroke:${colRef};/stroke:${themes[$theme]};/" "$svgAbsolute" > "${outDir}/${theme}/${svgFilename}"
            convertSvg "${outDir}/${theme}/${svgFilename%.svg*}.png" "${outDir}/${theme}/${svgFilename}"
            rm "${outDir}/${theme}/${svgFilename}"
        done

        printf '\n'
    fi
done

printf '%s\n' "Done." ""
