#!/usr/bin/env bash

# Copyright (c) 2025 Private Internet Access, Inc.
#
# This file is part of the Private Internet Access Desktop Client.
#
# The Private Internet Access Desktop Client is free software: you can
# redistribute it and/or modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# The Private Internet Access Desktop Client is distributed in the hope that
# it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with the Private Internet Access Desktop Client.  If not, see
# <https://www.gnu.org/licenses/>.

if [ $# -lt 1 ]; then
  echo "usage:"
  echo "$0 <brand> [--ico | --ico-fast]"
  echo ""
  echo "  brand: code of brand to render tray icons (pia, acme, etc.)"
  echo "  --ico: render Windows icons (requires manual UI for compression)"
  echo "  --ico-fast: render Windows icons without compression for preview"
  echo ""
  echo "Renders tray icon assets from the SVG files in <brand>/tray_svg."
  echo "Updates <brand>/gen_res/img/tray with new assets."
  echo "With --ico or --ico-fast, also updates <brand>/gen_tray_ico."
  echo ""
  echo "Inkscape is required.  For Windows icons, ImageMagick and GIMP are also"
  echo "required."
  echo ""
  echo "Rendering Windows icons will show a GIMP export prompt for each icon."
  echo "Check all \"Compressed (PNG)\" boxes and click Export each time."
  echo "--ico-fast skips the prompts but does not compress the icons (for quick"
  echo "testing cycles), do not merge uncompressed icons."
  exit 1
fi

set -e
set -x

BRANDS_DIR_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
BRAND=$1
TRAY_SVG_DIR="${BRANDS_DIR_ROOT}/${BRAND}/tray_svg/"

# Whether to generate Windows icons, and whether to compress them.
# Compression requires manual UI clicks for each icon due to GIMP limitations,
# it can be skipped for testing.  This sets the "noninteractive" flag in the
# GIMP icon export step. (1=noninteractive, 0=interactive)
GENERATE_ICO=""

# ICO files aren't generated by default
if [ "$2" = "--ico" ]; then
    GENERATE_ICO=0
    echo "Generating Windows icons"
    echo "For each GIMP export prompt, check all \"Compressed (PNG)\" boxes and click Export"
    echo "Use \"$0 --ico-fast\" to skip the prompts (without compressing) for quick testing of icon tweaks"
elif [ "$2" = "--ico-fast" ]; then
    GENERATE_ICO=1
    echo "Generating Windows icons without compression, do not merge uncompressed icons"
else
    echo "Skipping ICO generation, use \"$0 --ico\" to also generate Windows icons"
fi

# Make sure you install inkscape from brew. Change this if you need to:
inkscape_cli=$(command -v inkscape || echo /Applications/Inkscape.app/Contents/Resources/bin/inkscape)
gimp=$(command -v gimp || echo /Applications/GIMP.app/Contents/MacOS/GIMP)

# Inkscape's CLI changed significantly between 0.9 and 1.0.
# In 0.9*, use "-z --export-png=<file>" (-z=--without-gui).
# In 1.*, use "--batch-process --export-filename=<file>" (file type inferred from extension)
if [[ "$($inkscape_cli --version)" =~ "Inkscape 0.9" ]]; then
  INKSCAPE_ARGS=("-z")
  INKSCAPE_EXPORT="--export-png="
else
  INKSCAPE_ARGS=("--batch-process")
  INKSCAPE_EXPORT="--export-filename="
fi

TRAY_TMP_DIR="${BRANDS_DIR_ROOT}/tray_tmp"
PNG_TMP_DIR="$TRAY_TMP_DIR/png"
ICO_TMP_DIR="$TRAY_TMP_DIR/ico"
rm -rf "$PNG_TMP_DIR"
mkdir -p "$PNG_TMP_DIR"

for themedir in "$TRAY_SVG_DIR"/wide-*; do
    if [ -d "$themedir" ]; then
        theme=$(basename "$themedir")
        echo "$theme"
        for img in "$themedir"/*; do
                RESULT_FILE="$PNG_TMP_DIR/$theme-$(basename "$img" .svg).png"
                # The source svgs are 34x30 px for their source size.
                # We could just resize this to 40x30 by adding some extra padding using "-3:0:37:30" which goes from -3,0 to 37,30 - giving us a few extra pixels of width
                # however there is a bit of spare vertical padding around images. To compensate for this, change
                # the export area to skip the top 2 and bottom 2 vertical pixels. We'll have to compensate the x-coordinate of export rectangle accordingly
                # in order to maintain the 4:3 aspect ratio.
                #
                # the final coordinates of export rectangle are 1,2 to 33,28
                $inkscape_cli "--export-area=-1:1:35:28" "${INKSCAPE_ARGS[@]}" "$INKSCAPE_EXPORT$RESULT_FILE" -w 40 -h 30 "$img"
        done
    fi
done

for themedir in "$TRAY_SVG_DIR"/square-*; do
    if [ -d "$themedir" ]; then
        theme=$(basename "$themedir")
        echo "$theme"
        for img in "$themedir"/*; do
                # These samples are only used in the Tray Icon dropdown itself;
                # 20px height + 2x scale for high DPI
                RESULT_FILE="$PNG_TMP_DIR/$theme-$(basename "$img" .svg).png"
                if [ "$theme" = "square-classic" ]; then
                    # square-classic images are 34x30. Add 2 px extra padding on top and bottom to get a properly scaled square
                    EXPORT_AREA=2:-1:34:31
                elif [[ "$theme" =~ "no-outline" ]]; then
                    EXPORT_AREA=2:1:16:15
                    if [[ $img =~ .+alert.+ ]]; then
                        echo "Compensating for alert image"
                        EXPORT_AREA=3:1:17:15
                    fi
                else
                    EXPORT_AREA=1:0:17:16
                    if [[ $img =~ .+alert.+ ]]; then
                        echo "Compensating for alert image"
                        EXPORT_AREA=2:0:18:16
                    fi
                fi
                $inkscape_cli "${INKSCAPE_ARGS[@]}" "--export-area=$EXPORT_AREA" "$INKSCAPE_EXPORT$RESULT_FILE" -w 40 -h 40 "$img"

                # The actual Linux icons should occupy ~75% of the image bound.
                # Otherwise, they run right up to the edge of the taskbar and
                # adjacent icons.
                # This looks the best on all environments tested (GNOME in
                # Ubuntu 18.04, KDE, LXDE, and XFCE).
                # The icons are designed at 16x16, so export [-2,-2 - 18,18] to
                # create the margins.  (Except for Classic, which is 30x30.)
                if [ "$theme" = "square-classic" ]; then
                    EXPORT_AREA=1:-3:37:33
                else
                    EXPORT_AREA=-1:-2:19:18
                fi
                RESULT_FILE="$PNG_TMP_DIR/$theme-margins-$(basename "$img" .svg).png"
                $inkscape_cli "${INKSCAPE_ARGS[@]}" "$INKSCAPE_EXPORT$RESULT_FILE" "--export-area=$EXPORT_AREA" -w 88 -h 88 "$img"
        done
    fi
done

for img in "$TRAY_SVG_DIR/samples"/*; do
        RESULT_FILE="$PNG_TMP_DIR/sample-$(basename "$img" .svg).png"
        $inkscape_cli "${INKSCAPE_ARGS[@]}" "$INKSCAPE_EXPORT$RESULT_FILE" -w 40 -h 30 "$img"
done


if [ ! "$GENERATE_ICO" = "" ]; then
    rm -rf "$ICO_TMP_DIR"
    mkdir -p "$ICO_TMP_DIR"

    ico_sizes=(16 20 24 32 40 48 64 128)
    # Only do this for the themes actually needed, GIMP ICO compression is
    # tedious and time-consuming
    ico_themes=(square-classic square-colored-no-outline square-colored-with-dark-outline square-light-no-outline square-light-with-dark-outline square-dark-no-outline)
    # ico_themes=(square-colored-no-outline)

    for theme in "${ico_themes[@]}"; do


        if [ -d "$TRAY_SVG_DIR/$theme" ]; then
            echo "$theme"
            for img in "$TRAY_SVG_DIR/$theme"/*; do
                    RESULT_FILE="$ICO_TMP_DIR/$theme-$(basename "$img" .svg).ico"
                    if [ "$theme" = "square-classic" ]; then
                        # square-classic images are 34x30. Add 2 px extra padding on top and bottom to get a properly scaled square
                        EXPORT_AREA=2:-1:34:31
                    elif [[ "$theme" =~ "no-outline" ]]; then
                        EXPORT_AREA=2:1:16:15
                        if [[ $img =~ .+alert.+ ]]; then
                            echo "Compensating for alert image"
                            EXPORT_AREA=3:1:17:15
                        fi
                    else
                        EXPORT_AREA=1:0:17:16
                        if [[ $img =~ .+alert.+ ]]; then
                            echo "Compensating for alert image"
                            EXPORT_AREA=2:0:18:16
                        fi
                    fi

                    ico_png_temp="$ICO_TMP_DIR/png_temp"
                    rm -rf "$ico_png_temp"
                    mkdir -p "$ico_png_temp"
                            for size in "${ico_sizes[@]}"; do
                                    $inkscape_cli "${INKSCAPE_ARGS[@]}" "$INKSCAPE_EXPORT$ico_png_temp/render_$size.png" "--export-area=$EXPORT_AREA" -w "$size" -h "$size" "$img"
                            done
                            convert "$ico_png_temp"/*.png "$RESULT_FILE"
                            # GIMP's scripting interface doesn't let us control the
                            # compression flags for each layer, so you'll have to
                            # check all 8 compression boxes manually and click
                            # "Export" for each prompt when generating compressed
                            # icons.
                            $gimp -i -b - <<EOF
(
let* ((image (car (gimp-file-load 1 "$RESULT_FILE" "$RESULT_FILE")))
      (drawable (car (gimp-image-get-active-layer image))))
(file-ico-save $GENERATE_ICO image drawable "$RESULT_FILE" "$RESULT_FILE")
(gimp-quit 0)
)
EOF
            done
        fi
    done
fi

# Copy the PNG outputs that we're actually using right now to the
# 'client_res_img_tray_output' directory, which stages the new content for
# client/res/img/tray.
PNG_OUTPUT_DIR="${BRANDS_DIR_ROOT}/${BRAND}/gen_res/img/tray/"
rm -rf "$PNG_OUTPUT_DIR"
mkdir -p "$PNG_OUTPUT_DIR"
# Wide icons - Mac
cp "$PNG_TMP_DIR"/wide-*.png "$PNG_OUTPUT_DIR"
# Mac 'Auto' preview.  (Don't need the other samples, use the real icons)
cp "$PNG_TMP_DIR"/sample-auto.png "$PNG_OUTPUT_DIR"
# Square icons with margins - Linux icons
cp "$PNG_TMP_DIR"/square-classic-margins-*.png "$PNG_OUTPUT_DIR"
cp "$PNG_TMP_DIR"/square-colored-no-outline-margins-*.png "$PNG_OUTPUT_DIR"
cp "$PNG_TMP_DIR"/square-dark-no-outline-margins-*.png "$PNG_OUTPUT_DIR"
cp "$PNG_TMP_DIR"/square-light-no-outline-margins-*.png "$PNG_OUTPUT_DIR"
# Square icons without margins - Linux and Windows previews, only need 'connected'
cp "$PNG_TMP_DIR"/square-classic-connected.png "$PNG_OUTPUT_DIR"
cp "$PNG_TMP_DIR"/square-colored-no-outline-connected.png "$PNG_OUTPUT_DIR"
cp "$PNG_TMP_DIR"/square-colored-with-dark-outline-connected.png "$PNG_OUTPUT_DIR"
cp "$PNG_TMP_DIR"/square-light-no-outline-connected.png "$PNG_OUTPUT_DIR"
cp "$PNG_TMP_DIR"/square-light-with-dark-outline-connected.png "$PNG_OUTPUT_DIR"
cp "$PNG_TMP_DIR"/square-dark-no-outline-connected.png "$PNG_OUTPUT_DIR"

echo "Generated PNGs in $PNG_OUTPUT_DIR"

# Copy the ICON outputs for Windows to a staging directory too
if [ ! "$GENERATE_ICO" = "" ]; then
    ICO_OUTPUT_DIR="${BRANDS_DIR_ROOT}/${BRAND}/gen_tray_ico/"
    rm -rf "$ICO_OUTPUT_DIR"
    mkdir -p "$ICO_OUTPUT_DIR"
    cp "$ICO_TMP_DIR"/square-classic-*.ico "$ICO_OUTPUT_DIR"
    cp "$ICO_TMP_DIR"/square-colored-no-outline-*.ico "$ICO_OUTPUT_DIR"
    cp "$ICO_TMP_DIR"/square-colored-with-dark-outline-*.ico "$ICO_OUTPUT_DIR"
    cp "$ICO_TMP_DIR"/square-light-no-outline-*.ico "$ICO_OUTPUT_DIR"
    cp "$ICO_TMP_DIR"/square-dark-no-outline-*.ico "$ICO_OUTPUT_DIR"
    cp "$ICO_TMP_DIR"/square-light-with-dark-outline-*.ico "$ICO_OUTPUT_DIR"
    echo "Generated ICOs in $ICO_OUTPUT_DIR"
fi
