#!/bin/bash
##!/bin/bash               # For linux/unix
##!/usr/local/bin/bash     # For MacOS Homebrew (coreutils).
##!/opt/local/bin/bash     # For MacOS MacPorts (coreutils).

# Cowsay - get your cow talking!
# Author: Robert Sauve    2024/05/24
# To get this bash script up and running, install cowsay, fortunes or fortune-mod and perl.
# If you want to use the cowsay perl script and extra cow files in cowsay.zip, do this:
#    Extract cowsay.zip:
#       unzip ./cowsay.zip                                    (you may need to install unzip first)
#       cd cowsay
#    Copy the 'bin/cowsay' perl script to /usr/bin/:
#       sudo cp bin/cowsay /usr/bin                           (or to some other open path)
#    Make cowsay executable:
#       sudo chmod +x /usr/bin/cowsay                         (or where ever cowsay lives)
#    Create a cowthink symbolic link from cowsay:
#       sudo ln -s /usr/bin/cowsay /usr/bin/cowthink          (or where ever cowsay lives)
#    Copy cows library directory to:
#       sudo cp cows/*.* /usr/share/cowsay/cows/.
#    or wherever cowsay expects to find the cows directory:
#       cowsay -l
# Copy cowsay bash script file to the user directory of your choice.
# Make this file executable:
#   sudo chmod +x ~/<path>/cowsay
# Create an alias in .bashrc:
#   alias cowsay='~/<path>/cowsay'
# Save and exit out of .bashrc:
#   clear && source ~/.bashrc
# That's it!
#
# 2024/05/20: Straightened out some bugs and cleaned up old commented-out code.
# 2024/05/24: Solved the double cow name issue (see line 111).
# 2024/05/26: Sorted out function "check_exclusion".
# 2024/10/11: Some Terminals start with a window row value of less then 0. Updated line 59.

# These cows are either too big or too silly to display.
delete="beavis.zen blowfish calvin cheese daemon dragon dragon-and-cow eyes ghostbusters gnu head-in kiss mech-and-cow milk pony stegosaurus turkey turtle unipony sodomized sodomized-sheep telebears turkey turtle"

# Cow say or cow think.
arr[0]="say"     #cowsay
arr[1]="think"   #cowthink

# Your cow's state of mind.
state[0]="b"	 #Borg mode
state[1]="d"	 #Dead
state[2]="g"	 #Greedy mode
state[3]="p"	 #Paranoia
state[4]="s"	 #Stoned
state[5]="t"	 #Tired
state[6]="w"	 #Wired
state[7]="y"	 #Youthful

# Function: Get terminal column size and row size.
get_terminalSize () {
   min_terminalSize_col=8
   terminalSize_col=$(stty size | cut -d " " -f2)
   terminalSize_row=$(stty size | cut -d " " -f1)
   terminalSize_row=$(($terminalSize_row-2))
   if [ $terminalSize_row -le $min_terminalSize_col ] && [ $terminalSize_row -ge 0 ];
      then
         echo "Your terminal window row size is too small"
         exit 0
   fi      
}

# Function: Get a cow!
get_cow () {
   
   # Check terminal size.
   get_terminalSize
   
   # Grab a random cow.
   rand2=$[ $RANDOM % "${#cowName_list[@]}" ]
   cowName="${cowName_list[$rand2]}"
}   

# Function: Check exclusion list (delete). 
check_exclusion () {
   # Check for excluded cows from 'delete' list.
   while [[ $(echo $delete | grep -o $cowName) != "" ]]
   do
      get_cow
   done
}

# Function: Get the cow talking and get the row size of the caption.
get_talking () {
   # Put together a cow and a fortune.
   #<fortune> <cowsay/cowthink> <cow file> <cow state of mind> <caption column size> <arbitrary message>
   cowspeak=$(fortune | cow${arr[$rand1]} -f $cowName.cow -${state[$rand3]} -W$terminalSize_col -n)
   # Get the number of rows used to display the cow and fortune caption.
   rowCount=$(echo "$cowspeak" | wc -l)
}

# Main program starts here.

# Check terminal window size.
get_terminalSize

# Random cow type and random state of mind.
rand1=$[ $RANDOM % 2 ]		#Cow say or cow think.
rand3=$[ $RANDOM % 8 ]		#Pick a random 'state of mind'.

# Grab cowsay's cow list. 
cowName_list=$(cowsay -l | tail -n +2)


# Change end of line carriage return characters to space characters, place cow names into an array.
cowName_list=(${cowName_list//$/ })

# Grab a random cow.
get_cow

# Check to see if the cow is in the exclusion list (delete).
check_exclusion

# Put together a talking cow.
get_talking

# Keep the cow and fortune within the terminal window boundary.
while [ $rowCount -gt $terminalSize_row ]
do
   # Get another cow!
   get_cow
   
   # Check to see if it is in the exclusion list (delete).
   check_exclusion
   get_talking
done

# A fortune telling cow.
echo "$cowspeak"

# Use the line below for troubleshooting.
#echo -e "\e[0;31mSay\e[0m"/"\e[0;32mThink\e[0m": ${arr[$rand1]} - "\e[0;31mCow\e[0m": $cowName - "\e[0;31mMind\e[0m": ${state[$rand3]} - "\e[0;31mTerminal size\e[0m": C=$terminalSize_col R=$terminalSize_row - "\e[0;31mRow count\e[0m": $(echo "$cowspeak" | wc -l)

