#! /bin/sh
#
# UNDUL: The driver script for the undulator modeling code of SHADOW.
#
# Author: Mumit Khan <khan@xraylith.wisc.edu>
# Copyright (c) 1990-1999 Mumit Khan
#
# Source: src/source/id/undul
#
# ----------------------------------------------
#               SHADOW
#    Center for X-ray Lithography
#  University of Wisconsin-Madison
#  3731 Schneider Dr., Stoughton, WI, 53589
# ------------------------------------------------
#
#

#
# external programs used:
#
#   cat
#   rm
#

#
# local variables for communication among modules.
#
debug=0				;# used wherever there is a reason ;-)

#
# This is the undulator driver script. It's called by MAKE_ID.
#

# First of all, Where are all the programs? Set it to nothing if all the
# programs are in the PATH variable of the SHELL.

#
# 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_ENV_FILE=${SHADOW_ENV_FILE-$tmpdir/shenv.$$}

  export USER LOGNAME 
  export SHADOW_ROOT SHADOW_BIN_DIR SHADOW_ENV_FILE

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

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

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

# 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_ENV_FILE : $SHADOW_ENV_FILE
------------------------------- x --------------------------------
EOB

# The VMS version of UNDUL runs a set of 3 programs, and these programs
# communicate with this shell script via LOGICALS. Since Unix processes 
# can't set the environment of parent processes, we have to kludge it 
# (sort of like tset does) by writing the environment strings to a file 
# and source'ing the file. So define the SHADOW_ENV_FILE to pick a file. 

# Now set up the undulator parameters by running undul_set. UNDUL_SET 
# sets a environment variable F_EXTERNAL to either 'INTERNAL' or
# 'EXTERNAL' depending on whether we should use the supplied UNDULATOR
# program (UNDUL_PHOT), or run a user specified one.

$SHADOW_BIN_DIR/undul_set

prog_type=`cat $SHADOW_ENV_FILE`
rm -f $SHADOW_ENV_FILE

#
# Loop until we are signalled to be done by UNDUL_CDF.
#

while true; do
  case "$prog_type" in
  *INTERNAL)
    $SHADOW_BIN_DIR/undul_phot
    ;;

  *EXTERNAL)
    echo -n "Name of External Program ? "; read prog
    $prog
    ;;
  
  *)
    echo "Bad environment return from UNDUL_SET: $prog_type"
    cleanup_and_exit 1
    ;;
  esac

  #
  # Compute the CDF and also do the output. This program sets the
  # environment variable FINISH to 'YES' if the optimization is done. If
  # not, we simply loop back.
  #

  $SHADOW_BIN_DIR/undul_cdf

  finish=''
  [ -f $SHADOW_ENV_FILE ] && {
    finish=`cat $SHADOW_ENV_FILE`
    rm -f $SHADOW_ENV_FILE
  }

  #
  # Loop back unless ALL the optimizations are done. The 'done' flag is
  # set by UNDUL_CDF. It sets the environment string FINISH to 'YES'. In
  # effect, we loop as long as FINISH in NOT defined, since it can take
  # only one value.
  #
  case "$finish" in
  *FINISH*)
    break;
    ;;
  *)
    ;;
  esac

done

cleanup_and_exit 0

