#####################################################################
#!/usr/local/bin/perl -w
# Programmer: Kuan Chang
# Date: 05/22/2002
# Version: 2.2
#####################################################################

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

use constant HOME => '../../plant_ontology/index.html';

use constant EXE_NAME => '/db/ontology/search_term';

my $entries_per_page = 25;


use constant BASIC_TERM_TYPE => 4;


my %term_type_ids=(
       'GO' => 4,
       'PO' => 6,
       'TO' => 5,
       'GRO' =>7,
       'EO' => 9,
       'GR_tax' => 10
    );
  
####################################################################
my $cgi = new CGI;
my $table_only = $cgi->param("table");     #Added for quick search --- 04/02/02     
my $page_no = param('page_no') || 1; 


#check which types of query
my $input = param('query');
my @raw_ontology_types = param('ontology_type');
my @ontology_types;
foreach my $type (@raw_ontology_types){
    push @ontology_types, $term_type_ids{$type};
    if($type eq 'GO'){
	push @ontology_types, (2, 3); # another GO type ids
    }elsif($type eq 'PO'){
	push @ontology_types, (11); # PO growth stage
    }
}

$input =~s/^\s+|\s+$//g;
my $co_tag = "";                                                                 
$co_tag = '<span class="matching">'.$input.'</span>';
# print redirect("$HOME") if (remove_spaces_on_both_sides($input) eq "");

print redirect(HOME) if (remove_spaces_on_both_sides($input) eq "") && ! $table_only;

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

my @candidates = get_possible_matches($dbh,$input,@ontology_types);

my $page;


unless( ( $table_only ) && ( $table_only eq "1" ) ) {       #Added for quick search --- 04/02/02 
   warn( "==>foo ".caller );
   $page = Gramene::Page->new(Apache->request);

    print $cgi->header,
          $page->start_html(-title=>"Search for $input");
    print $page->start_body;
    # print "whatever: @ontology_types";
    #print_top("Search for $input");
    print_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) || ($#candidates+1 == 0 )){
  if($#ontology_types == -1){
    print h1("Sorry! Cannot find any information about <i>$input</i>");
  }
  else{
    print h1("Sorry! Cannot find any information about <i>$input</i> in ". join(" & ", @raw_ontology_types));
  }
} else {
  print h1("Summary for <i>$input</i>");
  print_suspects($dbh,\@candidates, $input,$table_only, $page_no,$cgi->url(-relative=>1,-query=>1),$entries_per_page );
}

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);

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

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; 
    eval{  
      $dbh = Gramene::DB->new('ontology');  
    };  
  
    if($@){   
        die "ontology DB connection failed\n";   
    }   



  return $dbh;
}

sub get_possible_matches{
    my ($dbh,$pattern,@type_ids) = @_;
    return unless $pattern;

    $pattern = uc($pattern);
    my $sql = q[
	SELECT term.term_id
	FROM   term
	LEFT   join term_definition
	ON     term.term_id = term_definition.term_id
	LEFT   join term_synonym
	ON     term.term_id = term_synonym.term_id
	WHERE  (UPPER(term_accession) like ?
	OR     UPPER(term_name) like ?
	OR     UPPER(definition) like ?
	OR     UPPER(synonym_name) like ?
	)
    ];

    my $type_condition = '';
    foreach my $type_id (@type_ids){
	if($type_condition){
	    $type_condition.= " OR term_type_id = $type_id ";
	}else{
	    $type_condition = " term_type_id = $type_id ";
	}

    }

    $sql .= " AND ( $type_condition ) "  if $type_condition;

    
    my $sth =$dbh->prepare($sql);
    $sth->execute(("%$pattern%","%$pattern%","%$pattern%","%$pattern%"));


    my @matches = ();
    my %seen;
    while(my $row = $sth->fetchrow_array){
	unless($seen{$row}++){
	    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=?")
    || die $dbh->errstr;
  $sth->bind_param(1,$id);
  $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=?") || die $dbh->errstr;
  $sth->bind_param(1,$id);
  $sth->execute || die "Execute: ", $sth->errstr;
  my ($accession)=$sth->fetchrow_array; 
 
  $sth->finish;
  return $accession;
}

sub print_suspects {
  my ($dbh,$suspects_ref, $input,$table_only,$page_no,$url,$entries_per_page ) = @_;
    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'});
	if($#$suspects_ref>0) {
  		print TR({-class=>'datatitle', -align=>'center'}, 
	       th('Candidate Term'."    (".($#$suspects_ref+1)." terms found)"));
   	}
	else {
  		print TR({-class=>'datatitle', -align=>'center'}, 
	      th('Candidate Term'."    (".($#$suspects_ref+1)." term found)"));
        }
  	print end_TR, end_table;
  
  }else{ 
    
    ( $pager, $data ) = pager( 
    current_page       => $page_no, 
    url                => $url, 
    entries_per_page   => $entries_per_page , 
    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(['#', 'Term Accession', 'Aspect', 'Term Name', 'Synonym', 'Definition']));

  # print start_TR({-class=>'searchbody'}), start_td;
  my $count = ($page_no -1)* $entries_per_page  +1 ; 
  foreach my $suspect (@$data){
    if($count % 2 == 0) {
      print start_TR({-class=>'databody', -align=>'center'});
     } else {
      print start_TR({-align=>'center'}); 
     }
    print td($count);
    print td(a({-href=>EXE_NAME."?id=".get_accession($dbh,$suspect)}, get_accession($dbh,$suspect)));
    print td(get_term_type($dbh,$suspect));
    my $yoyo = highlight_patterns2(get_name($dbh,$suspect),$input);
    print td(p({-align=>'left'},$yoyo));
my $all_synonym = highlight_patterns2(get_synonym($dbh,$suspect), $input);
    print td(p({-align=>'left'}, $all_synonym  || 'None'));		
    print td(  p({-align=>'left'}, highlight_patterns2(get_definition($dbh,$suspect), $input) || 'No Definition Available'));

    print end_TR;
    $count += 1;
  }

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

sub highlight_patterns {
  my ($input,$co_tag,$text) = @_;
  $input = quotemeta($input);
  $text =~ s/$input/$co_tag/g;
  return $text;
}

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

sub get_term_type{
  my ($dbh,$id) = @_;
  die "Invalid input in get_name" unless defined $id;
  my $sth = $dbh->prepare("SELECT term_type FROM term, term_type 
  WHERE term_type.term_type_id = term.term_type_id 
  AND  term_id=?")
        || die $dbh->errstr;
  $sth->bind_param(1,$id);
  $sth->execute || die "Execute: ", $sth->errstr;
  my ($term_type) = $sth->fetchrow_array;
  $sth->finish;
  return $term_type;

}

sub get_synonym {
  my ($dbh,$id) = @_;
  die "Invalid input in get_synonym" unless defined $id;
  my $sth = $dbh->prepare("SELECT synonym_name FROM term_synonym WHERE term_id=?")
    || die $dbh->errstr;
  $sth->bind_param(1,$id);
  $sth->execute || die "Execute: ", $sth->errstr;
  # my $synonym = $sth->fetchrow_array;
  # my @reference_ids = ();
 my $synonym;	
  while(my $row = $sth->fetchrow_array){
    $synonym .= $row .", ";
  }
  
  if(defined $synonym){
     $synonym =~ s/, $/./;
  }
		
  $sth->finish;
  return $synonym;
}

sub get_definition {
  my ($dbh,$id) = @_;
  die "Invalid input in GetDefinition" unless defined $id;
  my $sth = $dbh->prepare("SELECT definition FROM term_definition WHERE term_id=?")
    || die $dbh->errstr;
  $sth->bind_param(1,$id);
  $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 <<SMALLBAR;
<table>
  <tr>
    <td align="LEFT">&nbsp;<img src="/images/icons/grain_icon.jpg" alt="grain_icon" height=16 width=16 align="top">
    </td>
    <td align="LEFT">
        &nbsp;<a href="/plant_ontology/index.html#ontology" class="gopage"><b>Current Ontologies</b></a>&nbsp; 
        |&nbsp;<a href="/plant_ontology/index.html#doc" class="gopage"><b>Documentation</b></a>&nbsp; 
        |&nbsp;<a href="/plant_ontology/index.html#evi" class="gopage"><b>Evidence code</b></a>&nbsp; 
        |&nbsp;<a href="/plant_ontology/index.html#ftp" class="gopage"><b>FTP</b></a>&nbsp; 
        |&nbsp;<a href="/plant_ontology/index.html#sub" class="gopage"><b>Ontology suggestion</b></a>&nbsp; 
        |&nbsp;<a href="/plant_ontology/index.html#assoc" class="gopage"><b>Associations</b></a>&nbsp; 
        |&nbsp;<a href="/plant_ontology/index.html#pub" class="gopage"><b>Publications</b></a>&nbsp;
        |&nbsp;<a href="/tutorials/ontologies.html" class="gopage"><b>Tutorial</b></a>  &nbsp;
       |</b>&nbsp;<a href="/fom/cache/1.html" class="gopage"><b>FAQ</b></a>  &nbsp;
       |</b>&nbsp;<a href="/documentation/ontology_help.html" class="gopage"><b>HELP</b></a>  &nbsp;
 
    </td>
  </tr>
</table>
<p></p>
        <form action="/db/ontology/search" method=get name=f>
          <table align=center border=0 cellspacing=0 cellpadding=1 width='98%'>
            <tr>
            <th colspan=3 align=center class=searchtitle>Ontology Database</th>
            </tr>
            <tr align=center class=searchbody>
              <td align=center width=30%><span class="alert">Type ID or keyword to search</span></td>
              <td align=left width=40%><input type=text value="" framewidth=4 name=query size=55 maxlength=256></td>
              <td align=center width=30%>&nbsp;<input name=btn type=submit value="Search"> &nbsp;<input name=Clear type=reset value="Clear">
                                                                                                                             
              </td>
                                                                                                                             
                                                                                                                             
            </tr>
            <tr class=searchbody>
                                                                                                                             
              <td align=center nowrap width=30%>
              select ontology (optional) &nbsp;
              </td>
              <td align=left nowrap width=30%>
 
                 <input type=checkbox name=ontology_type value="GO">Gene (GO)&nbsp;
                 <input type=checkbox name=ontology_type value="PO">Plant structure (PO)&nbsp;
                 <input type=checkbox name=ontology_type value="GRO">Growth stage (GRO)<br>
                 <input type=checkbox name=ontology_type value="TO">Trait (TO) &nbsp;&nbsp;
                 <input type=checkbox name=ontology_type value="EO">Environment (EO)&nbsp;&nbsp;
                 <input type=checkbox name=ontology_type value="GR_tax">Taxonomy(GR_tax)
              </td>
              <td align=center width=30%>[e.g. <a href="/db/ontology/search?query=flower&btn=Search">flower</a> or <a href="/db/ontology/search_term?id=TO:0000303&ontology_type=TO&btn=Search">TO:0000303</a>]
                          </td>
            </tr>
<tr><td>&nbsp;</td></tr>
<tr>
<td align="center" valign="CENTER" colspan="3">
<hr width="100%">
</tr>
</td>
          </table>
        </form>


SMALLBAR

}

sub print_top {
  my $title = shift;

#Already done before here:
# print table( {-border=>'0',
#		-cellpadding=>'0',
#		-width=>'100%'},
#  TR(td( {-width=>'150', -valign=>'TOP'} ), 
#		  td( p( {-align=>'CENTER'}, a( {-href=>'/index.html'}, img( {-src=>'/gramene/images/icons/gramene_banner.gif',
#									      -alt=>'[Gramene Home]',
#									      -border=>'0'} ) ) ) ) ) );
 # print "<hr>";
 # print h1($title);
}


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

