#####################################################################
#!/usr/bin/perl -w
# Programmer: Kuan Chang
# Date: 12/27/2001
# Version: 1.1
#####################################################################

use strict;
use lib '/export/share_more/ensembl/gramene_ensembl/perl/mutant/';

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

#####################################################################
#constants
my $HOME = '../../rice_mutant/index.html';
my $GO_PREFIX = "GO:";
my $TO_PREFIX = "TO:";
my $MUTANT_PREFIX = "GR:";
my $TRAIT = 5;
my $EXE_NAME = 'search_mutant';

#####################################################################
# 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("$HOME") 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($input);
} else {
  @candidates = get_possible_matches($input);
}

#####################################################################
if($#candidates+1 == 1){
  terminate_database($dbh);
  my $only_you = get_mutant_key($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_mutant_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 $page->end_body;
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 = shift;
  $query =~ s/^$MUTANT_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) = @_;
  $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 $pattern = shift;
  die "Invalid input in get_possible_matches" unless defined $pattern;
  my %seen;
  my $sth = $dbh->prepare("SELECT mutant_id FROM core_mutant WHERE lower(mutant_name) like '%$pattern%' OR lower(mutant_symbol) like '%$pattern%'") || die $dbh->errstr;
  $sth->execute || die "Execute: ", $sth->errstr;
  my $sth2 =  $dbh->prepare(" SELECT mutant_id FROM core_mutant WHERE lower(phenotypic_description) 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_match_II {
my $id = shift;
die "Invalid input in get_possible_match_II" unless defined $id;
my $sth = $dbh->prepare("SELECT mutant_id FROM core_mutant where mutant_id = $id") || die $dbh->errstr;
$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;
  die "Invalid input in add_mutant_prefix" unless defined $id;
  my $mutant_phrase = $MUTANT_PREFIX; 
  my $length = 7 - length($id);
  for my $x (1 .. $length){
      $mutant_phrase .= "0";
  }
  $mutant_phrase .= $id;
  return $mutant_phrase;
}

#####################################################################
sub print_suspects {
  my ($suspects_ref, $input) = @_;
  # CSHL true color
  my $ctag = '<span class="matching">'.$input.'</span>';

  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 Mutants'."    (".($#$suspects_ref+1)." terms found)"));
  }
  else {
    print TR({-class=>'datatitle', -align=>'center'}, 
	   th('Candidate Rice Mutant'."    (".($#$suspects_ref+1)." term found)"));
  }
  print end_TR, end_table;
  
  print start_table({-border=>'1', -width=>'98%',-cellpadding=>4,-cellspacing=>1, -align=>'center'});
  print TR({-align=>"center", -class=>"datatitle"},
	  th(['#', 'Mutant ID', 'Mutant Name', 'Phenotypic Description']));

  # 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($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('mutant_name', $suspect),$input);
    print td(p({-align=>'left'},$yoyo));
    print td(  p({-align=>'left'}, highlight_patterns(get_core_mutant_info('phenotypic_description', $suspect), $input) || 'No Phenotypic Description Available'));

    print end_TR;
    $count += 1;
  }
  print end_td,end_TR,end_table;
}

#####################################################################
### database routines
sub exist_mutant_id {
  my $id = shift;
  die "Invalid input in exist_mutant_id" unless defined $id;
  my $sth = $dbh->prepare("SELECT mutant_symbol FROM core_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 core mutant; given its mutant id
# post: return its info
#####################################################################
sub get_core_mutant_info {
  my ($column_name, $id) = @_;
  die "Invalid input in get_mutant_info" unless defined $id;
  my $sth = $dbh->prepare("SELECT $column_name FROM core_mutant WHERE mutant_id = $id") || die $dbh->errstr;
  $sth->execute || die "Execute: ", $sth->errstr;
  my $info = $sth->fetchrow_array;
  $sth->finish;
  return $info;
}

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

  return $dbh;
}

sub terminate_database{
  $dbh->disconnect();
}
