#!/usr/bin/perl -w
{
$version = "makematlab.pl version 2.3 15 May 2012";
#  15 May 12.  WJS
#	Most recent matlab build uses linker switch  -rpath , which
#    puts the runtime lib defns into the executable image at link time.
#    This obviates the need to set LD_LIBRARY_PATH in here.  I forget
#    what happens if LD_LIBRARY_PATH is specified anyway; ie, I don't
#    know which specification takes effect
#	[begin v 2.3]

#   5 Sep 09.  WJS
#	Allow for created matlab file along with non-empty err file
#	Allow user to specify makemat's -maxwidth= switch
#	[begin v 2.2]

#   9 May 08.  WJS
#	New test to distinguish direct from indirect access
#	[begin v 2.1a]
#  22 May 07.  WJS
#	Allow "direct" access; ie, no forms.  For first cut, send same
#    html to stdout for direct and indirect cases.  At some point might
#    change this.  In particular, in addition to getting rid of html,
#    might want to format for machine use; eg, start off with a line
#    saying SUCCESS or FAILURE, followed by either the URL of the .mat
#    file or the error info.
#	[begin v 2.1]

#  27 Aug 05.  WJS
#	Better checks on env var setup
#  23 Aug 05.  WJS
#	Transfer object spec via hidden form variable rather than
#    QUERY_STRING or PATH_INFO
#	Check accessibility of makemat image
#	Add explicit exit after processing form
#  19 Aug 05.  WJS
#	Display list of variables considered alpha in case user wants
#     to change these (most likely because 1st record happens to contain
#     an 'nd')
#   3 Aug 05.  WJS
#	Give up on fancy matlab locations
#	Use wjs_web_perl_utilities.pl; hence make error msgs, etc, a bit
#     more similar to other OO routines I've fiddled with
#	[begin v 2.0]

# Mar 12, 2005.  WJS
#	Bug fix: need URL of download file in href, not download file name
#	Change perl location
#??????, 2004
#	No need for template w/new opt-build-env.pl.  Get lib locs
#	  from there (variant of "alternative" in 5 May comment)
# Jun 23, 2004. WJS
#	Name temp file after the object instead of "makemat"
#	Indicate that one should download w/shift-click instead of click
#	  (until/unless Bob defines .mat file type on server)
# May 5, 2004.  WJS
#	cgi-lib.pl's PrintHeader seems to work, replacing system echo's
#	  Thought orig problem might have to do w/flushing STDOUT, but
#	  could not easily reproduce orig problem...
#	Do some error handling.
#	Library path stuff
#	  Setup in here in anticipation of user being able to select 
#		matlab 5 or 6.
#	  Take a cut at dealing w/a path that already includes a matlab lib defn
#	  Create template version of this file so we can get lib locs
#	    from opt-build-env at server build time.  (Alternative is
#	    to have optbin/build-opt-env.pl propagate the value at run
#	    time.  I could be persuaded the other way...)
#	Present the download as a link instead of sending output to stdout
# April 1, 2004.  WJS/RCG
#	System echo works but print STDOUT does not, but this
#	  matches what K. Krueger says he has observed.  
#	Outputting directly from makemat did not work, but outputting
#	  to a temporary file and then catting the results did work.
#  Mar. 23, 2004: Make into a Perl script  rcg/wjs
#  Jan. 10, 2000: replace if test expression to make valid  rcg

require ("cgi-lib.pl");
require "wjs_web_perl_utilities.pl";

#   Set up environment.  Assume .pl routine is in our directory
$build_opt_env = "./build-opt-env.pl";
&check_r_access($build_opt_env);
require $build_opt_env;
                            
# Define form action routine and hidden html var name for that routine.
$form_action = "form_action";
$form_action_routine = $ENV{"SCRIPT_NAME"} ?
			$ENV{"SCRIPT_NAME"} : "/jg/makematlab.pl";

#   Check that build-opt-env set up things as expected
defined ($ENV{'OPTHOME'}) ||
	&quit ("Internal problem.  ",
    		"Did not get defined env var 'OPTHOME' from $build_opt_env");
$bindir = &abs_filespec($ENV{"OPTHOME"},"Env var OPTHOME") . "/bin";

#   html form variable names
$alpha_list_form_var_name = "list_of_alpha_variables";
$object_form_var_name = "object_spec";
$varwidth_form_var_name = "varwidths";

&ReadParse(*form_info);

#   See if we are being called for human interface or direct-to-machine
#   interface.  First stab at this: assume if args come from QUERY_STRING,
#   it's direct.  Take a 2nd stab: QUERY_STRING is defined if there are
#   sel/projs
$object = &get_form_var($object_form_var_name,'OPT','NOCHECK');
$direct_action = ($object ne "") && ($ENV{"REQUEST_METHOD"} eq "GET");

if ($direct_action) {
  &process_form($object);
} else {
#     Main purpose of putting form action routine on form as a hidden
#     variable is to distinguish between use of this program in the
#     "put the form up" and "process the form results" modes.  The
#     consistency check is just on general principles - anyone who de-
#     liberately mis-routes things here can change the hidden value as well.
#	Can probably do this better w/the combo of ENV{'REQUEST_METHOD'}
#     and a required variable like $object_form_var_name, or maybe w/
#     the return value from ReadParse... some other time.
    if (  $after_submit = (defined $form_info{$form_action})  ) {
      ($form_info{$form_action} eq $form_action_routine) ||
	&quit ("Submit action routine should be same as form value"   ,
		  "Action = $form_action_routine; " .
				"Form value = $form_info{$form_action}"     );
    }

  if ($after_submit) {
    &process_form($object);
  } else {
    &print_form;
  }
}

exit;
}

sub print_form
{
  &printheader();

  print "<html>\n";

  $title = 'Matlab alpha variable selection page';
  print "<head><title>$title</title></head>\n";
  print "<h1>$title</h1>\n";

#   Check that build-opt-env set up things as expected
  defined ($ENV{'OBJECT'}) ||
	&quit ("Internal problem.  ",
    		"Did not get defined env var OBJECT from $build_opt_env");
  ($object = $ENV{'OBJECT'}) || 
	&quit ("Internal problem.  ",
		"Did not get non-empty env var OBJECT from $build_opt_env");
  defined ($ENV{'SUBSELS'}) ||
	&quit ("Internal problem.  ",
    		"Did not get defined env var SUBSELS from $build_opt_env");

  print "<form method=\"POST\"" .
			" action=\"$form_action_routine" .
			"\">\n";

#   Put object spec into form as hidden variable
  $ENV{'SUBSELS'} && (  $object .=  "(" . $ENV{'SUBSELS'} . ")"  );
  $h = "input type=\"hidden\"";
  print "<$h name=\"$object_form_var_name\" value=\"$object\">\n";

#   Put name of form action routine on form
  print "<$h name=\"$form_action\" value=\"$form_action_routine\">\n";

  &print_select_alpha_variables 
		("$bindir/list",$object,$alpha_list_form_var_name,"FALSE");
  &print_choose_memory_algorithm($varwidth_form_var_name);

  print "<br><br><input type=\"SUBMIT\" value=\"Generate matlab data\">\n";

  print "</form></body></html>\n";
  exit;
}

sub process_form
{
my ($object) = @_;
#     Try to get "creating..." msg on screen while work is going on
use FileHandle;
STDOUT->autoflush(1);

&printheader();

print "<html>\n";

$title = 'Matlab generation results page';
print "<head><title>$title</title></head>\n";
print "<h1>$title</h1>\n";

print "<pre>\n";
$open_pre_tag = 1;	# Global variable used by quit

($status,$errmsg,undef,$object_name) = &parse_object_spec($object);
($status eq "OK") || 
		&quit ("Parsing problem $errmsg with object spec",$object);

$alpha_list = &get_form_var($alpha_list_form_var_name,'OPT','STRING_LIST');
$alpha_list =~ s/\0/\,/g;
($before,$after) = ($alpha_list =~ /(.*)#NONE#(.*)/);
($before || $after) &&
	   &quit ("Cannot select an alpha " .
		"variable along with the 'no alpha variables' choice");

$var_width = &get_form_var($varwidth_form_var_name,'OPT','NUMBER');
($var_width eq "") && ($var_width = 0);
$width_switch = "-maxwidth=$var_width";

foreach ('USETEMPDIR','USETEMPADDR') {
  defined ($ENV{"$_"}) || 
      &quit ("Internal problem.  ",
			"Did not get defined env var $_ from $build_opt_env");
}
$tempfile_name = "$object_name.mat";
$tempfile = &abs_filespec($ENV{"USETEMPDIR"},"Env var USETEMPDIR") . 
							"/$tempfile_name";
$ENV{'USETEMPADDR'} || 
    &quit ("Internal problem.  ",
	"Did not get non-empty env var USETEMPADDR from $build_opt_env");
$tempfile_url = "$ENV{'USETEMPADDR'}/$tempfile_name";
$errfile = "$tempfile.err";

#   If we need to go back to fooling with LD_LIBRARY_PATH, code
#   can go here (or anyplace before the system command.  Old code is
#   commented out at bottom

(-e $tempfile) && (unlink $tempfile);
(-e $errfile) && (unlink $errfile);

print "Creating matlab file...\n";

$command = "$bindir/makemat";
&check_x_access($command);
$command .= " $width_switch ";
$command .= qq| "$object" "$alpha_list" |;
$command .= " >> $tempfile 2> $errfile";

$! = $? = 0;
system $command;
$ok_command = (($! == 0) && ($? == 0));
if ( ! $ok_command) {
  push @err_array, "Problem executing command (below)\n\$! = $!; \$? = $?\n";
  if (  $errfile && ( -e $errfile ) && ( -s _ )   ) {
    push @err_array, "\nOutput sent to stderr:\n";
    push @err_array, `cat $errfile`;
  }
  if (  $tempfile && ( -e $tempfile ) && ( -s _ ) && (-T _)   ) {
    push @err_array, "\nText sent to stdout:\n";
    push @err_array, `cat $tempfile`;
  }
  push @err_array, "Attempted command: $command\n";
  &quit (@err_array);
}

if (  ( -e $tempfile ) && ( -s _ )   ) {
  if (  ( -e $errfile ) && ( -s _ )   ) {
    print "\nWarnings/errors associated w/matlab file creation\n\n";
    print `cat $errfile`;
    print "\n";
  }
  print "\n<a href=\"$tempfile_url\">" .
  	"Download matlab file</a> (Hold SHIFT key and Click to download)\n";
  print "</pre></html>";
} else {
  push @err_array, "No matlab file created or nothing in matlab file\n";
  if (  ( -e $errfile ) && ( -s _ )   ) {
    push @err_array, "\nContents of $errfile:\n";
    push @err_array, `cat $errfile`;
    push @err_array, "Above error file produced by: $command\n";
  }
  &quit (@err_array);
}

$open_pre_tag = 0;
undef $version;		# Global variable used by quit

exit;
}

#	Code that originally dealt with LD_LIBRARY_PATH

#$library_path_name = "LD_LIBRARY_PATH";
##   List of possible matlab libs just in case multiple ones are in
##   LD_LIBRARY_PATH.  No big deal if this not kept up to date (tried to
##   have this come from build-env.pl, but just not worth it - Aug 05)
#$ENV{'MATLABLIBDIR'} && push (@matlablib_list, $ENV{'MATLABLIBDIR'});
#$ENV{'MATLAB5LIBDIR'} && push (@matlablib_list, $ENV{'MATLAB5LIBDIR'});
#
##   Some day, get $which_matlab from either otheropt page or a
##   dedicated "matlab download page"
##   "master" locations from opt-build-env
#$which_matlab = "MATLAB";	#  latest
#$lib_env_var = $which_matlab . "LIBDIR";
#$lib_file = ($ENV{$lib_env_var}) ? $ENV{$lib_env_var} : "";
#
#if ($lib_file) {
#  ($status1,$status2,$new_lib_path) = 
#			&add_file_to_path_string($library_path_name,
#						 $lib_file,
#						 @matlablib_list);
#} else {
#  $status1 = "NG";
#  $status2 = "UNDEFINED_" . $lib_env_var;
#}
#if ($status1 eq "OK") {
#  $ENV{$library_path_name} = $new_lib_path;
#} else {
#  print " *** Cannot seem to find $which_matlab library $lib_file\n" .  
#	" *** Possible problem: $status2\n" .
#        " *** Proceeding in case correct library has been defaulted somehow\n" .
#        " *** Check resulting matlab file for version, if appropriate\n\n";
#}
