#! /bin/sh
#
# setc2run
#
# Author: Michael Peeler
#
# Purpose:
# This script creates a directory with all necessary files to run Cerius2
# in a customized environment
#
# Copyright (c) 1995 - 1997, Molecular Simulations Inc.
#
###########################################################################


Usage() {
cat <<EOF >&2

Usage: `basename $0` <directory> [...] [-target <target-directory>]

Each <directory> may contain *.pal, *.gdf and/or auto/*.hlp files.
All of these files will be processed.

If the '-target' option is used, the run-time environment is to be set up in
the <target-directory>.
Otherwise, the run-time environment is to be set up in the current directory.

Example:
	`basename $0` /u/sdk/dev/proc1 /u/sdk/dev/proc2

EOF
# Development Options:
#	<process>:<executable>		# add <executable> for <process> to applcomm.db
#	-c2 <Cerius2-executable>	# use special Cerius2 executable
#	-rmc2				# don't use special Cerius2 executable
#	-b				# backup existing files before modification
#	-v				# verbose mode
exit 1
}

ErrorMsg() {
echo  >&2
echo "************ ERROR ************"  >&2
echo $1  >&2
echo "*******************************"  >&2
}

CreateApplReg() {
# Creating appl.reg
cat << END_OF_APPLREG > appl.reg
+ \$C2DIR/libraries/appl.reg
#
#----------------------------------------
# C2 FILE WRITTEN BY setc2run:   appl.reg
#----------------------------------------
#
# This file automatically includes all programs defined in the local Cerius2
# installation; see first line of the file. (\$C2DIR is defined by the Cerius2
# runscript to reference the Cerius2 installation directory.)
#
# For each external Cerius2 program, add a section to this file to
# define the process name and its constituent applications. Begin in
# column 1, using the following format.
#
#    process <processname>
#    <application_identifier> <application_name>  <Comments>
#    ... repeat line for each application ...
#
# Example
#
#process myproc
#apa  APPLICATION_A    Application A
#apb  APPLICATION_B    Application B
#
# Add non-installation process sections below:
#
END_OF_APPLREG
}

CreateApplComm() {
# Creating applcomm.db
if [ -n "$APPLCOMM_DB" ]
then OldApplCommDB=$APPLCOMM_DB
else OldApplCommDB='$C2DIR/libraries/applcomm.db'
fi

cat << END_OF_APPLCOMM > applcomm.db

+ $OldApplCommDB

#
#-------------------------------------------
# C2 FILE WRITTEN BY setc2run:   applcomm.db
#-------------------------------------------
#
# For each external Cerius2 program add a line to the top of this file,
# beginning in column 1, using the format:
#
#        "A <platform> <processname> <filepath>"
#
# Unless the installed Cerius2 applcomm.db file (referenced above via
# the \$C2DIR variable defined in the Cerius2 run script) has been
# amended since installation, the <platform> name should be "unix",
# which will at least include the localhost machine.
#
# For setting up remote running programs or versions on multiple platforms,
# see separate documentation on the syntax of the applcomm.db file.
#
# The <processname> should correspond to a named process in the appl.reg file.
#
# The <filepath> should reference a valid binary file that will run as the
# named process on the chosen platform.
#
# Examples:
#
# A unix myproc /u/work/myproc/obj/irix5/myproc.exe
# A unix myproc /u/work/myproc/obj/irix/myproc.exe
# A unix myproc /u/work/myproc/obj/aix/myproc.exe
#
# Add your external process lines at top of file (begin in column 1):
END_OF_APPLCOMM
}

CreateSetEnv() {
# Creating setcerius2.dev
cat << END_OF_SETENV > setcerius2.dev
#
#----------------------------------------------
# C2 FILE WRITTEN BY setc2run:   setcerius2.dev
#----------------------------------------------
#
# This file is invoked at Cerius2 run time to define eny environment
# variables which may be employed by Cerius2. In particular, it may
# include settings for variables which define access to external programs
# and data which are not in the standard Cerius2 installation.
#
# Variables of this type which may be defined in this file are:
#
# UI_RESOURCES : a directory search path for GUI definition files and other GUI
#                resource files, such as pixmaps and cursors.
# HELP         : a directory search path for files containing application
#                command HELP text.
# APP_RESOURCES: a directory search path for sub-directories containing
#                application data files.
# C2_APPLREG   : a directory search path for the appl.reg file, which holds the
#                list of external programs and applications which Cerius2 knows
#                about at run time.
# APPLCOMM_DB  : a file search path for the applcomm.db file which maps a
#                program name in appl.reg onto a binary executable files on a
#                specified machine.
#
# Add any Cerius2 run time variable settings below.
#

END_OF_SETENV
}


Backup() {
file=$1
number=1
while [ -f $file,$number ]
do
   number=`expr $number + 1`
done
echo Creating backup file $file,$number
mv $file $file,$number
cp $file,$number $file
}

Add2AMD() {
   record="$1"
   file=$2
   grep "$record" $file > /dev/null
   if [ $? = 0 ]
   then
      [ -n "$Verbose" ] && echo "'$record' is already in $file" >&2
   else
      (echo $record; cat $file) > $file.new
      mv $file.new $file
      [ -n "$Verbose" ] && echo "'$record' added to $file" >&2
   fi
}
Add2Env() {
   record="$1"
   file=$2
   set -- `echo $record | sed -e 's/=/ /'`
   target=$1
   value=$2
   if [ ! -f $file ]
   then
      echo $record > $file
      [ -n "$Verbose" ] && echo "'$record' initialized $file" >&2
   elif grep "^$record$" $file > /dev/null
   then
      [ -n "$Verbose" ] && echo "'$record' is already in $file" >&2
   else
      old_values=`egrep "$target=" $file | sed -e "s/$target=//" -e 's/:/ /g'`
      for old in $old_values
      do
         [ "$value" = "$old" ] && break
      done
      if [ "$value" = "$old" ]
      then
         [ -n "$Verbose" ] && echo "'$value' is already assigned to $target in $file" >&2
      else
         echo $record >> $file
         [ -n "$Verbose" ] && echo "'$record' added to $file" >&2
      fi
   fi
}

### Execution Starts HERE ##########################################

InputTargetDir=
TargetDir=.
SourceDirList=
SourceDirList1=
PalFile=
AMD_Update=
Cerius2=
backup=
Verbose=

# version
echo
echo `basename $0`  version 1.18
echo

while [ -n "$1" ]
do
   case $1 in
      -target)	shift; [ -z "$1" ] && Usage
		InputTargetDir=$1;;
      -c2)  shift; [ -z "$1" ] && Usage
            Cerius2=$1;;
      -rmc2) Cerius2='$RemoveMe$';;
      -b)   backup=yes;;
      -v)   Verbose=yes;;
      *:*)  AMD_Update="$AMD_Update $1";;
      -help)	Usage;;
      -*)	echo "Unrecognized option $1"; Usage;;
      *)	SourceDirList1="$SourceDirList1 $1";;
   esac
   shift
done

# Check that we have something specified to do
[ -z "$SourceDirList1" ] && [ -z "$Cerius2" ] && [ -z "$AMD_Update" ] && 
        ErrorMsg "Missing arguments" && Usage

# Expand all source directory names to their full paths
SaveDir=`pwd`
for SourceDir in $SourceDirList1
do
  if [ ! -d $SourceDir ]
  then ErrorMsg "Directory $SourceDir does not exist"
       Usage
  fi
  cd $SourceDir
  SourceDirList="$SourceDirList `pwd`"
  cd $SaveDir
done

echo
# Any target directory specified?
if [ -z "$InputTargetDir" ]
then
   echo "No target directory is specified, so assigning the current"
   echo "directory as the Cerius2 run directory.            Proceed? [Y] \c"
   read proceed
   [ -z "$proceed" ] && proceed="Y"
   proceed=`echo $proceed | tr '[a-z]' '[A-Z]'`
   echo
   [ "$proceed" != Y ] && Usage
else
   TargetDir=$InputTargetDir
fi
if [ ! -d $TargetDir ] 
then
   echo "Creating directory $TargetDir"
   mkdir $TargetDir
   if [ $? != 0 ]
   then ErrorMsg "Cannot create directory $TargetDir"
        Usage
   fi
fi

cd $TargetDir
if [ $? != 0 ]
then ErrorMsg "Cannot change directory to $TargetDir"
     Usage
fi

# Backup (if specified) & create appl.reg, applcomm.db, setcerius2.dev
if [ -f appl.reg ]
then
   [ -n "$backup" ] && Backup appl.reg
else CreateApplReg
fi
if [ -f applcomm.db ]
then
   [ -n "$backup" ] && Backup applcomm.db
else CreateApplComm
fi
if [ -f setcerius2.dev ]
then
   [ -n "$backup" ] && Backup setcerius2.dev
else CreateSetEnv
fi

# Set some useful variables

hostname=`hostname`
get_platform=
platform=
machine=
Platform=
for dir in `echo $PATH | sed -e 's/:/ /g'`
do
   [ -z "$get_platform" -a -x $dir/sdk_platform ] && get_platform=$dir/sdk_platform
   [ -z "$machine" -a -x $dir/machine ] && machine=$dir/machine
done
[ -n "$get_platform" ] && platform=`$get_platform`
[ -n "$machine" ] && Platform=`$machine`

# Add context specific lines to appl.reg, applcomm.db, setcerius2.dev

for SourceDir in $SourceDirList
do
   echo "Adding context for source directory $SourceDir"
   for pal in $SourceDir/*.pal
   do
      if [ -r "$pal" ]
      then
         process=`basename $pal .pal`
         # Updating appl.reg
         awk 'BEGIN {state=0; insert="+ '$pal'";}
           {if (state==1) {
               if ($1=="process") {print "+ '$pal'"; state=-1;}
               else if ($0==insert) {state=-1;}
            }
            if ($1=="process" && $2=="'$process'") state=1;
            print $0;}
           END {if (state==0) print "process '$process'";
                if (state>=0) print "+ '$pal'"; }' appl.reg > appl.reg.new
         mv appl.reg.new appl.reg
         # Adding application path to applcomm.db
         for appl in $SourceDir/obj/$platform/$process.exe \
		     $SourceDir/obj/$platform.*/$process.exe \
		     $SourceDir/obj/$platform.*/$process
         do
            [ -x $appl ] && Add2AMD "A $hostname $process $appl" applcomm.db
         done
      fi

      # Check gdf files
      gdf_present=
      for gdf in $SourceDir/*.gdf
      do
         [ -r $gdf ] && gdf_present=yes && break
      done
      [ "$gdf_present" ] && Add2Env "UI_RESOURCES=$SourceDir:\$UI_RESOURCES" setcerius2.dev

      # Check help files
      hlp_present=
      for hlp in $SourceDir/*.hlp
      do
         [ -r $hlp ] && hlp_present=yes && break
      done
      [ "$hlp_present" ] && Add2Env "HELP=$SourceDir:\$HELP" setcerius2.dev
      hlp_present=
      for hlp in $SourceDir/auto/*.hlp
      do
         [ -r $hlp ] && hlp_present=yes && break
      done
      [ "$hlp_present" ] && Add2Env "HELP=$SourceDir/auto:\$HELP" setcerius2.dev

      # Check data resource directory, named 'res'
      res="res"
      [ -d $SourceDir/$res ] && Add2Env "APP_RESOURCES=$SourceDir/$res:\$APP_RESOURCES" setcerius2.dev
   done
done

# Update applcomm.db - (separately from pal-related executables)
for pair in $AMD_Update
do
   set -- `echo $pair | sed -e 's/:/ /g'`
   if [ -z "$2" ]
   then
      ErrorMsg "Incorrect format of option '$pair'"
      Usage
   fi
   process=$1
   shift
   for appl in $*
   do
      Add2AMD "A $hostname $process $appl" applcomm.db
   done
done

# More lines for setcerius2.dev
Add2Env 'C2_APPLREG=.:$C2_APPLREG' setcerius2.dev
Add2Env 'APPLCOMM_DB=./applcomm.db:$APPLCOMM_DB' setcerius2.dev
if [ -x "$Cerius2" ]
then
   dir=`dirname $Cerius2`
   Add2Env "PATH=$dir:\$PATH" setcerius2.dev
   Add2Env "development=yes" setcerius2.dev
elif [ "$Cerius2" = '$RemoveMe$' ]
then
   egrep -v '^PATH=' setcerius2.dev > setcerius2.dev.new
   mv setcerius2.dev.new setcerius2.dev
fi

cd $SaveDir
# Completion message
echo `basename $0` completed successfully. 
echo "Run Cerius2 from \c"
if [ $TargetDir = . ]
then
   echo "the current directory."
else
   echo "directory ${TargetDir}."
fi

