#!/usr/bin/perl
package PhenotypeCurationPage_base;

#######################################################################
##### 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 lib "/usr/local/dicty/www_dictybase/db/lib/common";
use Login qw (ConnectToDatabase);
use lib "/usr/local/dicty/www_dictybase/db/lib/dictyBase";
use dictyBaseCentralMod qw(:formatPage :getInfo);
use Pubmed;
use lib "/usr/local/dicty/www_dictybase/db/lib/dictyBase/Objects";
use ConfigURLdictyBase;
use Phenotype;
use Reference;
use Locus_pheno;
use Feat_pheno;
use Reflink;
use Feature;
use Locus;

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

our $dbh;
our $dblink; 
our $configUrl;

#######################################################################
sub new {      ############ constructor ###############################
#######################################################################
       
	my ($type, %args) = @_;

	my $self = {};
	bless $self, $type;

      	$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;
    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 $ph = Phenotype->new(dbh=>$dbh,
			    phenotype_no=>$phenotypeNo);
    foreach my $rowRef (@{$ph->getLocusArrayRef}) {
	my ($locus_no, $locus_name) = @$rowRef;
	if ($locus_no != $self->{'_locusNo'}) {
	    return "yes";
	}
    }	       
    foreach my $rowRef (@{$ph->getFeatureArrayRef}) {
	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");
	my $phenotypeNo = param("phenotypeNo$i");
	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) {
	    $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;
	    }
	}

	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',
		 -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('morerows','More Rows'), " ",
	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'},
			       "Enter Phenotype")).br.
			i(font({size=>'-1'},
			       "(search existing phenotypes first; enter phenotype_no to use existing phenotype, or enter new phenotype in the text box)"))).
	      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 %typeLabels = ('type'=>'-Type-',
		      'Free text'=>'Free text',
		      'Null'=>'Null',
		      'Temperature sensitive'=>'TS',
		      'Cold sensitive'=>'CS',
		      'Overexpression'=>'Overexp',
		      'Systematic deletion'=>'Sys Del',
		      'Genetic footprinting'=>'Footprint',
		      'Synthetic/multiple'=>'Synthetic/multiple',
		      'Unknown'=>'Unknown',
		      'Other'=>'Other');
    my @typeValues = ('type', ,'Free text', 'Null', 'Temperature sensitive', 'Cold sensitive', 'Overexpression', 'Systematic deletion', 'Genetic footprinting', 'Synthetic/multiple', 'Unknown', 'Other');
    my $defaultType = "$type";
    return popup_menu(-name=>"type$i",
                   -"values"=>\@typeValues,
		   -default=>$defaultType,
                   -labels=>\%typeLabels
                  );      
}


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

########################################################################
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 = 2;
    }
    else {
	$end = 7;
    }

    for (my $i = 1; $i <= $end; $i++) {
	print $self->phenotypeSearch;
        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 $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')).
	     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;

}

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



















