#!/usr/bin/perl
$MKFRINGE = mkfringe;

# strip off args related to the elixir config system, set env PTOLEMY
@ARGV = elixir_config (@ARGV);

# interpret command-line arguments
if (@ARGV < 1) {
    print STDOUT "USAGE: $MKFRINGE (mode) [arguments]\n";
    print STDOUT "mode = help gives a complete list\n";
    &escape;
}
if ($ARGV[0] eq "help") { &usage; }

# user level commands
if ($ARGV[0] eq "create")     { &mk_create;     }
if ($ARGV[0] eq "config")     { &mk_config;     }
if ($ARGV[0] eq "init")       { &mk_init;       }
if ($ARGV[0] eq "run")        { &mk_run;        }
if ($ARGV[0] eq "state")      { &mk_state;      }
if ($ARGV[0] eq "mkconfig")   { &mk_mkconfig;   }
if ($ARGV[0] eq "list.runs")  { &mk_list_runs;  }
if ($ARGV[0] eq "clean")      { &mk_cleanup;    }
if ($ARGV[0] eq "set")        { &mk_set;        }
if ($ARGV[0] eq "reg")        { &mk_reg;        }

if ($ARGV[0] eq "dup")        { &mk_dup;        }
if ($ARGV[0] eq "del")        { &mk_del;        }
if ($ARGV[0] eq "def")        { &mk_def;        }
if ($ARGV[0] eq "list.init")  { &mk_list_init;  }
if ($ARGV[0] eq "list.reinit")  { &mk_list_reinit;  }
if ($ARGV[0] eq "detrend")    { &mk_detrend;    }
if ($ARGV[0] eq "merge")      { &mk_merge;      }
if ($ARGV[0] eq "mkrough")    { &mk_mkrough;    }
if ($ARGV[0] eq "mksmooth")   { &mk_smooth;    }
if ($ARGV[0] eq "regimage")   { &mk_regimage;    }
if ($ARGV[0] eq "defringe")   { &mk_defringe;   }

if ($ARGV[0] eq "map")        { &mk_map;        }
if ($ARGV[0] eq "map.reg")    { &mk_map_reg;    }

# HTML cgibin commands
if ($ARGV[0] eq "htmldup")    { &mk_htmldup;    }
if ($ARGV[0] eq "htmldel")    { &mk_htmldel;    }
if ($ARGV[0] eq "htmldef")    { &mk_htmldef;    }
if ($ARGV[0] eq "htmlmod")    { &mk_htmlmod;    }
if ($ARGV[0] eq "htmlmodes")  { &mk_htmlmodes;  }
if ($ARGV[0] eq "htmlmaps")   { &mk_htmlmaps;   }
if ($ARGV[0] eq "htmlkeep")   { &mk_htmlkeep;   }
if ($ARGV[0] eq "htmlmapkeep"){ &mk_htmlmapkeep;}
if ($ARGV[0] eq "htmlconfig") { &mk_htmlconfig; }
if ($ARGV[0] eq "html1")      { &mk_html1;      }
if ($ARGV[0] eq "html2")      { &mk_html2;      }
if ($ARGV[0] eq "html3")      { &mk_html3;      }
# support commands
if ($ARGV[0] eq "dads")       { &mk_dads;       }
if ($ARGV[0] eq "dads.top")   { &mk_dads_top;   }
if ($ARGV[0] eq "eval")       { &mk_eval;       }

&escape ("invalid mkfring command $ARGV[0]");

############# define/redefine config ##############
sub mk_create {
    
    if ($ARGV[1] eq "run") { &mk_createrun; }
    if (@ARGV != 5) { &escape ("USAGE: $MKFRINGE create (camera) (run) (startdate) (stopdate)"); }
    
    # setting $run & $start here overrides default values loaded by set_globals()
    $camera = $ARGV[1];
    $run    = $ARGV[2];
    $start  = $ARGV[3];
    $stop   = $ARGV[4];

    if (0) {
	# set current run id:
	system ("mkrun sys camera.mkfringe $camera");
	if ($?) { &escape ("can't define camera: error in mkrun"); }
    
	# set current camera:
	system ("mkrun sys runid.mkfringe $run");
	if ($?) { &escape ("can't define run: error in mkrun"); }
    }

    # reset values for the directories, etc.
    $oldenv = $tmpenv;
    &elixir_config (split (" ", "-run $run -camera $camera"));
    unlink ($oldenv);

    # create the new detdir (& subdirectories?)
    $file = mkfiles ("detdir");
    if (! -d $file) {
	if (! mkdir ($file, 0777)) {
	    &escape ("can't create detdir $file");
	}
    }
    ($tmp, $tmp, $mode) = &load_dates;
    &save_dates ($start, $stop, $mode);

    # create run-specific config file
    @list = ();
    for ($i = 0; $i < @filt; $i++) {
	$line = stconfig ("$run $type[$i] $filt[$i] 0 $start $stop init", "all");
	@list = (@list, $line);
    }
    save_config (@list);
    
    &goodbye;
}

############# define/redefine config ##############
sub mk_createrun {
    
    if (@ARGV != 3) { &escape ("USAGE: $MKFRINGE create run (run)"); }
    if ($ARGV[1] ne "run") { &escape ("USAGE: mkdetrend create run (run)"); }
    
    # setting $run & $start here overrides default values loaded by set_globals()
    $run    = $ARGV[2];
    $answer = `mkrun run $run`;
    if ($?) { &escape ("run $run not defined, use 'mkrun'"); }
    ($newrun, $start, $stop, $camera) = split (" ", $answer);
    if ($run ne $newrun) { &escape ("inconsistent answer from mkrun run $run"); }

    # reset values for the directories, etc.
    $oldenv = $tmpenv;
    &elixir_config (split (" ", "-run $run -camera $camera"));
    unlink ($oldenv);

    # create the new detdir (& subdirectories?)
    $file = mkfiles ("detdir");
    if (! -d $file) {
	if (! mkdir ($file, 0777)) {
	    &escape ("can't create detdir $file");
	}
    }
    ($tmp, $tmp, $mode) = &load_dates;
    &save_dates ($start, $stop, $mode);

    # create run-specific config file
    @list = ();
    for ($i = 0; $i < @filt; $i++) {
	$line = stconfig ("$run $type[$i] $filt[$i] 0 $start $stop init", "all");
	@list = (@list, $line);
    }
    save_config (@list);
    
    &goodbye;
}

############# change current run ##############
sub mk_config {
    
    if (@ARGV != 3) { &escape ("USAGE: $MKFRINGE config (camera) (run)"); }    

    $camera = $ARGV[1];
    $run    = $ARGV[2];

    # set current run id:
    system ("mkrun sys camera.mkfringe $camera");
    if ($?) { &escape ("can't define camera: error in mkrun"); }
    
    # set current run id:
    system ("mkrun sys runid.mkfringe $run");
    if ($?) { &escape ("can't define run: error in mkrun"); }
    
    &goodbye;
}

############# init ##############
sub mk_init {
    
    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE run"); }

    system "$MKFRINGE list.init\n";
    system "$MKFRINGE detrend\n";
    system "$MKFRINGE merge\n";
    &goodbye;
}

############# main run ##############
sub mk_run {
    
    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE run"); }
    
    system "$MKFRINGE mkrough";
    system "$MKFRINGE defringe";
    system "$MKFRINGE merge";
    
    &goodbye;
}

############# main run ##############
sub mk_reg {
    
    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE reg"); }
    
    system "$MKFRINGE mksmooth";
    system "$MKFRINGE regimage";
    
    &goodbye;
}

############# show current state ##############
sub mk_state {
    
    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE state"); }
    
    ($start, $stop, $mode) = &load_dates;

    print STDOUT "CAMERA    $camera\n";
    print STDOUT "RUN       $run\n";
    print STDOUT "START     $start\n";
    print STDOUT "STOP      $stop\n";
    print STDOUT "MODE      $mode\n";
    
    @list = &load_config;
    if (@list == 0) { &escape ("$MKFRINGE not configured"); }

    for ($i = 0; $i < @list; $i++) {
	printf STDOUT "%3d %s\n", $i, $list[$i];
    }
    &goodbye;
}

############# show existing runs ##############
sub mk_list_runs {
    
    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE list.runs"); }
    
    system ("ls $root");
    &goodbye;
}

############# create config list ##############
sub mk_mkconfig {
    
    # create mkfringe config file from existing date entries
    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE mkconfig"); }
    
    # if new run, need to create the new detdir
    $file = mkfiles ("detdir");
    if (! -d $file) {
	if (! mkdir ($file, 0777)) {
	    &escape ("can't create detdir $file");
	}
    }

    ($start, $stop, $mode) = &load_dates;
    if (($start eq "") || ($stop eq "")) { &escape ("dates are not defined: use '$MKFRINGE config'"); }

    # create run-specific config file
    @list = ();
    for ($i = 0; $i < @filt; $i++) {
	$line = stconfig ("$run $type[$i] $filt[$i] 0 $start $stop init", "all");
	@list = (@list, $line);
    }
    save_config (@list);
    &goodbye;
}

############## duplicate config ###############
sub mk_dup {
    
    if (@ARGV != 2) { &escape ("USAGE: $MKFRINGE dup (config)"); }
    
    $key = $ARGV[1];
    @list = load_config ();
    
    # look for entry that matches requested config.ver
    @match = ();
    for ($i = 0; $i < @list; $i++) {
	$config = gtconfig ($list[$i], "config");
	if ($key eq $config) { @match = (@match, $i); }
    }
    if (@match == 0) { &escape ("config.ver $key not found"); }
    
    # create new config version based on config version # 0
    $Nnew = @match;
    $old = $list[$match[0]];
    $new = stconfig ($old, "version", $Nnew);
    @list = (@list, $new);
    save_config (@list);
    
    # now we need to duplicate all of the reference files from the first config 
    &goodbye;
}

############## cleanup config ###############
sub mk_cleanup {
    
    if ((@ARGV != 1) && (@ARGV != 2)) { &escape ("USAGE: $MKFRINGE cleanup [mode]"); }

    @list = load_config ();

    $detdir = mkfiles ("detdir");
    open (CF, ">$detdir/clean.fail");

    $Nmiss = 0;
    $Nfail = 0;
    $Ngood = 0;

    $mode = "partial"; 
    if (@ARGV == 2) { $mode = $ARGV[1]; }

    if (($mode ne "partial") && ($mode ne "total")) { &escape ("invalid cleanup mode $mode: use 'partial' or 'total'"); }

    foreach $confline (@list) {
	$status = gtconfig ($confline, "status");
	if ($status ne "done") { next; }

	print STDERR "deleting files from $confline\n";
	$confline = stconfig ($confline, "status", "running.clean");
	save_config (@list);

	foreach $ccd (@ccds) { 
	    @dlist = ();

	    # delete these specific files:
	    push @dlist, &mknames ("frfile", $confline, $ccd); 
	    push @dlist, &mknames ("smfile", $confline, $ccd); 

	    # delete file, if it exists
	    foreach $file (@dlist) { 
		if (! -e $file) { $Nmiss ++; next; }
		if (!unlink $file) { $Nfail ++; print CF "$file\n"; next; }
		$Ngood ++;
	    }
	}

	# delete final MEF image
	@dlist = ();
	push @dlist, &mknames ("mef", $confline); 

	# delete proc defringe, medbin images
	$name = &mknames ("detrend", $confline);
	open (FILE, $name);
	@deflist = <FILE>;
	close (FILE);

	$proc = &mkfiles ("proc");
	foreach $line (@deflist) {
	    ($tmp, $root) = split (" ", $line);
	    push @dlist, <$proc/$root.med/*.fits>;
	    push @dlist, <$proc/$root.def/*.fits>;
	}	    

	# delete file, if it exists
	foreach $file (@dlist) { 
	    if (! -e $file) { $Nmiss ++; next; }
	    if (!unlink $file) { $Nfail ++; print CF "$file\n"; next; }
	    $Ngood ++;
	}

	$confline = stconfig ($confline, "status", "clean");
	save_config (@list);
    }
    close (CF);

    print STDERR "$Ngood files deleted\n";
    print STDERR "$Nmiss files already removed\n";
    print STDERR "$Nfail files not deleted, see '$detdir/clean.fail'\n";

    &goodbye;
}



############## delete config ###############
sub mk_del {
    
    if (@ARGV != 2) { &escape ("USAGE: $MKFRINGE del (config.ver)"); }
    
    $key = $ARGV[1];
    @list = load_config ();
    
    # look for entry that matches requested config
    $match = -1;
    for ($i = 0; $i < @list; $i++) {
	$version = gtconfig ($list[$i], "version");
	if ($key eq $version) {
	    $match = $i;
	    last;
	}	
    }
    if ($match == -1) { &escape ("config.ver $key not found"); }
    
    # create new list without match:
    @newlist = ();
    for ($i = 0; $i < @list; $i++) {
	if ($i == $match) { next; }
	@newlist = (@newlist, $list[$i]);
    }
    
    save_config (@newlist);
    &goodbye;
    
}



############## define config ###############
sub mk_def {
    
    if (@ARGV != 4) { &escape ("USAGE: $MKFRINGE def (config.ver) (start) (stop)"); }
    
    $key   = $ARGV[1];
    $start = $ARGV[2];
    $stop  = $ARGV[3];
    
    @list = load_config ();
    
    # find specific config:
    $match = -1;
    for ($i = 0; $i < @list; $i++) {
	$version = gtconfig ($list[$i], "version");
	if ($key eq $version) {
	    $match = $i;
	}	
    }
    if (@match == -1) { &escape ("config.ver $key not found"); }
    
    $new = $list[$match];
    $new = stconfig ($new, "start", $start);
    $new = stconfig ($new, "stop", $stop);
    $list[$match] = $new;
    save_config (@list);

    &goodbye;
}



############## set state ###############
sub mk_set {
    
    if (@ARGV != 3) { &escape ("USAGE: $MKFRINGE set (config number) (state)"); }
    
    @list = load_config ();
    
    $key = $ARGV[1];
    $state = $ARGV[2];
    
    $new = stconfig ($list[$key], "status", $state);
    $list[$key] = $new;
    
    save_config (@list);
    
    &goodbye;
}

############## init run ###############


# get valid images, create static lists
sub mk_list_init {
    
    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE list.init"); }
    
    # create necessary directories
    foreach $name ("html", "proc", "fringe") {
	$dir = mkfiles ($name);
	if (! -e $dir) {
	    print STDERR "making $dir\n";
	    $status = mkdir ("$dir", 0777);
	    if (!$status) { die "can't create directory $dir\n"; }
	}
    }
    @list = load_config ();
    
    # create elixir input list, set status to 'running.init'
    $file = mkfiles ("list");
    open (FILE, ">$file");
    foreach $confline (@list) {
	$status = gtconfig ($confline, "status");
	if ($status eq "skip.init") { next; }

	$line = gtconfig ($confline, "elixir");
	print FILE "$line\n";
	$confline = stconfig ($confline, "status", "running.init");
    }
    close (FILE);
    save_config (@list);
    
    vsystem ("elixir -D DETREND_DIR $det -D mode fringe1 $file");
    vsystem ("$MKFRINGE eval $file init");

    open (FILE, "$file.eval");
    @eval = <FILE>;
    close (FILE);

    # there is an entry in @eval for each @list with status of "running.init"
    $N = 0;
    foreach $confline (@list) {
	$status = gtconfig ($confline, "status");
	if ($status ne "running.init") { next; }
	@words = split (" ", $eval[$N]);
	if ($words[-1] == 0) { $status = "done.init"; }
	if ($words[-1] == 1) { $status = "fail.init"; }
	if ($words[-1] == 2) { $status = "fail.init"; }
	if ($words[-1] == 3) { $status = "not.available"; }
	$confline = stconfig ($confline, "status", $status);
	$N++;
    }
    save_config (@list);
    &goodbye;
}

# is this segment still used?
# run mode.fringe1, skipping image selection
sub mk_list_reinit {
    
    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE list.init"); }
    
    # create necessary directories
    foreach $name ("html", "proc", "fringe") {
	$dir = mkfiles ($name);
	mkdir ("$dir", 0777);
    }
    
    @list = load_config ();
    
    # create elixir input list, set status to 'running.init'
    $file = mkfiles ("list");
    open (FILE, ">$file");
    foreach $confline (@list) {
	$status = gtconfig ($confline, "status");
	if ($status eq "skip.init") { next; }

	$line = gtconfig ($confline, "elixir");
	print FILE "$line\n";
	$confline = stconfig ($confline, "status", "running.reinit");
    }
    close (FILE);
    save_config (@list);
    
    vsystem ("elixir -D DETREND_DIR $det -D mode fringe1 -D global.pending master.lists $file");
    vsystem ("$MKFRINGE eval $file init");

    open (FILE, "$file.eval");
    @eval = <FILE>;
    close (FILE);

    # there is an entry in @eval for each @list with status of "running.init"
    $N = 0;
    foreach $confline (@list) {
	$status = gtconfig ($confline, "status");
	if ($status ne "running.reinit") { next; }
	@words = split (" ", $eval[$N]);
	if ($words[-1] == 0) { $status = "done.init"; }
	if ($words[-1] == 1) { $status = "fail.init"; }
	if ($words[-1] == 2) { $status = "fail.init"; }
	if ($words[-1] == 3) { $status = "not.available"; }
	$confline = stconfig ($confline, "status", $status);
	$N++;
    }
    save_config (@list);
    &goodbye;
}


############## detrend ###############
sub mk_detrend {
    
    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE detrend"); }

    @list = load_config ();
    
    # create namelist for those with appropriate status
    $Nrun = 0;
    $file = mkfiles ("list");
    system ("rm -f $file");

    foreach $confline (@list) {
	$status = gtconfig ($confline, "status");
	if (($status ne "done.init") && ($status ne "modified") && ($status ne "detrend")) { next; }

	$Nrun ++;
	$detrend = mknames ("detrend", $confline);

	# merge lines from the "detrend" list to make elixir list
	system ("cat $detrend >> $file");
	
	# set status for these config entries
	$confline = stconfig ($confline, "status", "running.detrend");
    }
    save_config (@list);
    
    if ($Nrun == 0) { &goodbye; }
    
    vsystem ("elixir -D DETREND_DIR $det -D mode fringe2 $file"); 
    vsystem ("$MKFRINGE eval $file detrend");

    open (FILE, "$file.eval");
    @eval = <FILE>;
    close (FILE);

    $N = 0;
    foreach $confline (@list) {
	$status = gtconfig ($confline, "status");
	if ($status ne "running.detrend") { next; }

	$detrend = mknames ("detrend", $confline);
	open (FILE, "$detrend");
	@testlist = <FILE>;
	close (FILE);
	
	# each entry in $detrend must succeed for config to succeed
	$status = "done.detrend";
	for ($i = 0; $i < @testlist; $i++) {
	    @words = split (" ", $eval[$N]);
	    if ($words[-1] == 1) { $status = "fail.detrend"; }
	    if ($words[-1] == 2) { $status = "fail.detrend"; }
	    $N++;
	}
	$confline = stconfig ($confline, "status", $status);

	$detrend = mknames ("detrend", $confline);
	$master = mknames ("master", $confline);
	# update master list (2 -> 0, 3 -> 1)
	vsystem ("fr.mklists -master $master $detrend");
    }
    save_config (@list);

    &goodbye;
}

############## map run ###############
sub mk_map {
    
    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE map"); }

    @list = load_config ();
    
    # this can be parallelized with elixir later...
    foreach $confline (@list) {
	$status = gtconfig ($confline, "status");
	if (($status ne "map") && ($status ne "modified.map")) { next; }
	$Nrun ++;
	$confline = stconfig ($confline, "status", "running.map");
	save_config (@list);

	$maplist  = mknames ("maplist",  $confline);
	$modelist = mknames ("modelist", $confline);
	$modefits = mknames ("modefits", $confline);

	$modesjpg = mknames ("modesjpg", $confline);
	$residjpg = mknames ("residjpg", $confline);
	$inmapjpg = mknames ("inmapjpg", $confline);

	vsystem ("fr.mkmodes $maplist $modefits $modelist");
	if ($status) { 
	    $confline = stconfig ($confline, "status", "fail.map");
	    save_config (@list);
	    next;
	}
	vsystem ("fr.modestats $maplist $modefits $modelist $modesjpg $residjpg $inmapjpg");
	if ($status) { 
	    $confline = stconfig ($confline, "status", "fail.map");
	    save_config (@list);
	    next;
	}
	$confline = stconfig ($confline, "status", "done.map");
	save_config (@list);
    }
    &goodbye;
}

############## map reg ###############
sub mk_map_reg {
    
    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE map.reg"); }
    
    @list = load_config ();
    
    # this can be parallelized with elixir later...
    foreach $confline (@list) {
	$status = gtconfig ($confline, "status");
	if ($status ne "accept.map") { next; }
	$Nrun ++;
	$confline = stconfig ($confline, "status", "register.map");
	save_config (@list);

	$modelist = mknames ("modelist", $confline);
	$modefits = mknames ("modefits", $confline);
	$modesave = mknames ("modesave", $confline);
	$ID     = gtconfig ($confline, "ID");
	$filter = gtconfig ($confline, "filter");
	$from   = gtconfig ($confline, "from");
	$to     = gtconfig ($confline, "to");

	vsystem ("fr.modesave $modefits $modelist $modesave $from $to $filter");
	vsystem ("detregister $modesave -label elixir -ID $ID");
	$confline = stconfig ($confline, "status", "done.map.reg");
	save_config (@list);
    }
    &goodbye;
}

############## mkrough run ###############
sub mk_mkrough {
    
    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE mkrough"); }
    
    @list = load_config ();
    
    # create namelist for those with appropriate status
    $Nrun = 0;
    $file = mkfiles ("list");
    open (FILE, ">$file");
    foreach $confline (@list) {
	$status = gtconfig ($confline, "status");
	if (($status ne "done.prep") && ($status ne "mkrough") && ($status ne "modified")) { next; }

	$Nrun ++;

	# one line for each config.ver.ccd:
	for ($j = 0; $j < $Nccd; $j++) {
	    $line = gtconfig ($confline, "chiprun", $ccds[$j]);
	    print FILE "$line\n";
	}
	$confline = stconfig ($confline, "status", "running.mkrough");

	$CONFIG  = mknames ("config", $confline);

	# extract the selected subset of detrend images from master & statlist to sublist
	vsystem ("fr.mklists -subset  $CONFIG.master $CONFIG.med.statlist $CONFIG.med.sublist");
	if ($?) { &escape ("failure running fr.mklists -subset"); }

	# extract the selected subset of defringed images from master & statlist to sublist
	vsystem ("fr.mklists -subset  $CONFIG.master $CONFIG.def.statlist $CONFIG.def.sublist");
	if ($?) { &escape ("failure running fr.mklists -subset"); }

	# calculate fit parameters based on subset
	vsystem ("fr.frstats -fitpars $CONFIG.med.sublist $CONFIG.fitpar");
	if ($?) { &escape ("failure running fr.frstats -fitpars"); }

	# calculate optimal per-image fringe statistics based on fit parameters
	vsystem ("fr.frstats -frstats $CONFIG.med.statlist $CONFIG.fitpar $CONFIG.med.imstats");
	if ($?) { &escape ("failure running fr.frstats -frstats"); }

	# calculate per-image residual fringe stats 
	vsystem ("fr.frstats -dfstats $CONFIG.def.statlist $CONFIG.fitpar $CONFIG.def.imstats");
	if ($?) { &escape ("failure running fr.frstats -dfstats"); }

	# assemble master fringe statistic file needed by web tools
	vsystem ("fr.mklists -imstats $CONFIG.master $CONFIG.med.imstats $CONFIG.def.imstats $CONFIG.datlist $CONFIG.imstats");
	if ($?) { &escape ("failure running fr.mklists -imstats"); }

    }
    close (FILE);
    save_config (@list);

    if ($Nrun == 0) { &goodbye; }
    
    vsystem ("elixir -D DETREND_DIR $det -D mode fringe4 $file");
    vsystem ("$MKFRINGE eval $file mkrough");

    open (FILE, "$file.eval");
    @eval = <FILE>;
    close (FILE);

    # there is one entry in @eval for each ccd for each confline:
    $N = 0;
    foreach $confline (@list) {
	$status = gtconfig ($confline, "status");
	if ($status ne "running.mkrough") { next; }

	# each chip must succeed for config to succeed
	$status = "done.mkrough";
	for ($j = 0; $j < $Nccd; $j++) {
	    @words = split (" ", $eval[$N]);
	    if ($words[-1] == 1) { $status = "fail.mkrough"; }
	    if ($words[-1] == 2) { $status = "fail.mkrough"; }
	    $N++;
	}
	$confline = stconfig ($confline, "status", $status);
    }
    save_config (@list);
    
    &goodbye;
}

############## defringe ###############
sub mk_defringe {
    
    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE defringe"); }

    @list = load_config ();
    
    # create namelist for those with appropriate status
    $Nrun = 0;
    $file = mkfiles ("list");
    system ("rm $file");

    foreach $confline (@list) {
	$status = gtconfig ($confline, "status");
	if (($status ne "done.mkrough") && ($status ne "defringe")) { next; }

	$Nrun ++;
	$defringe = mknames ("defringe", $confline);
	
	# merge lines from the "defringe" list to make elixir list
	system ("cat $defringe >> $file");
	
	$confline = stconfig ($confline, "status", "running.defringe");
    }
    save_config (@list);
    
    if ($Nrun == 0) { &goodbye; }
    
    vsystem ("elixir -D DETREND_DIR $det -D mode fringe3 $file"); 
    vsystem ("$MKFRINGE eval $file defringe");

    open (FILE, "$file.eval");
    @eval = <FILE>;
    close (FILE);

    $N = 0;
    foreach $confline (@list) {
	$status = gtconfig ($confline, "status");
	if ($status ne "running.defringe") { next; }

	$defringe = mknames ("defringe", $confline);
	open (FILE, "$defringe");
	@testlist = <FILE>;
	close (FILE);
	
	# each entry in $defringe must succeed for config to succeed
	$status = "done.defringe";
	for ($i = 0; $i < @testlist; $i++) {
	    @words = split (" ", $eval[$N]);
	    if ($words[-1] == 1) { $status = "fail.defringe"; }
	    if ($words[-1] == 2) { $status = "fail.defringe"; }
	    $N++;
	}
	$confline = stconfig ($confline, "status", $status);
    }
    save_config (@list);
    &goodbye;
}



############## merge run ###############
sub mk_merge {
    
    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE merge"); }

    @list = load_config ();
    
    foreach $confline (@list) {
	$status = gtconfig ($confline, "status");
	if (($status ne "done.detrend") && ($status ne "done.defringe") && ($status ne "merge")) { next; }

	$confline = stconfig ($confline, "status", "running.merge");
	save_config (@list);

	$CONFIG  = mknames ("config", $confline);
	$VERSION = gtconfig ($confline, "version");
	$HTML    = mkfiles ("html");

	vsystem ("fr.mklists -subset  $CONFIG.master $CONFIG.med.statlist $CONFIG.med.sublist");
	if ($?) { &escape ("failure running fr.mklists -subset"); }

	vsystem ("fr.mklists -subset  $CONFIG.master $CONFIG.def.statlist $CONFIG.def.sublist");
	if ($?) { &escape ("failure running fr.mklists -subset"); }

	vsystem ("fr.frstats -fitpars $CONFIG.med.sublist $CONFIG.fitpar");
	if ($?) { &escape ("failure running fr.frstats -fitpars"); }

	vsystem ("fr.frstats -plotstats $CONFIG.med.statlist $CONFIG.fitpar $CONFIG.stats.png");
	if ($?) { &escape ("failure running fr.frstats -plotstats"); }

	vsystem ("fr.frstats -frstats $CONFIG.med.statlist $CONFIG.fitpar $CONFIG.med.imstats");
	if ($?) { &escape ("failure running fr.frstats -frstats"); }

	vsystem ("fr.frstats -dfstats $CONFIG.def.statlist $CONFIG.fitpar $CONFIG.def.imstats");
	if ($?) { &escape ("failure running fr.frstats -dfstats"); }

	vsystem ("fr.mklists -imstats $CONFIG.master $CONFIG.med.imstats $CONFIG.def.imstats $CONFIG.datlist $CONFIG.imstats");
	if ($?) { &escape ("failure running fr.mklists -imstats"); }

	$file = `head -1 $CONFIG.frlist`; chop ($file);
	if (-e "$file") { 
	    vsystem ("fr.jpegs $CONFIG.frlist $CONFIG.medbin.jpg $CONFIG.tenbin.jpg 0.02");
	    if ($?) { &escape ("failure running fr.jpegs"); }
	    vsystem ("fr.mkhtml -imstats $CONFIG.medbin.jpg $HTML");
	    if ($?) { &escape ("failure running fr.mkhtml -jpgmain"); }
	    vsystem ("fr.mkhtml -imstats $CONFIG.tenbin.jpg $HTML");
	    if ($?) { &escape ("failure running fr.mkhtml -jpgmain"); }
	} else {
	    print STDOUT "no fits file $file\n";
	}

	vsystem ("fr.mkhtml -imstats $CONFIG.imstats $HTML");
	if ($?) { &escape ("failure running fr.mkhtml -imstats"); }

	vsystem ("fr.mkhtml -imstats $CONFIG.stats.png $HTML");
	if ($?) { &escape ("failure running fr.mkhtml -imstats"); }

	vsystem ("fr.mkhtml -jpglist $CONFIG.med.medbin.list $HTML $VERSION.med.medbin");
	if ($?) { &escape ("failure running fr.mkhtml -jpglist"); }

	vsystem ("fr.mkhtml -jpglist $CONFIG.med.tenbin.list $HTML $VERSION.med.tenbin");
	if ($?) { &escape ("failure running fr.mkhtml -jpglist"); }

	vsystem ("fr.mkhtml -jpglist $CONFIG.def.medbin.list $HTML $VERSION.def.medbin");
	if ($?) { &escape ("failure running fr.mkhtml -jpglist"); }

	vsystem ("fr.mkhtml -jpglist $CONFIG.def.tenbin.list $HTML $VERSION.def.tenbin");
	if ($?) { &escape ("failure running fr.mkhtml -jpglist"); }

	print STDOUT "CONFIG: $CONFIG.def.imstats\n";

	if (-e "$CONFIG.def.imstats") { 
	    $confline = stconfig ($confline, "status", "done.merge");
	} else {
	    $confline = stconfig ($confline, "status", "done.prep");
	}
	save_config (@list);
    }

    &goodbye;
}

############## reg run ###############
sub mk_smooth {
    
    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE mksmooth"); }
    
    @list = load_config ();
    
    # create namelist for those with appropriate status
    $Nrun = 0;
    $file = mkfiles ("list");
    open (FILE, ">$file");
    foreach $confline (@list) {
        $status = gtconfig ($confline, "status");
        if (($status ne "accepted") && ($status ne "smooth")) { next; }

        $Nrun ++;

        # one line for each config.ver.ccd:
        for ($j = 0; $j < $Nccd; $j++) {
            $line = gtconfig ($confline, "chiprun", $ccds[$j]);
            print FILE "$line\n";
        }
        $confline = stconfig ($confline, "status", "running.smooth");
    }
    close (FILE);
    save_config (@list);

    if ($Nrun == 0) { &goodbye; }
    
    vsystem ("elixir -D DETREND_DIR $det -D mode fringe4 -D global.pending mksmooth $file");
    vsystem ("$MKFRINGE eval $file smooth");

    open (FILE, "$file.eval");
    @eval = <FILE>;
    close (FILE);

    # there is one entry in @eval for each ccd for each confline:
    $N = 0;
    foreach $confline (@list) {
        $status = gtconfig ($confline, "status");
        if ($status ne "running.smooth") { next; }

        # each chip must succeed for config to succeed
        $status = "done.smooth";
        for ($j = 0; $j < $Nccd; $j++) {
            @words = split (" ", $eval[$N]);
            if ($words[-1] == 1) { $status = "fail.smooth"; }
            if ($words[-1] == 2) { $status = "fail.smooth"; }
            $N++;
        }
        $confline = stconfig ($confline, "status", $status);
    }
    save_config (@list);
    
    &goodbye;
}

############## reg run ###############
sub mk_regimage {
    
    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE regimage"); }
    
    @list = load_config ();
    
    # create directory for fhtool to work in
    $links = mkfiles ("links");
    if (! -e $links) { system ("mkdir -p $links"); }

    # create namelist for those with appropriate status
    foreach $confline (@list) {
	$status = gtconfig ($confline, "status");
	if (($status ne "done.smooth") && ($status ne "reg")) { next; }
	$confline = stconfig ($confline, "status", "running.reg");
	save_config (@list);

	$success = 1;
	$ID = gtconfig ($confline, "ID");

	$DBmode = `gconfig DETREND-DB-MODE`; chop $DBmode;
	$DBmode = "\U$DBmode\E";

	if ($DBmode eq "SPLIT") {
	    for ($j = 0; $j < $Nccd; $j++) {
		$file = mknames ("smfile", $confline, $ccds[$j]);
		$line = "detregister $file -label fringe-2.1 -ID $ID";
		$status = system ($line);
		if ($status) { 
		    print STDERR "error registering $file\n";
		    $success = 0;
		}
	    }
	    goto registered;
	}

	if ($DBmode eq "MEF") {
	    # empty link directory:
	    system ("rm -f $links/*.fits");

	    # make links 
	    foreach $ccd (@ccds) {
		$file = mknames ("smfile", $confline, $ccd);
		$link = mknames ("link", $confline, $ccd);
		symlink $file, $link;
	    }

	    # mef, register
	    $mef = mknames ("mef", $confline);
	    system ("rm -f $mef");

	    vsystem ("fhtool -P $links $mef");
	    if ($status) { $success = 0; }
	    vsystem ("detregister $mef -label fringe-2.1 -ID $ID");
	    if ($status) { $success = 0; }

	    # remove links
	    foreach $ccd (@ccds) {
		$link = mknames ("link", $confline, $ccd);
		unlink $link;
	    }
	    goto registered;
	}
	print STDERR "DB mode not defined?\n";
	$success = 0;

      registered:
	if ($success) {
	    $confline = stconfig ($confline, "status", "done");
	} else {
	    print STDERR "error registering $file\n"; 
	    $confline = stconfig ($confline, "status", "fail.reg");
	}
	save_config (@list);
    }
    &goodbye;
}

############## evaluate elixir run ###############
sub mk_eval {
    
    if (@ARGV != 3) { &escape ("USAGE: $MKFRINGE meval (file) (step)"); }
    
    $infile = $ARGV[1];
    $step = $ARGV[2];

    open (FILE, "$infile");
    @list = <FILE>;
    close (file);
    
    # load success fifo info:
    $file = `gconfig -D mode fringe1 global.success`; chop $file;
    open (FILE, "$file");
    @success = <FILE>;
    close (FILE);
    
    # load failure fifo info:
    $file = `gconfig -D mode fringe1 global.failure`; chop $file;
    open (FILE, "$file");
    @failure = <FILE>;
    close (FILE);
    
    # possible states:
    #   0 entry in success
    #   1 entry in failure
    #   2 entry missing   
    #   3 special case    
    
    $outfile = "$infile.eval";
    open (FILE, ">$outfile");
    foreach $list (@list) {

	# force lines to have only single spaces between words
	@words = split (" ", $list);
	$key = join (' ', @words);

	$state = 2;
      MCHECK: {
	  foreach $entry (@success) {
	      @words = split (" ", $entry);
	      $value = join (' ', @words);
	      if ($value =~ /$key/) { 
		  $state = 0;
		  last MCHECK;
	      }
	  }
	  
	  foreach $entry (@failure) {
	      @words = split (" ", $entry);
	      $value = join (' ', @words);
	      if ($value =~ /$key/) { 
		  $state = 1;
		  $level = $words[-1];
		  # SPECIAL CASES:
		  if (($step eq "init") && ($level eq "master.lists")) {
		      $state = 3;
		  }
		  last MCHECK;
	      }
	  }
	  
      }
	print FILE "$key $state\n";
    }
    close (FILE);
    &goodbye;
}

############## html duplicate ###############
sub mk_htmldup {
    
    if (@ARGV != 2) { &escape ("USAGE: $MKFRINGE htmldup (config)"); }
    
    $config = $ARGV[1];
    system ("$MKFRINGE dup $config");
    print STDOUT "<meta http-equiv=refresh content=\"0; url=$CGI/fr.elixir1?&elconf=$elconf\">\n";
    
    &goodbye;
}

############## html delete ###############
sub mk_htmldel {
    
    if (@ARGV != 2) { &escape ("USAGE: $MKFRINGE htmldel (config.ver)"); }
    
    $config = $ARGV[1];
    system ("$MKFRINGE del $config");
    print STDOUT "<meta http-equiv=refresh content=\"0; url=$CGI/fr.elixir1?&elconf=$elconf\">\n";
    
    &goodbye;
}

############## html define ###############
sub mk_htmldef {
    
    if (@ARGV != 2) { &escape ("USAGE: $MKFRINGE htmldef (config.ver)"); }
    
    $key = $ARGV[1];
    
    # find (config.ver) in list:
    
    @list = load_config ();
    
    $match = -1;
    for ($i = 0; $i < @list; $i++) {
	$version = gtconfig ($list[$i], "version");
	if ($key eq $version) {
	    $match = $i;
	    last;
	}
    }
    if ($match == -1) { &escape ("error: can't find config entry"); }
    
    # show the complete list for reference
    print STDOUT "<HEADER> <TITLE>Elixir Mkfringe Report</TITLE> </HEADER>\n";
    print STDOUT "<BODY BGCOLOR=#fff0e0 TEXT=#000000 LINK=#0000ff VLINK=#6600ff ALINK=#a0a0a0>\n";
    print STDOUT "<table border>\n";
    for ($i = 0; $i < @list; $i++) {
	$config  = gtconfig ($list[$i], "config");
	$version = gtconfig ($list[$i], "version");
	$status  = gtconfig ($list[$i], "status");
	$from    = gtconfig ($list[$i], "from");
	$to      = gtconfig ($list[$i], "to");
	print STDOUT "<tr><td> $version </td>\n";
	print STDOUT "<td> $from </td><td> $to </td>\n";
	print STDOUT "<td> <a href=$CGI/fr.elixir2?$version&elconf=$elconf> $status </a></td>\n";
	print STDOUT "<td> <a href=$CGI/fr.split?$config&elconf=$elconf>      split </a></td>\n";
	print STDOUT "<td> <a href=$CGI/fr.delete?$version&elconf=$elconf>   delete </a></td>\n";
	print STDOUT "<td> <a href=$CGI/fr.redef?$version&elconf=$elconf>  redefine </a></td>\n";
	print STDOUT "</tr>\n";
    }
    print STDOUT "</table></body><br><br>\n";
    
    $version = gtconfig ($list[$match], "version");
    $status  = gtconfig ($list[$match], "status");
    $from    = gtconfig ($list[$match], "from");
    $to      = gtconfig ($list[$match], "to");
    print STDOUT "redefining <b> $key: </b> <br>\n";    
    print STDOUT "<table border>\n";
    print STDOUT "<tr><td> $version </td>\n";
    print STDOUT "<td> $from </td><td> $to </td><td> $status </a></td>\n";
    print STDOUT "</tr></table>\n";
    
    
    # create a simple form for redefine:
    print STDOUT "<form method=post action=$CGI/fr.redefine?&elconf=$elconf>\n";
    print STDOUT "start: <input type=text value=$from name=start size=40 maxlength=40> <br>\n";
    print STDOUT "stop: <input type=text value=$to name=stop size=40 maxlength=40> <br>\n";
    print STDOUT "<input type=hidden name=config value=\"$key\">\n";
    print STDOUT "<input type=\"submit\" value=\"submit\"><input type=\"reset\" value=\"reset\">\n";
    print STDOUT "</form>\n";
    print STDOUT "</body>\n";
    
    &goodbye;
}

############## html modify ###############
sub mk_htmlmod {
    
    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE htmlmod"); }
    
    # images which are marked for exclusion are included in the 
    # environment variable as $WWW_image_NN -- NN = sequence number
    # in the master / defringe file

    $key = $ENV{'WWW_config'};
    $Nimage = $ENV{'WWW_Nimage'};
    
    @list = load_config ();

    $match = -1;
    for ($i = 0; $i < @list; $i++) {
	$version = gtconfig ($list[$i], "version");
	if ($key eq $version) {
	    $match = $i;
	    last;
	}
    }
    if ($match == -1) { &escape ("ERROR: can't find config entry"); }
    
    # change status entry in master list & $HTML.imstats
    $HTML    = mkfiles ("html");
    $imstat = "$HTML/$version.imstats";
    $master = mknames ("master", $list[$match]); 

    # load data from master list
    open (FILE, "$master");
    @master = <FILE>;
    close (FILE);
    if ($Nimage != @master) { &escape ("mis-match in image list lengths"); }

    # load data from imstats list
    open (FILE, "$imstat");
    @imstat = <FILE>;
    close (FILE);
    if ($Nimage != @imstat) { &escape ("mis-match in image list lengths"); }

    for ($i = 0; $i < @master; $i++) {
	chop ($master[$i]);
	chop ($imstat[$i]);
	($path, $root, $mode, $status) = split (" ", $master[$i]);
	$name = "WWW_image_$i";
	$newstatus = $status;
	if ($ENV{$name} eq "") { 
	    $hstatus = 0;
	    if (($status == 0) || ($status == 1)) { $newstatus = 0; }
	    if (($status == 2) || ($status == 3)) { $newstatus = 2; }
	} else {
	    $hstatus = 1;
	    if (($status == 0) || ($status == 1)) { $newstatus = 1; }
	    if (($status == 2) || ($status == 3)) { $newstatus = 3; }
	}	    
	$master[$i] = "$path $root $mode $newstatus";
	($line, $status) = $imstat[$i] =~ m|(\s*\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+)(\S)|;
	$imstat[$i] = "$line $hstatus";
    }

    # save master list
    open (FILE, ">$master");
    foreach $line (@master) { print FILE "$line\n"; }
    close (FILE);

    # save imstats list
    open (FILE, ">$imstat");
    foreach $line (@imstat) { print FILE "$line\n"; }
    close (FILE);

    print STDOUT "<meta http-equiv=refresh content=\"0; url=$CGI/fr.elixir2?$key&elconf=$elconf\">\n";
    
    # adjust the config file: convert status to 'modified'
    $list[$match] = stconfig ($list[$match], "status", "modified");
    save_config (@list);
    &goodbye;
    
}

############## html changes modes ###############
sub mk_htmlmodes {
    
    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE htmlmodes"); }
    
    # modes which are marked for exclusion are included in the 
    # environment variable as $WWW_mode_NN -- NN = sequence number

    $key = $ENV{'WWW_config'};
    $Nmode = $ENV{'WWW_Nmode'};
    
    @list = load_config ();

    $match = -1;
    for ($i = 0; $i < @list; $i++) {
	$version = gtconfig ($list[$i], "version");
	if ($key eq $version) {
	    $match = $i;
	    last;
	}
    }
    if ($match == -1) { &escape ("ERROR: can't find config entry"); }
    
    $modelist = mknames ("modelist", $list[$match]);
    open (FILE, "$modelist");
    @inlist = <FILE>;
    close (FILE);

    open (FILE, ">$modelist");
    for ($i = 0; $i < @inlist; $i++) {
	($N, $status) = split (" ", $inlist[$i]);
	if ($i < $Nmode) {
	    $name = "WWW_mode_$i";
	    $newstatus = $status;
	    if ($ENV{$name} eq "") { 
		$newstatus = 0;
	    } else {
		$newstatus = 1;
	    }	    
	} else {
	    $newstatus = 0;
	}
	print FILE "$i $newstatus\n";
    }
    close (FILE);

    print STDOUT "<meta http-equiv=refresh content=\"0; url=$CGI/fr.elixir2?$key&elconf=$elconf\">\n";
    
    # adjust the config file: convert status to 'modified'
    $list[$match] = stconfig ($list[$match], "status", "modified.map");
    save_config (@list);
    &goodbye;
}

############## html changes modes ###############
sub mk_htmlmaps {
    
    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE htmlmaps"); }
    
    # maps which are marked for inclusion are given in the 
    # environment variable as $WWW_mode_NN -- NN = sequence number

    $key = $ENV{'WWW_config'};
    $Nmaps = $ENV{'WWW_Nmaps'};
    
    @list = load_config ();

    $match = -1;
    for ($i = 0; $i < @list; $i++) {
	$version = gtconfig ($list[$i], "version");
	if ($key eq $version) {
	    $match = $i;
	    last;
	}
    }
    if ($match == -1) { &escape ("ERROR: can't find config entry"); }

    $maplist = mknames ("maplist", $list[$match]);
    open (FILE, "$maplist");
    @inlist = <FILE>;
    close (FILE);

    open (FILE, ">$maplist");
    for ($i = 0; $i < @inlist; $i++) {
	($Name, $status) = split (" ", $inlist[$i]);
	$name = "WWW_map_$i";
	$newstatus = $status;
	if ($ENV{$name} eq "") { 
	    $newstatus = 0;
	} else {
	    $newstatus = 1;
	}	    
	print FILE "$Name $newstatus\n";
    }
    close (FILE);

    print STDOUT "<meta http-equiv=refresh content=\"0; url=$CGI/fr.elixir2?$key&elconf=$elconf\">\n";

    # adjust the config file: convert status to 'modified'
    $list[$match] = stconfig ($list[$match], "status", "modified.map");
    save_config (@list);
    &goodbye;
}

############## html accept ###############
sub mk_htmlkeep {
    
    if (@ARGV != 2) { &escape ("USAGE: $MKFRINGE htmlkeep (config.ver)"); }
    
    $key = $ARGV[1];
    @list = load_config ();
    
    $match = -1;
    for ($i = 0; $i < @list; $i++) {
	$version = gtconfig ($list[$i], "version");
	if ($key eq $version) {
	    $match = $i;
	    last;
	}
    }
    if ($match == -1) { &escape ("ERROR: can't find config entry"); }
    
    # adjust the config file: convert status to 'accepted'
    $list[$match] = stconfig ($list[$match], "status", "accepted");
    save_config (@list);
    
    print STDOUT "<meta http-equiv=refresh content=\"0; url=$CGI/fr.elixir1?&elconf=$elconf\">";
    &goodbye;
}

############## html accept ###############
sub mk_htmlmapkeep {
    
    if (@ARGV != 2) { &escape ("USAGE: $MKFRINGE htmlmapkeep (config.ver)"); }
    
    $key = $ARGV[1];
    @list = load_config ();
    
    $match = -1;
    for ($i = 0; $i < @list; $i++) {
	$version = gtconfig ($list[$i], "version");
	if ($key eq $version) {
	    $match = $i;
	    last;
	}
    }
    if ($match == -1) { &escape ("ERROR: can't find config entry"); }
    
    # adjust the config file: convert status to 'accepted'
    $list[$match] = stconfig ($list[$match], "status", "accept.map");
    save_config (@list);
    
    print STDOUT "<meta http-equiv=refresh content=\"0; url=$CGI/fr.elixir1?&elconf=$elconf\">";
    &goodbye;
}

############## html config ###############
sub mk_htmlconfig {
    
    if (@ARGV != 1) { &escape ("USAGE: mkdetrend htmlconfig"); }
    
    ## html headers
    print STDOUT "<HEADER> <TITLE>Elixir Mkdetrend Report</TITLE> </HEADER>\n";
    print STDOUT "<BODY BGCOLOR=#fff0f0 TEXT=#000000 LINK=#0000ff VLINK=#6600ff ALINK=#a0a0a0>\n";
    
    # create a simple form for redefine:
    print STDOUT "<form method=post action=$CGI/fr.newconfig?&elconf=$elconf>\n";
    if ($elconf) {
	print STDOUT "enter new config: <input type=text value=$elconf name=config size=40 maxlength=40> <br>\n";
    } else {
	print STDOUT "enter new config: <input type=text name=config size=40 maxlength=40> <br>\n";
    }
    print STDOUT "<input type=\"submit\" value=\"submit\"><input type=\"reset\" value=\"reset\">\n";
    print STDOUT "</form>\n";
    print STDOUT "</body>\n";
    
    &goodbye;
}

############## html level 1 ###############
sub mk_html1 {
    

    if (@ARGV != 1) { &escape ("USAGE: $MKFRINGE html1"); }
    
    @list = load_config ();
    
    ## html headers
    print STDOUT "<HEADER> <TITLE>Elixir Mkfringe Report</TITLE> </HEADER>\n";
    print STDOUT "<BODY BGCOLOR=#fff0f0 TEXT=#000000 LINK=#0000ff VLINK=#6600ff ALINK=#a0a0a0>\n";

    print STDOUT "<table border>\n";
    for ($i = 0; $i < @list; $i++) {
	$config  = gtconfig ($list[$i], "config");
	$version = gtconfig ($list[$i], "version");
	$from    = gtconfig ($list[$i], "from");
	$to      = gtconfig ($list[$i], "to");
	$status  = gtconfig ($list[$i], "status");
	print STDOUT "<tr><td> $version </td>\n";
	print STDOUT "<td> $from </td><td> $to </td>\n";
	print STDOUT "<td> <a href=$CGI/fr.elixir2?$version&elconf=$elconf> $status </a></td>\n";
	print STDOUT "<td> <a href=$CGI/fr.split?$config&elconf=$elconf> split </a></td>\n";
	print STDOUT "<td> <a href=$CGI/fr.delete?$version&elconf=$elconf> delete </a></td>\n";
	print STDOUT "<td> <a href=$CGI/fr.redef?$version&elconf=$elconf> redefine </a></td>\n";
	print STDOUT "</tr>\n";
    }
    
    print STDOUT "</table><br>\n";
    if ($elconf eq "") {
	print STDOUT "Current Config: <b>default</b><br>\n";
    } else {
	print STDOUT "Current Config: <b>$elconf</b><br>\n";
    }
    print STDOUT "<a href=$CGI/fr.config?&elconf=$elconf>Change Config</a></td>\n";
    print STDOUT "</body>\n";
    &goodbye;
    
}



############## html level 2 ###############
sub mk_html2 {
    
    if (@ARGV != 2) {
	print STDERR "USAGE: $MKFRINGE html2 (config.ver)\n";
	&goodbye; 
    }
    
    @list = load_config ();
    
    # config:  run.type.filter
    # key:     run.type.filter.ver
    # key.col  run.type.filter.ver.column
    # the words in config and key may consist of alphanumeric plus '_', '-'
    # the words in col number be digits

    # entry on line will be either config.ver (== key) or config.ver.col for sorting
    # grab just the key portion
    $status = "none";
    ($key) = $ARGV[1] =~ /([-\w]+\.[-\w]+\.[-\w]+\.[-\w]+)/; # (config.ver)
    $arg = $ARGV[1];
    
    # find appropriate config.ver entry:
    for ($i = 0; $i < @list; $i++) {
	$version = gtconfig ($list[$i], "version");
	if ($key eq $version) {
	    $confline = $list[$i];
	    $status = gtconfig ($confline, "status");
	    last;
	}
    }
    
    $from = gtconfig ($confline, "from");
    $to   = gtconfig ($confline, "to");
    print STDOUT "<HEADER> <TITLE>Elixir Mkfringe Report</TITLE> </HEADER>\n";
    print STDOUT "<BODY BGCOLOR=#fff0f0 TEXT=#000000 LINK=#0000ff VLINK=#6600ff ALINK=#a0a0a0>\n";
    print STDOUT "<center><table border>\n";
    print STDOUT "<tr><th>config   </th><th> from  </th><th> to  </th><th> status  </th></tr>\n";
    print STDOUT "<tr><td>$version </td><td> $from </td><td> $to </td><td> $status </th></tr>\n";
    print STDOUT "</table></center><hr>\n";
    
    if ($status eq "modified")    { flips_report ($arg, $confline, "modified"); }
    if ($status eq "accepted")    { flips_report ($arg, $confline, "accepted"); }
    if ($status eq "done.merge")  { flips_report ($arg, $confline, "merged"); }
    if ($status eq "done.prep")   { flips_report ($arg, $confline, "prepped"); }
    if ($status eq "done.reg")    { flips_report ($key, $confline, "registered"); }
    if ($status eq "done")        { flips_report ($key, $confline, "done"); }

    if ($status eq "done.map")     { map_report ($arg, $confline, "mapped"); }
    if ($status eq "modified.map") { map_report ($arg, $confline, "mapped"); }
    
    if ($status eq "none")              { $message = "not found"; }
    if ($status eq "init")              { $message = "initialized, not yet run."; }
    if ($status eq "not.available")     { $message = "has no images available for detrend creation."; }
    
    foreach $step (init, flips, norm, merge) {
	if ($status eq "running.$step") { $message = "running step $step"; }
	if ($status eq "fail.$step")    { $message = "failed step $step"; }
	if ($status eq "done.$step")    { $message = "has finished $step"; }
    }      

    print STDOUT "config <b> $key </b> $message <br>\n";
    
    $master = mknames ("master", $confline);
    print STDOUT "<table border>\n";
    open (FILE, "$master");
    while ($line = <FILE>) {
	chop ($line);
	@entry = split ("/", $line);
	$N = @entry - 1;
	print STDOUT "<tr><td>$entry[$N]</td></tr>\n";
    }
    print STDOUT "</table>\n";
    
    # print STDOUT "</body>\n";
    &goodbye;
    print STDOUT "<form method=get action=$CGI/fr.elixir1?&elconf=$elconf> <input type=submit value=\"back to config list\"></form>";
}



############## html level 3 ###############
sub mk_html3 {
    
    if (@ARGV != 3) {
	print STDERR "USAGE: $MKFRINGE html3 (entry.config.ver) (mode)\n";
	&goodbye; 
    }
    
    @list = load_config ();
    
    # extract the entry and key values from $ARGV[1]
    ($entry, $key) = $ARGV[1] =~ /(\d+)\Q.\E(.*)/;
    $mode = $ARGV[2];
    
    $status = "none";
    # find appropriate config.ver entry:
    for ($i = 0; $i < @list; $i++) {
	$version = gtconfig ($list[$i], "version");
	if ($key eq $version) {
	    $confline = $list[$i];
	    $status = gtconfig ($confline, "status");
	    last;
	}
    }
    
    print STDOUT "<HEADER> <TITLE>Elixir Mkfringe Report</TITLE> </HEADER>\n";
    print STDOUT "<BODY BGCOLOR=#fff0f0 TEXT=#000000 LINK=#0000ff VLINK=#6600ff ALINK=#a0a0a0>\n";
    
    if ($status eq "none")              { print STDOUT "config <b> $key </b> not found\n </body>\n"; &goodbye; }
    if ($status eq "init")              { print STDOUT "config <b> $key </b> initialized, not yet run\n </body>\n"; &goodbye; }
    if ($status eq "not.available")     { print STDOUT "config <b> $key </b> has no images available for detrend creation\n </body>\n"; &goodbye; }

    if ($status eq "done.prep")   { flips_entry ($key, $entry, $confline, $mode); }
    if ($status eq "done.merge")  { flips_entry ($key, $entry, $confline, $mode); }
    if ($status eq "accepted")    { flips_entry ($key, $entry, $confline, $mode); }
    if ($status eq "modified")    { flips_entry ($key, $entry, $confline, $mode); }
    if ($status eq "done.reg")    { flips_entry ($key, $entry, $confline, $mode); }
    if ($status eq "done")        { flips_entry ($key, $entry, $confline, $mode); }
    
    foreach $step (init, flips, norm, merge) {
	# print "step: $step, $status: $status\n";
	if ($status eq "running.$step") { print STDOUT "config <b> $key </b> running step $step \n </body>\n"; &goodbye; }
	if ($status eq "fail.$step")    { print STDOUT "config <b> $key </b> failed step $step\n </body>\n"; &goodbye; }
	
	if ($status eq "done.$step") {
	    print STDOUT "config <b> $key </b> has finished $step\n";
	    
	    # load image names from CCD 0 list:
	    $master = mknames ("master", $confline, "00");
	    print STDOUT "<table border>\n";
	    open (FILE, "$master");
	    while ($line = <FILE>) {
		chop ($line);
		@entry = split ("/", $line);
		$N = @entry - 1;
		print STDOUT "<tr><td>$entry[$N]</td></tr>\n";
	    }
	    print STDOUT "</table>\n";
	}
    }
    
    # print STDOUT "</body>\n";
    &goodbye;
}

$dadswww = "img";


############## html for dads ###############
sub mk_dads {
    
    if (@ARGV != 2) {
	print STDERR "USAGE: $MKFRINGE dads (config.ver)\n";
	&goodbye; 
    }
    
    @list = load_config ();
    
    # entry on line will be either config.ver (== key) or config.ver.col for sorting
    # grab just the key portion
    $status = "none";
    $arg = $ARGV[1];
    ($key) = $arg =~ /([-\w]+\.[-\w]+\.[-\w]+\.[-\w]+)/; # (config.ver)
    
    # find appropriate config.ver entry:
    for ($i = 0; $i < @list; $i++) {
	$version = gtconfig ($list[$i], "version");
	if ($key eq $version) {
	    $confline = $list[$i];
	    $status = gtconfig ($confline, "status");
	    last;
	}
    }
    
    print STDOUT "<HEADER> <TITLE>Elixir Mkfringe Report</TITLE> </HEADER>\n";
    print STDOUT "<BODY BGCOLOR=#ffffff TEXT=#000000 LINK=#0000ff VLINK=#6600ff ALINK=#a0a0a0>\n";

    # only print for config.ver entries which are ready
    if ($status ne "done") {
	&escape ("$version is not ready for release by Elixir");
    }

    # parse config entry and get data from appropriate files
    $from = gtconfig ($confline, "from");
    $to   = gtconfig ($confline, "to");
    open (STAT,   mknames ("stats", $confline));     @statdata = <STAT>;        close (STAT);
    open (MED,    mknames ("medbin", $confline));    @medndata = <MED>;         close (MED);
    open (TEN,    mknames ("tenbin", $confline));    @tenndata = <TEN>;         close (TEN);
    open (MASTER, mknames ("master", $confline, 0)); @mastdata = <MASTER>;      close (MASTER);
    
    $tmpname = mknames ("master", $confline, 0);

    # get stats from the stats & master files
    $Nkeep = 0;
    $Ncnt = 0;
    $Sigma = 0;
    $Nimage = @statdata;
    for ($i = 0; $i < $Nimage; $i++) {
	@tmpw = split (" ", $mastdata[$i]);
	@tmps = split (" ", $statdata[$i]);
	if ($tmpw[1]) { $Nkeep++; $Ncnt += $tmps[3]; $Sigma += $tmps[8]*$tmps[8]; }
    }
    $Sigma = sprintf "%5.3f", 100*sqrt ($Sigma/$Nkeep);

    print STDOUT "<center><table border>\n";
    print STDOUT "<tr><th>config   </th><th> from  </th><th> to </th></tr>\n";
    print STDOUT "<tr><td>$version </td><td> $from </td><td> $to</td></tr>\n";
    print STDOUT "</table></center><hr>\n";

    $imbin = mknames ("dads.imbin", $confline);
    print STDOUT "<table width=80%><tr><td valign=top>\n";
    print STDOUT "this config has been created by Elixir. <br>\n";
    print STDOUT "there are $Nimage images, $Nkeep used. <br>\n";
    print STDOUT "Total Counts: $Ncnt<br> r.m.s. median sigma: $Sigma% <br><br>\n";
    print STDOUT "</td><td align=right><img src=$imbin></td></tr></table>\n";
    
    print STDOUT "<center><b>Statistics on each available input image.</b></center>
  Time is in UT, light background means dawn, grey means dusk.\n";

    print STDOUT "<table bgcolor=#fff0e0 border=1 cellspacing=0 cellpadding=3>\n";
    print STDOUT "<tr >\n";
    print STDOUT "<th > image </th>\n";
    print STDOUT "<th > Date  </th>\n";
    print STDOUT "<th > Time  </th>\n";
    print STDOUT "<th > Mean  </a></th>\n";
    print STDOUT "<th > Sigma (raw) </a></th>\n";
    print STDOUT "<th > Sigma (clipped) </a></th>\n";
    print STDOUT "<th > Sigma (med) </a></th>\n";
    print STDOUT "<th > image </th>\n";
    print STDOUT "<th > used? </th></tr>\n";
    
    # sort the list by image seq number
    @order = ();
    for ($i = 0; $i < $Nimage; $i++) { @order = (@order, $i); }
    $col = 0;
    @entry = sort by_col @order;
    
    # create the image-by-image table lines
    for ($i = 0; $i < $Nimage; $i++) {
	$N = $entry[$i];
	
	@word = split (" ", $statdata[$N]);
	$used = $word[12];
	$dawn = $word[11];
	
	@tmpw = split (" ", $mastdata[$N]);
	$keep = $tmpw[1];
	
	@tmpw = split ("/", $medndata[$N]);
	$medname = $tmpw[-1];
	
	@tmpw = split ("/", $tenndata[$N]);
	$tenname = $tmpw[-1];
	
	print STDOUT "<tr><td> $word[0] </td><td> $word[1] </td>\n";
	if ($dawn) { print STDOUT "<td bgcolor=#cccccc> $word[2] </td>\n"; }
	else       { print STDOUT "<td> $word[2] </td>\n"; }
	print STDOUT "<td> $word[3] </td>\n";
	print STDOUT "<td> $word[4] </td><td> $word[6] </td><td> $word[8] </td>\n";
	print STDOUT "<td> <a border=0 href=$dadswww/$tenname> <img src=$dadswww/$medname></a></td>\n";
	if ($used) { print STDOUT "<td bgcolor=#00c000>yes</td>\n"; }
	else       { print STDOUT "<td bgcolor=#d00000>no</td>\n"; }
	print STDOUT "</tr>\n\n"; 	
    }
    
    print STDOUT "</table>\n";
    &goodbye;
}



############## html level 1 ###############
sub mk_dads_top {
    
    if (@ARGV != 1) {
	print STDERR "USAGE: $MKFRINGE dads.top\n";
	&goodbye; 
    }
    
    @list = load_config ();
    
    ## html headers
    print STDOUT "<HEADER> <TITLE>Elixir Mkfringe Report</TITLE> </HEADER>\n";
    print STDOUT "<BODY BGCOLOR=#fff0f0 TEXT=#000000 LINK=#0000ff VLINK=#6600ff ALINK=#a0a0a0>\n";

    print STDOUT "<table border>\n";
    for ($i = 0; $i < @list; $i++) {
	$config  = gtconfig ($list[$i], "config");
	$version = gtconfig ($list[$i], "version");
	$from    = gtconfig ($list[$i], "from");
	$to      = gtconfig ($list[$i], "to");
	$status  = gtconfig ($list[$i], "status");
	print STDOUT "<tr><td> $version </td>\n";
	print STDOUT "<td> $from </td><td> $to </td>\n";
	print STDOUT "<td> <a href=$version.html> $status </a></td>\n";
	print STDOUT "</tr>\n";
    }
    
    print STDOUT "</table></body>\n";
    &goodbye;
    
}

sub by_col { 
    @word = split (" ", $statdata[$a]); $va = $word[$col]; 
    @word = split (" ", $statdata[$b]); $vb = $word[$col]; 
    $va <=> $vb;
}

sub flips_report {
    
    $col = 0;
    ($config) = $_[0] =~ /([-\w]+\.[-\w]+\.[-\w]+)/;
    ($key)    = $_[0] =~ /([-\w]+\.[-\w]+\.[-\w]+\.[-\w]+)/; # (config.ver)

    # look for optional sort key (config.ver[.key])
    if ($_[0] =~ /$key.(\d+)/) {
	($col) = $_[0] =~ /$key.(\d+)/; 
    } else {
	$col = 0;
    }

    $line = $_[1];
    $message = $_[2];
    
    # list files: VERSION.imstats, VERSION.med.medbin.list, VERSION.med.tenbin.list, VERSION.def.medbin.list VERSION.def.tenbin.list

    $root = mknames ("htmlroot", $line);
    open (FILE, "$root.imstats");         @statdata = <FILE>; close (FILE);
    open (FILE, "$root.med.medbin.list"); @meddata = <FILE>; close (FILE);
    open (FILE, "$root.def.medbin.list"); @defdata = <FILE>; close (FILE);

# format of statdata file:
#  OBS     DATE        TIME        SKY      FLUX   FR1    dFR1    FR2   dFR2  stat keep
#  606363  2001-10-09  10:21:15.62 12455.7  20.76  246.9   84.0   N/A    N/A   1   1

    $Nkeep = 0;
    $Ncnt = 0;
    $Resid = 0;
    $fResid = 0;
    $Nimage = @statdata;
    for ($i = 0; $i < $Nimage; $i++) {
	@tmp = split (" ", $statdata[$i]);
	if ($tmp[9]) { $Nkeep++; $Ncnt += $tmp[3]; }
	$Resid  += $tmp[8];
	$fResid += $tmp[8] / $tmp[3];
    }
    if ($Nimage > 0) { $Resid = $Resid / $Nimage; }
    if ($Nimage > 0) { $fResid = $fResid / $Nimage; }
    $Resid = sprintf "%7.3f", $Resid;
    $fResid = sprintf "%7.3f", $fResid;

    # $imbin = mknames ("dads.imbin", $line);
    print STDOUT "<table width=100%><tr><td valign=top>\n";
    print STDOUT "this config has been $message. <br>\n";
    print STDOUT "there are $Nimage images, $Nkeep used. <br>\n";
    print STDOUT "Total Counts: $Ncnt<br>\n";
    print STDOUT "Median residual scatter: $Resid <br>\n";
    print STDOUT "Median fractional residual: $fResid <br><br>\n";
    print STDOUT "you have the following choices: <br>\n";
    print STDOUT "<a href=$CGI/fr.elixir1?&elconf=$elconf> <b> return to top level </b><br></a>";
    print STDOUT "<a href=$CGI/fr.split?$config&elconf=$elconf> <b> split config </b><br></a>";
    print STDOUT "<a href=$CGI/fr.accept?$key&elconf=$elconf> <b> accept config </b><br></a></td>";
    if (-e "$root.medbin.jpg") { 
	@tmpw = split ("/", "$root.medbin.jpg");
	$imname = "$www/$tmpw[-1]";
	print STDOUT "<td align=right><img width=100% src=$imname></td>\n";
    }
    print STDOUT "</tr></table>\n";

    print STDOUT "<form method=post action=$CGI/fr.modify?&elconf=$elconf>\n";
    print STDOUT "<center><b>Statistics on each available input image.</b></center>\n";
    print STDOUT "Time is in UT. Click on the column heading to sort by that entry\n";

    print STDOUT "<table bgcolor=#fff0e0 border=1 cellspacing=0 cellpadding=3>\n";
    print STDOUT "<tr bgcolor=#00aaaa>\n";
    print STDOUT "<th > <a href=$CGI/fr.elixir2?$key.0&elconf=$elconf> image </a></th>\n";
    print STDOUT "<th > Date </th>\n";
    print STDOUT "<th > Time </th>\n";
    print STDOUT "<th > <a href=$CGI/fr.elixir2?$key.3&elconf=$elconf> Sky </a></th>\n";
    print STDOUT "<th > <a href=$CGI/fr.elixir2?$key.4&elconf=$elconf> Flux </a></th>\n";
    print STDOUT "<th > <a href=$CGI/fr.elixir2?$key.5&elconf=$elconf> Fringe </a></th>\n";
    print STDOUT "<th > <a href=$CGI/fr.elixir2?$key.6&elconf=$elconf> dFringe </a></th>\n";
    print STDOUT "<th > <a href=$CGI/fr.elixir2?$key.7&elconf=$elconf> Resid </a></th>\n";
    print STDOUT "<th > <a href=$CGI/fr.elixir2?$key.8&elconf=$elconf> dResid </a></th>\n";
    print STDOUT "<th > F image </th>\n";
    print STDOUT "<th > R image </th>\n";
    print STDOUT "<th > used? </th>\n";
    print STDOUT "<th > keep? </th></tr>\n\n";
    
    @order = ();
    for ($i = 0; $i < $Nimage; $i++) { @order = (@order, $i); }
    
    @entry = sort by_col @order;
    
    for ($i = 0; $i < $Nimage; $i++) {
	$N = $entry[$i];
	
	@word = split (" ", $statdata[$N]);
	$used = $word[9];
	$keep = $word[10];
	
	@tmpw = split ("/", $meddata[$N]);
	$medname = $tmpw[-1];
	@tmpw = split ("/", $defdata[$N]);
	$defname = $tmpw[-1];
	
	print STDOUT "<tr><td> <a href=$CGI/fr.elixir3?$N.$key&med&elconf=$elconf> $word[0] </a></td><td> $word[1] </td>\n";
	print STDOUT "<td> $word[2] </td>\n"; 
	print STDOUT "<td> $word[3] </td>\n";
	print STDOUT "<td> $word[4] </td>\n";
	print STDOUT "<td> $word[5] </td>\n";
	print STDOUT "<td> $word[6] </td>\n";
	print STDOUT "<td> $word[7] </td>\n";
	print STDOUT "<td> $word[8] </td>\n";
	print STDOUT "<td> <a border=0 href=$CGI/fr.elixir3?$N.$key&med&elconf=$elconf> <img src=$www/$medname></a></td>\n";
	if ("$defname" ne "") {
	    print STDOUT "<td> <a border=0 href=$CGI/fr.elixir3?$N.$key&def&elconf=$elconf> <img src=$www/$defname></a></td>\n";
	} else {
	    print STDOUT "<td> N/A </td>\n";
	}
	if ($used) { print STDOUT "<td>yes</td>\n"; }
	else       { print STDOUT "<td>no</td>\n"; }
	if ($keep) { print STDOUT "<td bgcolor=#00c000><input type=checkbox checked name=image.$N value=$N size=1></td></tr>\n\n"; }
	else       { print STDOUT "<td bgcolor=#d00000><input type=checkbox name=image.$N value=$N size=1></td></tr>\n\n"; }	
	
    }
    
    print STDOUT "</table>\n";
    print STDOUT "<input type=hidden    name=Nimage value=\"$Nimage\">\n";
    print STDOUT "<input type=hidden    name=config value=\"$key\">\n";
    print STDOUT "<input type=submit    value=\"apply changes\">\n";
    print STDOUT "<input type=reset     value=Reset>\n";
    print STDOUT "</form>\n";

    print STDOUT "<center>\n";
    print STDOUT "<b>Fringe Correlation Plot</b><br>\n";
    if (-e "$root.stats.png") { 
	@tmpw = split ("/", "$root.stats.png");
	$imname = "$www/$tmpw[-1]";
	print STDOUT "<img src=$imname>\n";
    }
    print STDOUT "</center>\n";

    print STDOUT "</body>\n";
    &goodbye;
    
}

sub flips_report_done {
    
    ($config) = $_[0] =~ /([-\w]+\.[-\w]+\.[-\w]+)/;
    ($key)    = $_[0] =~ /([-\w]+\.[-\w]+\.[-\w]+\.[-\w]+)/; # (config.ver)

    $line = $_[1];
    
    open (STAT, mknames ("stats", $line));
    open (MED,  mknames ("medbin", $line));
    open (MASTER, mknames ("master", $line, 0));
    
    print STDOUT "<table border>\n";
    print STDOUT "<tr><th> image </th><th> Date </th><th> Time </th><th> Mean </th>\n";
    print STDOUT "<th> Sigma (raw) </th><th> Sigma (clipped) </th><th> Sigma (med) </th><th> image </th><th> used? </th></tr>\n\n";
    
    for ($i = 0; $line = <STAT>; $i++) {
	
	chop ($line);
	# print STDOUT "$line<br>\n";
	@word = split (" ",$line);
	$used = $word[12];
	$dawn = $word[11];
	
	$line = <MASTER>;
	chop ($line);
	# print STDOUT "$line<br>\n";
	@tmpw = split (" ",$line);
	$keep = $tmpw[1];
	
	# mkfringe works with files in the user's paths, but the web page needs 
	# to work with files visible to the web server
	$line = <MED>;
	chop ($line);
	@tmpw = split ("/", $line);
	$N = @tmpw - 1;
	$medname = $tmpw[$N];
	
	$sig1 = sprintf "%5.3f", $word[4];
	$sig2 = sprintf "%5.3f", $word[5];
	$sig3 = sprintf "%5.3f", $word[6];
	$sig4 = sprintf "%5.3f", $word[7];
	$mean = sprintf "%8.1f", $word[3];
	
	print STDOUT "<tr><td> <a href=$CGI/fr.elixir3?$i.$key&med&elconf=$elconf> $word[0] </a></td><td> $word[1] </td>\n";
	if ($dawn) { print STDOUT "<td bgcolor=#cccccc> $word[2] </td>\n"; }
	else       { print STDOUT "<td> $word[2] </td>\n"; } 
	print STDOUT "<td> $word[3] </td>\n";
	print STDOUT "<td> $word[5] </td><td> $word[6] </td><td> $word[8] </td><td><img src=$www/$medname></td>\n";
	if ($used) { print STDOUT "<td bgcolor=#00c000>yes</td>\n"; }
	else       { print STDOUT "<td bgcolor=#d00000>no</td>\n"; }
    }
    $Nimage = $i;
    
    print STDOUT "</table>\n";
    print STDOUT "</body>\n";
    
    &goodbye;
    
}

sub flips_entry {
    
    my($version)= $_[0];		# version of desired entry
    my($entry)  = $_[1];		# desired entry in list
    my($line)   = $_[2];		# list of image stats
    my($mode)   = $_[3];                # 'def' or 'med'
    
    if (($mode ne "def") && ($mode ne "med")) {
	print STDOUT "error in $MKFRINGE mode\n";
	&goodbye;
    }

    # load image & stat lists
    $root = mknames ("htmlroot", $line);
    open (FILE, "$root.imstats");         @statdata = <FILE>; close (FILE);
    open (FILE, "$root.$mode.tenbin.list"); @meddata = <FILE>; close (FILE);

    $Nimage = @statdata;
    if ($entry >= $Nimage) {
	print STDOUT "</table> selected entry out of range\n";
	&goodbye;
    }
    
    $first = ($entry == 0);
    $last  = ($entry == $Nimage - 1);
    $next  = $entry + 1;
    $prev  = $entry - 1;
    
    $line = $statdata[$entry];
    chop ($line);
    @word = split (" ",$line);
    $used = $word[9];
    $keep = $word[10];
    
    # mkfringe works with files in the user's paths, but the web page needs 
    # to work with files visible to the web server
    $line = $meddata[$entry];
    chop ($line);
    @tmpw = split ("/", $line);
    $name = "$www/$tmpw[-1]";
    
    print STDOUT "<img width=100% src=$name>\n";
    print STDOUT "mode: $mode<br>\n";
    
    print STDOUT "<table><tr><td>\n";
    print STDOUT "<table border>\n";
    print STDOUT "<tr><th> image    </th><th> Date     </th><th> Time     </th><th> Sky      </th><th> Flux     </th><th> Fringe   </th><th> dFringe  </th><th> Resid    </th><th> dResid   </th><th> used? </th></tr>\n";
    if ($mode eq "med") {
	print STDOUT "<tr><td> <a href=$CGI/fr.elixir3?$entry.$version&def&elconf=$elconf> $word[0] </a></td>\n";
    } else {
	print STDOUT "<tr><td> <a href=$CGI/fr.elixir3?$entry.$version&med&elconf=$elconf> $word[0] </a></td>\n";
    }
    print STDOUT "<td> $word[1] </td><td> $word[2] </td><td> $word[3] </td><td> $word[4] </td><td> $word[5] </td><td> $word[6] </td><td> $word[7] </td><td> $word[8] </td>\n";
    if ($used) {
	print STDOUT "<td>yes</td>\n";
    } else {
	print STDOUT "<td bgcolor=#ff0000>no</td>\n";
    }	
    print STDOUT "</tr>\n\n";
    print STDOUT "</table>\n";
    
    print STDOUT "</td></tr>\n";

    print STDOUT "<tr><td> return to <a href=$CGI/fr.elixir1?&elconf=$elconf> config list </a></tr></td>\n"; 
    print STDOUT "<tr><td> return to <a href=$CGI/fr.elixir2?$version&elconf=$elconf> $version </a></tr></td>\n"; 
    if (!$first) { print STDOUT "<tr><td> goto <a href=$CGI/fr.elixir3?$prev.$version&$mode&elconf=$elconf> prev </a> image </td></tr>\n"; }
    if (!$last)  { print STDOUT "<tr><td> goto <a href=$CGI/fr.elixir3?$next.$version&$mode&elconf=$elconf> next </a> image </td></tr>\n"; }
    print STDOUT "</table>\n";
    
    print STDOUT "</body>\n";
    &goodbye;
}

sub map_report {
    
    print STDOUT "A Simple Test <br>\n";

    $col = 0;
    ($config) = $_[0] =~ /([-\w]+\.[-\w]+\.[-\w]+)/;
    ($key)    = $_[0] =~ /([-\w]+\.[-\w]+\.[-\w]+\.[-\w]+)/; # (config.ver)

    # look for optional sort key (config.ver[.key])
    if ($_[0] =~ /$key.(\d+)/) {
	($col) = $_[0] =~ /$key.(\d+)/; 
    } else {
	$col = 0;
    }

    $line = $_[1];
    $message = $_[2];
    
    open (LIST, mknames ("maplist",  $line)); @mapdata  = <LIST>; close (LIST);
    open (LIST, mknames ("modelist", $line)); @modedata = <LIST>; close (LIST);
    
    open (LIST, mknames ("modesjpg", $line)); @modeslist = <LIST>; close (LIST);
    open (LIST, mknames ("residjpg", $line)); @residlist = <LIST>; close (LIST);
    open (LIST, mknames ("inmapjpg", $line)); @inmaplist = <LIST>; close (LIST);
    foreach $name (@modeslist) { chop ($name); }
    foreach $name (@residlist) { chop ($name); }
    foreach $name (@inmaplist) { chop ($name); }

    print STDOUT "You have the following choices: <br>\n";
    print STDOUT "<a href=$CGI/fr.elixir1?&elconf=$elconf> <b> return to top level </b><br></a>";
    print STDOUT "<a href=$CGI/fr.mapaccept?$key&elconf=$elconf> <b> accept config </b><br></a></td>";

    print STDOUT "Modes avaliable for this config <br>\n";
    print STDOUT "<form method=post action=$CGI/fr.modes?&elconf=$elconf>\n";
    # 4 x N table of possible modes
    $MaxModes = 8;
    print STDOUT "<table bgcolor=#fff0e0 border=1 cellspacing=0 cellpadding=3>\n";
    for ($i = 0; $i < $MaxModes; $i++) {
	if ((($i - 0) % 4) == 0) { print STDOUT "<tr>\n"; }
	($junk, $status) = split (" ", $modedata[$i]);
	$name = sprintf "%s/%s", $www, $modeslist[$i];
	print STDOUT "<td> <img height=64 src=$name> </td>\n";
	if ($status) { print STDOUT "<td bgcolor=#00c000> <input type=checkbox checked name=mode.$i value=$i size=1> </td>\n"; }
	else {         print STDOUT "<td bgcolor=#d00000> <input type=checkbox name=mode.$i value=$i size=1> </td>\n"; }
	if ((($i - 3) % 4) == 0) { print STDOUT "</tr>\n"; }
    }
    print STDOUT "</table>\n";
    print STDOUT "<input type=hidden    name=Nmode value=\"$MaxModes\">\n";
    print STDOUT "<input type=hidden    name=config value=\"$key\">\n";
    print STDOUT "<input type=submit    value=\"set mode selection\">\n";
    print STDOUT "<input type=reset     value=Reset>\n";
    print STDOUT "</form>\n";

    # 2 x N table of image residuals
    print STDOUT "Residual images <br>\n";
    print STDOUT "<form method=post action=$CGI/fr.maps?&elconf=$elconf>\n";
    print STDOUT "<table bgcolor=#fff0e0 border=1 cellspacing=0 cellpadding=3>\n";
    for ($i = 0; $i < @mapdata; $i++) { 
	if ((($i - 0) % 6) == 0) { print STDOUT "<tr>\n"; }

	($name, $status) = split (" ", $mapdata[$i]);
	@words = split ("/", $name);
	$basename = $words[-1];
	$basename =~ s/.maplist$//;

	$imname = sprintf "%s/%s", $www, $residlist[$i];
	print STDOUT "<td> $basename </td>\n";
	print STDOUT "<td> <img height=64 src=$imname> </td>\n";
	if ($status) { print STDOUT "<td bgcolor=#00c000> <input checked type=checkbox name=map.$i value=$i size=1> </td>\n"; }
	else         { print STDOUT "<td bgcolor=#d00000> <input         type=checkbox name=map.$i value=$i size=1> </td>\n"; }

	if ((($i - 5) % 6) == 0) { print STDOUT "</tr>\n"; } 
	else { print STDOUT "<td width=10 bgcolor=#ffffff> &nbsp; </td>\n"; }
	
    }
    print STDOUT "</table>\n";
    $Nmaps = @mapdata;
    print STDOUT "<input type=hidden    name=Nmaps value=\"$Nmaps\">\n";
    print STDOUT "<input type=hidden    name=config value=\"$key\">\n";
    print STDOUT "<input type=submit    value=\"set image selection\">\n";
    print STDOUT "<input type=reset     value=Reset>\n";
    print STDOUT "</form>\n";

    # 2 x N table of source images 
    print STDOUT "Source images <br>\n";
    print STDOUT "<form method=post action=$CGI/fr.maps?&elconf=$elconf>\n";
    print STDOUT "<table bgcolor=#fff0e0 border=1 cellspacing=0 cellpadding=3>\n";
    for ($i = 0; $i < @mapdata; $i++) { 
	if ((($i - 0) % 6) == 0) { print STDOUT "<tr>\n"; }

	($name, $status) = split (" ", $mapdata[$i]);
	@words = split ("/", $name);
	$basename = $words[-1];
	$basename =~ s/.maplist$//;

	$imname = sprintf "%s/%s", $www, $inmaplist[$i];
	print STDOUT "<td> $basename </td>\n";
	print STDOUT "<td> <img height=64 src=$imname> </td>\n";
	if ($status) { print STDOUT "<td bgcolor=#00c000> <input checked type=checkbox name=map.$i value=$i size=1> </td>\n"; }
	else         { print STDOUT "<td bgcolor=#d00000> <input         type=checkbox name=map.$i value=$i size=1> </td>\n"; }

	if ((($i - 5) % 6) == 0) { print STDOUT "</tr>\n"; } 
	else { print STDOUT "<td width=10 bgcolor=#ffffff> &nbsp; </td>\n"; }
    }
    print STDOUT "</table>\n";
    $Nmaps = @mapdata;
    print STDOUT "<input type=hidden    name=Nmaps value=\"$Nmaps\">\n";
    print STDOUT "<input type=hidden    name=config value=\"$key\">\n";
    print STDOUT "<input type=submit    value=\"set image selection\">\n";
    print STDOUT "<input type=reset     value=Reset>\n";
    print STDOUT "</form>\n";
    &goodbye;
    
}

print STDOUT "error: invalid $MKFRINGE command\n";

# run:    $root/detrend.config    - current run
# detdir: $det                    - directory for current run
# config: $det/fringe.config      - config info for specific run, 1 line per setup
# dates:  $det/dates.dat          - dates for specific run
# list:   $det/fringe.list        - temporary list to pass to elixirs
# plist:  $det/fringe.plist       - list of files to process (detrend) for elixir
# proc:   $det/proc               - directory to store temporary processed images
# fringe: $det/fringe             - directory to store data files
# html:   $det/html               - directory to store results for www
# www:    $www/$run/html          - html directory as seen by Web server

####  TOOLS TO ABSTRACT FILENAMES  ###################################################################

# construct specific file names
sub mkfiles {
    # in: (type)
    my($type) = $_[0];
    my($value);
    
    { 
	if ($type eq "run") {
	    $value = "$root/fringe.config";
	    last;
	}
	if ($type eq "detdir") {
	    $value = "$det";
	    last;
	}
	if ($type eq "config") {
	    $value = "$det/fringe.config";
	    last;
	}
	if ($type eq "dates") {
	    $value = "$det/dates.dat";
	    last;
	}
	if ($type eq "list") {
	    $value = "$det/fringe.list";
	    last;
	}
	if ($type eq "plist") {
	    $value = "$det/fringe.plist";
	    last;
	}
	if ($type eq "proc") {
	    $value = "$det/proc";
	    last;
	}
	if ($type eq "fringe") {
	    $value = "$det/fringe";
	    last;
	}
	if ($type eq "links") {
	    $value = "$det/flips/links";
	    last;
	}
	if ($type eq "html") {
	    $value = "$det/html";
	    last;
	}
	if ($type eq "www") {
	    $value = "$www";
	    last;
	}
	&escape ("unknown type for mkfiles");
    }
    $value;    
}

# construct files from config info:
# CRUNID TYPE FILTER [CCD] VERSION START STOP STATE
#**************************

sub mknames {
    # in: (type) (config.ver) [ccd]
    my ($type, $version, @words, $dir, $value, $ccd);

    $type = $_[0];
    $version = $_[1];
    @words = split (" ", $version);
    $ccd = $_[2];
    
    { 
	# list of fringe frames
	if ($type eq "config") {
	    $dir = mkfiles ("fringe");
	    $value = sprintf "$dir/$words[0].$words[1].$words[2].$words[3]";
	    last;
	}
	# list of fringe frames
	if ($type eq "frlist") {
	    $dir = mkfiles ("fringe");
	    $value = sprintf "$dir/$words[0].$words[1].$words[2].$words[3].frlist";
	    last;
	}
	# smoothed (final) fringe image
	if ($type eq "smfile") {
	    $dir = mkfiles ("fringe");
	    $value = sprintf "$dir/$words[0].$words[1].$words[2].$ccd.$words[3].sm.fits";
	    last;
	}
	# raw fringe image
	if ($type eq "frfile") {
	    $dir = mkfiles ("fringe");
	    $value = sprintf "$dir/$words[0].$words[1].$words[2].$ccd.$words[3].fr.fits";
	    last;
	}
	# master list of input images
	if ($type eq "master") {
	    $dir = mkfiles ("fringe");
	    $value = sprintf "$dir/$words[0].$words[1].$words[2].$words[3].master";
	    last;
	}
	# output link file for fhtool
	if ($type eq "link") {
	    $dir = mkfiles ("links");
	    if ($ccd eq "") { &escape ("missing CCD for mknames link"); }
	    $value = "$dir/$words[0].$words[1].$words[2].$ccd.$words[3].fits";
	    last;
	}
	# output mef file name
	if ($type eq "mef") {
	    $dir = mkfiles ("fringe");
	    $value = "$dir/$words[0].$words[1].$words[2].$words[3].fits";
	    last;
	}
	# list of image statistics files
	if ($type eq "imstats") {
	    $dir = mkfiles ("fringe");
	    $value = sprintf "$dir/$words[0].$words[1].$words[2].$words[3].imstats";
	    last;
	}
	# list of image map lists
	if ($type eq "maplist") {
	    $dir = mkfiles ("fringe");
	    $value = sprintf "$dir/$words[0].$words[1].$words[2].$words[3].maplist";
	    last;
	}
	# list of image map lists
	if ($type eq "modelist") {
	    $dir = mkfiles ("fringe");
	    $value = sprintf "$dir/$words[0].$words[1].$words[2].$words[3].mode.list";
	    last;
	}
	# list of image map lists
	if ($type eq "modefits") {
	    $dir = mkfiles ("fringe");
	    $value = sprintf "$dir/$words[0].$words[1].$words[2].$words[3].mode.fits";
	    last;
	}
	# list of image map lists
	if ($type eq "modesave") {
	    $dir = mkfiles ("fringe");
	    $value = sprintf "$dir/$words[0].$words[1].$words[2].$words[3].mode.mef.fits";
	    last;
	}
	# mosaic fringe statistics file
	if ($type eq "frstats") {
	    $dir = mkfiles ("fringe");
	    $value = sprintf "$dir/$words[0].$words[1].$words[2].$words[3].frstats";
	    last;
	}
	# images to be detrended
	if ($type eq "detrend") {
	    $dir = mkfiles ("fringe");
	    $value = sprintf "$dir/$words[0].$words[1].$words[2].$words[3].detrend";
	    last;
	}
	# list of input image lists to defringe
	if ($type eq "defringe") {
	    $dir = mkfiles ("fringe");
	    $value = sprintf "$dir/$words[0].$words[1].$words[2].$words[3].defringe";
	    last;
	}
	# file in HTML dir with all image stats
	if ($type eq "htmlroot") {
	    $dir = mkfiles ("html");
	    $value = "$dir/$words[0].$words[1].$words[2].$words[3]";
	    last;
	}
	# file in HTML dir with all image stats
	if ($type eq "stats") {
	    $dir = mkfiles ("html");
	    $value = "$dir/$words[0].$words[1].$words[2].$words[3].stats";
	    last;
	}
	# file in HTML dir with all medbin jpg image names (also root for images)
	if ($type eq "modesjpg") {
	    $dir = mkfiles ("html");
	    $value = "$dir/$words[0].$words[1].$words[2].$words[3].modes";
	    last;
	}
	# file in HTML dir with all medbin jpg image names (also root for images)
	if ($type eq "residjpg") {
	    $dir = mkfiles ("html");
	    $value = "$dir/$words[0].$words[1].$words[2].$words[3].resid";
	    last;
	}
	# file in HTML dir with all medbin jpg image names (also root for images)
	if ($type eq "inmapjpg") {
	    $dir = mkfiles ("html");
	    $value = "$dir/$words[0].$words[1].$words[2].$words[3].inmap";
	    last;
	}
	# file in HTML dir with all medbin jpg image names (also root for images)
	if ($type eq "medbin") {
	    $dir = mkfiles ("html");
	    $value = "$dir/$words[0].$words[1].$words[2].$words[3].medbin";
	    last;
	}
	# file in HTML dir with all tenbin jpg image names (also root for images)
	if ($type eq "tenbin") {
	    $dir = mkfiles ("html");
	    $value = "$dir/$words[0].$words[1].$words[2].$words[3].tenbin";
	    last;
	}
	# file in HTML dir with jpg image of fringe framge
	if ($type eq "imbin") {
	    $dir = mkfiles ("html");
	    $value = "$dir/$words[0].$words[1].$words[2].$words[3].imbin.jpg";
	    last;
	}
	# file in WWW dir with jpg image of fringe framge
	if ($type eq "dads.imbin") {
	    $dir = mkfiles ("www");
	    $value = "$dir/$words[0].$words[1].$words[2].$words[3].imbin.jpg";
	    last;
	}
	&escape ("unknown type for mknames: $type");
    }    
    return ($value);
}

####  TOOLS TO INTERACT WITH FORMATED CONFIG FILE  #####################################################

# parse config info
# CRUNID TYPE FILTER [CCD] VERSION START STOP STATE
#**************************
sub gtconfig {
    my ($value, $type, @words, $ccd);
    # in: (config line) (type)
    @words = split (" ", $_[0]);
    $type = $_[1];

    { 
	if ($type eq "elixir") {
	    $value = "$words[0] $words[1] $words[2] $words[3] $words[4] $words[5]";
	    last;
	}
	if ($type eq "chiprun") {
	    $ccd  = $_[2];
	    $value = "$words[0] $words[1] $words[2] $ccd $words[3] $words[4] $words[5]";
	    last;
	}
	if ($type eq "config") {
	    $value = "$words[0].$words[1].$words[2]";
	    last;
	}
	if ($type eq "filter") {
	    $value = "$words[2]";
	    last;
	}
	if ($type eq "ID") {
	    $value = "$words[0]";
	    last;
	}
	if ($type eq "version") {
	    $value = "$words[0].$words[1].$words[2].$words[3]";
	    last;
	}
	if ($type eq "from") {
	    $value = "$words[4]";
	    last;
	}
	if ($type eq "to") {
	    $value = "$words[5]";
	    last;
	}
	if ($type eq "status") {
	    $value = "$words[6]";
	    last;
	}
	&escape ("unknown type for gtconfig");
    }

    return $value;
}

# set config value
# TYPE FILTER CRUNID VERSION START STOP STATE
# CRUNID TYPE FILTER [CCD] VERSION START STOP STATE
#**************************
sub stconfig {
    # in: (config line) (value) (type)
    my (@words) = split (" ", $_[0]);
    my ($type)  = $_[1];
    my ($value) = $_[2];
    my ($line);

    { 
	if ($type eq "all") {
	    $line = sprintf "%s %6s %4s %2d %s %s %s", $words[0], $words[1], $words[2], $words[3], $words[4], $words[5], $words[6];
	    last;
	}
	if ($type eq "version") {
	    $line = sprintf "%s %6s %4s %2d %s %s %s", $words[0], $words[1], $words[2], $value, $words[4], $words[5], $words[6];
	    last;
	}
	if ($type eq "start") {
	    $line = sprintf "%s %6s %4s %2d %s %s %s", $words[0], $words[1], $words[2], $words[3], $value, $words[5], $words[6];
	    last;
	}
	if ($type eq "stop") {
	    $line = sprintf "%s %6s %4s %2d %s %s %s", $words[0], $words[1], $words[2], $words[3], $words[4], $value, $words[6];
	    last;
	}
	if ($type eq "status") {
	    $line = sprintf "%s %6s %4s %2d %s %s %s", $words[0], $words[1], $words[2], $words[3], $words[4], $words[5], $value;
	    last;
	}
	&escape ("unknown type for stconfig");
    }

    return $line;
}

# load dates & mode (returns @list)
sub load_dates {
    my ($file, $line, @list);
    my ($start, $stop);
    
    $file = mkfiles ("dates");
    @list = ();
    open (FILE, "$file");
    @list = <FILE>;
    close (FILE);

    ($tmp, $start) = split (" ", $list[0]);
    if ($tmp ne "START") { print STDERR "dates file is confused\n"; }

    ($tmp, $stop) = split (" ", $list[1]);
    if ($tmp ne "STOP") { print STDERR "dates file is confused\n"; }
    
    ($tmp, $mode) = split (" ", $list[2]);
    if ($tmp ne "MODE") { print STDERR "dates file missing mode\n"; }
    if ($mode eq "") { $mode = "hold"; }

    ($start, $stop, $mode);
}

# write to dates file
sub save_dates {
    # save_dates start stop auto.mode
    my (@outlist) = @_;

    my ($file) = mkfiles ("dates");
    open (FILE, ">$file");
    print FILE "START $outlist[0]\n";
    print FILE "STOP  $outlist[1]\n";
    print FILE "MODE  $outlist[2]\n";
    close (FILE);
}    

# load config lines (returns @list)
sub load_config {
    my ($file, $line, @list);
    
    $file = mkfiles ("config");
    @list = ();
    open (FILE, "$file");
    while ($line = <FILE>) {
	chop ($line);
	@list = (@list, $line);
    }
    close (FILE);
    
    @list;
}

# write to config file
sub save_config {

    my(@outlist) = sort @_;
    
    my($file) = mkfiles ("config");
    open (FILE, ">$file");
    for ($i = 0; $i < @outlist; $i++) {
	print FILE "$outlist[$i]\n";
    }
    close (FILE);
    
}    

####  USEFUL TOOLS  #################################################################################

sub vsystem {
    print STDERR "@_\n";
    $status = system ("@_");
    $status;
}

sub goodbye { 
    unlink $tmpenv;
    exit 0; 
}

sub escape { 
    unlink $tmpenv;
    print STDERR "$_[0]\n";
    exit 1;
}

# grab complete configuration info from the elixir config system, 
# applying appropriate command-line arguments
sub elixir_config {
    my (@argv) = @_;
    my ($opt, $config, @tmparg, $status);
    $config = "";
    if ($ENV{'PTOLEMY'}) { $config = "-c $ENV{'PTOLEMY'}"; }
    umask (0);

    # look for optional command-line arguments
    @tmparg = @argv;
    foreach (@tmparg) {
	$value = shift @argv;

	if ($value eq "-c") {
	    $value = shift @argv;
	    $config = "-c $value";
	    next;
	}

	if ($value eq "-C") {
	    push @opt, $value;
	    $value = shift @argv;
	    push @opt, $value;
	    $elconf = $value;
	    next;
	}
	
	if ($value eq "-D") {
	    push @opt, $value;
	    $value = shift @argv;
	    push @opt, $value;
	    $value = shift @argv;
	    push @opt, $value;
	    next;
	}
	
	if ($value eq "-run") {
	    $run = shift @argv;
	    push @opt, "-D RUNID.MKFRINGE $run -D RUNID $run";
	    next;
	}
	
	if ($value eq "-camera") {
	    $camera = shift @argv;
	    push @opt, "-D CAMERA.MKFRINGE $camera -D CAMERA $camera";
	    next;
	}
	push @argv, $value;
    }

    # load RUNID from state.data (unless set on command line)
    if ($run eq "") {
	$run = `gconfig RUNID.MKFRINGE`; chop $run;
	if ($?) {  &escape ("run is not defined: use 'mkdetrend config' or 'mkrun sys'\n"); }
	if ($run eq "") {  &escape ("run is not defined: use 'mkdetrend config' or 'mkrun sys'\n"); }
	push @opt, "-D RUNID.MKDETREND $run -D RUNID $run";
    }

    # load CAMERA from state.data (unless set on command line)
    if ($camera eq "") {
	$camera = `gconfig CAMERA.MKFRINGE`; chop $camera;
	if ($?) {  &escape ("camera is not defined: use 'mkrun sys' to set\n"); }
	if ($camera eq "") {  &escape ("camera is not defined: use 'mkrun sys'\n"); }
	push @opt, "-D CAMERA.MKDETREND $camera -D CAMERA $camera";
    }

    # set env PTOLEMY using values from command line
    $config = join (" ", $config, @opt);
    $tmpenv = `mktemp /tmp/elixir.XXXXXX`; chop ($tmpenv);
    $status = system ("gconfig -raw $config > $tmpenv");
    if ($status) { &escape ("error in elixir configuration: gconfig fails"); }
    $ENV{'PTOLEMY'} = "$tmpenv";

    # set global variables based on new config info
    $root = `gconfig DETREND_ROOT`;  chop $root;
    if ($?) { &escape ("error with elixir configuration variable: DETREND_ROOT"); }

    $wwwroot  = `gconfig DETREND_WWW`;  chop $wwwroot;
    if ($?) { &escape ("error with elixir configuration variable: DETREND_WWW"); }
    
    $Nccd = `cameraconfig -Nccd`; chop ($Nccd);
    if ($?) { &escape ("error with elixir camera configuration"); }

    @ccds = split (" ", `cameraconfig -ccdn`);
    if ($?) { &escape ("error with elixir camera configuration"); }

    # get list of valid filters from lookup table
    @filters = split (" ", `filtnames list`);
    if ($?) { &escape ("error with elixir filter configuration"); }

    # recipe file defines detrend types & cutoff exptime values
    $recipefile = `gconfig DETREND_RECIPES`; chop $recipefile;
    if ($?) { &escape ("missing DETREND_RECIPES in configuration"); }

    @filt = ();
    foreach $filter (@filters) {
	($detypes) = split (" ", `gconfig -c $recipefile $filter`);
	if ($?) { die "ERROR: missing detrend recipe for $filter\n"; }

	@detypes = split (",", $detypes);
	for ($i = 0; $i < @detypes; $i++) {
	    if ($detypes[$i] eq "fringe") {
		push @filt, $filter;
		push @type, "fringe";
		last;
	    }
	}
    }

    $CGI = `gconfig CGIBIN`; chop ($CGI);
    if ($?) { &escape ("error with elixir configuration variable: CGIBIN"); }

    $det  = "$root/$run";
    $www  = "$wwwroot/$run/html";
    return (@argv);
}

sub usage {

    if (@ARGV == 1) {
	print STDERR "\n --- user modes ---\n";
	print STDERR "create (run) (startdate) (stopdate)\n";
	print STDERR "mkconfig\n";
	print STDERR "config (run)\n";
	print STDERR "init\n";
	print STDERR "run\n";
	print STDERR "list.runs\n";
	print STDERR "set (config.ver) (state)\n";
	print STDERR "reg\n";
	print STDERR "state \n";
	print STDERR "help \n";
	print STDERR "\n --- internal modes --- \n";
	print STDERR "flips\n";
	print STDERR "norm\n";
	print STDERR "update\n";
	print STDERR "merge\n";
	print STDERR "dup (config)\n";
	print STDERR "del (config)\n";
	print STDERR "def (config.ver) (start) (stop)\n";
	print STDERR "eval (step)\n";
	print STDERR "mevel (step)\n";
	print STDERR "htmldup\n";
	print STDERR "htmldel\n";
	print STDERR "htmldef\n";
	print STDERR "htmlmod\n";
	print STDERR "htmlkeep\n";
	print STDERR "html1\n";
	print STDERR "html2 (config.ver)\n";
	print STDERR "html3 (entry.config.ver)\n";
	&goodbye;
    }
    
    if (@ARGV > 2) { print STDERR "USAGE: $MKFRINGE (help) [mode]\n"; &goodbye; }
    
    if ($ARGV[1] eq "config") {
	print STDERR "set up initial configuration\n";
	&goodbye;
    }
    
    if ($ARGV[1] eq "save") {
	print STDERR "save results from current configuration\n";
	&goodbye;
    }
    
    print STDERR "help for $ARGV[1] not defined\n";
    &goodbye;
}

#### overview ########

# init: create lists of possible images for each master type:
#       01Ak01.fringe.I.0.master  (MOSAIC)

# detrend: detrend the input images

# files needed for html pages:

# html/*
# fringe/*.master
