#!/usr/bin/env bash

show_help() {
    printf """
vifm-thumbnailer

Easily show images/thumbnails from the vifm file manager.

Usage:  vifm-thumbnailer <current file>

Point it to a file whose directory you want thumbnailed.
If you point it to a directory itself, it will list its contents.

Options:

    -h      Display this help.

    -r      Show images recursively from current folder.

    -t      Open viewer in thumbnail mode.

    -m      Show thumbnails for video files in addition to image files.
            Will take longer to load up and requires ffmpeg utilities.

Vifm:

    If the file is on your path (e.g. in ~/.vifm/scripts) from within
    vifm you can run the script by invoking it with:
    \`:!vifm-thumbnailer \%%c\`
    which will show all directory thumbnails with the current file
    initially shown.

    If you want to have vifm show a filtered view for selected files
    afterwards add a \%%u to the command.

"""
}

TMPDIR="$(mktemp -d)"
valid_files_tmp="$TMPDIR/nsxiv_rifle_$$"

# get all files in directory
list_img_files() {
    if exist fd; then
        fd --max-depth="$maxdepth" -tf . "${1%/*}" | is_img_extension | sort | tee -a "$valid_files_tmp"
    else
        find -L "${1%/*}" -maxdepth "$maxdepth" -type f -print | is_img_extension | sort | tee -a "$valid_files_tmp"
    fi
}

list_vid_files() {
    # shellcheck disable=2016
    find "${1%/*}" -mindepth 1 -maxdepth "$maxdepth" \( -type f -o -type l \) -printf "%P\0" |
        xargs -r0 -n 20 -P 64 file -00 -L --mime-type -- |
        xargs -r0 -n 2 sh -c '
            case "$2" in
                video/*) printf "%s\0" "$1";;
            esac
        ' -- |
        sort -z |
        xargs -r0 -I FILE ffmpegthumbnailer -i FILE -o "$TMPDIR/FILE.jpg" -m -s 384
    find -L "$TMPDIR/" -maxdepth "$maxdepth" -type f -print | sort | tee -a "$valid_files_tmp"
}

img_ext="jpe?g|png|gif|svg|webp|tiff|heif|avif|ico|bmp"
is_img_extension() {
    grep -iE "\.($img_ext)$"
}

# TODO if marking video thumbnail - will use wrong temporary path on output, makes e.g. vifm %u not work
open() {
    trap 'rm -rf -- $TMPDIR' TERM INT EXIT
    current="$(list_img_files "$1" | grep -nF "$1")"
    if [ "$videos" = true ]; then
        list_vid_files "$1"
    fi
    [ "$thumbnails" = true ] && nsxiv_args="-t"
    if [ -n "$current" ]; then
        nsxiv "$nsxiv_args" -i -n "${current%%:*}" -o -- <"$valid_files_tmp"
    else
        # fallback incase file didn't have a valid extension, or we couldn't
        # find it inside the list
        nsxiv -o -i -- <"$valid_files_tmp"
    fi
}

maxdepth=1
while getopts "mrt?h" opt; do
    case "$opt" in
    r)
        maxdepth=100
        ;;
    m)
        videos=true
        ;;
    t)
        thumbnails=true
        ;;
    h | \? | *)
        show_help
        exit 0
        ;;
    esac
done
shift $((OPTIND - 1))
[ "$1" = '--' ] && shift
case "$1" in
"")
    echo "Usage: ${0##*/} PICTURES" >&2
    exit 1
    ;;
/*) open "$1" ;;
"~"/*) open "$HOME/${1#"~"/}" ;;
*) open "$PWD/$1" ;;
esac