#####################################################################
#!/usr/local/bin/perl -w
# Programmer: Kuan Chang
# Date: 05/01/2001
# Version: 1.1
#####################################################################

use strict;
use CGI qw(:standard *table *TR *th *td *ul *ol);
use Gramene::Page;
use Gramene::DB;
use Gramene::Utils 'pager';
#####################################################################

use constant GR_PREFIX => 'GR:';
use constant TRAIT => 5;
use constant EXE_NAME => '/db/mutant/search_mutant';      #Modified for quick search --- 04/02/02 

#####################################################################

my $page_no = param('page_no') || 1;
# check which types of query
my $input = param('query');

# switch to lower cases
$input =~ tr/A-Z/a-z/;
$input = remove_mutant_prefix($input);

# if nothing, redirect back to home page
print redirect("/rice_mutant/index.html") if (remove_spaces_on_both_sides($input) eq "");

# CSHL true color   
my $co_tag = '<span class="matching">'.$input.'</span>';

#####################################################################
# Connect to the database
my $dbh  = initialize_database();
my @candidates;
if(is_digit($input)){
  # only one possible match if only digit.  Assume the digit is mutant id
  @candidates = get_possible_match_II($dbh,$input);
} else {
  @candidates = get_possible_matches($dbh,$input);
}

#####################################################################
my $cgi = new CGI;

my $table_only = $cgi->param("table");     #Added for quick search --- 04/02/02

if(scalar(@candidates) == 1 && !$table_only){
  terminate_database($dbh);
  my $only_you = get_mutant_key($candidates[0]); 
  #print redirect("./".EXE_NAME."?id=$only_you");
  print redirect(EXE_NAME."?id=$only_you");	
}

#####################################################################

my $page = Gramene::Page->new(Apache->request);

unless( ( $table_only ) && ( $table_only eq "1" ) ) {       #Added for quick search --- 04/02/02 

    print $cgi->header,
          $page->start_html(-title=>"Search for $input");
    print $page->start_body;

    print_mutant_search_area();

} #Added for quick search --- 04/02/02 


#Added for quick search --- 04/02/02
if($table_only && $table_only eq "1" ) {
    print( "<br></br>" );
}

if($#candidates+1 == 0){
    print h1("Sorry! Cannot find any information about <i>$input</i>");
} else {
   
    print h1("Summary for <i>$input</i>");
    print_suspects($dbh,\@candidates, $input,$table_only, $page_no,$cgi->url(-relative=>1,-query=>1));
   
}

unless( ( $table_only ) && ( $table_only eq "1" ) ) {     #Added for quick search --- 04/02/02  

    print $page->end_body;

} #Added for quick search --- 04/02/02 

terminate_database($dbh);

#####################################################################
# Utility functions
# post: return 1 if true; otherwise return 0 
#####################################################################
sub is_digit{
  my $query = shift;
  $query =~ s/^\s+//;
  $query =~ s/\s+$//;
  if ($query =~ /^\d+$/ ){
    return 1;
  }else{ 
    return 0;
  }
}

sub remove_mutant_prefix{

  my ($query) = @_;
  my $GR_PREFIX = GR_PREFIX;
  $query =~ s/^$GR_PREFIX//i;
  return $query;
}

sub remove_spaces_on_both_sides{
  my $query = shift;
  $query =~ s/^\s+//;
  $query =~ s/\s+$//;
  return $query;
}

# post: add CSHL style to text to highlight matching input
sub highlight_patterns{
  my ($text, $input) = @_;
  $input = quotemeta($input);
  $text =~ s/($input)/<span class="matching">$1<\/span>/ig;
  return $text;  
}

#######################################################################
# pre: assume the input pattern contains non-digit
# post: return all possible matches from mutant name, mutant symbol, 
#       and phenotypic description.   
#       Given priority (mutant name or symbol) > phenotypic description
#######################################################################
sub get_possible_matches {
  my ($dbh,$pattern) = @_;
  die "Invalid input in get_possible_matches" unless defined $pattern;
  my %seen;
 # my $sth = $dbh->prepare("SELECT mutant_id FROM mutant WHERE lower(mutant_name) like '%$pattern%' OR lower(mutant_symbol) like '%$pattern%'") || die $dbh->errstr;
  
###error prone, such as $pattern ='Miz 4'
#  my $sth = $dbh->prepare("SELECT mutant_id FROM mutant_list WHERE lower(mutant_name) like '%$pattern%' OR lower(mutant_symbol) like '%$pattern%' OR lower(mutant_synonym) like '%$pattern%'") || die $dbh->errstr;
  
 my $sth = $dbh->prepare("SELECT mutant_id FROM mutant_list WHERE lower(mutant_name) like ? OR lower(mutant_symbol) like ? OR lower(mutant_synonym) like ?") or die $dbh->errstr;

$sth->bind_param(1,"%$pattern%");
$sth->bind_param(2,"%$pattern%");
$sth->bind_param(3,"%$pattern%");


  $sth->execute || die "Execute: ", $sth->errstr;
  my $sth2 =  $dbh->prepare(" SELECT mutant_id FROM mutant WHERE lower(mutant_description) like ?") || die $dbh->errstr;

$sth2->bind_param(1,"%$pattern%");
  $sth2->execute || die "Execute: ", $sth2->errstr;
  my @matches = ();
  while(my $row = $sth->fetchrow_array){
    $seen{$row}++;
    push @matches, $row;
  }
  $sth->finish;
  
  while(my $row = $sth2->fetchrow_array){
    if(!$seen{$row}){
      push @matches, $row;
    }
  }
  $sth2->finish;
  return @matches; 
}

sub get_possible_match_II {
my ($dbh,$id) = @_;
die "Invalid input in get_possible_match_II" unless defined $id;
my $sth = $dbh->prepare("SELECT mutant_id FROM mutant where mutant_id = ?") || die $dbh->errstr;

$sth->bind_param(1,$id);

$sth->execute || die "Execute: ", $sth->errstr;
  my @match = ();
  while(my $row = $sth->fetchrow_array){
    push @match, $row;
  }
  $sth->finish;
return @match;
}

#####################################################################
#####################################################################
# pre: id is the mutant id
# post: add mutant prefix to ids; key to show its mutant secret
#####################################################################
sub get_mutant_key {
  my $id = shift;
  my $GR_PREFIX = GR_PREFIX;
  die "Invalid input in add_mutant_prefix" unless defined $id;
  my $mutant_phrase = $GR_PREFIX; 
  my $length = 7 - length($id);
  for my $x (1 .. $length){
      $mutant_phrase .= "0";
  }
  $mutant_phrase .= $id;
  return $mutant_phrase;
}

#####################################################################
sub print_suspects {
   my ($dbh,$suspects_ref, $input,$table_only,$page_no,$url) = @_;

   my ($pager,$data); 
   
   if($table_only && $table_only eq "1"){  # for quick search
        
      $data = $suspects_ref;

      print start_table({-border=>'1', -width=>'98%',-cellpadding=>0,-cellspacing=>0, -align=>'center'});
     # check plural or not
     if($#$suspects_ref>0) {
       print TR({-class=>'datatitle', -align=>'center'}, 
	  th('Candidate Rice Genes'."    (".($#$suspects_ref+1)." terms found)"));
      }
      else {
         print TR({-class=>'datatitle', -align=>'center'}, 
	   th('Candidate Rice Gene'."    (".($#$suspects_ref+1)." term found)"));
      }
      print end_TR, end_table;


   }else{
   
    ( $pager, $data ) = pager(
    current_page       => $page_no,
    url                => $url,
    entries_per_page   => 25,
    data               => $suspects_ref,
   );


    print qq{
   	 <center><table cellspacing=3 cellpadding=3 border=0 width="98%">
  	  <tr><td align="center" colspan="5">$pager</td></tr>
  	  </table></center>
    };
 
  } 
  print start_table({-border=>'1', -width=>'98%',-cellpadding=>4,-cellspacing=>1, -align=>'center'});
 
   print TR({-align=>"center", -class=>"datatitle"},
	  th(['Gene Name','Gene symbol','Synonym','Phenotypic Description','Gramene ID']));  


  # print start_TR({-class=>'searchbody'}), start_td;
  my $count = 0;
  foreach my $suspect (@$data){ #@$suspects_ref if $table_only
    if($count % 2 == 0) {
      print start_TR({-class=>'databody', -align=>'center'});
    } else {
      print start_TR({-align=>'center'}); 
    }
    #print td($count+1);

# print td(a({-href=>EXE_NAME."?id=".get_mutant_key($suspect)}, get_mutant_key($suspect)));
  
    my $yoyo = highlight_patterns(get_core_mutant_info($dbh,'mutant_name', $suspect),$input);
    # print td(p({-align=>'left'},$yoyo));
    print td({-align=>'left'}, a({-href=>EXE_NAME."?id=".get_mutant_key($suspect)}, $yoyo));

    my $symbol = highlight_patterns(get_core_mutant_info($dbh,'mutant_symbol',$suspect),$input);
    print td($symbol);

  
    my $synonym = get_mutant_synonym($dbh,$suspect);
   
    $synonym ? print td(highlight_patterns($synonym,$input)) : print td("&nbsp;&nbsp");
  
    my $desc = get_core_mutant_info($dbh,'mutant_description', $suspect);
    if(length($desc)>200){  
       my @descs = split(/\./,$desc);
       $desc = $descs[0];     #only display the first sentence if desc is too long.
       my $more_index = 1;
       if(substr($desc,-2,1) eq ' '){
	  $desc = $desc.'.'.$descs[1];
	  $more_index = 2;
       }
       if($descs[$more_index]){
	 $desc = $desc.'. (more ...)';
       }
    }    

    print td(p({-align=>'left'}, highlight_patterns($desc, $input) || 'No Phenotypic Description Available'));
 
   print td(get_mutant_key($suspect)); #mutant id
    print end_TR;
    $count += 1;
  }
  print end_table;
  #print end_td,end_TR,end_table;
}

#####################################################################
### database routines
sub exist_mutant_id {
  my ($dbh,$id) = @_;
  die "Invalid input in exist_mutant_id" unless defined $id;
  my $sth = $dbh->prepare("SELECT mutant_symbol FROM mutant WHERE mutant_id = $id") || die $dbh->errstr;
  $sth->execute || die "Execute: ", $sth->errstr;
  my $row = $sth->fetchrow_array;
  $sth->finish;
  if ($row == ""){
    return 0;
  }

  return 1;
}

#####################################################################
# one function fits all
# pre: search info in mutant; given its mutant id
# post: return its info
#####################################################################
sub get_core_mutant_info {
  my ($dbh,$column_name, $id) = @_;
  die "Invalid input in get_mutant_info" unless defined $id;
  my $sth = $dbh->prepare("SELECT $column_name FROM mutant WHERE mutant_id = ?") || die $dbh->errstr;
  $sth->bind_param(1,$id);
  $sth->execute || die "Execute: ", $sth->errstr;
  my $info = $sth->fetchrow_array;
  $sth->finish;
  return $info;
}

sub get_mutant_synonym{

   my ($dbh,$id)=@_;
    die "Invalid input in get_mutant_synonym" unless defined $id;
   my $sth = $dbh->prepare("SELECT mutant_synonym FROM mutant_synonym WHERE mutant_id = ?") || die $dbh->errstr;
   $sth->bind_param(1,$id);
    $sth->execute || die "Execute: ", $sth->errstr;
  my $synonym = $sth->fetchrow_array;
  $sth->finish;
  return $synonym;
   
}

sub initialize_database {
  # obsolete
  #my $dbh =  DBI->connect(MutantDataSource, MutantDBUser, MutantDBPassword, MutantDBOptions); 

  my $dbh;
  eval{ 
       $dbh = Gramene::DB->new('mutant'); 
  }; 
 
  if($@){  
        die "DB connection failed: $@\n";  
     }  

  return $dbh;
}

sub terminate_database{
  my $dbh=shift;
  #Gramene::DB' destory method will call disconnect
  #$dbh->disconnect();
}


#################
sub print_mutant_search_area {
    my $self = url(-relative=>1);
    print start_form(-method=>'GET', -action=>"search_core");


  print <<SEARCH_AREA;
&nbsp;<img src="/images/icons/grain_icon.jpg" alt="grain_icon" height="16" width="16">
<a href="/rice_mutant/index.html" class="gopage">Gene Home</a> |
<a href="/rice_mutant/gene_search.html" class="gopage">Search</a> |
<a href="/rice_mutant/gene_submit.html" class="gopage">Submit</a> |
<a href="/rice_mutant/gene_help.html" class="gopage">Help Documents</a> |
<a href="/tutorials/mutant.html" class="gopage">Tutorial</a> |
<a href="/documentation/faq/mut_faq.html" class="gopage">FAQ</a>
<p></p>
<table align="center" cellspacing="0" cellpadding="3" border="0" width="98%" align=center>
  <tr><th align=center class=searchtitle>Gene Search</th></tr>
  <tr align=center class=searchbody>
    <td align=center>&nbsp;&nbsp;&nbsp;&nbsp;<input type=text value="" framewidth=4 name=query size=40 maxlength=256>&nbsp;&nbsp;&nbsp;&nbsp;<input name=btn type=submit value="Search">&nbsp;&nbsp;<input name=Clear type=reset value="Clear">
      <br><span class="alert">Search by Gene Symbol, Gene Name, Gramene Accesssion&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>[e.g. <a href="/db/mutant/search_mutant?id=GR:0060198">dwarf-15</a> or <a href="/db/mutant/search_mutant?id=GR:0060198">GR:0060198</a>]&nbsp;&nbsp;<a href="/rice_mutant/Mutant_Help1.html">HELP</a> 
    </td>
  </tr>
</table>
SEARCH_AREA
  
    print end_form();
    print "<hr>";
}
