#!/usr/bin/perl -w
#
# Name:         $OPTHOME/optbin/download-2
# Purpose:      part of JGOFS data download package
#		can we find the requested data object and
#		how should dataset be split into multiple small files
#		select list options
#				  C Chandler Dec 98

$version = "download-2  version 3.3  2 Dec 12";

#  2 Dec 12	WJS
#	Check variable names for legal chars
#  5 Jan 12     WJS
#	Make available features like compression depend on build-env env
#    vars.  download-2's mod is to check the validity of the bulk/compression
#    combos.  Would be better if download-1 only offered valid combos, but
#    that would need a download-1.5.  Further, if there ARE no "compression"
#    options available when needed, that's most likely an OOserver 
#    installation issue, it's better to issue a noisy message than to just
#    refuse to offer the affected "bulk" option
#  5 Jan 12	WJS
#	Use OOserver library routine get_cached_varlist to get varlist
#	Get rid of  $maxlev  parameter, whose meaning wobbled around.
#    Since it was passed to download-3, requires mods there.
#	Pass to download-3 the "magic" value that means user did not pick a 
#    "determinant" variable at a particular level. 
#	(Version goes to next "major" # for coordination w/other download pieces)
#	  [begin v 3.3]

# 10 Aug 11	WJS
#	Change "Plotting and ..." to "Download and ..."
#	  [begin v 3.2a]
#  7 Feb 10	WJS
#	Put correct infoserver and dirserver values into form for download-3
#    Older versions used values from INFOSERVER & DIRSERVER env vars, but
#    those are values for OOserver itself, not data object.
#	Pass along URLOBJX, too, for use by info
#	While at it, check input from build-opt-env, and do general checks
#    on form vars
#	  [begin v 3.2]

# 28 Nov 08	WJS
#	1 Nov mods in download-1 can destroy dobjext.  Add code
#  1 Nov 08	WJS
#	Parametrize tracefile but leave it as STDERR
#	Use parse_object_spec to determine objnameonly
#	  [begin v 3.1]
#  9 May 08	WJS
#	Log with $version rather than script name
#	Allow user to spec missing value string replacement.  This also
#     addresses the bug that if you selected missing value replacement,
#     you couldn't change your mind
#	See download-3 regarding why this is version 3.0
# 30 Aug 07	WJS
#	Remove some code duplicated in utilities.pl
# 29 Jun 05	WJS
#	Get rid of a (seemingly spurious) "only used once" error
#  9 Jun 05	WJS
#	Do a more sophisticated read of the listvar pipe.
#	Get rid of $errsta.  Does not seem to be used anyplace and always
#    had value 0.
# 17 Dec 04	WJS
#	Assume all download programs execute build-opt-env.pl
#    This allows removal of template & reduction in # hidden vars
#	Hardcode perl location (part of template removal) & add -w
#	Move old comments to download-X_tmp.comments
#
# =====================================================================

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

MAIN:
{
  $tracefile = "STDERR";

  print $tracefile " DWNLD: using script: $version \n";

  $build_opt_env = "./build-opt-env.pl";
  &check_r_access($build_opt_env);
  require "$build_opt_env";

#   color palette
  $credhi = "indianred";
  $chdrbar1 = "skyblue";
  $cgobar = "mediumaquamarine";

#     Next is form value sent to download-3 to mean that user did not select a
#   "determinant" variable at a particular level.  Formerly this string was
#   a piece of the user prompt for "select a determinant".  The old string did
#   not pass get_form_var's most strict test, and I'd rather not relax the test
#   when I can do this.  Further, passing this value means that if it changes here,
#   it will automatically propagate to download-3 ... as long as both download-2 and
#   download-3 use the same form variable name, of course.  Sigh.
#     String must not be a legit JGOFS variable name
  $user_did_not_pick = "##NOPICK##";
  
  $previous_page = $ENV{'HTTP_REFERER'};	# page we just came from
#
# These variables set by opt-build-env.pl via build-opt-env.pl
#
#   CGI script location
  $jgscdir   = &check_build_opt_env_var("JGSCRIPTDIR",$build_opt_env);
#   web images
  $webimages = &check_build_opt_env_var("BUTTONIMAGESDIR",$build_opt_env);
#   URL for web help docs
  $helpaddr  = &check_build_opt_env_var("HELPADDR",$build_opt_env);
#   top of JGOFS tree
  $jgtopdir  = &check_build_opt_env_var("JGOFSDIR",$build_opt_env);
#   scratch directory - most effective if common one all OOserver routines use
  $cache_dir = &check_build_opt_env_var("USETEMPDIR",$build_opt_env);


#   Next is the OOserver's OOserver, not the data object's OOserver
#   Latter is not available.  We rely on their being "only 1", leaving
#     the problem of port 8200 & other test servers to the testers
  $optsmenu  = ($ENV{'OPTIONSERVER'}) ?
	"http://" . $ENV{'OPTIONSERVER'}    :     "NO_OPTSMENU";
#
  $jgbindir = "$jgtopdir/bin";		# JGOFS binary execs
  $listvar_exe = "$jgbindir/listvar";	# OOserver lib will test for existence, etc

  $no_goback_url = "http://" . 
	&check_build_opt_env_var("MYADDR",$build_opt_env) . 
						     "/no_download_goback.html";

#  
# Read in all the variables set by the form
#
  &ReadParse(*form_info);
 
  $format = &get_form_var('format','REQ');
  $dobject = &get_form_var('dobject','REQ','OBJSPEC');
  $dobjext = &get_form_var('dobjext','REQ','OBJSPEC');	# jgofs object string with extension
  $dispobj = &get_form_var('dispobj','REQ','OBJSPEC');	# jgofs object+(QS) for display
  $subsels = &get_form_var('subsels','OPT','NOCHECK');
  $dobj_dirserver = &get_form_var('dobj_dirserver','OPT','OBJSPEC');
#   Next seems unused.  Avoid "one use" diagnostic
#######	  $subsdisp = &get_form_var('subsdisp','NOCHECK');

  $jgdatadir = ($dobj_dirserver)  ?  ""  :  "http://$dobj_dirserver";

  ($status,$errmsg,undef,$objnameonly,undef) = &parse_object_spec($dobject);
  ($status eq "OK") || 
	&we_have_a_problem ("Problem parsing obj spec $dobject" .
			    "Problem = $errmsg");

#   Print the header
  print &PrintHeader;    
  print <<ENDOFTEXT; 
   <BODY BGCOLOR="#FBFBFF">
   <h1>Data download continuing ...</h1>
   <b>Current object is:  $dispobj</b></br>
   <hr noshade><p>
   <form method="post" action="$jgscdir/download-3">
ENDOFTEXT


  ($form_info{'compress'} eq "NONE") && ($form_info{'bulk'} eq "moresmall") &&
	&we_have_a_problem("This installation of the Other Options server" .
		" seems to have no \"compression\" options available, which" .
		" might be an installation problem.  A \"compression\"" .
		" option is required to download \"multiple smaller files\"");
  ($form_info{'compress'} eq "gz") && ($form_info{'bulk'} eq "moresmall") &&
	&we_have_a_problem("gzip compression not allowed for" .
		" \"multiple smaller files\" downloads");


  print "<H3>Data will be packaged into \n"; 
  if ($form_info{'bulk'} eq "onebig") {
    print "one file.</H3></B></FONT> \n";
    &one_proc;
  } elsif ($form_info{'bulk'} eq "moresmall") {
    print "multiple smaller files.</H3></B></FONT> \n";
    &many_proc;
  } else {
    &we_have_a_problem (qq|Illegal value "$form_info{'bulk'}" for | .
			qq| "data packaging" form item|);
  }

#   Close the document cleanly
  print &HtmlBot;

#   Avoid "one time use" diagnostic
  undef ($credhi);
}


sub one_proc {
 
 ($format eq "text") && &select_list_options;
 
 print <<ENDOFTEXT; 
 <input type="hidden" name="format" value="$format">
 <input type="hidden" name="dobject" value="$form_info{'dobject'}">
 <input type="hidden" name="dobjext" value="$form_info{'dobjext'}">
 <input type="hidden" name="urlobjx" value="$form_info{'urlobjx'}">
 <input type="hidden" name="dobj_dirserver" value="$form_info{'dobj_dirserver'}">
 <input type="hidden" name="dobj_infoserver" value="$form_info{'dobj_infoserver'}">
 <input type="hidden" name="dispobj" value="$dispobj">
 <input type="hidden" name="bulk" value="$form_info{'bulk'}">
 <input type="hidden" name="compress" value="$form_info{'compress'}">
 <input type="hidden" name="subsels" value="$form_info{'subsels'}">
 <input type="hidden" name="subsdisp" value="$form_info{'subsdisp'}">
 <input type="hidden" name="no_pick_key" value="$user_did_not_pick">
 <TABLE BORDER=0 WiDTH=100% CELLSPACING=0 CELLPADDING=5>
  <TR><TD BGCOLOR="$cgobar">
   <H3><font color=black><input width="80" type="submit" value="Go"></font>
  </TR></TABLE></H3></form>
ENDOFTEXT

}


sub many_proc {

#   Generate tab-separated lines of variables; 1 line per level.
#   Tabs come from "def format" returned by get_cached_varlist

  my ($save_RS,$lev);

  print $tracefile (" DWNLD: get_cached_varlist call for object $dobject\n");
  (undef,@varlist_by_levels) = &get_cached_varlist($listvar_exe,$cache_dir,$dobject,0);

#   Need to remove \n's and the def varlist line separator >
  chomp @varlist_by_levels;
  $save_RS = $/;	# perl book offers RS as short mnemonic for $/
  $/ = '>';		# non-last def-formatted varlist lines end in >
  chomp @varlist_by_levels;
  $/ = $save_RS;

  print <<ENDOFTEXT; 
  <TABLE WIDTH=100% BORDER=0 CELLSPACING=0 CELLPADDING=6>
  <TR><TD COLSPAN=3 BGCOLOR="$chdrbar1">
    <H3>How would you like to divide up your data?</TD>
    <TD BGCOLOR="$chdrbar1">
      <A HREF="$helpaddr/download-help.html#params"><img alt="[HELP]" 
      align=absmiddle border=0 src="$webimages/helpbutton.gif"></A></TD>
  </TR></H3></TABLE>
ENDOFTEXT


  if (@varlist_by_levels > 0) {
#    Good, we have at least 1 level to determine multi file output.  
   $button="Go";
   $submit_msg="to continue with the next form.";

   print <<ENDOFTEXT;
   <dl>
   <dt>
    
ENDOFTEXT
   
   $lev = 0;
   foreach (@varlist_by_levels) {
#      Don't want to do last level
     ($lev == $#varlist_by_levels) && last;
     print "<dd><select name=\"determine$lev\">";
     print "<option selected value=$user_did_not_pick>Pick one parameter at level $lev\n";
     foreach $item (split /\t/) {
	($item =~ /^[a-z0-9A-Z_]+$/) ||
	  &we_have_a_problem ("Illegal character in varname about to be offered for level selection.  ",
	       "Legal chars letters, digits, underscores.  Problem string: $item");
        $item && print "<option>$item";		#  Might be empty field at end; I forget
     }
     print "</select>";
     $lev++;
   }
   print "</dl><p>";
   
   ($format eq "text") && &select_list_options;
     
  } else {
   
   # Need to redirect user if they requested multi file output, 
   # but only level is level 0, meaning the data has not been levelized
   # [? meaning only level is level 0.  Levelization or not, point is that
   # "splitting on values of variables at other levels" is meaningless. WJS Dec 11]
   # Someday I'll use listvar on another form to present user with some logical options.
      $submit_msg=" to submit a request for assistance.";
      $button="Help";
      print <<ENDOFSORRY; 
      Sorry, but this data has not yet been levelized.
      In the future we hope to provide for this situation.
      For now, please go <A HREF=\"$previous_page$ENV{'PATH_INFO'}\"><B>back</B></A>, 
      or use your Browser's <B>Back Button</B> 
      and try one big file instead.<p>  
      <form method="post" action="$jgscdir/download-problem">
ENDOFSORRY

   }

#
# pass along rest of user response information
#
print <<ENDOFSUB;
<P>
<input type="hidden" name="format" value="$format">
<input type="hidden" name="dobject" value="$form_info{'dobject'}">
<input type="hidden" name="dobjext" value="$form_info{'dobjext'}">
<input type="hidden" name="urlobjx" value="$form_info{'urlobjx'}">
<input type="hidden" name="dobj_dirserver" value="$form_info{'dobj_dirserver'}">
<input type="hidden" name="dobj_infoserver" value="$form_info{'dobj_infoserver'}">
<input type="hidden" name="dispobj" value="$dispobj">
<input type="hidden" name="bulk" value="$form_info{'bulk'}">
<input type="hidden" name="compress" value="$form_info{'compress'}">
<input type="hidden" name="subsels" value="$form_info{'subsels'}">
<input type="hidden" name="subsdisp" value="$form_info{'subsdisp'}">
<input type="hidden" name="no_pick_key" value="$user_did_not_pick">
<TABLE BORDER=0 WiDTH=100% CELLSPACING=0 CELLPADDING=5>
  <TR><TD BGCOLOR="$cgobar">
   <H3><font color=black><input width="80" type="submit" value="Go"></font>
  </TR></TABLE></H3></form>

ENDOFSUB

}


sub select_list_options {
# allow user to select some list options
# Optional command line list options: 
#     -s   space-separated
#     -t   tab-separated
#     -b   brief flat file (no header info)
#     -m   string to assign to missing values
#     -z   delete extra spaces

  print <<END_OF_TEXT;
    <TABLE WIDTH=100% BORDER=0 CELLSPACING=0 CELLPADDING=6>
    <TR><TD COLSPAN=3 BGCOLOR="$chdrbar1">
      <H3>Data file formatting options: </TD>
      <TD BGCOLOR="$chdrbar1">
        <A HREF="$helpaddr/download-help.html#format"><img alt="[HELP]" 
        align=absmiddle border=0 src="$webimages/helpbutton.gif"></A></TD>
    </TR></H3></TABLE><BR>
    The default is to generate a space-separated file with column header 
    information, and data visually aligned in columns, suitable for importing 
    into a spreadsheet program. You may override this by selecting options 
    from the list below.
    <P>
    Select the character with which to separate data fields and whether you want 
    your data visually aligned in columns? <BR>
    <SELECT NAME="opt_sep">
    <option value="SPACESEP" SELECTED> space-separated, data aligned in columns 
    <option value="TABSEP"> tab-separated, data aligned in columns 
    <option value="DEFAULT"> comma-separated, data aligned in columns
    <option value="SUPPRESS_SPACES"> comma-separated (no columnar alignment)
    </SELECT>
    <P>
    Additional data formatting options: 
     <TABLE BORDER="0" CELLSPACING="10">  
     <TR>
      <TD COLSPAN=3><input type="radio" name="opt_brief" value="FLAT" CHECKED> flat file w/column headers</TD>
      <TD COLSPAN=3><input type="radio" name="opt_brief" value="NOHEADERS"> brief (no column headers)</TD>
    </TR>   
    </TABLE>

    Missing data should have the value:  &nbsp
    <select name="missingstring">
    <option value="nd" selected> default missing value string (nd)
    <option value="-9999.0"> default missing value number (-9999.0)
    </select>
    or type another string or number in this box &nbsp
    <input name="custommissing"><p>
    <p>
END_OF_TEXT

}


sub we_have_a_problem {
  @errmsg = @_;
  print $tracefile " DWNLD:  errormsg= @errmsg \n";

#
# get ready to pass the data object and QUERY_STRING back
#
  $back_to_opts =  
	(  ($dobjext eq "NO_VALID_DOBJEXT") || ($optsmenu eq "NO_OPTSMENU") )
			 ? 
	$no_goback_url   :   "$optsmenu"."$dobjext"."?"."$subsels";

print <<ENDOFSUB1;
  Sorry, we have encountered a problem processing the $objnameonly data:<BR>
  @errmsg
  
  <BR><PRE><H3>
  Please go <A HREF=\"$previous_page\"><B>back</B></A> and try again, 
  or <A HREF="$back_to_opts">return</A> to the Download and Other Options menu,
ENDOFSUB1

$jgdatadir && 
	     print qq|  or the <A HREF="$jgdatadir">Data Directory</A> menu \n|;

print <<ENDOFSUB2;
  or try using your browser's 'Go' menu to return and relocate the data object.</H3>
  </PRE>
  
  <form method="post" action="$jgscdir/download-problem">
  <input type="hidden" name="dobject" value="$form_info{'dobject'}">
  <input type="hidden" name="dobjext" value="$form_info{'dobjext'}">
  <input type="hidden" name="urlobjx" value="$form_info{'urlobjx'}">
  <input type="hidden" name="dobj_dirserver" value="$form_info{'dobj_dirserver'}">
  <input type="hidden" name="dobj_infoserver" value="$form_info{'dobj_infoserver'}">
  <input type="hidden" name="dispobj" value="$dispobj">
  <input type="hidden" name="subsels" value="$form_info{'subsels'}">
  <input type="hidden" name="subsdisp" value="$form_info{'subsdisp'}">
  <input type="hidden" name="no_pick_key" value="$user_did_not_pick">
  <input type="hidden" name="bulk" value="$form_info{'bulk'}">
  <input type="hidden" name="compress" value="$form_info{'compress'}">
  <input type="hidden" name="errmsg" value="@errmsg">
  

  <H3>&nbsp or press <font color="blue"><input width="80" type="submit" value="help"></font> 
        to submit a request for assistance.</H3>
  </form>

  <p><HR SIZE=4 NOSHADE>
    
ENDOFSUB2
}
