#!/usr/bin/env bash

version=0.10
SYSTEMPONIES="/usr/share/ponysay/ponies"
HOMEPONIES="${HOME}/.ponysay/ponies"
pony="*"
wrap=""

if [ "$TERM" = "linux" ]; then
    SYSTEMPONIES="/usr/share/ponysay/ttyponies"
    HOMEPONIES="${HOME}/.ponysay/ttyponies"
fi

cmd=cowsay
[[ ${0} == *ponythink ]] && cmd=cowthink

version() {
    echo "ponysay v$version"
}

list() {
    echo "ponyfiles located in $SYSTEMPONIES:"
    ls -1 $SYSTEMPONIES | sed "s/.pony//"
    if [[ -d $HOMEPONIES ]]; then
	echo "ponyfiles located in $HOMEPONIES:"
	ls -1 $HOMEPONIES | sed "s/.pony//"
    fi
}

usage() {
    version
    cat <<EOF

Usage:
${0##*/} [options] [message]

If [message] is not provided, reads the message from STDIN.

Options:
  -v          Show version and exit.
  -h          Show this help and exit.
  -l          List pony files.
  -f[name]    Select a pony (either a file name or a pony name.)
  -W[column]  The screen column where the message should be wrapped.

See man ponysay(1) for more information.
EOF
}

# if no stdin and no arguments then print usage and exit
if [[ -t 0 && $# == 0 ]]; then
  usage
  exit
fi

say() {
    # Ponies use UTF-8 drawing characters. Prevent a Perl warning.
    export PERL_UNICODE=S
    
    if [ "$TERM" = "linux" ]; then
    	echo -ne '\ec'
    fi
    
    function wtrunc
    {
	if [ "$PONYSAY_FULL_WIDTH" = 'no' ] || [ "$PONYSAY_FULL_WIDTH" = 'n' ] || [ "$PONYSAY_FULL_WIDTH" = '0' ]; then
	    cat
	else
	    WIDTH=`(stty size <&2 || echo 0 0) | cut -d ' ' -f 2`
	    ponysaytruncater $WIDTH 2>/dev/null                    ||
	    ${HOME}/.local/bin/ponysaytruncater $WIDTH 2>/dev/null ||
	    ./ponysaytruncater $WIDTH 2>/dev/null                  ||
	    cat
	fi
    }
    
    function htrunc
    {
	if [ "$PONYSAY_SHELL_LINES" = "" ]; then
	    PONYSAY_SHELL_LINES=2
	fi
	head --lines=$(( `stty size <&2 | cut -d ' ' -f 1` - $PONYSAY_SHELL_LINES ))
    }
    
    if [ "$TERM" = "linux" ] || [ "$PONYSAY_TRUNCATE_HEIGHT" = 'yes' ] || [ "$PONYSAY_TRUNCATE_HEIGHT" = 'y' ] || [ "$PONYSAY_TRUNCATE_HEIGHT" = '1' ]; then
	if [ "$PONYSAY_BOTTOM" = 'yes' ] || [ "$PONYSAY_BOTTOM" = 'y' ] || [ "$PONYSAY_BOTTOM" = '1' ]; then
	    exec "$cmd" -f "$pony" "${wrap:+-W$wrap}" | wtrunc | tac | htrunc | tac
	else
	    exec "$cmd" -f "$pony" "${wrap:+-W$wrap}" | wtrunc | htrunc
	fi
    else
	exec "$cmd" -f "$pony" "${wrap:+-W$wrap}" | wtrunc
    fi
}

while getopts f:W:lhv OPT
do
    case ${OPT} in
        v)  version; exit ;;
        h)  usage; exit ;;
        f)  pony="$OPTARG" ;;
	l)  list; exit ;;
        W)  wrap="$OPTARG" ;;
        \?) usage >&2; exit 1 ;;
    esac
done
shift $((OPTIND - 1))

hash $cmd &>/dev/null; if [ $? -ne 0 ]; then
    cat >&2 <<EOF
You don't seem to have the $cmd program.
Please install it in order to use this wrapper.

Alternatively, symlink it to '$cmd' in anywhere in \$PATH
if it actually exists under a different filename.
EOF
    exit 1
fi

if [[ ! -f $pony ]]; then
    # Pony not a file? Search for it

    ponies=()
    [[ -d $SYSTEMPONIES ]] && ponies+=( "$SYSTEMPONIES"/$pony.pony )
    [[ -d $HOMEPONIES ]] && ponies+=( "$HOMEPONIES"/$pony.pony )

    if (( ${#ponies} < 1 )); then
        echo >&2 "All the ponies are missing! Call the Princess!"
        exit 1
    fi

    # Choose a random pony
    pony="${ponies[$RANDOM%${#ponies[@]}]}"
fi

if [[ -n "$*" ]]; then
  # Handle a message given via arguments
  say <<<"$*"
else
  say
fi