---
version: '3'

vars:
  TINYPNG_API_KEY: z4qhFBLRvNMG9rHmdkSLx1DR1FNZN5gc

tasks:
  compress:
    deps:
      - :install:npm:tinypng
      - :install:software:exiftool
    desc: Compress JPG/PNG images via TinyPNG
    summary: |
      # Compress JPG/PNG images via TinyPNG

      Finding the best stack for compressing images is not easy. All the best stacks seem to
      only be available for macOS. This task gets around this shortcoming by using [TinyPNG](https://tinypng.org)
      to compress images. Although relying on a third-party service is not ideal, TinyPNG does
      a fantastic job compressing images. After an image is compressed, file meta is stored to the
      image using 'exiftool'. This helps us avoid compressing the same image twice.

      An API key is embedded in these Taskfiles but it is a free one and has usage limits. If you
      would like to use your own credits then you can [sign up for a developer account here]
      (https://tinypng.com/developers). After you sign up, save your key to a file at `~/.tinypng`
      and this task will use your API key instead.

      **Example of compressing all '**.*.(jpg|png)' files in a project:**
      `task image:compress`

      **Example of compressing single image:**
      `task image:compress -- ./path/image.png`
    cmds:
      - task: compress:{{if .CLI_ARGS}}cli{{else}}default{{end}}

  compress:cli:
    cmds:
      - |
        function compressImage() {
          if exiftool "$1" &> /dev/null; then
            if (exiftool "$1" | grep Comment | grep tinypng-compressed) > /dev/null; then
              .config/log info '`'"$1"'` has already been compressed by TinyPNG'
            else
              if [ -f ~/.tinypng ]; then
                tinypng "$1"
              else
                tinypng -k "{{.TINYPNG_API_KEY}}" "$1"
              fi
              .config/log "Adding 'tinypng-compressed' as a comment in the EXIF data"
              exiftool -overwrite_original -comment="tinypng-compressed" "$1"
              .config/log success "Successfully compressed $1"
            fi
          else
            .config/log error 'Failed to extract EXIF data from `$1` so the compression is being skipped'
          fi
        }
        compressImage '{{.CLI_ARGS}}'

  compress:default:
    cmds:
      - |
        function compressImage() {
          if exiftool "$1" &> /dev/null; then
            if (exiftool "$1" | grep Comment | grep tinypng-compressed) > /dev/null; then
              .config/log info '`'"$1"'` has already been compressed by TinyPNG'
            else
              if [ -f ~/.tinypng ]; then
                tinypng "$1"
              else
                tinypng -k "{{.TINYPNG_API_KEY}}" "$1"
              fi
              .config/log "Adding 'tinypng-compressed' as a comment in the EXIF data"
              exiftool -overwrite_original -comment="tinypng-compressed" "$1"
              .config/log success "Successfully compressed $1"
            fi
          else
            .config/log error 'Failed to extract EXIF data from `$1` so the compression is being skipped'
          fi
        }
        while read PATHH; do
          compressImage "$PATHH"
        done < <(find . -type d \( {{.IGNORE_FOLDERS}} \) -prune -o -type f \( -name '*.jpg' -o -name '*.png' \))
    sources:
      - '**/*.(jpg|png)'

  convert:logo:
    deps:
      - :install:npm:sharp
      - :install:npm:tinypng
    cmds:
      - sharp -i {{.CLI_ARGS}} -f png -o logo.png resize 200 200
      - tinypng -k "{{.TINYPNG_API_KEY}}" logo.png
      - .config/log info 'Generated `logo.png`'
      - rm -f {{.CLI_ARGS}}
      - .config/log info 'Ensured `{{.CLI_ARGS}}` is removed'

  favicons:
    deps:
      - :install:npm:real-favicon
    cmds:
      - task donothing

  resize:
    deps:
      - :install:npm:sharp
      - :install:software:exiftool
    desc: Resize an image
    summary: |
      # Resize images

      This task leverages the NPM package named `sharp` to resize images. To use this task,
      specify the width, followed by the height, and then the image path (or just the name
      if it is in the same directory). Alternatively, you can open an interactive dialog
      to walk you through the process.

      **Example opening an interactive dialog:**
      `task image:resize`

      **Example changing the width to 200px and height to 240px of an image named `image.png`:**
      `task image:resize -- 200 240 image.png`
    cmds:
      - task: resize:{{if .CLI_ARGS}}cli{{else}}default{{end}}

  resize:all:
    summary: |
      # Resize all images in a specific directory

      This task will scan a directory passed in via the CLI and resize the images it finds using arguments
      also passed in via the CLI. It will also scan subdirectories. To use this command, follow the following
      format:

      **Example for resizing to 250px width and 300px height:**
      `task image:resize:all -- path/to/dir ---- 250 300`
    cmds:
      - |
        RESIZE_ALL_ARRAY=({{index (splitList " ---- " .CLI_ARGS) 1}})
        while read IMAGE_PATH; do
          task image:resize:cli -- "$RESIZE_ALL_ARRAY[0]" "$RESIZE_ALL_ARRAY[1]" "$IMAGE_PATH"
        done < <(find "{{index (splitList " ---- " .CLI_ARGS) 0}}" -type f -name "*.jpg" -or -name "*.jpeg" -or -name "*.png" -or -name "*.bmp" -or -name "*.gif" -or -name "*.tif" -or -name "*.tiff" | sed 's/^.\///')

  resize:cli:
    cmds:
      - |
        ARGS_ARRAY=({{.CLI_ARGS}})
        if ! exiftool "${ARGS_ARRAY[2]}" | grep "Image Size" | grep "${ARGS_ARRAY[0]}x${ARGS_ARRAY[1]}"; then
          .config/log info "Resizing "'`'"${ARGS_ARRAY[2]}"'`'
          sharp -i "${ARGS_ARRAY[2]}" -o "${ARGS_ARRAY[2]}.resized" resize "${ARGS_ARRAY[0]}" "${ARGS_ARRAY[1]}"
          mv "${ARGS_ARRAY[2]}.resized" "${ARGS_ARRAY[2]}"
          .config/log success "Successfully resized "'`'"${ARGS_ARRAY[2]}"'`'
        else
          .config/log info '`'"${ARGS_ARRAY[2]}"'`'" appears to already be the appropriate size"
        fi
    status:
      - 'exiftool "${ARGS_ARRAY[2]}" | grep "Image Size" | grep "${ARGS_ARRAY[0]}x${ARGS_ARRAY[1]}"'

  resize:default:
    cmds:
      - |
        DIRS_TMP="$(mktemp)"
        find . -type d -not -path "*/.*" > "$DIRS_TMP"
        .config/log prompt 'Select the directory of the image(s) you would like to resize (hidden directories are omitted)'
        CHOSEN_DIR="$(.config/log filter "$DIRS_TMP")"
        FILES_TMP="$(mktemp)"
        find "$CHOSEN_DIR" -type f -name "*.jpg" -or -name "*.jpeg" -or -name "*.png" -or -name "*.bmp" -or -name "*.gif" -or -name "*.tif" -or -name "*.tiff" | sed 's/^.\///' > "$FILES_TMP"
        .config/log prompt 'Select the image that you would like to resize'
        CHOSEN_IMAGE="$(.config/log filter "$FILES_TMP")"
        .config/log prompt 'Enter the desired width'
        CHOSEN_WIDTH="$(.config/log input "Enter width..")"
        .config/log prompt 'Enter the desired height'
        CHOSEN_HEIGHT="$(.config/log input "Enter height..")"
        task image:resize:cli -- "$CHOSEN_WIDTH" "$CHOSEN_HEIGHT" "$CHOSEN_IMAGE"
