#!/bin/bash
# int-fiction.sh 1.0
# (c)2004 Lee Bigelow <ligelowbee@yahoo.com>
# 
# A bash script to display a menu of available int-fiction games
# from a directory and pick the right interpreter to play them. Or
# just play play a game passed on the command line with the right interpreter.
# It uses whiptail or dialog to make the menu.
#
# This program 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 2
# of the License, or (at your option) any later version.
# 
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
# or view it online at: http://www.gnu.org/copyleft/gpl.html

IFIC_DIR="$HOME/int-fiction/"  
IFSAVE_DIR="$IFIC_DIR/ifsaved/"

#####################
# This is where the graphic players would go
if [ $DISPLAY ]; then
    PLAYERS="
            zoom:[Zz][1-9]
            xnitfol:[Zz][1-9]
            glulxex:[Uu][Ll][Xx],[Bb][Ll][Bb]
            xtads:[Gg][Aa][Mm]
            hewx:[Hh][Ee][Xx]
            gtkscare:[Tt][Aa][Ff]
            "
fi

#####################
# This is where the console players go
PLAYERS=$PLAYERS"
         frotz:[Zz][0-9]
         nitfol:[Zz][1-9]
         t3run:[Tt]3
         t23run:[Tt]3,[Gg][Aa][Mm]
         glulxeterm:[Uu][Ll][Xx],[Bb][Ll][Bb]
         he:[hH][eE][xX]
         glkarun:[Aa][Cc][Dd]
         "

##################
#Check for passed gamefile or help
if [ "$#" -gt "1" ] || [ x"$@" = x"-h" ]; then
    echo "usage: $0 [gamefile]"
    echo
    echo "If passed a gamefile, it will play it with the apropriate player."
    echo "If nothing is passed it will attempt to make a menu of games"
    echo "available using whiptail."
    exit
fi
##################
# set game var to first argument passed, if relative make absolute path
if [ -f "$PWD/$1" ]; then
    game="$PWD/$1"
else 
    game="$1"
fi

#####################
# check the directory where game files are located, if no gamefile passed.
if [ ! "$game" ] && [ ! -d "$IFIC_DIR" ]; then
    echo Could not find directory: 
    echo $IFIC_DIR 
    echo
    echo Please set up such a directory for your int-fiction story files, or
    echo edit and change the default directory this script: 
    echo "$0".
    echo
    read -p "Press Enter to Exit..."
    exit
fi

#####################
# Set up and change into a save directory
[ ! -d "$IFSAVE_DIR" ] && mkdir "$IFSAVE_DIR"
if [ -d "$IFSAVE_DIR" ]; then
    cd $IFSAVE_DIR
else
    echo Error could not create IF save directory:
    echo $IFSAVE_DIR
    echo
    echo Please edit this file: $0 
    echo to change the defaults
    echo
    read -p "Press Enter to Exit..."
    exit
fi

####################
# function to playgame with appropriate interp
playgame ()
{
    game="$1"
    echo game $game
    gameext="${game##*.}"
    interp=""
    for player in $PLAYERS 
    do
        exts="${player##*:}"
        exts="${exts//,/ }"
        for ext in $exts 
        do
            if [[ "$gameext" == $ext ]]; then
                interp="$(which ${player%%:*})"
                possible=$possible"${player%%:*} "
            fi
        done
        [ "$interp" ] && break
    done
    if [ "$interp" ]; then
        $interp "$game" 
    else
        whiptail --clear --title "Error" --msgbox \
"Player for file $game not found....
===================================

For the game type \"$gameext\"
Install one of the following players:

$possible

Or edit this file \"$0\" 
to include a player not listed" 0 0
    fi 
}


##################
# if game passed to script play it
if [ "$game" ]; then
    playgame $game
    exit
fi

#####################
# make a list files based on interpreters.
EXTS="" # regex container for all file extensions
for player in $PLAYERS; do
    exts="${player##*:}" 
    exts="${exts//,/\|}" 
    EXTS=$EXTS"\|"$exts
done

files=$(find $IFIC_DIR -regex ".*\.\($EXTS\)")
if [ -z "$files" ]; then
    echo Could not find any int-fiction files in $IFIC_DIR
    read -p "Press Enter to Exit..."
    exit
fi

#####################################
#make file name list for whiptail menu and full path lookup
tag=$(echo $'\b') #needed for empty whiptail tag entry
for file in $files;
do
    gpaths=$gpaths"$file:$(basename $file) "
    gmenu=$gmenu"$(basename $file) $tag\n"
done
gmenu=$(echo -e $gmenu|sort -f)

#######################
# and now the menu loop
if which whiptail; then
    MENUPRG="whiptail"
elif which dialog; then
    MENUPRG="dialog"
else
    echo Error no menuing program found.
    echo I require the program whiptail or dialog
    echo in order to make the menu.
    echo
    echo Press Enter to exit...
    read x
    exit
fi

tempfile=$(tempfile 2>/dev/null) || tempfile=/tmp/ific$$

while true  
do
    
    $MENUPRG --clear \
             --title "Interactive Fiction Game Selector" \
             --menu "For more games and reviews see
Baf's Guide to Interactive Fiction:
http://www.wurb.com/if/index

Select a Game to Play:" 0 0 0\
             $gmenu 2> $tempfile
    
    game=$(cat $tempfile)
    rm -f $tempfile

    for gpath in $gpaths; do
        if [ "${gpath##*:}" = "$game" ]; then
            game="${gpath%%:*}"
            break
        fi 
    done
    if [ "$game" ]; then 
        playgame "$game"
    else exit 
    fi
done