#
# Project Directory and Scratch Directory Management Script
# Written by Leor Zolman, 10/92
#
# For inclusion in .profile under sh or ksh shells.
# This code is generalized, and will work as shown under both shells,
# though slightly better performance may be obtained under ksh by changing
# invocations of pwd into interpolations of the $PWD environment variable.
#

#### Project directory management: #########################################

PROJDIR=$HOME/.Proj     # Master directory for all project definitions
export PROJDIR          # (required for use by showp and shows scripts)
NPROJDIRS=12            # Maximum number of project directories
SCRATCHDIRS="x y z"     # scratchpad directory memory variables
SHOWCHANGE=Y            # Y to show result of dir change, else N (set to N
                        # if your prompt already displays working directory)
#
# Master project directory control function (called by p# functions below)
# usages: 
#   p proj# dir     - add given directory (. for current) to project list
#   p proj#         - change directory to given project
#   p proj# done    - drop given project from project list
#

showdir() { [ "$SHOWCHANGE" = Y ] && pwd; return 0; } # show new dir, if desired

p()
{
    [ $# -eq 0 ] && echo "p() shell function invoked imcorrectly." && return
    [ $1 -ge 1 ] 2>/dev/null && [ $1 -le $NPROJDIRS ] 2>/dev/null &&
    {
        if [ $# -eq 2 ]; then
            if [ $2 = done -a -f $PROJDIR/Proj$1 ]; then
                rm $PROJDIR/Proj$1
                eval "unset proj$1"
                return
            fi
            target=$2
            [ $2 = "." ] && target=`pwd`
            echo $target >$PROJDIR/Proj$1
            # Define and export environment variable proj#:
            eval "proj$1=$target; export proj$1"
        else
            if [ ! -f $PROJDIR/Proj$1 ]; then
                echo "No Project #$1 defined."
                return
            fi
            touch $PROJDIR/Proj$1
            cd `cat $PROJDIR/Proj$1`
            showdir
        fi
        return
    }
    echo "p() function called with invalid project register number: $1"
}

# Create project directory, if it does not already exist:
[ ! -d $HOME/.Proj ] && mkdir $HOME/.Proj   

#
# Define all quick-access functions p#(), and define simple
# environment variables proj# (for active projects only) by
# reading in their values from the .Proj directory:
#

i=1
while [ $i -le $NPROJDIRS ]
do
    # Define quick-access function p#():
    eval "p$i() { p $i "'$*'"; }"

    # if project active, define environment variable proj#:
    [ -f $PROJDIR/Proj$i ] &&
        eval "proj$i=`cat $PROJDIR/Proj$i`; export proj$i"

    i=`expr $i + 1`
done


#### scratchpad directory shorthand function/variable definitions: #########

for X in $SCRATCHDIRS
do
    # Define assignment function setX() for each X in SCRATCHLIST (each such
    # function defines a directory and a corresponding environment variable)
    eval "set$X() { $X=\`pwd\`; echo \$$X >$PROJDIR/${X}dir; }"

    # Define function to undefine a directory and corresponding env. var:
    eval "unset$X() { unset $X; rm $PROJDIR/${X}dir; }"

    # Define quick-access function goX() for each X in SCRATCHLIST:
    eval "go$X() {
        [ \"\$$X\" != \"\" ] && cd \$$X && touch $PROJDIR/${X}dir \
                && showdir && return
            echo directory $X undefined.; }"

    # Define environment variable X for each *defined* X in SCRATCHLIST: 
    [ -f $PROJDIR/${X}dir ] && read $X < $PROJDIR/${X}dir
done
