#! /bin/sh
#
# go.sh: the master SHADOW driver.
#
# Author: Mumit khan <khan@xraylith.wisc.edu>
# Copyright (c) 1999 Mumit Khan
#
# Source: src/drivers/go.sh
#
# ----------------------------------------------
#               SHADOW
#    Center for X-ray Lithography
#  University of Wisconsin-Madison
#  3731 Schneider Dr., Stoughton, WI, 53589
# ------------------------------------------------
# 
#

#
# external programs used:
#
#   cat
#   clear
#   rm
#   tr
#
clear_screen=clear

#
# local variables for communication among modules.
#
debug=0				;# used wherever there is a reason ;-)
toplevel=0			;# for interrupt handling
progname=$0			;# used only in setup_env
menu_error=0			;# used only in source_command
source_fname=start.00		;# used only in source_command
skip_menu=0			;# used only in trace_command

#
# Make sure the environment is correctly set up.
#
setup_env () 
{
  # what platform? We only care about Unix vs Windows32.
  if [ -n "$SystemRoot" -o -n "$SYSTEMROOT" -o -n "$COMSPEC" ]; then
    os=win32
    shell=sh
    # canonicalize the argv0.
    progname=`cygpath -u $progname 2>/dev/null || echo $progname`
    tmpdir=${TMPDIR-.}
  else
    os=unix
    shell=/bin/sh
    tmpdir=${TMPDIR-/tmp}
  fi

  # Deduce SHADOW_ROOT from argv0, but only if SHADOW_ROOT is not
  # defined by the user.
  if [ -z "$SHADOW_ROOT" ]; then
    case $progname in 
    \./* | /*)
      ;;
    *)
      IFS_SAVE="$IFS"
      IFS=:
      for d in $PATH; do
        if [ -f $d/$progname ]; then
	  progname=$d/$progname
	  break
	fi
      done
      IFS="$IFS_SAVE"
      ;;
    esac
    progdir=`dirname $progname`
    rootdir=`dirname $progname`
    shadow_root=`(cd $rootdir; pwd)`
    # echo "progdir = $progdir" >&2
    # echo "SHADOW_ROOT NOW set to $shadow_root" >&2
  else
    # echo "SHADOW_ROOT preset to $SHADOW_ROOT" >&2
    shadow_root=$SHADOW_ROOT
  fi

  LOGNAME=${LOGNAME-"User"}
  USER=${USER-$LOGNAME}

  SHADOW_ROOT=$shadow_root
  SHADOW_BIN_DIR=${SHADOW_BIN_DIR-$SHADOW_ROOT/bin}
  SHADOW_DATA_DIR=${SHADOW_DATA_DIR-$SHADOW_ROOT/data}
  SHADOW_MENU_ENV=${SHADOW_MENU_ENV-$tmpdir/shmenu.$$}

  export USER LOGNAME 
  export SHADOW_ROOT SHADOW_BIN_DIR SHADOW_MENU_ENV

  echo os="$os" shell="$shell" progname="$progname" >&1
}

cleanup_and_exit ()
{
  rm -f $SHADOW_MENU_ENV
  if [ $# -eq 1 ]; then
    status=$1
  else
    status=0
  fi
  exit $status
}

handle_interrupt () 
{
  echo ""
  #[ $toplevel -eq 0 ] && {
  #  toplevel=1
  #  return
  #}
  echo "Exiting SHADOW due to interrupt ..."
  cleanup_and_exit 1
}

handle_interrupt_old () 
{
  echo ""
  echo "Abort? (y/n) [y]: \\c"
  read ans
  case "$ans" in
  n* | N*)
    # not aborting. Onwards. 
    ;;
  *)
    cleanup_and_exit 1
    ;;
  esac
}

help_command () 
{
  cat $GO
}

unknown_command ()
{
  cat << EOB
? Command "$1" not recognized ?
  
 Legal commands are: 
EXIT     MENU	 TRACE      SOURCE     HELP    CD   PWD

EOB
}

menu_command () 
{
  echo ""
  echo "Prepare MENU ..."
  echo ""
  $MENU
}

source_command ()
{

  echo ""
  echo "SOURCE selected. Begin procedure."
  echo ""

  mode_selected=0
  while true; do
    echo "This procedure generates a SOURCE for SHADOW."
    echo "Mode selected [ ? <ret> for HELP ] ? \\c"; read mode
    [ -z "$mode" ] && continue
    case `echo $mode | tr '[A-Z]' '[a-z]'` in
    \? | help)
      echo "Enter:"
      echo "MENU:		for screen-driven menus"
      echo "PROMPT:		prompted session"
      echo "BATCH:		file-oriented session"
      echo ""
      ;;
    prompt | batch | menu)
      break;
      ;;
    *)
      echo "Allowed modes are: MENU PROMPT BATCH"
      ;;
    esac
  done

  case $mode in
  prompt)
    source_fname=start.00
    $INPUT_SOURCE
    ;;
  batch)
    while true; do
      echo "File containing source description [ start.00 ] ? \\c"
      read source_fname
      [ -z "$source_fname" ] && continue
      if [ ! -f $source_fname ]; then
	echo "Source file $source_fname does not exist. Try again."
      else 
	break
      fi
    done
    ;;
  menu)
    menu_error=0
    rm -f ${SHADOW_MENU_ENV}
    if [ -f $SHADOW_MENU_ENV -a ! -w $SHADOW_MENU_ENV ]; then
      echo ""
      echo "Error: cannot delete temporary file ${SHADOW_MENU_ENV}"
      echo "    Please have your sysadmin delete it, or"
      echo "    change SHADOW_MENU_ENV environment variable to point"
      echo "    to another file name, eg., ./shadow_menu_env"
      echo "    Exiting MENU ..."
      echo ""
      cleanup_and_exit 1
    fi
    $MENU
    if [ ! -f $SHADOW_MENU_ENV ]; then
      echo ""
      echo "	Hmmm! Did you forget to SAVE SOURCE in MENU?"
      menu_error=1
    else
      source_fname=`cat $SHADOW_MENU_ENV 2>/dev/null`
      if [ ! -f $source_fname ]; then
	echo ""
	echo "	Hmmm! MENU didn't create source namelist file"
	menu_error=1
      fi
    fi
    ;;
  esac

  if [ $menu_error -eq 1 ]; then
    echo "	Warning! SOURCE not created"
    echo ""
    echo "Hit <ret> to continue: \\c" ; read dummy
    $clear_screen 2>/dev/null
    cat $SHADOW_DATA_DIR/go.txt
    echo ""
    return
  fi
  echo "Calling gen_source with $GEN_SOURCE $source_fname"
  $GEN_SOURCE $source_fname
  rm -f $SHADOW_MENU_ENV
  echo ""
  echo "SOURCE procedure completed."
  echo ""
}

trace_command ()
{
  echo ""
  echo "Ray Tracing Selected. Begin procedure."
  echo ""

  mode_selected=0
  while true; do
    echo "Mode selected [ ? <ret> for HELP ] ? \\c"; read mode
    [ -z "$mode" ] && continue
    case `echo $mode | tr '[A-Z]' '[a-z]'` in
    \? | help)
      echo "Enter:"
      echo "MENU:		for screen-driven menus"
      echo "PROMPT:		prompted session"
      echo "BATCH:		file-oriented session"
      echo ""
      ;;
    prompt | batch | menu)
      break;
      ;;
    *)
      echo "Allowed modes are: MENU PROMPT BATCH"
      ;;
    esac
  done

  case $mode in
  prompt | batch)
    ;;
  menu)
    skip_menu=0
    echo "MENU selected."
    if [ -f systemfile.dat ]; then
      echo "Execute existing SYSTEMFILE ? (y/n) : \\c"; read ans
      case "$ans" in
      y* | Y*)
        skip_menu=1
	;;
      *)
        skip_menu=0
        ;;
      esac
    fi
    [ $skip_menu -eq 0 ] && $MENU
    ;;
  esac

  $TRACE -m $mode
  echo ""
  echo "Procedure completed."
  echo ""
}
  
handle_command () 
{
  toplevel=0
  cmd=$1
  case `echo $1 | tr '[A-Z]' '[a-z]'` in
  menu)
    menu_command
    ;;
  source)
    source_command
    ;;
  trace)
    trace_command
    ;;
  cd | setdir)
    shift
    newdir="$@"
    [ -z "$newdir" ] && {
      echo "  Enter new working directory: \\c"
      read newdir
    }
    if [ -n "$newdir" ]; then
      cd "$newdir" && handle_command pwd
    else 
      echo "  Syntax: $cmd newdir"
    fi
    ;;
  pwd)
    echo "Current working directory: `pwd`"
    ;;
  \? | help)
    help_command
    ;;
  exit)
    echo "Exiting"
    return 1
    ;;
  *)
    unknown_command $cmd
    ;;
  esac
  return 0
}

# Catch signals. ($xs kludge needed by Sun /bin/sh).
xs=0
trap 'cleanup_and_exit $xs' 0
trap 'handle_interrupt' 2 15
trap 'echo "Aborting."; xs=1; cleanup_and_exit' 1 3 13

eval setup_env >/dev/null

[ "$debug" -eq 1 ] && cat << EOB
------------------------------------------------------------------
OS              : $os
SHELL           : $shell
USER            : $USER
LOGNAME         : $LOGNAME
SHADOW_ROOT     : $SHADOW_ROOT
SHADOW_BIN_DIR  : $SHADOW_BIN_DIR
SHADOW_MENU_ENV : $SHADOW_MENU_ENV
------------------------------- x --------------------------------
EOB

#
# define the programs to run.
#
MENU=$SHADOW_ROOT/bin/menu
TRACE=$SHADOW_ROOT/bin/trace
SOURCE=$SHADOW_ROOT/bin/source
GEN_SOURCE=$SHADOW_ROOT/bin/gen_source
INPUT_SOURCE=$SHADOW_ROOT/bin/input_source

# define utility files that are printed to the screen.
BANNER=$SHADOW_DATA_DIR/banner.txt
GO=$SHADOW_DATA_DIR/go.txt

# 
# The main part begins here.
#

#
# Check for a startup program on the command line. If exists, bypass
# printing the initial screen and go for the guts directly.
#

$clear_screen 2>/dev/null

if [ $# -eq 0 ]; then
  cat $BANNER
  echo "Hit <ret> when ready: \\c"; read dummy
  $clear_screen 2>/dev/null
  help_command
else
  handle_command "$@" || cleanup_and_exit
fi

echo "Shadow:: \\c" 
while read input; do
  toplevel=1
  [ -n "$input" ] && {
    handle_command $input || break
  }
  echo "Shadow:: \\c" 
done
echo

cleanup_and_exit $status

