package PhenotypeCurationPage;

#######################################################################
##### Author :        Shuai Weng
##### Date   :  August 2000
##### Description : This package contains all necessary methods for dictyBase
#####               curators to display, update, insert or delete
#####               Phenotype related info in oracle database.
#####
#######################################################################
use strict;
use DBI;
use CGI qw/:all/;
use CGI::Carp qw(fatalsToBrowser);
use DictyBaseConfig;
use Login qw (ConnectToDatabase);
use dictyBaseCentralMod qw(:formatPage :getInfo);
use Pubmed;
use ConfigURLdictyBase;
use Phenotype;
use Reference;
use Locus_pheno;
use Feat_pheno;
use Reflink;
use Feature;
use Locus;
use dicty::Search::Cvterm;
use Data::Dumper;
use dicty::CV::Ontology;
use dicty::CV::Term;

#######################################################################
#################### global variables #################################
#######################################################################

my $dbh;
my $dblink;
my $configUrl;

#######################################################################
sub new {      ############ constructor ###############################
#######################################################################

        my ($self, %args) = @_;

        $self = {};
        bless $self;

              $self->{'_database'} = $args{'database'};
        $self->{'_help'}     = defined($args{'help'}) ?
                               $args{'help'} : "phenotype.html";
        $self->{'_title'}    = defined($args{'title'}) ?
                               $args{'title'} : "Phenotype Curation Page";
        $self->{'_user'}     = $args{'user'};
        $self->{'_feat'}     = $args{'feat'};
        $self->{'_type'}     = $args{'type'};
        $dbh = &ConnectToDatabase($self->database);
            return $self;
}

sub help { $_[0]->{_help} }
sub database { $_[0]->{_database} }
sub title { $_[0]->{_title} }
sub user { $_[0]->{_user} }

######################################################################
sub DESTROY {   ############ destructor ##############################
######################################################################
            if (defined $dbh) {
                $dbh->disconnect;
            }
}

######################################################################
sub start{
######################################################################

            my ($self) = @_;
        $configUrl = ConfigURLdictyBase->new;
        $dblink = $configUrl->dblink($self->database);
        if (!$self->user) {
            print "location: ", $configUrl->dictyBaseCGIRoot, "$dblink/curatorLogin\n";
            print "Content-type: text/html\n\n";
            exit;
        }
        my ($dbuser, $dbpasswd) = &getUsernamePassword(uc($self->user),
                                                       $self->database);
        if (!$dbuser || !$dbpasswd) {
            print "location: ", $configUrl->dictyBaseCGIRoot, "$dblink/curatorLogin\n";
            print "Content-type: text/html\n\n";
            exit;
        }
        $self->{'_feat'} =~ s/^ *//;
        $self->{'_feat'} =~ s/ *$//;
        $self->{'_feat'} =~ s/[\t\r\f\n]+//g;
        if (param('commit')) {
            $dbh->disconnect;
            $dbh = &ConnectToDatabase($self->database, $dbuser, $dbpasswd);
            $self->commitInfo;
        }
        elsif (param('type')) {
            if (!param('morerows')) {
                $self->checkQuery;
                $self->displayRowsFromDB;
            }
            else {
                $self->displayMoreRows;
            }
        }
        else {
            $self->printEntryForm;
        }
}

#######################################################################
sub printEntryForm {
#######################################################################
        my ($self) = shift;

        &printStartPage($self->database, $self->title, $self->help);

        print p, font({-color=>'red'},
                       "This interface should not yet be used for typical phenotype annotation. A controlled vocabulary for phenotypes needs to be developed first. Please use the \"ACEDB Phenotype\" box on the Curate Locus Info (or Curate Feature Info) page to enter, edit, or delete phenotype information for a locus or feature."),p;


        my %typeLabels = ('Locus'=>'Locus or locus_no',
                          'Feature'=>'Feature or feature_no');
        my @typeValues = qw/Locus Feature/;
        my $defaultType = 'Locus';

        ##########################
        print
            table(Tr(td(
                        startform,
                        b("This form is for dictyBase curators to display, update, insert or delete phenotype related info in oracle database"),p,
                        b(font({-size=>"+1"}, 'Enter ')),
                        popup_menu(-name=>'type',
                                   -"values"=>\@typeValues,
                                   -default=>$defaultType,
                                   -labels=>\%typeLabels
                                   ), b(": "),
                        textfield(-name=>'feat', -size=>30),
                        p,
                        hidden('user', $self->user),
                        submit('Submit','Submit'), " ",
                        reset,
                        endform)));
        &printEndPage;
}

########################################################################
sub displayRowsFromDB {
########################################################################
    my ($self) = shift;
    my $title;
    if (param('type') =~ /Feature/i) {
        $title = $self->title." for ".$self->{'_featNm'};
    }
    else {
        $title = $self->title." for ".$self->{'_locusNm'};
    }
    &printStartPage($self->database, $title, $self->help);
    if (param('type') =~ /Feature/i) {
        $self->printSubtitle($self->{'_featNm'},
                             "(feature_no=$self->{'_featNo'})");
    }
    else {
        $self->printSubtitle($self->{'_locusNm'},
                             "(locus_no=$self->{'_locusNo'})");
    }
    print startform(-name => "phenotype_data");
    print "<table border=1 cellpadding=1 cellspacing=1>";
    my $i;
    my $phenoArrayRef;
    if (param('type') =~ /locus/i) {
        my $locusObj = Locus->new(dbh=>$dbh,
                                  locus_no=>$self->{'_locusNo'});
        $phenoArrayRef = $locusObj->phenotypeInfoArrayRef;
    }
    else {
        my $featObj = Feature->new(dbh=>$dbh,
                                   feature_no=>$self->{'_featNo'});
        $phenoArrayRef = $featObj->phenotypeInfoArrayRef;
    }
    my $deleteAnnot = "";
    my @phenoNm;
    my @shared;
    foreach my $phenoRow (@$phenoArrayRef) {
        my ($phenotypeNo, $phenotype, $phenotypeType, $sentence) = @$phenoRow;
        my $shared = $self->checkSharedListBYphenotypeNo($phenotypeNo);
        my $paperArrayRef;
        if (param('type') =~ /locus/i) {
            $paperArrayRef = Phenotype->GetReferenceInfo(dbh=>$dbh,
                                         No=>$self->{'_locusNo'},
                                         phenotype_no=>$phenotypeNo,
                                         phenotype_type=>$phenotypeType,
                                         type=>'LOCUS');
        }
        else {
            $paperArrayRef = Phenotype->GetReferenceInfo(dbh=>$dbh,
                                         No=>$self->{'_featNo'},
                                         phenotype_no=>$phenotypeNo,
                                         phenotype_type=>$phenotypeType,
                                         type=>'FEATURE');
        }
        foreach my $paperRow(@$paperArrayRef) {
            $i++;
            if ($i == 1) {
                $self->printHeaderRow4existingInfo;
            }
            my ($refNo, $citation) = @$paperRow;
            print hidden("typeDB$i", "$phenotypeType"),
                  hidden("sharedDB$i", "$shared"),
                  hidden("phenotypeNoDB$i", "$phenotypeNo"),
                  hidden("phenotypeDB$i", "$phenotype"),
                  hidden("sentenceDB$i", "$sentence"),
                  hidden("paperDB$i", "$citation"),
                  hidden("refNoDB$i", "$refNo");
            $self->printOneRow4existingInfo($i, $phenotypeType, $phenotype,
                                            $phenotypeNo, $sentence,
                                            $citation, $refNo,
                                            $deleteAnnot, $shared);
            push(@phenoNm, $phenotype);
            push(@shared, $shared);
        }
    }
    print hidden('phenoNm', "@phenoNm"),
          hidden('shared', "@shared");
  #   for (my $i = 0; $i <= $#phenoNm; $i++) {
#         $self->phenotypeDeleteCB($i+1, $phenoNm[$i], $shared[$i]);
#     }

#######
    print "</table>";
    print "<p><table>";
    $self->printNewEntryTitle;
    $self->printMoreRows($i);
    print "</table>";
    if (param('type') =~ /Feature/i) {
        $self->printEndForm($self->{'_featNm'}, $self->{'_featNo'});
    }
    else {
        $self->printEndForm($self->{'_locusNm'}, $self->{'_locusNo'});
    }
    &printEndPage;
}

########################################################################
sub displayMoreRows {
########################################################################
    my ($self) = shift;
    my ($title, $featNm, $featNo, $locusNm, $locusNo);
    if (param('type') =~ /Feature/i) {
        $title = $self->title." for ".param('featNm');
    }
    else {
        $title = $self->title." for ".param('locusNm');
    }
    &printStartPage($self->database, $title, $self->help);
    ######################
    if (param('type') =~ /Feature/i) {
        my $featNo = param('featNo');
        $self->printSubtitle(param('featNm'),
                             "(feature_no=$featNo)");
    }
    else {
        my $locusNo = param('locusNo');
        $self->printSubtitle(param('locusNm'),
                             "(locus_no=$locusNo)");
    }
    print startform;
    print "<table border=1 cellpadding=1 cellspacing=1>";
    my $i;
    for ($i = 1; $i <= 10; $i++) {
        ##### use locus_no (Or fearure_no), phenotype_no
        ##### and phenotype_type as a composite primary_key to
        ##### identify a record
        my $phenotypeNo = param("phenotypeNoDB$i");
        my $type = param("typeDB$i");
        my $phenotype = param("Uphenotype$i");
        if (!$phenotype) { next; }
        my $sentence = param("Usentence$i");
        my $shared = param("sharedDB$i");
        my $phenotypeDB = param("phenotypeDB$i");
        my $sentenceDB = param("sentenceDB$i");
        my $paperDB = param("paperDB$i");
        my $refNoDB = param("refNoDB$i");
        my $refNo = param("UrefNo$i");
        my $deleteAnnot = param("deleteAnnot$i");
        print hidden("typeDB$i", "$type"),
              hidden("sharedDB$i", "$shared"),
              hidden("phenotypeNoDB$i", "$phenotypeNo"),
              hidden("phenotypeDB$i", "$phenotypeDB"),
              hidden("sentenceDB$i", "$sentenceDB"),
              hidden("paperDB$i", "$paperDB"),
              hidden("refNoDB$i", "$refNoDB"),
              hidden("refNo$i", "$refNo");
        if ($i == 1) {
            $self->printHeaderRow4existingInfo;
        }
        $self->printOneRow4existingInfo($i, $type, $phenotype,
                                        $phenotypeNo, $sentence,
                                        $paperDB, $refNo,
                                        $deleteAnnot, $shared);

    }
    my @phenoNm = param('phenoNm');
    my @shared = param('shared');
    print hidden('phenoNm', "@phenoNm"),
          hidden('shared', "@shared");
    for (my $i = 0; $i <= $#phenoNm; $i++) {
        $self->phenotypeDeleteCB($i+1, $phenoNm[$i], $shared[$i]);
    }
    print "</table><p>";
    print "<table>";
    $self->printNewEntryTitle;
    for ($i = 1; $i <= 100; $i++) {
        my $type = param("type$i");
        if (!$type) { last; }
        my $phenotypeNo = param("phenotypeNo$i");
        my $phenotype = param("phenotype$i");
        if (!$phenotypeNo && !$phenotype) { next; }
        my $refNo = param("UrefNo$i");
        my $pubmed = param("pubmed$i");
        if (!$refNo && !$pubmed) { next; }
        my $sentence = param("sentence$i");
        my $locuslist = param("locuslist$i");
        my $featlist = param("featlist$i");

        $self->printOneRow($i, $type, $phenotype, $phenotypeNo,
                           $sentence, $refNo, $pubmed, $locuslist,
                           $featlist);
    }
    $self->printMoreRows($i);
    print "</table>";

    if (param('type') =~ /Feature/i) {
        $self->printEndForm(param('featNm'),
                            param('featNo'),
                            param('rowNo'));
    }
    else {
        $self->printEndForm(param('locusNm'),
                            param('locusNo'),
                            param('rowNo'));
    }
    &printEndPage;
}


########################################################################
sub commitInfo {
########################################################################
    my ($self) = shift;
    my ($title, $type, $locusORfeatNo);
    if (param('locusNm')){
        $title = $self->title." for ".param('locusNm');
        $locusORfeatNo = param('locusNo');
        $type = "locus";
    }
    else {
        $title = $self->title." for ".param('featNm');
        $locusORfeatNo = param('featNo');
        $type = "feature";
    }
    &printStartPage($self->database, $title, $self->help);
    ##### delete annotation, delete phenotype entry, and
    ##### update existing entries
    for (my $i = 1; $i <= 100; $i++) {
        if (!param("phenotypeNoDB$i")) { last;}
        if (!param("Uphenotype$i")){ next; }
        if (!param("UrefNo$i")){ next; }

        $self->commitExistingEntry($i, $type, $locusORfeatNo);
    }
    #####
    ##### process new entries
    #####
    for (my $i = 1; $i <= 100; $i++) {
        if (!param("type$i")) { last; }
        $self->commitNewEntry($i, $type, $locusORfeatNo);
    }

    ##################
    if ($type =~ /locus/i) {
        print p, b("View locus ".a({-href=>$configUrl->dictyBaseCGIRoot."gene_page.pl?gene_name=".param('locusNm'),
                                    -target=>'infowin'},
                                   param('locusNm')));
    }
    elsif ($type =~ /feature/i) {
        print p, b("View feature ".a({-href=>$configUrl->dictyBaseCGIRoot."$dblink/locus.pl?featureName=".param('featNm'),
                                      -target=>'infowin'},
                                     param('featNm')));
    }
    print p, b("Return to ".a({-href=>$configUrl->dictyBaseCGIRoot."$dblink/curatorLogin?user=".$self->user}, "dictyBase Curator Central")), br;

    ##################
    &printEndPage;
    ##################
}

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

########################################################################
sub checkQuery {
########################################################################
    my ($self) = shift;
    if (!$self->{'_feat'}) {
        $self->err_report("You have to enter locus or feature name or number before press the Submit button. Please go back and try again.");
    }
    if ($self->{'_type'} =~ /Feature/i) {
        my $feature;
        if ($self->{'_feat'} =~ /^[0-9]+$/) {
            $self->{'_featNo'} = $self->{'_feat'};
            $feature = Feature->new(dbh=>$dbh,
                                       feature_no=>$self->{'_featNo'});
            if (!$feature) {
                $self->err_report("The feature_no you entered ($self->{'_featNo'}) is not found in database. Please go back, change the input and try again.");
                exit;
            }
            $self->{'_featNm'} = $feature->feature_name;
        }
        else {
            $self->{'_featNm'} = "\U$self->{'_feat'}";
            $feature = Feature->new(dbh=>$dbh,
                                       feature_name=>$self->{'_featNm'});
            if (!$feature) {
                $self->err_report("The feature_name you entered ($self->{'_featNm'}) is not found in database. Please go back, change the input and try again.");
                exit;
            }
            $self->{'_featNo'} = $feature->feature_no;
        }
        $self->{'_locusNm'} = $feature->locus_name;
        $self->{'_locusNo'} = $feature->locus_no;
    }
    else {
        my $locus;
        if ($self->{'_feat'} =~ /^[0-9]+$/) {
            $self->{'_locusNo'} = $self->{'_feat'};
            $locus = Locus->new(dbh=>$dbh,
                                locus_no=>$self->{'_locusNo'});
            if (!$locus) {
                $self->err_report("The locus_no you entered ($self->{'_locusNo'}) is not found in database. Please go back, change the input and try again.");
            }
            $self->{'_locusNm'} = $locus->locus_name;
        }
        else {
            $self->{'_locusNm'} = "\U$self->{'_feat'}";
            $locus = Locus->new(dbh=>$dbh,
                                locus_name=>$self->{'_locusNm'});
            if (!$locus) {
                $self->err_report("The locus_name you entered ($self->{'_locusNm'}) is not found in database. Please go back, change the input and try again.");
            }
            $self->{'_locusNo'} = $locus->locus_no;
        }
        $self->{'_featNm'} = $locus->featureNameList;
        $self->{'_featNm'} =~ s/\|.+$//;
        if ($self->{'_featNm'}) {
            my $feature = Feature->new(dbh=>$dbh,
                                       feature_name=>$self->{'_featNm'});
            $self->{'_featNo'} = $feature->feature_no;
        }
    }
}

########################################################################
sub checkVariables {
########################################################################
    my ($self, $phenotypeType, $phenotypeNo, $phenotype) = @_;
    if ($phenotypeType =~ /type/i && !$phenotypeNo &&
        !$phenotype) {
        return "next";
    }
    elsif ($phenotypeType !~ /type/i && ($phenotypeNo || $phenotype)) {
        return "continue";
    }
    else {
        return "fillall";
    }
}

########################################################################
sub checkSharedListBYphenotypeNo {
########################################################################
    #### if it is found, return "yes", otherwise return "no".
    my ($self, $phenotypeNo) = @_;

     my $sth = $dbh->prepare("
        SELECT  unique ft.feature_id, ft.uniquename
        FROM    CGM_CHADO.feature ft, locus_pheno LP
        WHERE   LP.phenotype_no = ?
        AND     LP.locus_no = ft.feature_id
        ORDER BY upper(ft.uniquename)
    ");

    $sth->execute($phenotypeNo);
    my $arrayRef = $sth->fetchall_arrayref();
    $sth->finish;

#     my $ph = Phenotype->new(dbh=>$dbh,
#                             phenotype_no=>$phenotypeNo);

    foreach my $rowRef (@{$arrayRef}) {
        my ($locus_no, $locus_name) = @$rowRef;
        if ($locus_no != $self->{'_locusNo'}) {
            return "yes";
        }
    }
#     foreach my $rowRef (@{$arrayRef}) {
#         my ($feature_no, $feature_name) = @$rowRef;
#         if ($feature_no != $self->{'_featNo'}) {
#             return "yes";
#         }
#     }

    return "no";
}

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


########################################################################
sub commitExistingEntry {
########################################################################
        my ($self, $i, $type, $locusORfeatNo) = @_;
        my $phenotypeNo = param("phenotypeNoDB$i");
        my $phenotypeType = param("typeDB$i");
        my $phenotype = param("Uphenotype$i");
        my $sentence = param("Usentence$i");
        my $shared = param("sharedDB$i");
        my $refNoDB = param("refNoDB$i");
        my $refNo = param("UrefNo$i");

        if (param("deleteAnnot$i") =~ /on/i) {
            eval {
                Phenotype->DeleteAnnotation(dbh=>$dbh,
                                            reference_no=>$refNo,
                                            No=>$locusORfeatNo,
                                            phenotype_no=>$phenotypeNo,
                                            phenotype_type=>$phenotypeType,
                                            type=>$type);
            };
            if (!$@) {
                $dbh->rollback;
                print font({-color=>'red'},b("The annotation for ${type}_no=$locusORfeatNo, phenotype_no=$phenotypeNo, phenotype='$phenotype', sentence='$sentence' and refNo='$refNo' has been deleted from database.")).p;
            }
            else {
                $dbh->commit;
                print "An error occurred when deleting the annotation for ${type}_no=$locusORfeatNo, phenotype_no=$phenotypeNo, phenotype='$phenotype', sentence='$sentence' and refNo='$refNo' from database.", $@,p;
            }
            return;
        }
        if (param("deletePheno$i") =~ /on/i) {
            my $ph = Phenotype->new(dbh=>$dbh,
                                    phenotype=>param("deletePhenoNm$i"));
            eval { $ph->delete; };
            if ($@) {
                print "An error occurred when deleting phenotype '".param("deletePhenoNm$i")."' from database.",p;
                $dbh->rollback;
            }
            else {
                $dbh->commit;
                print font({-color=>'red'},b("The phenotype '".param("deletePhenoNm$i")."' has been deleted from database.")).p;
            }
            return;
        }
        my $phenotypeDB = param("phenotypeDB$i");
        my $sentenceDB = param("sentenceDB$i");

#         if ("\U$phenotype" ne "\U$phenotypeDB") {
#             $self->updatePhenotype($type, $locusORfeatNo, $phenotype,
#                                    $phenotypeNo, $phenotypeType,
#                                    $sentence, $refNo, $refNoDB);
#
#         }
#         else {


            if ("\U$sentence" ne "\U$sentenceDB") {

                $self->updateSentence($type, $locusORfeatNo, $phenotypeNo,
                                  $phenotypeType, $sentence);
            }
            if ($refNo != $refNoDB) {
                my ($tabNm, $priKey, $newPriKey, $priKeyCol);
                if ($type =~ /locus/i) {
                    $tabNm = "LOCUS_PHENO";
                    $priKeyCol = "LOCUS_NO::PHENOTYPE_NO::PHENOTYPE_TYPE";
                }
                else {$tabNm = "FEAT_PHENO";
                    $priKeyCol = "FEATURE_NO::PHENOTYPE_NO::PHENOTYPE_TYPE";
                }
                $priKey = $locusORfeatNo."::".$phenotypeNo."::".$phenotypeType;
                $newPriKey = $priKey;
                $self->updateRefLink($tabNm, $priKeyCol, $refNoDB,
                                     $refNo, $priKey, $newPriKey);
            }
#        }

}

########################################################################
sub commitNewEntry {
########################################################################
        my ($self, $i, $type, $locusORfeatNo) = @_;

        my $phenotypeType = param("type$i");
        $phenotypeType =~ s/\b(\w)/\U$1/g;
        my $pheno_no = "phenotype".$i."No";
        my $phenotypeNo = param($pheno_no);
        my $phenotype = param("phenotype$i");
        my $sentence = param("sentence$i");

        #### reference_no OR pubmed id
        my $refNo = param("refNo$i");
        $refNo =~ s/^0+//;
        $refNo =~ s/[\r\f\n\t ]*//g;
        my $pubmed = param("pubmed$i");
        $pubmed =~ s/^0+//;
        $pubmed =~ s/[\r\f\n\t ]*//g;
        if (!$refNo && !$pubmed) {
            return;
        }

        if (!$refNo && $pubmed) {
            my $refObject = Pubmed->new(dbh=>$dbh,
                                             pubmed=>$pubmed);
            $refNo = $refObject->referenceNo;
            if (!$refNo) {
                print "The pubmed=$pubmed is not found in database or can't create reference info for it from NCBI.", p;
                return;
            }
        }

        my $checkVar = $self->checkVariables($phenotypeType, $phenotypeNo, $phenotype);

        if ($checkVar =~ /next/i) { return;}
        elsif ($checkVar =~ /fillall/i) {
            print b("You have to choose ".font({-color=>'red'}, "Mutant/Phenotype Type"). ", enter ".font({-color=>'red'}, "Phenotype_No")." or ".font({-color=>'red'}, "Phenotype")." Please go back, make all necessary changes and try again."), p;
            &printEndPage;
            exit;
        }

        if(!$phenotypeNo) {
            print b("You have to enter ".font({-color=>'red'}, "Phenotype_No")." Please go back, select phenotype from the ontology search interface and try again."), p;
            &printEndPage;
            exit;

        }

#         if (!$phenotypeNo) {
#             $phenotypeNo = $self->insertPhenotype($phenotype);
#             if (!$phenotypeNo) { return; }
#         }
#         else {
#             my $ph = Phenotype->new(dbh=>$dbh,
#                                     phenotype_no=>$phenotypeNo);
#             if (!$ph) {
#                 print "The phenotype_no ($phenotypeNo) you entered is not found in database.",p;
#                 return;
#             }
#         }

        my $cv = new dicty::CV::Ontology(-name => "Dicty Phenotypes");
        my $term = new dicty::CV::Term(-identifier => $phenotypeNo, -ontology => $cv);

        if($term->_database_object()) {
                $phenotypeNo = $term->_database_object()->cvterm_id();
        }else {
                print "$phenotypeNo is not a valid id in the Dicty Phenotypes ontology. Please enter a valid ontology id\n";
        return;
        }


        if($self->check_locus_pheno_entry($locusORfeatNo, $phenotypeNo,$phenotypeType)) {
        print "This Phenotype entry is already exisitng in the database.\n";
        return;
        }



        if ($type =~ /locus/i) {
            $self->insertLocusPheno($locusORfeatNo, $phenotypeNo,
                                    $phenotypeType, $sentence);

            $self->insertRefLink($refNo, 'LOCUS_PHENO',
                     $locusORfeatNo."::".$phenotypeNo."::".$phenotypeType,
                     'LOCUS_NO::PHENOTYPE_NO::PHENOTYPE_TYPE');
        }
        else {
            $self->insertFeatPheno($locusORfeatNo, $phenotypeNo,
                                    $phenotypeType, $sentence);
            $self->insertRefLink($refNo, 'FEAT_PHENO',
                     $locusORfeatNo."::".$phenotypeNo."::".$phenotypeType,
                     'FEATURE_NO::PHENOTYPE_NO::PHENOTYPE_TYPE');
        }

        ######## locus list
        my $locuslist = param("locuslist$i");
        $locuslist =~ s/[\r\n\t\f ]//g;
        my @loci = split(/\|/, $locuslist);
        foreach my $locusNm (@loci) {
            my $locus = Locus->new(dbh=>$dbh,
                                   locus_name=>$locusNm);
            if (!$locus) {
                print p, "The locus ".font({-color=>'red'}, $locusNm)." is not found in database.",p;
                next;
            }
            my $locusNo = $locus->locus_no;
            ########
            my $locusPheno = Locus_pheno->new(dbh=>$dbh,
                                      locus_no=>$locusNo,
                                      phenotype_no=>$phenotypeNo,
                                      phenotype_type=>$phenotypeType);
            if (!$locusPheno) {
                $self->insertLocusPheno($locusNo, $phenotypeNo,
                                        $phenotypeType, $sentence);
            }
            else {
                my $sentenceDB = $locusPheno->sentence;
                if ("\U$sentence" ne "\U$sentenceDB") {
                    $self->updateSentence("LOCUS", $locusNo, $phenotypeNo,
                                      $phenotypeType, $sentence);
                }
            }

            $self->insertRefLink($refNo, 'LOCUS_PHENO',
                     $locusNo."::".$phenotypeNo."::".$phenotypeType,
                     'LOCUS_NO::PHENOTYPE_NO::PHENOTYPE_TYPE');

        }
        ####### feature list
        my $featlist = param("featlist$i");
        $featlist =~ s/[\r\n\t\f ]//g;
        my @feats = split(/\|/, $featlist);
        foreach my $featNm (@feats) {
            my $feature = Feature->new(dbh=>$dbh,
                                       feature_name=>$featNm);
            if (!$feature) {
                print p, "The feature ".font({-color=>'red'}, $featNm)." is not found in database.",p;
                next;
            }
            my $featNo = $feature->feature_no;
            ########
            my $featPheno = Feat_pheno->new(dbh=>$dbh,
                                      feature_no=>$featNo,
                                      phenotype_no=>$phenotypeNo,
                                      phenotype_type=>$phenotypeType);
            if (!$featPheno) {
                $self->insertFeatPheno($featNo, $phenotypeNo,
                                       $phenotypeType, $sentence);
            }
            else {
                my $sentenceDB = $featPheno->sentence;
                if ("\U$sentence" ne "\U$sentenceDB") {
                    $self->updateSentence("FEATURE", $featNo, $phenotypeNo,
                                      $phenotypeType, $sentence);
                }
            }

            $self->insertRefLink($refNo, 'FEAT_PHENO',
                     $featNo."::".$phenotypeNo."::".$phenotypeType,
                     'FEATURE_NO::PHENOTYPE_NO::PHENOTYPE_TYPE');

        }
}


########################################################################
sub updatePhenotype {
########################################################################
    my ($self, $type, $locusORfeatNo, $newPhenotype,
        $phenotypeNo, $phenotypeType, $sentence,
        $newRefNo, $refNo) = @_;

    my $newPhenotypeNo = $self->insertPhenotype($newPhenotype);
    if (!$newPhenotypeNo) { return ; }
    if ($type =~ /locus/i) {
        my $locusPheno = Locus_pheno->new(dbh=>$dbh,
                                      locus_no=>$locusORfeatNo,
                                      phenotype_no=>$phenotypeNo,
                                      phenotype_type=>$phenotypeType);
        eval { $locusPheno->delete; };
        if ($@) {
            $dbh->rollback;
            print "An error occurred when deleting locus_pheno entry for locus_no = $locusORfeatNo, phenotype_no = $phenotypeNo and phenotype_type = $phenotypeType:", $@, p;
        }
        else {
            $dbh->commit;
            $self->insertLocusPheno($locusORfeatNo, $newPhenotypeNo, $phenotypeType, $sentence);
        }
        my $tabNm = "LOCUS_PHENO";
        my $priKey = $locusORfeatNo."::".$phenotypeNo."::".$phenotypeType;
        my $newPriKey = $locusORfeatNo."::".$newPhenotypeNo."::".$phenotypeType;
        my $priKeyCol = 'LOCUS_NO::PHENOTYPE_NO::PHENOTYPE_TYPE';
        $self->updateRefLink($tabNm, $priKeyCol, $refNo, $newRefNo,
                             $priKey, $newPriKey);

    }
    else {
        my $featPheno = Feat_pheno->new(dbh=>$dbh,
                                      feature_no=>$locusORfeatNo,
                                      phenotype_no=>$phenotypeNo,
                                      phenotype_type=>$phenotypeType);
        eval { $featPheno->delete; };
        if ($@) {
            $dbh->rollback;
            print "An error occurred when deleting feat_pheno entry for feature_no = $locusORfeatNo, phenotype_no = $phenotypeNo and phenotype_type = $phenotypeType:", $@, p;
        }
        else {
            $dbh->commit;
            $self->insertFeatPheno($locusORfeatNo, $newPhenotypeNo, $phenotypeType, $sentence);
        }
        my $tabNm = "FEAT_PHENO";
        my $priKey = $locusORfeatNo."::".$phenotypeNo."::".$phenotypeType;
        my $newPriKey = $locusORfeatNo."::".$newPhenotypeNo."::".$phenotypeType;
        my $priKeyCol = 'FEATURE_NO::PHENOTYPE_NO::PHENOTYPE_TYPE';
        $self->updateRefLink($tabNm, $priKeyCol, $refNo, $newRefNo,
                             $priKey, $newPriKey);
    }
}

##################################################################
sub updateSentence {
##################################################################
    my ($self, $type, $locusORfeatNo, $phenotypeNo,
        $phenotypeType, $sentence) = @_;
    if ($type =~ /locus/i ) {
        my $locusPheno = Locus_pheno->new(dbh=>$dbh,
                                      locus_no=>$locusORfeatNo,
                                      phenotype_no=>$phenotypeNo,
                                      phenotype_type=>$phenotypeType);
        $locusPheno->updateSentence($sentence);
        eval { $locusPheno->enterUpdates; };
        if ($@) {
            print "An error occurred when updating sentence in locus_pheno table: $@", p;
            $dbh->rollback;
        }
        else {
            $dbh->commit;
            print "The sentence for locus_no=$locusORfeatNo, phenotype_no=$phenotypeNo and phenotype_type='$phenotypeType' in locus_pheno table has been updated to ".font({-color=>'red'}, $sentence), p;
        }
    }
    else {
        my $featPheno = Feat_pheno->new(dbh=>$dbh,
                                      feature_no=>$locusORfeatNo,
                                      phenotype_no=>$phenotypeNo,
                                      phenotype_type=>$phenotypeType);
        $featPheno->updateSentence($sentence);
        eval { $featPheno->enterUpdates; };
        if ($@) {
            print "An error occurred when updating sentence in feat_pheno table: $@", p;
            $dbh->rollback;
        }
        else {
            $dbh->commit;
            print "The sentence for feature_no=$locusORfeatNo, phenotype_no=$phenotypeNo and phenotype_type='$phenotypeType' in feat_pheno table has been updated to ".font({-color=>'red'}, $sentence),p;
        }
    }
}

########################################################################
sub updateRefLink  {
########################################################################
    my ($self, $tabNm, $priKeyCol, $refNo, $newRefNo,
        $priKey, $newPriKey) = @_;

    my $ref = Reference->new(dbh=>$dbh,
                             reference_no=>$newRefNo);
    if (!$ref->reference_no) {
        print "The new reference_no = $newRefNo is not found in database.",p;
        return;
    }
    my $refLink = Reflink->new(dbh=>$dbh,
                               reference_no=>$refNo,
                               tab_name=>'LOCUS_PHENO',
                               primary_key_col=>$priKeyCol,
                               primary_key=>$priKey);
    eval { $refLink->delete; };
    if ($@) {
        print "An error occurred when deleting reflink entry for reference_no = $refNo, tab_name = 'LOCUS_PHENO', primary_key_col = '$priKeyCol' and primary_key = '$priKey':$@", p;
        $dbh->rollback;
    }
    else {
        print "The reflink entry for reference_no = $refNo, tab_name = 'LOCUS_PHENO', primary_key_col = '$priKeyCol' and primary_key = '$priKey' has been deleted from database.", p;
        $dbh->commit;
    }
    $self->insertRefLink($newRefNo, $tabNm, $newPriKey, $priKeyCol);
}


########################################################################
sub insertPhenotype {
########################################################################
    my ($self, $phenotype) = @_;
    my $ph = Phenotype->new(dbh=>$dbh,
                            phenotype=>$phenotype);
    if ($ph) {
        return $ph->phenotype_no;
    }
    eval {
        Phenotype->Insert(dbh=>$dbh,
                          literals=>{phenotype_no=>'CGM_DDB.phenono_seq.nextval'},
                          binds=>{phenotype=>$phenotype});
    };
    if ($@) {
        print "An error occurred when inserting new phenotype '$phenotype' into database:", $@,p;
        return;
    }
    else {
        $dbh->commit;
        my $ph = Phenotype->new(dbh=>$dbh,
                                    phenotype=>$phenotype);
        return $ph->phenotype_no;
    }
}

########################################################################
sub insertLocusPheno {
########################################################################
    my ($self, $locusNo, $phenotypeNo, $phenotypeType, $sentence)
        = @_;
    eval {
        Locus_pheno->Insert(dbh=>$dbh,
                            binds=>{locus_no=>$locusNo,
                                    phenotype_no=>$phenotypeNo,
                                    phenotype_type=>$phenotypeType,
                                    sentence=>$sentence});
    };
    if ($@) {
        print "An error occurred when inserting locus_pheno entry for locus_no = $locusNo, phenotype_no = $phenotypeNo, phenotype_type = '$phenotypeType', and sentence = '$sentence' into database:$@", p;
    }
    else {
        $dbh->commit;
        print "The new locus_pheno entry for locus_no = $locusNo, phenotype_no = $phenotypeNo, phenotype_type = '$phenotypeType', and sentence = '$sentence' has been inserted into database:$@", p;
    }
}

########################################################################
sub insertFeatPheno {
########################################################################
    my ($self, $featNo, $phenotypeNo, $phenotypeType, $sentence)
        = @_;
    eval {
        Feat_pheno->Insert(dbh=>$dbh,
                           binds=>{feature_no=>$featNo,
                                   phenotype_no=>$phenotypeNo,
                                   phenotype_type=>$phenotypeType,
                                   sentence=>$sentence});
    };
    if ($@) {
        print "An error occurred when inserting feat_pheno entry for feature_no = $featNo, phenotype_no = $phenotypeNo, phenotype_type = '$phenotypeType', and sentence = '$sentence' into database:$@", p;
    }
    else {
        $dbh->commit;
        print "The new feat_pheno entry for feature_no = $featNo, phenotype_no = $phenotypeNo, phenotype_type = '$phenotypeType', and sentence = '$sentence' has been inserted into database:$@", p;
    }

}
########################################################################
sub insertRefLink {
########################################################################
    my ($self, $refNo, $tabNm, $priKey, $priKeyCol) = @_;
    eval {
        Reflink->Insert(dbh=>$dbh,
                      literals=>{reflink_no=>'CGM_DDB.reflinkno_seq.nextval'},
                      binds=>{reference_no=>$refNo,
                              tab_name=>$tabNm,
                              primary_key_col=>$priKeyCol,
                              primary_key=>$priKey});
    };
    if ($@) {
        print "An error occurred when inserting reflink entry for reference_no = $refNo, tab_name = '$tabNm', primary_key_col = '$priKeyCol', and primary_key = '$priKey' into database:$@", p;
        $dbh->rollback;
    }
    else {
        $dbh->commit;
        print "The new reflink entry for reference_no = $refNo, tab_name = '$tabNm', primary_key_col = '$priKeyCol', and primary_key = '$priKey' has been inserted into database.", p;
    }
}

########################################################################
sub printSubtitle {
########################################################################
    my ($self, $feature, $text) = @_;
    print center(h2(a({-href=>$configUrl->dictyBaseCGIRoot. "gene_page.pl?gene_name=$feature",
                       -target=>"infowin"},
                      $feature).$text
                     ));
}

########################################################################
sub printNewEntryTitle {
########################################################################
    print Tr(td({-colspan=>'4',
                 -align=>'center'},
              submit('commit','Submit')
               ));

    print Tr(td({-colspan=>'4',
                 -align=>'center',
                 -bgcolor=>'#a4abc2'},
                b("Enter New Phenotypes")));
}



########################################################################
sub printEndForm {
########################################################################
    my ($self, $Nm, $No) = @_;
    print
        hidden('user', $self->user),
        hidden('type', $self->{'_type'});
    if (param('type') =~ /feature/i) {
        print
            hidden('featNm', $Nm),
            hidden('featNo', $No);
    }
    else {
        print
            hidden('locusNm', $Nm),
            hidden('locusNo', $No);
    }
    print
        submit('commit','Submit'), " ",
        endform;
}



########################################################################
sub headerRow {
########################################################################
    return Tr(td({-align=>'center'},
                        b(font({-size=>'-1'},
                               "Choose Mutant/Phenotype Type"))).
              td({-align=>'center'},
                        b(font({-size=>'-1'},
                               "Phenotype"))).
              td({-align=>'center'},
                        font({-size=>'-1'},
                              b("Enter Sentence"))).
              td({-align=>'center'},
                        b(font({-size=>'-1'},
                               "Enter reference_no OR pubmed ID")))
           );

}

########################################################################
sub typeField {
########################################################################
    my ($self, $i, $type) = @_;
    my @results = dicty::Search::Cvterm->find(-ontology => "Mutant Types", -id => "PT:%");
    my @tmp_types; #= map { $_->name() } @results;

    foreach my $term (@results) {
       if(($term->name() =~ /[A-Za-z]/) && !($term->name() =~ /Mutant Type/)) {
        push (@tmp_types,$term->name());
       }
    }
    my @types =  sort(@tmp_types);

    my %typeLabels;

    foreach my $type (@types) {
       $typeLabels{$type} = $type;
    }



    my $defaultType = "$type";
    return popup_menu(-name=>"type$i",
                   -values=>\@types,
                   -default=>$defaultType,
                   -labels=>\%typeLabels
                  );



 #        my $str = textfield(-name=>"type$i",
#                     -value=>"",
#                     -size=>'25'
#                     );
#         $str .= br.br.br;
#         my @ontologies = ("Mutant Types");
#         $str .= dicty::UI::Form->ontology_search_button_return_term(
#                  -ontologies   => \@ontologies,
#                  -item_name    => "Mutant type",
#                  -field_name   => "type".$i,
#                  -parent_name  => 'phenotype_data',
#                  -search_url   => "/db/cgi-bin/dictyBase/search/search_ontology_popup.pl"
#         );
#        return $str;

}


########################################################################
sub phenotypeField {
########################################################################
    my ($self, $i, $phenotype, $phenotypeNo) = @_;
    my $pheno_no = "phenotype".$i."No";
    return table(Tr(td({-align=>'left'},
                       b(font({-size=>'-1'},
                              "Phenotype Ontology ID: ")).
                       textfield(-name=>$pheno_no,
                                 -value=>"$phenotypeNo",
                                 -size=>'25'
                                 ))).
                 Tr(td({-align=>'left'},
                       textarea(-name=>"phenotype$i",
                                -value=>"$phenotype",
                                -rows=>2,
                                -columns=>25,
                                -readonly => 1
                                )))
                 .Tr(td($self->phenotypeSearch($i))));


}

########################################################################
sub sentenceField {
########################################################################
    my ($self, $i, $sentence) = @_;
    return table(Tr(td({-align=>'left'},
                       textarea(-name=>"sentence$i",
                                -value=>"$sentence",
                                -rows=>2,
                                -columns=>25)))
                 );

}

########################################################################
sub paperField {
########################################################################
    my ($self, $i, $refNo, $pubmed) = @_;
    return table(Tr(td({-align=>'right'},
                       b(font({-size=>'-1'},
                              "Reference_no:"))).
                    td({-align=>'left'},
                       textfield(-name=>"refNo$i",
                                 -value=>"$refNo",
                                 -size=>'10'))).
                 Tr(td({-align=>'right'},
                       b(font({-size=>'-1'},
                              "Pubmed ID:"))).
                    td({-align=>'left'},
                       textfield(-name=>"pubmed$i",
                                 -value=>"$pubmed",
                                 -size=>'10'))));
}

########################################################################
sub locusFeatureListFields {
########################################################################
    my ($self, $i, $locusList, $featList) = @_;
    return Tr(td({-colspan=>'4'},
                 "Enter loci/features that share this phenotype below; ".
                 "separate multiples by |")
              ).
           Tr(td({-colspan=>'2'},
                 font({-size=>'-1'},
                      "Loci: ").
                 textfield(-name=>"locuslist$i",
                           -value=>"$locusList",
                           -size=>'40')).
              td({-colspan=>'2'},
                 font({-size=>'-1'},
                      "Features: ").
                 textfield(-name=>"featlist$i",
                           -value=>"$featList",
                           -size=>'40'))
           );
}


########################################################################
sub printMoreRows {
########################################################################
    my ($self, $num) = @_;
    my $end;
    if ($num >= 5) {
        $end = 6;
    }
    else {
        $end = 6;
    }

    for (my $i = 1; $i <= $end; $i++) {
#        print $self->phenotypeSearch($i);
        print $self->headerRow;
        print Tr(td($self->typeField($i)).
                 td($self->phenotypeField($i)).
                 td($self->sentenceField($i)).
                 td($self->paperField($i))),
              $self->locusFeatureListFields($i),
              $self->rowSeparator;
    }
}


#######################################################################
sub printOneRow {
#######################################################################
    my ($self, $i, $type, $phenotype, $phenotypeNo, $sentence, $refNo,
        $pubmed, $locusList, $featList) = @_;

    print
        Tr(td($self->typeField($i, $type)).
           td($self->phenotypeField($i, $phenotype, $phenotypeNo)).
           td($self->sentenceField($i, $sentence)).
           td($self->paperField($i,$refNo, $pubmed))
        ),
        $self->locusFeatureListFields($i, $locusList, $featList),
        $self->rowSeparator;
}


########################################################################
sub rowSeparator {
########################################################################
    return Tr(td({-colspan=>'4'},
                 hr));

}

########################################################################
sub phenotypeSearch {
########################################################################
    my ($self, $num) = @_;
    my @ontologies = ("Dicty Phenotypes");
    return dicty::UI::Form->ontology_search_button_return_term_and_id(
            -ontologies   => \@ontologies,
            -item_name    => "Ontology",
            -field_name   => "phenotype".$num,
            -id_field_name => "phenotype".$num."No",
            -parent_name  => 'phenotype_data',
            -search_url   => "/db/cgi-bin/dictyBase/search/search_ontology_popup.pl"
        );

#     my $searchUrl = "<b><a href=\"" .$configUrl->dictyBaseCGIRoot ."$dblink/curation/dbSearch?type=phenotype\" target=\"infowin\"><font color=red>Search existing phenotypes</font></a></b>";
#     return Tr(td({-colspan=>'4'},
#                  $searchUrl));

}


########################################################################
sub printHeaderRow4existingInfo {
########################################################################
    print "<tr><td colspan=6 align = center BGCOLOR='#a4abc2'><b>Existing Phenotypes</b></td></tr>";
    print Tr(td({-align=>'center'},
                b(font("Type"))).
             td({-align=>'center'},
                b(font("Phenotype"))).
             td({-align=>'center'},
                b(font("Sentence"))).
             td({-align=>'center'},
                b(font("Reference"))).
             td({-align=>'center'},
                b(font("Delete?"))).
             td({-align=>'center'},
                b(font({-size=>'-1'},
                  "Shared?"))));
}

########################################################################
sub printOneRow4existingInfo {
########################################################################
    my ($self, $i, $type, $phenotype, $phenotypeNo, $sentence, $paper,
        $refNo, $deleteAnnot, $shared) = @_;
    if ($shared =~ /yes/i) {
        my $user = $self->user;
        $shared = "<a href='". $configUrl->dictyBaseCGIRoot ."$dblink/curation/dbSearch?type=phenotype&id=$phenotypeNo' target='infowin' onClick='open_win()'>$shared</a>";

    }
    print Tr(td({-align=>'center'},
                $type).
             td({-align=>'center'},
             textfield(-name=>"Uphenotype$i",
                          -value=>"$phenotype",
                          -size=>'20',
                          -readonly => 1)).
             td({-align=>'center'},
                textarea(-name=>"Usentence$i",
                         -value=>"$sentence",
                         -rows=>2,
                         -columns=>25)).
             td({-align=>'center'},
                $paper.br.
                "reference_no=".
                textfield(-name=>"UrefNo$i",
                          -value=>"$refNo",
                          -size=>'5')).
             td({-align=>'center'},
                 checkbox(-name=>"deleteAnnot$i",
                          -label=>"").br."delete").
             td({-align=>'center'},
                $shared)
          );

}

########################################################################
sub phenotypeDeleteCB {
########################################################################
    my ($self, $i, $phenotype, $shared) = @_;
    my $msg = " Delete the '<b>$phenotype</b>' phenotype from the database.";
    if ($shared =~ /yes/i) {
        $msg .= "<font color=red>Warning: this phenotype is shared by other loci/features in the database!!!</font>";
    }
    print hidden("deletePhenoNm$i", "$phenotype");
    print Tr(td({-colspan=>'6', align=>'left'},
             checkbox(-name=>"deletePheno$i",
                      -label=>"").$msg));

}


########################################################################
sub err_report {
########################################################################
    my ($self, $err) = @_;

    &printStartPage($self->database, $self->title, $self->help);

    print b($err);

    &printEndPage;

    $dbh->disconnect;

    exit;

}

sub check_locus_pheno_entry {

my ($self, $feature_id, $phenotype_no, $type) = @_;
my $stmt = $dbh->prepare("SELECT * FROM CGM_DDB.LOCUS_PHENO WHERE LOCUS_NO = ? AND PHENOTYPE_NO = ? AND PHENOTYPE_TYPE =?");
$stmt->execute($feature_id, $phenotype_no, $type);
my @result = $stmt->fetchrow();

if($result[0]) {

       return 1;
  }else
 {
      return 0;
 }

}

########################################################################
1;
########################################################################








