#!/bin/bash

# Title......: menu
# Description: ksh based menu program
# Author.....: Mitchell Johnston - uid 0
# Contact....: http://www.bdragon.net
# Date.......: Mon Sep 07 2009
#----------------------------------

trap "continue" 2     # allows you to break a bad connection

# variables
#----------------------------------
BOLD=$(tput bold)                          # turn bold on
DIM=$(tput dim)                            # turn dim mode on
LINE=$(tput smul)                          # turn underline on
ULINE=$(tput rmul)                         # turn underline off
REV=$(tput rev)                            # turn on reverse mode
STDO=$(tput smso)                          # Standout mode (bold on rxvt)
USTDO=$(tput rmso)                         # Exit standout mode
NORM=$(tput sgr0)                          # Turn of all attributes

REDF=$(tput setaf 1)                       # Red foreground
LIGHT_REDF=$(tput setaf 1 ; tput bold )    # Light Red foreground
GREENF=$(tput setaf 2)                     # Green foreground
LIGHT_GREENF=$(tput setaf 2 ; tput bold )  # Light Green foreground
YELLOWF=$(tput setaf 3)                    # Yellow foreground
LIGHT_YELLOWF=$(tput setaf 3 ; tput bold ) # Light Yellow foreground
BLUEF=$(tput setaf 4)                      # Blue foreground
LIGHT_BLUEF=$(tput setaf 4 ; tput bold )   # Light Blue foreground
PURPLEF=$(tput setaf 5)                    # Purple foreground
LIGHT_PURPLEF=$(tput setaf 5 ; tput bold ) # Light Purple foreground
CYANF=$(tput setaf 6)                      # Cyan foreground
LIGHT_CYANF=$(tput setaf 6 ; tput bold )   # Light Cyan foreground
WHITEF=$(tput setaf 7)                     # White foreground
LIGHT_WHITEF=$(tput setaf 7 ; tput bold )  # Light White foreground
typeset -i CNT=0                           # define the variable as integer
typeset -i NUMBER=0                        # define the variable as integer
SHOW=n                                     # set default of show to no
DATE=$(date +"%a %b %d")                   # sets up the date display
OS=$(uname -s)                             # OS type: SunOS Linux
PS4='$SECONDS $LINENO: '                   # debug prompt
DEBUG=0                                    # turn on (1) debug mode
LOG=~/etc/log.txt                          # my log file

## set the menu file
if [ -z "$1" ]
then
    FILE=~/.menu         # location of the menu file
else
    if [ -f "$1" ]       # check the file
    then
        FILE=$1
    else
        echo "Bad file: $1"
        echo ^G
        exit 1
    fi
fi

# functions
#----------------------------------
echon(){     # echo with no LF
    [ $DEBUG == 1 ] && set -x

    if [ "$OS" = "Linux" -o "$OS" = "CYGWIN_NT-5.1" ]
    then
        echo -n $*
    else
        /usr/ucb/echo -n $*
    fi
}

pause(){ # simple pause routine
    [ $DEBUG == 1 ] && set -x
    echon "Please hit ENTER: "
    read x
}

bl(){ # write a blank line
    [ $DEBUG == 1 ] && set -x
    echo " "
}

xtitle(){ # set window title
    [ $DEBUG == 1 ] && set -x
    printf "\033]0;$*\007"    
}

log(){ ## log entry tool
    [ $DEBUG == 1 ] && set -x
    if [ $# == 0 ] # display todays entry's
    then
            grep $(date '+%D') $LOG
    else
            # make an entry
            echo "$(date '+%D %T') $HOSTNAME [$$] $*">>$LOG
            echo "${GREENF}$(date '+%D %T')${NORM} $HOSTNAME ${YELLOWF}[$$]${NORM} $*"
    fi
}

# main
#----------------------------------
[ $DEBUG == 1 ] && set -x

## set default title
xtitle "Menu"

## get data
while read LINE
do
    if [ ! $(echo "$LINE"|egrep -c '^#') -eq 1 ]
    then
        DISPLAY[$CNT]=$(echo $LINE| cut -d',' -f1)
        COMMAND[$CNT]=$(echo $LINE| cut -d',' -f2)
        PAUSE[$CNT]=$(echo $LINE| cut -d',' -f3)
        PROMPT[$CNT]=$(echo $LINE| cut -d',' -f4)
        ((CNT = CNT + 1))
    fi
done <$FILE

NUMBER=$CNT     # Set to the total number of lines

while :
do
    ## display header
    CNT=0
    clear
    echo "${BOLD}$LOGNAME${NORM} "${LINE}SHOW=$SHOW${ULINE}" "${LINE}$(uname -n)${ULINE}"  ${BOLD}$DATE${NORM}"
    bl


    ## display selections
    until [ $CNT -eq $NUMBER ]
    do
        case  ${DISPLAY[$CNT]}
        in
         -) echo "${LIGHT_REDF}----------------------------------${NORM}";;
         :) xtitle "${COMMAND[$CNT]}"
            echo "${LIGHT_GREENF}${COMMAND[$CNT]}${NROM}";;
         *) echo "${LIGHT_GREENF}$CNT${NORM}. ${DISPLAY[$CNT]}";;
        esac
        ((CNT = CNT + 1))
    done

    bl
    echo "${LIGHT_GREENF}c${NORM}.    Run a command line"
    echo "${LIGHT_GREENF}s${NORM}.    Toggle show mode"
    echo "${LIGHT_GREENF}q${NORM}.    Quit"

    ## get and run choice
    bl
    echon "${LIGHT_BLUEF}Please select option:${NORM}  "
    read CHOICE

    case $CHOICE in
        [Cc])bl
          echon "Run: "
          read RUN
          ${RUN}
          pause;;
        [Ee])clear
        log "menu: edit $FILE"
        vi $FILE
        exec $0;;
        [Ss])if [ "$SHOW" = "n" ]
          then
            SHOW=y
          else
            SHOW=n
          fi;;
        [Qq])printf "\033]0;$LOCATION\007"
        exit;;
        *)if [ "$CHOICE" -le "$NUMBER" ]
          then
            ## prompt if needed
            if [ -n "${PROMPT[$CHOICE]}" ]
            then
                bl
                echon "${PROMPT[$CHOICE]}"
                read OPTION
                export OPTION
            fi

            ## if show is set
            if [ "$SHOW" = "y" ]
            then
                bl
                echo "${COMMAND[$CHOICE]}"
                pause
            fi

            #------------------------------------------------------
            # This crap is because it was the only method I could think
            # of to handle multiple commands.
            #------------------------------------------------------
            echo ${COMMAND[$CHOICE]} >/tmp/$$  # write to a temp file
            chmod +x /tmp/$$                   # make it runnable
            /tmp/$$ 2>&1                       # run it
            \rm /tmp/$$                        # remove it

            if [ "${PAUSE[$CHOICE]}" = "y" ] ## if pause is set
            then
                pause
            fi
          else
            clear
            echo ^G
            echo "Not a valid number"
            sleep 2
          fi;;
    esac
done

[ $DEBUG == 1 ] && set +x