#!/opt/local/bin/perl
#.....................................................................
#	PROGRAM:	fof_menu
#	USAGE:	fof_menu [-c] [-t title] [menufile]
#           
#.....................................................................
#       
# Syntax for entries in the menufile:
#       Text to be displayed :: script to run
#
# For example:
# Pickup DEPOSIT :: /SCRIPTS_DIR/SCRIPTS/foo.sh
#
#
# Any line beginning with a pound sign (#) is a comment.
# Any line without two consecutive colons (::) is printed as is.
# Lines with a :: are selectable menu items.  
#     Text before the :: is displayed with a number (a, b, c, ... ).
#     Text after the :: is not displayed, but is the associated unix 
#     command to be executed.
# Lines with :: TEXT->LOCATION/file.sh 
#     are resolved to $TEXT/LOCATION/file.sh
#
# where $TEXT is obtained from TEXT={some path}
#
# The menu program will add these two entries:
#
#    cd  Change directory   
#     X  Exit this menu

#
# Options:
# -c           clear. Clear screen before each display.
# -d           Change Directory entry at bottom
# -m #         # columns menu
# -t title     Display title at top of listing.
#  
#....................................................................

#use warnings;                                             # I turned these off
#use strict;

# .................. command line options ...........................

use Getopt::Std;

my %opts;
die &error_message unless &getopts( 'm:cdt:', \%opts );    # command line options
die &error_message if $opts{'h'} ;                         # no help available yet

use Term::ANSIColor;                                       #somehow, I cannot get this to work

# ................... temp variables ................................

my $Usage="Usage: fof_menu [-c] [-d] [-m number] [-t title] [menufile] \n" ;
my $SYS_DEFAULT_MENU =  "ADD_DECK/BIN/adds.menu" ;         # System default menu
my $USER_DEFAULT_MENU = "$ENV{'HOME'}" . "/.mymenu";	     # user default menu

my %BASE_DIR = ();                                         #stores a hash of PATHS
my (@commands, @prompts, @items, $item, $menufile);

# .................. which menu to use .............................
if (@ARGV) {
	$menufile = shift ; 		                                # Menufile on command line 
}elsif (-f $USER_DEFAULT_MENU ){
	$menufile = $USER_DEFAULT_MENU;                         # Or use User default
}else {
	$menufile = $USER_DEFAULT_MENU;                         # else System default
}

# ..................................................................
# Use the PWD tracker

require "pwd.pl" ;
&initpwd;

# Read and process Menu file.
# Lines with a :: are treated as selectable commands,
# and will get a number when displayed.

open (MENU, $menufile) || die "\n\a Cannot find menu file $menufile \n" ;

item: while (<MENU>)
{
   chomp;
   next item if /^[\w]*#/ ;                               #skip comment lines
   if (/\s*=\s*/) {                                       #take note of PATH variables
   	my ($left, $right) = split(/\s*\=\s*/,$_,2);
		s/^\s+//, s/\s+$// for $left, $right;
		
		$BASE_DIR{$left} = $right if $right !~ /^\s*$/;
		next;
	}
	
   my ($prompt, $command) = split(/::/,$_,2) ; my $command_base_dir = "";
	
   push(@prompts, $prompt);
   if ( $command =~ /^\s*$/ ) {
		push (@items, " ");
   }
   else {
		push (@items, ++$item) ;
		if ( $command =~ /\-\>/ ) {
			($command_base_dir, $command) = split(/\s*->\s*/,$command,2);
			s/^\s+//, s/\s+$// for $command_base_dir, $command;

			$command="$BASE_DIR{$command_base_dir}/" . "$command"  if $BASE_DIR{"$command_base_dir"} !~ m/^\s*$/;
		}
		push(@commands, $command) ;
   }
}

my $numitems = @items ; my $numcomms = @commands; my $text = " " ;



# Redisplay menu until user enters X
# For a valid entry, execute corresponding unix command

while (1) 
{
	system ("clear") unless !$opts{'c'};                       # clear screen

	my $LINE="";
	if ($opts{'t'}) {
		$LINE="-" x length($opts{'t'});
		print ("\n\t$LINE\n\t$opts{'t'} \n\t$LINE\n");
	}

	# ...........   display menu ....................
	
	my $j=1;

	if ( $opts{'m'}){

		for (my $i=0 ; $i < $numitems; $i++ ) {
			if ($j < $opts{'m'}){
				if ( $items[$i] eq " " ) {
					#print ("\n\t    $prompts[$i]\n") ;
					if ( $prompts[$i] =~ /[\<\>\-\~\_\*]/ ) {
						print ("\t    $prompts[$i]\n") ;
					} else {
						print colored("\t    $prompts[$i]\n", "red", "on_blue", "blink");
						print color("reset");
					}
				}
				else{
					printf ("\t%2d  %s ", $items[$i], $prompts[$i] ) ;
					$j++;
				}
			}else{
				if ( $items[$i] eq " " ) {
					print ("\t    $prompts[$i]\n") ;
					#print colored("\t    $prompts[$i]\n", "red", "on_black", "blink");
					#print color("reset");
				}
				else{
					printf ("\t%2d  %s", $items[$i], $prompts[$i] ) ;
				}
				#print ("\n"); $j=1;
				$j=1;
			}
		}
	}else{
		for (my $i=0 ; $i < $numitems; $i++ ) {
			if ( $items[$i] eq " " ) {
				print colored("\t    $prompts[$i]\n", "red", "on_black", "blink");
				print color("reset");
			}
			else{
				printf ("\t%2d  %s \n", $items[$i], $prompts[$i] ) ;
			}
		}
	}

	# ................................................


   if ($opts{'d'}){
		print "\tcd     Change directory \n\t       (Current: $ENV{PWD}) \n";	# 
   	print "\n" ; print "\t!{cmd} Execute the UNIX command {cmd} ( e.g. !ls )\n\n" ;
   }

   print "\n" ; print "\t X     Exit this menu\n" ;
	print "\n\t$LINE\n";
	print  colored("                                            STATUS LINE\n\n", "red", "on_black", "blink");
	print color("reset");
	print "$text" ;
	#print "\n\t$LINE\n\n\tEnter Selection :> ";
	#print colored("\n\nTesting !!! \n\n", "green", "on_cyan", "blink");
	print colored("\n\t$LINE\n\n\tEnter Selection :> ", "red", "on_black", "blink");
	print color("reset");

	system("stty erase "); chop(my $choice = <STDIN>) ;

	# ...............   item processing ...............

	CHOICE: {
					print ("\n\n\t\t      O   U   T   P   U   T\n\n");

					# Exit on X
					if ($choice =~ /^[XxqQ]/ ) { print ("\n\n\n"); exit 0 ; } 

					# cd with no arg
					if ($choice =~ /^cd\s*$/) {
						$text = " ";
						&chdir($ENV{"HOME"} || $ENV{"LOGDIR"} || (getpwuid($<)) ) ; 
						last CHOICE ;
					}

					if ($choice =~ /^cd\s+(\S+)/) { # cd something
						$text = " " ;
						&chdir($1) || ( $text = "\tCan't cd to \"$1\": $! ") ;
						last CHOICE ;
					}      

					#  Execute some unix command
					if ($choice =~ s/^!\s*(\S+)/$1/) { # cd something
						$text = "\t*** previous command successfully executed  ***" ;
						system ($choice);
						print ("\n\n\a\tEnter to proceed ........"); <STDIN>;
						last CHOICE ;
					}      
				

					# Invalid entry
					if ($choice < 1 || $choice > $numcomms) {
						$text = "                       *** Invalid entry, ${choice}." .
						" Enter 1-$numcomms, X or !UNIX command *** " ;
						last CHOICE ;
					}				  

					# valid entry to execute
					$text = " ";
					system( $commands[$choice-1] ) ;


					print ("\n\n\a\tEnter to proceed ........"); <STDIN>;
			}
}
				
# End of menu perl script
    

#---------------------------- SUBROUTINES SECTION ----------------------------------
sub error_message {
   print <<EOF
                                E   R   R   O   R
                                -   -   -   -   -


       USAGE: $0 [-c] [-d] [-m number] [-t title] [menufile] 

          EG: $0 fofp_menu_gen.pl -m 2 -t ' P R O J E C T I O N ' /MENU/projection.menu 

EOF
;

  exit 1;   #++ failure
}

1;
