#####################################################################
#!/usr/bin/perl -w
# Programmer: Kuan Chang
# Date: 10/18/2001
# Version: 2.1
#####################################################################

use strict;
use DBI;
use CGI qw(:standard *table *TR *th *td *ul *ol);
use GramenePage;
use CSHL::Config;

#constants
my $HOME = '../../plant_ontology/index.html';
my $GO_PREFIX = "GO:";
my $TO_PREFIX = "TO:";
my $TRAIT = 5;
my $EXE_NAME = '/perl/ontology/search_term';

use vars qw ( $input $co_tag );

#check which types of query
$input = param('query');
$input =~ tr/A-Z/a-z/;
$co_tag = '<span class="matching">'.$input.'</span>';
#print redirect("$HOME") if (remove_spaces_on_both_sides($input) eq "");

# Connect to the database
my $dbh  = initialize_database();

my @candidates;
if(is_digit($input)){
  @candidates = get_possible_matches_II($dbh,$input);
} else {
  @candidates = get_possible_matches($dbh,$input);
}

#if($#candidates+1 == 1){
#  terminate_database($dbh);
#  my $only_you = get_accession($candidates[0]); 
#  print redirect("./$EXE_NAME?id=$only_you");
#}

#my $page = GramenePage->new(Apache->request);
my $cgi = new CGI;
#print $cgi->header,
 #     $cgi->start_html(-title=>"Search for $input",
	#		 -style=>{'src'=>'/stylesheets/gramene.css'});
print header();
#print $page->start_body;

#print_top("Search for $input");
#print_search_area();
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(\@candidates, $input);
}
#print_bottom();
#print $page->end_body;
#terminate_database($dbh);

sub is_digit{
  my $query = shift;
  $query =~ s/^\s+//;
  $query =~ s/\s+$//;
  if ($query =~ /^\d+$/ ){
    return 1;
  }else{ 
    return 0;
  }
}

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

sub initialize_database {
  my $dbh =  DBI->connect(OntologyDataSource, OntologyDBUser, OntologyDBPassword,   
{
        'PrintError'  => 1, 
        'RaiseError'  => 1,
        'LongReadLen' => 3000,
        'LongTruncOk' => 1,
      }); 

  return $dbh;
}

sub get_possible_matches {
  my ($dbh,$pattern) = @_;
  die "Invalid input in get_possible_matches" unless defined $pattern;
  my %seen;
  my $sth = $dbh->prepare("SELECT term_id FROM term WHERE lower(term_name) like '%$pattern%' UNION SELECT term_id FROM term_synonym WHERE lower(synonym_name) like '%$pattern%'") || die $dbh->errstr;
  $sth->execute || die "Execute: ", $sth->errstr;
  my $sth2 =  $dbh->prepare(" SELECT term_id FROM term_definition WHERE lower(definition) like '%$pattern%'") || die $dbh->errstr;
  $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_matches_II {
  my ($dbh,$id) = @_;
  die "Invalid input in get_possible_matches_II" unless defined $id;
  my $sth = $dbh->prepare("SELECT term_id FROM term WHERE term_accession=$id") || die $dbh->errstr;
  $sth->execute || die "Execute: ", $sth->errstr;
  my @matches = ();
  while(my $row = $sth->fetchrow_array){
    push @matches, $row;
  }
  $sth->finish;
  
  return @matches; 
}


sub get_name {
  my ($dbh,$id) = @_;
  die "Invalid input in get_name" unless defined $id;
  my $sth = $dbh->prepare("SELECT term_name FROM term WHERE term_id=$id")
    || die $dbh->errstr;
  $sth->execute || die "Execute: ", $sth->errstr;
  my $term_name = $sth->fetchrow_array;
  $sth->finish;
  return $term_name;
}

sub get_accession {
  my ($dbh,$id) = @_;
  die "Invalid input in GetAccessionID" unless defined $id;
  my $sth = $dbh->prepare("SELECT term_accession FROM term WHERE term_id=$id") || die $dbh->errstr;
  $sth->execute || die "Execute: ", $sth->errstr;
  my $sth2 = $dbh->prepare("SELECT term_type FROM term WHERE term_id=$id") || die $dbh->errstr;
  $sth2->execute || die "Execute: ", $sth2->errstr;
  my $exact_accession;
  if($sth2->fetchrow_array == $TRAIT) {
     $exact_accession = $TO_PREFIX;
  }
  else {
    $exact_accession = $GO_PREFIX;
  }
  my $accession = $sth->fetchrow_array;
  my $length = 7 - length($accession);
  for my $x (1 .. $length){
      $exact_accession .= "0";
  }
  $exact_accession .= $accession;
  $sth->finish;
  $sth2->finish;
  return $exact_accession;
}

sub print_suspects {
  my ($suspects_ref, $input) = @_;
  # my $pattern = shift;
  # my @suspects = get_possible_matches($dbh,$pattern);
  my $ctag = '<span class="matching">'.$input.'</span>';
  print ( "<center><h2>Ontology Search Result</h2></center>" );
  print start_table({-border=>'1', -width=>'98%',-cellpadding=>0,-cellspacing=>0, -align=>'center'});
if($#$suspects_ref>0) {
  #print TR({-class=>'datatitle', -align=>'center'}, 
	#   th('Candidate Term'."    (".($#$suspects_ref+1)." terms found)"));
  print TR({-class=>'datatitle', -align=>'center'}, 
	   th( ($#$suspects_ref+1)." candidate ontology terms have been found.") );
}
else {
  #print TR({-class=>'datatitle', -align=>'center'}, 
	#   th('Candidate Term'."    (".($#$suspects_ref+1)." term found)"));
  print TR({-class=>'datatitle', -align=>'center'}, 
	   th( ($#$suspects_ref+1)." candidate ontology term has been found.") );
}
  print end_table;
  print start_table({-border=>'1', -width=>'98%',-cellpadding=>4,-cellspacing=>1, -align=>'center'});
  print TR({-align=>"center", -class=>"datatitle"},
	  th(['#', 'TO ID | GO ID', 'Term Name', 'Definition']));

  # print start_TR({-class=>'searchbody'}), start_td;
  my $count = 0;
  foreach my $suspect (@$suspects_ref){
    if($count % 2 == 0) {
      print start_TR({-class=>'databody', -align=>'center'});
     } else {
      print start_TR({-align=>'center'}); 
     }
   # print td([a({-href=>"./$EXE_NAME?id=".get_GO_accession($suspect)}, get_GO_accession($suspect)), highlight_patterns(get_name($dbh,$suspect)), p({-align=>'left'}, highlight_patterns(get_definition($suspect)) || 'No Definition Available')]);
    print td($count+1);
    print td(a({-href=>"$EXE_NAME?id=".get_accession($dbh,$suspect)}, get_accession($dbh,$suspect)));
    my $yoyo = highlight_patterns2(get_name($dbh,$suspect),$input);
    print td(p({-align=>'left'},$yoyo));
    print td(  p({-align=>'left'}, highlight_patterns2(get_definition($suspect), $input) || 'No Definition Available'));

    print end_TR;
    $count += 1;
  }

 #print ul(li([map { a({-href=>"./$EXE_NAME?id=".get_GO_accession($_)}, get_name($dbh,$_) . " (".get_GO_accession($_).")") } @suspects]));
  print end_table;
}

sub highlight_patterns {
  my $text = shift;
  $text =~ s/$input/$co_tag/g;
  return $text;
}

sub highlight_patterns2{
  my ($text, $input) = @_;
  $text =~ s/($input)/<span class="matching">$1<\/span>/ig;
  return $text;  
}


sub get_definition {
  my $id = shift;
  die "Invalid input in GetDefinition" unless defined $id;
  my $sth = $dbh->prepare("SELECT definition FROM term_definition WHERE term_id=$id")
    || die $dbh->errstr;
  $sth->execute || die "Execute: ", $sth->errstr;
  my $term_definition = $sth->fetchrow_array;
  $sth->finish;
  return $term_definition;
}

sub print_search_area {
  my $self = url(-relative=>1);
  #print "<p align='center'><font size=-2>Type in ID or keyword to search for.</font>\n"; 
 # print table({-width=>'100%'},
 # TR({-class=>'searchtitle'},th("Search Gramene Ontology Database")));
  print start_form(-method=>'GET', -action=>"$self");
  print table({-width=>'100%', -align=>'center', -cellspacing=>1, -cellpadding=>0}, 
	'<th align=center class=searchtitle>Ontology Database</th><tr align=center class=searchbody><td align=center><span class=alert>Type in ID or keyword to search for</span>&nbsp;&nbsp;&nbsp;<input type=text value="" framewidth=4 name=query size=50 maxlength=256>&nbsp;&nbsp;&nbsp;&nbsp;<input name=btn type=submit value="Ontology Search"> &nbsp;&nbsp;<input name=Clear type=reset value="Clear"><p>[e.g. <a href="/perl/ontology/search_term?id=TO:0000303">cold tolerance</a> or <a href="/perl/ontology/search_term?id=TO:0000303">303</a>] </p></td></tr>' 
);
	  
#<td align=center><input type=text value="" framewidth=4 name=query size=55 maxlength=256><br><input name=btn type=submit value="GO Search"><input name=btn type=submit value="TO Search"></td
  print end_form();
 # print "<br>", "<hr>";
  print "<hr>";	
}



#sub terminate_database{
#  my($dbh)=@_;
#  $dbh->disconnect();
#}
