#!/usr/bin/perl -w

#    A new strainfinder that can handle multiple strain lists. 
#    v0.1 Written 2003, Rob Edwards

########################## License #######################################################
#
#    Copyright 2003 Rob Edwards
#    For updates, more information, or to discuss the scripts
#    please contact Rob Edwards at redwards@utmem.edu or via http://www.salmonella.org/
#
#    These scripts are free software; you can redistribute and/or modify
#    them under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    They are distributed in the hope that they will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    in the file (COPYING) along with these scripts; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#
##########################################################################################

#    This script will look through a directory of strain lists and if there is no search
#    present a blank form that will allow you to search the list. If a search query is used
#    it will return the appropriate strains.
 
 
#    The new strainfinder files will have one line that will contain information about the strainlists.
#    The first line should have information that will be put into the form, preceeded by a hash
#    The line may have valid html code too.

 
use strict;
use CGI::Carp qw(fatalsToBrowser);
use CGI qw/:standard/;

# $directory is a directory that contains all the strain files.
my $directory = "data/strainlists";

# there are some files that need to be here:
#privileges.txt a tab separated list with ip address and then strain lists that they are allowed to edit
#strainlists.txt that contains all the files that are strain lists, information about the list, and column headers
# history.txt will have the ip_address, time stamp, and then search parameters.

#get some information about the requestor
my $remote_host = $ENV{REMOTE_ADDR};



# first we are going to list the files. We will need this whatever we do.

# we are going to have a file called strainlists.txt that will contain a tab separated list of 
# all the files, column headers and the information about the files.

# the information will be:
# filename\tinformation\t<list of headers>\n
my @files; # all the files
my %fileheaders; # column headers for each of the files
my %fileinfo; # information about the file
open (IN, "$directory/strainlists.txt") || die "Can't open $directory/strainlists.txt";
while (<IN>) {
 next if (m/^\#/);
 chomp;
 my ($file, $info, @headers) = split /\t/;
 push (@files, "$directory/$file");
 $fileinfo{"$directory/$file"}=$info;
 @{$fileheaders{"$directory/$file"}}=@headers;
}

# just sort the list.
@files = sort {$a cmp $b} @files;

my $cgi=new CGI;
$cgi->autoEscape(0); # this turns off autoescaping, and so html should appear fine


foreach my $q ($cgi->param()) {print STDERR "param:$q value: ",$cgi->param($q),"\n"}


if ($cgi->param('submit') || $cgi->param('submit.x')) { # this just removes an error when submit is not defined
 if ($cgi->param('submit.x')) {
  if ($cgi->param('submit.x')>300) {add_new()}
  elsif ($cgi->param('submit.x')>200) {history()}
  elsif ($cgi->param('submit.x')>100) {advanced_search()}
  else {blankform()}
 }
 else {
  if ($cgi->param('submit') eq 'Edit Checked Strains') {edit_strains()}
  elsif ($cgi->param('submit') eq 'Check Edited Strains') {check_strains()}
  elsif ($cgi->param('submit') eq 'Add Edited Strains') {add_strains()}
  elsif ($cgi->param('submit') eq 'Add New Strain') {add_new()}
  elsif ($cgi->param('submit') eq 'Check New Strain') {check_new()}
  elsif ($cgi->param('submit') eq 'Get Results') {search()}
  elsif ($cgi->param('submit') eq 'Get More Results') {search()}
  elsif ($cgi->param('submit') eq 'advanced') {advanced_search()}
  elsif ($cgi->param('submit') eq 'history') {history()}
  elsif ($cgi->param('submit') eq 'search') {blankform()}
 }
}
elsif ($cgi->param('search')) {search()}
else {blankform()}


exit(0);


sub blankform {
 # this will just print a query and have a  bunch of hidden fields with all the files.
 my $html; # this will be the table
 my $filecount; # we are going to give each file a unique name.
 
 foreach my $f (@files) {
  $filecount++;
  $html .= "<input type=hidden name=file$filecount value=$f>\n";
 }
 
 print $cgi->header('text/html'), start_html(-title=>'Strain Finder Multiple Strain Searches', -BGCOLOR=>'#FFFFFF',
             -TEXT=>'#000000'),
    html((h1(big('<center>StrainFinder Searches.</center>'))),p,hr,p, start_form(),
    "You can now search multiple strain lists all at once. Please enter a search term in the box and select the strainlist(s) ",
    "that you want to search. Your results will be returned for all lists chosen",p, "\n",
    "<center>", image_button(-name=>'submit', -value=>'search', -src=>'/images/strainfinder/search_all.jpg'), "\n",
    "<center>", textfield('search','',50), "\n<input type=hidden name=\"filetotal\" value=\"$filecount\">\n", p, $html, p, "\n",
    "<input type=hidden name=minimum value=1><input type=hidden name=maximum value=100>", 
    hidden('case', 'insensitive'), "\n",
    submit(), reset(),p, end_form(), "<p></center><small>Request from: $remote_host</small></p>", end_html());
}

sub advanced_search {
 # starting from scratch. Ok
 # read the information in the files and put it into a table
 my $html = "<table border=1>"; # this will be the table
 my $filecount; # we are going to give each file a unique name.
 
 foreach my $f (@files) {
 $filecount++;
 $html .= "\n<tr><td><input type=\"checkbox\" name=\"file$filecount\" value=\"$f\" checked></td><td>$fileinfo{$f}</td></tr>\n";
 }
 $html .= "</table>\n\n";
 
 
 print $cgi->header('text/html'), start_html(-title=>'Strain Finder Multiple Strain Searches', -BGCOLOR=>'#FFFFFF',
             -TEXT=>'#000000'),
    html((h1(big('<center>StrainFinder Searches.</center>'))),p,hr,p, start_form(),
    "\nYou can now search multiple strain lists all at once. Please enter a search term in the box and select the strainlist(s) ",
    "\nthat you want to search. Your results will be returned for all lists chosen",p, 
    "\n<center>", image_button(-name=>'submit', -value=>'search', -src=>'/images/strainfinder/advanced_all.jpg'),
    p,"</center>",p,
    submit("submit", "Get Results"), reset(),p,"\n",
    "<table><tr><td>Search for:</td><td>", textfield('search','',50), "\n</td></tr><tr><td>But not:</td><td>", textfield('not_in_search','',50), "</td></tr></table>\n",
    "\n<input type=hidden name=\"filetotal\" value=\"$filecount\">\n", p, $html, p, 
    "<input type=hidden name=\"search_type\" value=\"advanced\">",
    "Start at result number: <input type=text size=3 name=\"minimum\" value=\"1\">&nbsp; Stop at result number: ",
    "<input type=text size=3 name=\"maximum\" value=\"100\">",
    p, "Case: &nbsp; ",  
    radio_group(-name=>'case', -values=>['insensitive', 'sensitive']) ,p,
    submit("submit", "Get Results"), reset(), end_form(), "<p><small>Request from: $remote_host</small></p>", end_html());
}
    
sub search {
 # first, lets get the list of files that we want to search
 my $filecount=$cgi->param('filetotal');
 my @searchfiles;
 for (my $i=1; $i<=$filecount; $i++) {
  if ($cgi->param("file$i")) {push @searchfiles, $cgi->param("file$i")}
 }
 
 # now lets search each file for the terms.
 my %results; # this will store all the results
 my %file; # what file was the result in
 my $count=1; # a counter
 my %filecount; # count for each file
 my $orsearch=$cgi->param('search'); # the search term
 my $notsearch=$cgi->param('not_in_search');# things we don't want in the search
 ### NOTE: need to add something here to split up OR searches, etc

my ($search, $or, $and) = split_search($orsearch);

my $min=1; my $max=100;
if ($cgi->param('submit') eq 'Get More Results') {
 $min=$cgi->param('minimum');
 $max=$cgi->param('maximum');
}
if ($cgi->param('search_type') eq "advanced") {
 $min=$cgi->param('minimum');
 $max=$cgi->param('maximum');
}
 

 my %maxcols; # number of columns in file (actually, just the number of tabs)
 
 foreach my $file (@searchfiles) {
  # now lets write the history
 history($search, $file, $min, $max, $cgi->param('case'));
  $maxcols{$file}=1;
#  last if ($count>=$max);
  open (IN, $file) || die "Can't open |$file|";
  while (<IN>) {
  next if (m/^\#/);
#  last if ($count>$max);
   if ($cgi->param('case') eq "sensitive") {
    if (/$search/) {
      my $continue;
      if (@$and) {
       foreach my $and (@$and) {if (/$and/) {$continue=1}}
      }
      else {$continue=1}
      undef $continue if ($notsearch && /$notsearch/);
      next unless ($continue);
      
      if ($count >= $min && $count<=$max) {
      $results{$count}=$_;
      $filecount{$count}=$file;
      # count the number of columns for this file
      my $tempcount = s/\t//;
      if ($tempcount > $maxcols{$file}) {$maxcols{$file}=$tempcount}
      }
     $count++;
    }
   }
   else {
    if (/$search/i) {
      my $continue;
      if (@$and) {
       foreach my $and (@$and) {if (/$and/i) {$continue=1}}
      }
      else {$continue=1}
      undef $continue if ($notsearch && /$notsearch/);
      next unless ($continue);


     if ($count >= $min && $count<=$max) {
      $results{$count}=$_;
      $filecount{$count}=$file;
      my $tempcount = s/\t//;
      if ($tempcount > $maxcols{$file}) {$maxcols{$file}=$tempcount}
      }
     $count++;
    }
   }
  }
 } 

 

 $count--; # compensate for $count being set to one and incremented after each match
 my $resultsto=$max;
 if ($max>$count) {$resultsto=$count}
 my $html = "<p><b>$count matches found. Here are results $min to $resultsto of your search</b></p>\n";
 $html .= "<p>(Searched for $search AND ". join (" AND ", @$and). " OR ". join (" OR ", @$or). " BUT NOT $notsearch)</p>";  
 my $header=' '; my $outputcount=$min;
 for (my $i=$min; $i<=$max; $i++) {
  if ($i>$count) {$i=$max; next}
   #%filecount contains the name of the file
  unless ($fileinfo{$filecount{$i}} eq $header) {
   $header=$fileinfo{$filecount{$i}};
   my $colspan=$#{$fileheaders{$filecount{$i}}}+3;
   if ($html =~ /<tr>/) {$html .= "</table>\n"}
   $html .= "<table border=1><tr><th colspan=".$colspan.">$header</th></tr>\n";
   $html .= "<tr><td><b>Count</b></td><td><b>Edit</b></td><td><b>".join ("</b></td><td><b>", @{$fileheaders{$filecount{$i}}})."</b></td></tr>\n";
  }
  my @line = split /\t/, $results{$i};
  $html .= "<tr><td>$outputcount</td><td><input type=checkbox name=straintoedit$outputcount value=$line[0]></td><td>".join ("</td><td>", @line)."</td></tr>\n";
  $outputcount++;
 }
 
 $html .= "</table>\n\n";
   
 if ($count>$max) {
  my $filecount=1;
  foreach my $f (@searchfiles) {
   $html .= "<input type=hidden name=\"file$filecount\" value=\"$f\">\n";
   $filecount++;
  }
  $html .= "<input type=submit name=submit value='Get More Results'>\n&nbsp; ";
 }
 $html .= "<input type=submit name=submit value='Edit Checked Strains'>\n";
 my $end=$max+($max-$min)+1;


 # now we just need to output the results.
 print $cgi->header('text/html'), start_html(-title=>'Strain Finder Multiple Strain Searches', -BGCOLOR=>'#FFFFFF',
            -TEXT=>'#000000'),
   html((h1(big('<center>StrainFinder Results.</center>'))),p,hr,p,"\n",
   "<center>", start_form(),
   image_button(-name=>'submit', -value=>'search', -src=>'/images/strainfinder/search_all.jpg'),
   p,"</center>",
   "\n", hidden('search','',50),"\n", hidden("filetotal", $filecount),  p, 
   "\n<input type=hidden name=maxoutput value=$outputcount>",
   "\n","<input type=hidden name=minimum value=$max>\n<input type=hidden name=maximum value=$end>\n",
   "\n",hidden('case', 'insensitive'),"\n", $html, p),
    end_form(), "<p><small>Request from: $remote_host</small></p>", end_html();
}
  
 

sub edit_strains {
 # an editor for the strains
 my %strainstoedit; my $edit;
 for (my $i=1; $i<=$cgi->param('maxoutput'); $i++) {
  if ($cgi->param("straintoedit$i")) {$strainstoedit{$cgi->param("straintoedit$i")}=1; $edit=1}
 }
 
 unless ($edit) {
  print STDERR "Checked from 1 to ", $cgi->param('maxoutput'), " but didn't find anything\n";
  exit(-1);
 }

 
 my ($allow, $cookie)=check_privileges(); my %allow=%$allow;
 
my %filetoedit;
 # now find where the strain that they wanted to edit is
 # store the file as a key in $filetoedit, and the strain info as the value
 foreach my $file (@files) {
  open (IN, $file) || die "Can't open $file";
  while (<IN>) {
   chomp;
   my @line = split /\t/;
   next unless (exists $strainstoedit{$line[0]});
   push (@{$filetoedit{$file}}, $_);
  }
 }
 
 my $html = "<table border=1>\n";
 my $outputcount=1;
 foreach my $file (keys %filetoedit) {
  my $colspan=$#{$fileheaders{$file}}+4;
  $html .= "<tr><th colspan=".$colspan.">$fileinfo{$file};</th></tr>\n";
  $html .= "<tr><td><b>Count</b></td><td><b>Edited</b></td><td><b>".join ("</b></td><td><b>", @{$fileheaders{$file}})."</b></td></tr>\n";

  foreach my $strain (@{$filetoedit{$file}}) {
   my @fileheaders=@{$fileheaders{$file}};
   my @strainparts = split /\t/, $strain;
   if ($allow{$file}) {
    $html .= "<tr><td>$outputcount</td><td><input type=checkbox name=edit$outputcount value=$strainparts[0]>";
    $html .= "<input type=hidden name=strainfile$outputcount value=$file></td>";
    my $name = shift(@fileheaders);
    my $value = shift(@strainparts); # generally don't want them to edit the strain number
    $html .= "<td><input type=hidden name=\"$name$outputcount\" value=$value>$value</td>";
    foreach $name (@fileheaders) {
     $value=shift(@strainparts);
     $html .= "<td><input type=text size=100 name=\"$name$outputcount\" value=\"$value\"></td>";
    }
    $html .= "</tr>\n";
    $outputcount++;
   }
   else {
    $html .= "<tr><td>$outputcount</td><td><b>Not Allowed</b></td><td>".join ("</td><td>", @strainparts)."</td></tr>\n";
    $outputcount++;
   }
  }
 }
 $html .= "</table>\n";
 
  print $cgi->header(-type=>'text/html', -cookie=>$cookie), start_html(-title=>'Strain Finder Multiple Strain Searches', -BGCOLOR=>'#FFFFFF',
            -TEXT=>'#000000'),
   html((h1(big('<center>StrainFinder Results.</center>'))),p,hr,p,"\n",
   start_form(),"\n", hidden("edittotal", $outputcount),  p, $html, p, 
   "<center>", image_button(-name=>'submit', -value=>'search', -src=>'/images/strainfinder/search_all.jpg'),
   p,"</center>",
   "<input type=submit name=submit value='Check Edited Strains'>", reset(),p),
   end_form(), "<p><small>Request from: $remote_host</small></p>", end_html();
}
  

sub check_strains {
 # we are just going to print out the information and make sure that it is right.
 # lets get the edited information
 my $edittotal = $cgi->param('edittotal');
 my $html = "<table border=1>\n"; 
 my $doing = ' '; # which file we are editing
 my @headers; # headers for the file
 my $outputcount=1;
 for (my $i=1; $i<=$edittotal; $i++) {
  if ($cgi->param("edit$i")) {
   # this strain has been edited.
   # get the new values and print it out again
   unless ($doing eq $cgi->param("strainfile$i")) {
    @headers = @{$fileheaders{$cgi->param("strainfile$i")}};
    $html .= "<tr><td><b>Count</b></td><td><b>Edited</b></td><td><b>".join ("</b></td><td><b>", @headers)."</b></td></tr>\n";
    $doing=$cgi->param("strainfile$i");
   }
   {
    my $temp; # a temporary store for the html, because we want to put a form element in but we don't know what its value is!
    my $straininfo; # the actual information about the strain
    foreach my $header (@headers) {
     $temp .= "<td>".$cgi->param($header.$i)."</td>";
     $straininfo .= "\t".$cgi->param($header.$i);
    }
    $straininfo =~ s/^\t//; # the first element is a tab!
    $html .= "<tr><td>$outputcount</td><td><input type=checkbox name=edit$outputcount value=\"$straininfo\">";
    $html .= "\n<input type=hidden name =strainfile$outputcount value=".$cgi->param("strainfile$i").">\n</td>$temp</tr>\n";
   }
   $outputcount++;
  }
 }
 $html .= "</table>\n";
 
  print $cgi->header('text/html'), start_html(-title=>'Strain Finder Multiple Strain Searches', -BGCOLOR=>'#FFFFFF',
            -TEXT=>'#000000'),
   html((h1(big('<center>StrainFinder Results.</center>'))),p,hr,p,"\n",
   start_form(),"\n", hidden("edittotal", $outputcount),  p,
   "<center>", 
   image_button(-name=>'submit', -value=>'Add New Strain', -src=>'/images/strainfinder/submit_all.jpg'), 
   p,"</center>",
   $html, 
   "<input type=submit name=submit value='Add Edited Strains'>", reset(),p),
   end_form(), "<p><small>Request from: $remote_host</small></p>", end_html();
}
    

sub add_strains {
 # now we have checked the output, we just need to add the strain to the list.
 # lets begin by hashing all the changes based on the filename
 my %filetochange;
 my %changed; # the lines that we have changed
 my @notchanged;
 for (my $i=1; $i<=$cgi->param('edittotal'); $i++) {
  if ($cgi->param("edit$i")) {push (@{$filetochange{$cgi->param("strainfile$i")}}, $cgi->param("edit$i"))}
 }

 my ($allow, $cookie)=check_privileges(); my %allow=%$allow;
 
 foreach my $file (keys %filetochange) {
  if (exists $allow{$file}) {
   # first we need to back the file up
   my $one=$file.".1"; my $two=$file.".2"; my $three=$file.".3"; my $four=$file.".4";
   if (-e $four) {unlink ($four)}
   if (-e $three) {rename("$three", "$four")}
   if (-e $two) {rename("$two", "$three")}
   if (-e $one) {rename("$one", "$two")}
   rename("$file", "$one");
   # lets find all the lines that we need to change
   my %need; # this will have the strain number as a key and the rest of the line joined with tabs
   foreach my $line (@{$filetochange{$file}}) {
    $line =~ s/\r//g;
    # make sure there is no return on the end so we can add it later.
    chomp($line);
    my @line=split /\t/, $line;
    $need{$line[0]}=$line;
   }
   
   
   # this will substitute existing lines.

   open (IN, $one) || die "Can't open $one";
   open (OUT, ">$file") || die "Can't open $file for writing";
   while (<IN>) {
    my @line = split /\t/;
    if (exists $need{$line[0]}) {
     print OUT "$need{$line[0]}\n";
     $changed{$line[0]}=1;
    }
    else {print OUT $_}
   }
   
   # now we will add new lines
   foreach my $strain (keys %need) {
    unless (exists $changed{$strain}) {
     print OUT "$need{$strain}\n";
     $changed{$strain}=1;
    }
   }
   close IN;
   close OUT;
  } 
 }
 
 my $outputcount=1;
 my $html = "<table border=1>\n";
 # now make a report for the user to show what was changed and what was not changed.
 foreach my $file (keys %filetochange) {
  my $colspan=$#{$fileheaders{$file}}+4;
  $html .= "<tr><th colspan=".$colspan.">$fileinfo{$file};</th></tr>\n";
  $html .= "<tr><td><b>Count</b></td><td><b>CHANGED</b></td><td><b>".join ("</b></td><td><b>", @{$fileheaders{$file}})."</b></td></tr>\n";
  foreach my $line (@{$filetochange{$file}}) {
   my @line = split /\t/, $line;
   if (exists $changed{$line[0]}) {$html .= "<tr><td>$outputcount</td><td>Yes</td><td>".join ("</td><td>", @line)."</td></tr>\n"}
   else {$html .= "<tr><td>$outputcount</td><td><font color=\"#FF0000\"><b>No Priveleges because you are coming from $remote_host</b></font></td><td>".join ("</td><td>", @line)."</td></tr>\n"}
   $outputcount++;
  }
 }
 $html .= "</table>";

 
   print $cgi->header(-type=>'text/html', -cookie=>$cookie), start_html(-title=>'Strain Finder Multiple Strain Searches', -BGCOLOR=>'#FFFFFF',
            -TEXT=>'#000000'),
   html((h1(big('<center>StrainFinder Results.</center>'))),p,hr,p,"\n",
   start_form(), "<center>", 
   image_button(-name=>'submit', -value=>'Add New Strain', -src=>'/images/strainfinder/submit_all.jpg'), 
   p,"</center>",
   $html,), end_form(), end_html();
}



sub add_new {
 # a form to submit a new strain to the collection
  my $html = "<table border=1>"; # this will be the table
 my $filecount; # we are going to give each file a unique name.
 
 my %files;
 foreach my $f (@files) {$files{$f}=$fileinfo{$f}} 
 
 my %bckgnd=(
  Ec=>'E. coli',
  St=>'S. Typhimurium',
  Se=>'S. Enteritidis',
  Sy=>'S. Typhi',
  Sg=>'S. Gallinarum',
  Sd=>'S. Dublin',
  Vp=>'V. parahaemolyticus',
 );
 my @bckgnd = sort keys %bckgnd;
 
 push @bckgnd, "Ot";
 $bckgnd{'Ot'}='Other';


 my %create=(
  "Tdx"=>'Transduction',
  "Tsf"=>'Transformation',
  "Epor"=>'Electroporation',
  "Mate"=>'Mating',
  "Mut"=>'Mutagenesis',
  "Rs"=>'Red swap (Wanner Method)',
  "No"=>'Nothing'
 );
 my @create = sort keys %create;
 
 
 my %resist=(
  "Amp(R)"=>'Ampicillin',
  "Azt(R)"=>'Azetidine carboxylic acid',
  "Cam(R)"=>'Chloramphenicol',
  "DHP(R)"=>'Dehydroproline',
  "Gen(R)"=>'Gentamicin',
  "Kan(R)"=>'Kanamycin',
  "Nal(R)"=>'Nalidixic acid',
  "Neo(R)"=>'Neomycin',
  "Rif(R)"=>'Rifampicin',
  "Spc(R)"=>'Spectinomycin',
  "Str(R)"=>'Streptomycin',
  "Tet(R)"=>'Tetracycline',
  "Zeo(R)"=>'Zeomycin'
 );
 my @resist = sort keys %resist;
 

 print $cgi->header('text/html'), start_html(-title=>'Strain Finder Multiple Strain Searches', -BGCOLOR=>'#FFFFFF', -TEXT=>'#000000'),
  html("<p><h2>Please read the <a href=\"/straininstructions.html\">Instructions</a> before adding a strain to the collection.</h2></p>",
 "<p>Please note that you will need appropriate privileges to add a new strain. If you don't have privileges, \n",
 "contact <a href=\"mailto:redwards\@utmem.edu\">Rob</a></p>",start_form(), 
 "<center>", 
 image_button(-name=>'submit', -value=>'Add New Strain', -src=>'/images/strainfinder/submit_all.jpg'), 
 p,"</center>",
 "\nPlease choose a file to add the strain to:",p, 
 radio_group(-name=>'file', -values=>\@files, -labels=>\%files, -linebreak=>'true'), p,hr,p,
 "\nPlease enter the strain number (just enter the number as the leader will be added for you):",
 textfield('number', '', 5), "\n &nbsp; or check this box to automatically use the next number in the collection:",
 checkbox(-name=>'nextno', -label=>'', -checked=>'checked'),p,hr,p,"\n<b>Answer the following about the strain:</b>",p,hr,p,
 "\nWhat is the background of the strain?",p,
 radio_group(-name=>'bckgnd', -values=>\@bckgnd, -labels=>\%bckgnd, -linebreak=>'true'), p,hr,p,
 "\nIf you created the strain, was it created by:",p,
 radio_group(-name=>'create', -values=>\@create, -labels=>\%create, -default=>'-', -linebreak=>'true'), p,hr,p,
 "\nIf the strain was received from somewhere else, what was the original name: ", textfield('aka', '', 10,),
 "\n&nbsp; who did it come from: &nbsp; ", textfield('via', '', 20), p,hr,p,
 "\nIs this strain resistant to:", p,
 checkbox_group(-name=>'resist', -values=>\@resist, -labels=>\%resist, -linebreak=>'true', -default=>['-']), p,hr,p,
 "\nIs this strain:",p,checkbox(-name=>'XG', -value=>"XG", -label=>'X-gal'), " (<I>lac</I>) plus",p,
 checkbox(-name=>"XP", -value=>"XP", -label=>'X-phos'), "(<I>phoA</I>) plus",p,
 "\nPlease enter the donor &nbsp ", textfield("donor", '', "20"), " &nbsp and recipient &nbsp ",
 textfield("recip", '', "20"), p,hr,p, "\nPlease enter any other relavent information about this strain: ",p,
 textarea("genotype",'',5,100),p,hr,p, "\n<input type=submit name=submit value='Check New Strain'>", reset(),), end_html;

}



 
sub check_new {
 # get the information for a new strain, find the strain number and put it into the add strain loop!
 my $file=$cgi->param('file');
 
 unless ($file) {die "Couldn't get a file"}
 my $strainlist = substr($file, rindex($file, "/")+1);
 print STDERR "GOT $strainlist for $file\n";
 
 my $number=1;
 if ($cgi->param('number')) {$number = $cgi->param('number')}
 else {
  open (IN, $file) || die "Can't open $file";
  while (<IN>) {
   /^\w+?(\d+)/;
   if ($1 > $number) {$number=$1}
  }
  $number++;
 }
 
 my @strain;
 push (@strain,$strainlist.$number);
  
 # for re strains only, set the alias
 if ($cgi->param('aka')) {if ($strainlist eq "RE") {push (@strain, $cgi->param('aka'))}}
 else {if ($strainlist eq "RE") {push (@strain, '')}}
 
 if ($cgi->param('bckgnd')) {push (@strain, $cgi->param('bckgnd'))}

 my $straininfo = $cgi->param('genotype');
 if ($cgi->param('donor')) {$straininfo .= " donor: ". $cgi->param('donor') . " recipient: ". $cgi->param('recip')}
 if ($cgi->param('create')) {$straininfo .= " ".$cgi->param('create')}
 if ($cgi->param('aka')) {$straininfo .= " alias: ". $cgi->param('aka') . " via: ". $cgi->param('via')}
 foreach my $resist ($cgi->param('resist')) {$straininfo .= " ".$resist}
 if ($cgi->param('XG')) {$straininfo .= " XG+"}
 if ($cgi->param('XP')) {$straininfo .= " XP+"}
 
 push (@strain, $straininfo);
 
 # unless this is an RE strain, we just need to pull out the first element, and then join everything else
 unless ($strainlist eq "RE") {
  my $temp=shift(@strain);
  my $temp2=join " ", @strain;
  @strain=($temp, $temp2);
 }
 
 # now I think we have everything we need, lets put it into the checking routine.
 my $colspan=$#{$fileheaders{$file}}+4;
 my $html = "<table border=1>\n<tr><th colspan=".$colspan.">$fileinfo{$file};</th></tr>\n";
 $html .= "<tr><td><b>Count</b></td><td><b>".join ("</b></td><td><b>", @{$fileheaders{$file}})."</b></td></tr>\n";
 
 # these are the parameters that we will expect:
 # edittotal - total number of strains to edit
 # edit$i - strain that was edited and the info
 # strainfile$i - file 

 $html .= "<tr><td>1</td><td><input type=hidden name=edit1 value=\"".join ("\t", @strain)."\">";
 $html .= "<input type=hidden name=edittotal value=1><input type=hidden name=strainfile1 value=$file>";
 $html .= join ("</td><td>", @strain)."</td></tr>\n</table>\n";
 
 print $cgi->header('text/html'), start_html(-title=>'Strain Finder Multiple Strain Searches', -BGCOLOR=>'#FFFFFF', -TEXT=>'#000000'),
 html((h1(big('<center>StrainFinder Results.</center>'))),p,hr,p,"\n",
 start_form(),"\n",p,
 "<center>", 
 image_button(-name=>'submit', -value=>'Add New Strain', -src=>'/images/strainfinder/submit_all.jpg'), 
 p,"</center>",
 $html, 
 "<input type=submit name=submit value='Add Edited Strains'>", reset(),p),
 end_form(), "<p><small>Request from: $remote_host</small></p>", end_html();

 
 }
 
 
 
 
sub history {
 # here we are going to use ip addresses and a file history.txt to store history of searches.
 my ($search, $qfile, $min, $max, $case)=@_;
 my $file="$directory/history.txt";
 if ($search) { # we are going to write the history. If there is no search, we are going to read it and output a form
  my $one=$file.".1"; my $two=$file.".2"; my $three=$file.".3"; my $four=$file.".4";
  if (-e $four) {unlink ($four)}
  if (-e $three) {rename("$three", "$four")}
  if (-e $two) {rename("$two", "$three")}
  if (-e $one) {rename("$one", "$two")}
  rename("$file", "$one");
   
  my $strainlist = substr($qfile, rindex($qfile, "/")+1);
  open (IN, $one) || die "Can't open $one";
  open (OUT, ">$file") || die "Can't open $file";
  while (<IN>) {print OUT}
  print OUT "$remote_host\t",time,"\t$search\t$strainlist\t$min\t$max\t$case\n";
  close IN;
  close OUT;
 }
 else {
  my $html = "<table border=1><tr><td><b>Time</b></td><td>Run Again</td><td>Query</td><td>File</td>";
  $html .= "<td>Min</td><td>Max</td><td>Case</td></tr>\n";
  open (IN, $file) || die "Can't open $file";
  while (<IN>) {
   my ($ip, $time, @line) = split /\t/;
   if ($ip eq $remote_host) {
    my $time=localtime($time);
    $html .= "<tr><td>$time</td><td>Run Again</td><td>";
    $html .= join ("</td><td>", @line). "</td></tr>\n";
   }
  }

  $html .= "</table>";

  print $cgi->header('text/html'), start_html(-title=>'Strain Finder Multiple Strain Searches', -BGCOLOR=>'#FFFFFF', -TEXT=>'#000000'),
  html((h1(big('<center>StrainFinder History.</center>'))),p,hr,p,"\n",
  start_form(),"\n",p,
  "<center>", 
  image_button(-name=>'submit', -value=>'history', -src=>'/images/strainfinder/history_all.jpg'),p,"</center>",
  $html,p),
  end_form(), "<p><small>Request from: $remote_host</small></p>", end_html();
 }
}

sub check_privileges {
 my %allow; my $allow_list;
 # we are going to use cookies for the privileges. If the user doesn't have a cookie, we'll check
 # privileges.txt. If they do, we'll ignore it.

 # first, see if they have a cookie.

 my $cookie_reply=$cgi->cookie('SFprivileges');
 open (IN, "$directory/privileges.txt") || die "Can't open $directory/privileges.txt";
 my $host_seen;
 while (<IN>) {
  chomp;
  my @line=split /\t/;
  #next unless ($line[0] eq $remote_host);
  next unless ($remote_host =~ /^$line[0]/);
  $host_seen=1;
  foreach my $l (@line) {
   next unless (-e "$directory/$l");
   $allow{"$directory/$l"}=1;
   $allow_list.="$l,";
  } # save all the files that they are allowed to access
 }
 
 unless ($host_seen) {
  foreach my $allowed (split /\,/, $cookie_reply) {
   next unless (-e "$directory/$allowed");
   $allow{"$directory/$allowed"}=1;
   $allow_list.="$allowed,"
  }
  
### We shouldn't try and do this
  # now we need to update privileges.txt

#  `cp -f $directory/privileges.txt $directory/privileges.1.txt`;
#  open (OUT, ">>$directory/privileges.txt") || die "Can't append to $directory/privileges.txt";
#  print OUT "$remote_host\t", join ("\t", (split /\,/, $allow_list)), "\n"; # note this is shit. But %allow has the full path and allow_list has the names
#  close OUT;
 }
 
 

 $allow_list =~ s/\,$//;

 # generate the cookie to return
 my $cookie=$cgi->cookie(-name=>'SFprivileges', -value=>$allow_list, -expires=>"+365d");
 return \%allow, $cookie;
}

sub split_search {
 my $search = shift;
 my @parts=split /\s+/, $search;
 my @or; my @and;
 my $searchterm=shift(@parts);
 while (@parts) {
  my $term=shift(@parts);
  next if ($term eq "AND");
  if ($term eq "OR") {
   $term=shift(@parts);
   push @or, $term;
  }
  else {push @and, $term}
 }
 return $searchterm, \@or, \@and;
} 

