#!/usr/bin/perl
package FeatureCurationPage_base;

#######################################################################
##### Author :	Shuai Weng
##### Date   :  August 2000
##### Update :  July 2001
##### Description : This package contains all necessary methods for dictyBase
#####               curators to display, update, insert or delete  
#####               FEATURE related info in oracle database. 
#####              
##################           RCS INFORMATION          ################
# $Author: emj466 $
# $Date: 2007/06/19 15:11:12 $
# $Header: /projects/dicty/build/source_files/db/lib/site_name/curation/FeatureCurationPage_base.pm,v 1.2 2007/06/19 15:11:12 emj466 Exp $
# $Log: FeatureCurationPage_base.pm,v $
# Revision 1.2  2007/06/19 15:11:12  emj466
# substitute @@_dbuser_ @@ for cgm_ddb
#
# Revision 1.1  2006/10/25 18:29:11  emj466
# new build directory
#
# Revision 1.1.1.2  2003/08/18 22:50:40  emj466
# no message
#
# Revision 1.1.1.1  2003/08/15 20:18:40  emj466
# initial load of dicty/build
#
# Revision 1.11  2003/06/26 18:51:46  shuai
# *** empty log message ***
#
# Revision 1.10  2003/06/25 23:44:49  anand
# Added code to handle alias_type field
#
# Revision 1.9  2003/04/15 22:20:31  anand
# Added a note to explain where to add Locus History notes
#
# Revision 1.8  2003/04/15 22:03:52  anand
# Added text to explain how to add Locus History notes
#
# Revision 1.7  2003/04/04 21:43:51  shuai
# *** empty log message ***
#
# Revision 1.6  2002/12/16 19:14:30  shuai
# *** empty log message ***
#
# Revision 1.5  2002/11/27 18:40:02  kara
# Made changes so that chromosome and coords cannot be updated with this
# interface (but new ones for a new feature can be inserted.)
#
# Revision 1.4  2002/11/27 01:55:39  kara
# added comments where the module needs to be updated.  also added note
# about loading new sequence data when a new feature is created.
#
# $Revision: 1.2 $
# $Source: /projects/dicty/build/source_files/db/lib/site_name/curation/FeatureCurationPage_base.pm,v $
# $State: Exp $
# $Locker:  $
######################################################################
#######################################################################
use strict;
use DBI;
use CGI qw/:all :html3/;
use CGI::Carp qw(fatalsToBrowser);
use lib "/usr/local/dicty/www_dictybase/db/lib/common";
use Login qw (ConnectToDatabase);
use TextUtil qw (DeleteUnwantedChar);
use lib "/usr/local/dicty/www_dictybase/db/lib/dictyBase";
use dictyBaseCentralMod qw(:formatPage :getInfo);
use lib "/usr/local/dicty/www_dictybase/db/lib/dictyBase/curation";
use printFeatureMod qw(:printInfo);
use lib "/usr/local/dicty/www_dictybase/db/lib/dictyBase/Objects";
use ConfigURLdictyBase;
use Feature_type;
use Curator_note;
use Delete_log;
use Update_log;
use Feature;
use Locus;
use Alias;

#######################################################################
#################### 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'}     = $args{'help'};
	$self->{'_title'}    = defined($args{'title'}) ? 
	                       $args{'title'} : "Feature Curation Page";
	$self->{'_user'}     = $args{'user'};
	
	$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;
	}
	
	if (param('commit') && param('feature')) {
	    $dbh->disconnect;
	    $dbh = &ConnectToDatabase($self->database, 
				      $dbuser, $dbpasswd);
	    $self->commitInfo;
	}
	elsif (param('feat')) {
	    $self->displayInfo;
	}
	else {
	    $self->displayEntryForm;
	}
}

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

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

    ##########################
    print 
    table(Tr(td(
		    startform,
		    b("This form is for dictyBase curators to display, update, insert or delete feature related info in oracle database."),p,
		    b(font({-size=>"+1"}, 'Enter Feature Name or Feature_no :')),
		         
		    textfield(-name=>'feat', -size=>30),
		    hidden('user', $self->user),   
		    submit('Submit','Submit'),
		    reset,

		    endform)));
    &printEndPage;
}


########################################################################
sub displayInfo {
########################################################################
    my ($self) = @_;
    my $featureObj = $self->createFeatureObject;
    &printStartPage($self->database, $self->title, $self->help);
    my ($locus, $aliasList, $uniformAliasList, $nonUniformAliasList, 
	$proteinNameAliasList, $featTypes, $chr, $beg, $end, $strand, 
	$isPmap, $desc, $noteArrayRef);
    if ($self->{'_featNo'}) {
	print center(h2(a({-href=>$configUrl->dictyBaseCGIRoot."$dblink/locus.pl?featureName=".$self->{'_featNm'}, 
			   -target=>"infowin"},
			  $self->{'_featNm'})." (feature_no=".$self->{'_featNo'}.")"));
	$locus = $featureObj->locus_name;
        #all aliases - Uniform, Non-uniform, and Protein name aliases
	$aliasList = $featureObj->aliasNameList;
	#Uniform aliases 
        $uniformAliasList = $featureObj->uniformAliasNameList; 
        #Non-uniform aliases 
        $nonUniformAliasList = $featureObj->nonUniformAliasNameList; 
        #Protein name aliases 
        $proteinNameAliasList = $featureObj->proteinNameAliasNameList; 
	$featTypes = $featureObj->featureTypeList;
	$chr = $featureObj->chromosome; 
        $beg = $featureObj->start_coord;
        $end = $featureObj->stop_coord;
	$strand = $featureObj->strand;
	$isPmap = $featureObj->is_on_pmap;
	$desc = $featureObj->brief_id;
	$noteArrayRef = $featureObj->curatorNoteInfoArrayRef;
    }
    else {
	print b("The feature_name (".font({-color=>'red'}, $self->{'_featNm'}).") you entered is not found in database. You may enter info for this new feature or go back, correct the name and try again.  If you create a new feature, be sure to use the Update Feature Sequence and Coords and Recreate Sequence Files tools off of Curator Central to load the sequence data and update the fasta data files (see Kara or Anand)."), p;
    }
    print startform,
          hidden('commit', "1"),
          hidden('user', $self->user);
    if ($self->{'_featNo'}) {
	print hidden('featNo', $self->{'_featNo'});
    }
    &printSubTitle("Name/Feature/Alias");
    print font({-color=>'red', -size=>-1}, 
               "NOTE: To delete an alias permanently from the database, 
    select the check box for deleting that alias and also remove it from the 
    text field."), br;
    &printUpdateFeatureBox($self->{'_featNm'});
    &printUpdateLocusBox($locus);
    &printUpdateUniformAliasBox($uniformAliasList);
    &printUpdateNonUniformAliasBox($nonUniformAliasList);
    &printUpdateProteinNameAliasBox($proteinNameAliasList);

    if ($aliasList) {
	&printDeleteAliasBox($aliasList);
    }

    if ($locus) {
	print p, a({-href=>$configUrl->dictyBaseCGIRoot."$dblink/curation/locusCuration?user=".$self->user."&locus=$locus", 
		    -target=>"info"},
		   "Edit locus details"), p;
    }
    &printSubTitle("Feature Type");
    &printFeatureTypes($featTypes);
    
    &printSubTitle("Positional Info");
    &printFeaturePosInfo($chr, $beg, $end, $strand, $isPmap);
    
    &printSubTitle("Brief Identification");
    &printFeatureDesc($desc);

    &printSubTitle("GO");
    print "GO not yet curated: ".a({-href=>$configUrl->dictyBaseCGIRoot."$dblink/curation/goCuration?user=".$self->user."&type=feature&feat=".$self->{'_featNm'}, 
				    -target=>"info"}, 
				   "curate GO"), p;

    &printSubTitle("Phenotype");
     if ($self->{'_featNm'}) {
	print a({-href=>$configUrl->dictyBaseCGIRoot."$dblink/curation/phenotypeCuration?user=".$self->user."&type=feature&feat=".$self->{'_featNm'},
		 -target=>"infowin"}, 
		"Curate Oracle phenotype"), br;
    }   
        
    print p;
    &printSubTitle("Curator Notes (table(s)=curator_note)");
    
    my $i = 0;
    foreach my $rowRef (@$noteArrayRef, '') {
	my($noteNo, $note, $isPublic);
	if ($rowRef){($noteNo, $note, $isPublic) = @$rowRef;}
	my $idList;
	if ($noteNo) {
	    $i++;
	    my $noteObj = Curator_note->new(dbh=>$dbh,
					    curator_note_no=>$noteNo);
	    $idList = $noteObj->getTableNmPrikeyList;
	    $isPublic =~ s/Y/for public/;
	    $isPublic =~ s/N/for private/;
	    print font({-color=>'red'}, "Note $i:"), br, "$note (".font({-color=>'red'}, $isPublic.")");
	    if ($idList =~ / /) {
		print " (".font({-color=>'red'}, "shared by $idList"), br;
	    }
	    print a({-href=>$configUrl->dictyBaseCGIRoot."$dblink/curation/curatorNote?curatorNoteNo=$noteNo&user=".$self->user, 
		     -target=>"infowin"}, "Update this note"), p;
	    next;
	}
	if ($i >= 0) {
	    print font({-color=>'red'}, "Enter \"Locus History\" information here: Please be sure to answer \"Yes\" if you want it displayed publicly on the Locus History page."), br;
	}
	&printCuratorNote($dbh, $note, $isPublic);
    }


    ######################
    ######################
    print submit('submit', "Commit"),
          reset,
          endform;
    &printEndPage;
}

########################################################################
sub commitInfo {
########################################################################
    my ($self) = @_;
    
    if (!param('feature')) { 
	$self->err_report("You should enter feature name before press the ".b("Commit")." button. Please go back, enter the feature name and submit again.");
        exit;
    }
    my $featNm = param('feature');
    my $otherTypes = join(':', param('featuretype2'));
    if (param('isOnPmap') =~ /Y/i && $otherTypes =~ /Deleted/i) {
	$self->err_report("Feature $featNm has been deleted, but is still on the physical map. If you wish to indicate the $featNm is deleted, please de-select 'is on the physical map display'. Thanks.");
	exit;
    }
    ################################################################
    $self->{'_title'} = "Commit $featNm Information";
    &printStartPage($self->database, $self->title, $self->help);
    ################################################################
    
    my $featObj;
    if (param('featNo')) {
	$featObj = Feature->new(dbh=>$dbh,
				feature_no=>param('featNo'));
	my $aliasArrayRef = $featObj->featureAliasArrayRef;
        #make a hash of alias_name with alias_no as the value
        my %alias_name_alias_no;
        foreach my $rowRef(@$aliasArrayRef) {
                my ($alias_no, $alias_name) = @$rowRef;
                $alias_name_alias_no{$alias_name} = $alias_no;
            }

	for (my $i = 1; $i <= 5; $i++) {
            ##### delete alias
	    if (param('aliasDelCB$i') =~ /on/i) {
	        my $aliasName = param("alias$i");
                my $aliasNo = $alias_name_alias_no{$aliasName};
                $self->deleteAlias($aliasNo, param("aliasDelLog$i"));
	    }
	}
	
    }
    
    my $locusNo;
    if (param('locusNm')) {
        my $locusObj = Locus->new(dbh=>$dbh,
				  locus_name=>param('locusNm'));
	if (!$locusObj) {
	     print "The locus (".font({-color=>'red'}, param('locusNm')).") you entered is not found in the database. Please correct it and try again. Thanks.",p;
	     exit;
	}
	$locusNo = $locusObj->locus_no;
    }
    
    if (param('featNo')) {
	$featObj = $self->updateFeatureTable;
	$self->updateFeatureTypeTable($featObj);
    }
    else {
	$featObj = $self->insertFeatureEntry;
	if ($featObj) {
	    $self->insertFeatureTypeTable($featObj);
	}
    }
    if (!$featObj) {
	&printEndPage;
	exit;
    }

    ##### update alias table
    $self->updateAlias($featObj);
       
    ##### update curator_note
    $self->updateCuratorNoteTable($featObj);

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

########################################################################
sub createFeatureObject {
########################################################################
    my ($self) = @_;
    my $feature = param('feat');
    &DeleteUnwantedChar(\$feature);
    my ($featureObj, $featNm, $featNo);
    if ($feature =~ /^[0-9]+$/) {
	$featureObj = Feature->new(dbh=>$dbh,
				   feature_no=>$feature);
	if ($featureObj) {
	    $self->{'_featNm'} = $featureObj->feature_name;
	    $self->{'_featNo'} = $feature;
	}
	else {
	    $self->err_report("The feature_no ".font({-color=>'red'}, $feature)." you entered is not found in the database. Please go back, correct it and try again. Thanks.");
	}    
    }
    else {
	$featureObj = Feature->new(dbh=>$dbh,
				   feature_name=>$feature);
	if ($featureObj) {
	    $self->{'_featNo'} = $featureObj->feature_no;
	    $self->{'_featNm'} = $featureObj->feature_name;
	}   
	else {
	    $self->{'_featNm'} = $feature;
	}
    }
    $self->{'_title'} .= " for ".$self->{'_featNm'};
    return $featureObj;
}


########################################################################
sub updateAlias {
########################################################################
    my ($self, $featObj) = @_;
    my @aliasDB = split(/\|/, $featObj->aliasNameList);
    
    my ($aliasList, $uniform_aliasList, $non_uniform_aliasList, 
        $protein_name_aliasList);
    $uniform_aliasList = param('uniform_alias');
    $non_uniform_aliasList = param('non_uniform_alias');
    $protein_name_aliasList = param('protein_name_alias');

    $uniform_aliasList =~ s/ //g; 
    ####don't want to remove spaces, if any, 
    ####in non_uniform and protein name aliases
    
    if ($uniform_aliasList) {
        $aliasList .= $uniform_aliasList . '|';
    }

    if ($non_uniform_aliasList) {
        $aliasList .= $non_uniform_aliasList . '|';
    }

    if ($protein_name_aliasList) {
        $aliasList .= $protein_name_aliasList;
    }

    my @alias = split(/\|/, $aliasList);
    my @uniform_aliasNm = split(/\|/, $uniform_aliasList);
    my @non_uniform_aliasNm = split(/\|/, $non_uniform_aliasList);
    my @protein_name_aliasNm = split(/\|/, $protein_name_aliasList);

    my %alias_type;
    foreach my $aliasNm (@uniform_aliasNm) {
        if ($aliasNm =~ /^\w{3}\d+$/i){
            $alias_type{"$aliasNm"} = 'Uniform';
        }
        else {
            $alias_type{"$aliasNm"} = 'Non-uniform';
        }
    }
    
    foreach my $aliasNm (@non_uniform_aliasNm) {
        if (! exists $alias_type{"$aliasNm"}) {
            $alias_type{"$aliasNm"} = 'Non-uniform';
        }
    }

    foreach my $aliasNm (@protein_name_aliasNm) {
        if (! exists $alias_type{"$aliasNm"}) {
            $alias_type{"$aliasNm"} = 'Protein name';
        }
    }

    my (%found, %foundDB);
    foreach my $alias (@aliasDB) {
	$foundDB{"\U$alias"}++;
    }
    foreach my $alias (@alias) {
	$found{"\U$alias"}++;
	if ($foundDB{"\U$alias"}) { next; }
	my $type = $alias_type{$alias};
	if ($type eq 'Uniform') {
	    $alias = uc($alias);
	}
	$self->insertAlias($featObj->feature_no, $alias, $type);
    }

    foreach my $alias (@aliasDB) {
	if ($found{"\U$alias"}) { next; }
        my $aliasArrayRef = $featObj->featureAliasArrayRef;
        #make a hash of alias_name with alias_no as the value
        my %alias_name_alias_no;
        foreach my $rowRef(@$aliasArrayRef) {
                my ($alias_no, $alias_name) = @$rowRef;
                $alias_name_alias_no{$alias_name} = $alias_no;
            }
        my $aliasNo = $alias_name_alias_no{$alias};
	$self->deleteAlias($aliasNo);
    }

}

########################################################################
sub insertAlias {
########################################################################
    my ($self, $featNo, $alias, $type) = @_;
    eval {
	Alias->Insert(dbh=>$dbh,
		      literals=>{alias_no=>'CGM_DDB.aliasno_seq.nextval'},
		      binds=>{feature_no=>$featNo,
			      alias_name=>$alias, 
			      alias_type=>$type});
    };
    if ($@) {
	print "An error occurred when inserting new alias '$alias' for feature_no = $featNo into database:$@", br;
	$dbh->rollback;
    }
    else {
	print "The new alias '$alias' for feature_no = $featNo has been inserted into database.", br;
	$dbh->commit;
    }
}

########################################################################
sub deleteAlias {
########################################################################
    my ($self, $alias, $log) = @_;
    my $aliasObj = Alias->new(dbh=>$dbh,
                              alias_no=>$alias);
       
    my $deletedRow;
    if ($log) { $deletedRow = $aliasObj->getRow; }
    
    eval { $aliasObj->delete; };
    if ($@) {
        print "An error occurred when deleting alias $alias from database:$@", br;
        $dbh->rollback;
    }
    else {
        print "The alias $alias has been deleted from database.", br;
        $dbh->commit;
        if ($log) {
            my $dlog = Delete_log->new(dbh=>$dbh,
                                       tab_name=>'ALIAS',
                                       deleted_row=>$deletedRow);
            $dlog->updateDescription($log);
            eval { $dlog->enterUpdates($self->user); };
            if ($@) {
                print "An error occurred when updating the delete_log table:$@", br;
                $dbh->rollback;
            }
            else {
                print "The delete log has been inserted into delete_log table.", br;
                $dbh->commit;
            }
        }
    }
}

########################################################################
sub updateFeatureTable {
########################################################################
    my ($self) = @_;
    my $featObj = Feature->new(dbh=>$dbh,
			       feature_no=>param('featNo'));
    
    my $featNmDB = $featObj->feature_name;
    my $locusNmDB = $featObj->locus_name;
    my $chrDB = $featObj->chromosome; 
    my $begDB = $featObj->start_coord;
    my $endDB = $featObj->stop_coord;
    my $strandDB = $featObj->strand;
    my $isPmapDB = $featObj->is_on_pmap;
    my $descDB = $featObj->brief_id;

    my $featNm = param('feature');
    my $locusNm = param('locusNm');
    ## KD: position info: 
    ## will comment this section out and add note about using other interface
#    my $chr = param('chr');
#    my $beg = param('beg');
#    my $end = param('end');
    my $strand = param('strand');
    my $isPmap = param('isOnPmap');
    my $desc = param('desc');
    
    &DeleteUnwantedChar(\$featNm);
    &DeleteUnwantedChar(\$locusNm);
    &DeleteUnwantedChar(\$desc);

    if ($strand =~ /^W/i) { $strand = "W"; }
    elsif ($strand =~ /^C/i) { $strand = "C"; }
    else { $strand = ""; }	
#    $chr =~ s/[^0-9]//g;
#    $beg =~ s/[^0-9]//g;
#    $end =~ s/[^0-9]//g;
    if ($isPmap =~ /on/i) { $isPmap = "Y"; }
    else { $isPmap = "N"; }

    my (@oldVal, @newVal, @colNm, @log);
    if ("\U$featNm" ne "\U$featNmDB") {
	$featObj->updateFeature_name($featNm);
	push(@oldVal, $featNmDB);
	push(@newVal, $featNm);
	push(@colNm, "FEATURE_NAME");
	push(@log, param('featUpdLog'));
    }
    ## KD: position info: 
    ## will comment this section out and add note about using other interface
#    if ($chr != $chrDB) {
#	$featObj->updateChromosome($chr);
#	push(@oldVal, $chrDB);
#	push(@newVal, $chr);
#	push(@colNm, "CHROMOSOME");
#	push(@log, param('posInfoUpdLog'));
#    }
#    if ($beg != $begDB) {
#	$featObj->updateStart_coord($beg);
#	push(@oldVal, $begDB);
#	push(@newVal, $beg);
#	push(@colNm, "START_COORD");
#	push(@log, param('posInfoUpdLog'));
 #   }
 #   if ($end != $endDB) {
#	$featObj->updateStop_coord($end);
#	push(@oldVal, $endDB);
#	push(@newVal, $end);
#	push(@colNm, "STOP_COORD");
#	push(@log, param('posInfoUpdLog'));
#    }
    ### KD: end position info
    if ("\U$strand" ne "\U$strandDB") {
	$featObj->updateStrand($strand);
	push(@oldVal, $strandDB);
	push(@newVal, $strand);
	push(@colNm, "STRAND");
	push(@log, param('posInfoUpdLog'));
    }

    if ($isPmap ne $isPmapDB) {
	$featObj->updateIs_on_pmap($isPmap);
	push(@oldVal, $isPmapDB);
	push(@newVal, $isPmap);
	push(@colNm, "IS_ON_PMAP");
	push(@log, param('posInfoUpdLog'));
    }
    if ($desc ne $descDB) {
	$featObj->updateBrief_id($desc);
	push(@oldVal, $descDB);
	push(@newVal, $desc);
	push(@colNm, "BRIEF_ID");
	push(@log, param('descUpdLog'));
    }
    if ("\U$locusNm" ne "\U$locusNmDB") {
	my $locusNoDB = $featObj->locus_no;
	my $locusObj = Locus->new(dbh=>$dbh,
				  locus_name=>$locusNm);
	my $locusNo = $locusObj->locus_no;
	$featObj->updateLocus_no($locusNo);
	push(@oldVal, $locusNoDB);
	push(@newVal, $locusNo);
	push(@colNm, "LOCUS_NO");
	push(@log, param('locusUpdLog'));
    }
    if (!@colNm) { return $featObj; } 
    eval { $featObj->enterUpdates; };
    if ($@) {
	print "An error occurred when updating feature table for feature_no = ".param('featNo').":$@", br;
        $dbh->rollback;
    }
    else {
	print "The feature entry for feature_no = ".param('featNo')." has been updated.", br;
	$dbh->commit;
	for (my $i = 0; $i <= $#colNm; $i++) {
	    if (!$log[$i]) { next; }
	    my $ulog = Update_log->new(dbh=>$dbh,
				       tab_name=>'FEATURE',
				       col_name=>$colNm[$i],
				       primary_key=>param('featNo'),
				       old_value=>$oldVal[$i],
				       new_value=>$newVal[$i]);
	    $ulog->updateDescription($log[$i]);
	    eval { $ulog->enterUpdates($self->user); };
	    if ($@) {
		print "An error occurred when updating update_log table:$@", br;
		$dbh->rollback;
	    }
	    else {
		print "The update_log comment for updating $colNm[$i] has been inserted into update_log table.", br;
		$dbh->commit;
	    }
	}
    }
    return $featObj;
}

########################################################################
sub insertFeatureEntry {
########################################################################
    my ($self) = @_;

    my $featNm = param('feature');
    my $locusNm = param('locusNm');
    my $chr = param('chr');
    my $beg = param('beg');
    my $end = param('end');
    my $strand = param('strand');
    my $isPmap = param('isOnPmap');
    my $desc = param('desc');
    
    &DeleteUnwantedChar(\$featNm);
    &DeleteUnwantedChar(\$locusNm);
    &DeleteUnwantedChar(\$desc);
    
    my $locusNo;
    if ($locusNm) {
	my $locusObj = Locus->new(dbh=>$dbh,
				  locus_name=>$locusNm);
	$locusNo = $locusObj->locus_no;
    }

    if ($strand =~ /^W/i) { $strand = "W"; }
    elsif ($strand =~ /^C/i) { $strand = "C"; }
    else { $strand = ""; }	
    $chr =~ s/[^0-9]//g;
    $beg =~ s/[^0-9]//g;
    $end =~ s/[^0-9]//g;
    if (!$isPmap) { $isPmap = "N"; }
    else { $isPmap = "Y"; }

    eval {
	Feature->Insert(dbh=>$dbh,
			literals=>{feature_no=>'CGM_DDB.featno_seq.nextval',
			           feature_version=>'SYSDATE'},
			binds=>{feature_name=>$featNm,
				chromosome=>$chr,
				start_coord=>$beg,
				stop_coord=>$end,
				strand=>$strand,
				is_on_pmap=>$isPmap,
				locus_no=>$locusNo,
				brief_id=>$desc});
    };
    if ($@) {
	print "An error occurred when inserting new feature entry for feature_name = '$featNm' into database:$@", br;
	$dbh->rollback;
	return;
    }
    else {
	print "The new feature entry for feature_name = '$featNm' has been inserted into database.", br;
	$dbh->commit;
	my $featObj = Feature->new(dbh=>$dbh,
				   feature_name=>$featNm);
	return $featObj;
    }
}

########################################################################
sub updateFeatureTypeTable {
########################################################################
    my ($self, $featObj) = @_;
    my @featTypeDB = split(/\|/, $featObj->featureTypeList);
    my @featType = param('featuretype1');
    push(@featType, param('featuretype2'));
 
    my (%found, %foundDB);
    foreach my $featType (@featTypeDB) {
	$foundDB{$featType}++;
    }
    foreach my $featType (@featType) {
	&DeleteUnwantedChar(\$featType); 
	$found{$featType}++;
	if ($foundDB{$featType}) { next; }
	$self->insertFeatureType($featObj->feature_no, $featType);
    }
    foreach my $featType (@featTypeDB) {
	if ($found{$featType}) { next; }
	$self->deleteFeatureType($featObj->feature_no, $featType);
    }
}

########################################################################
sub insertFeatureTypeTable {
########################################################################
    my ($self, $featObj) = @_;
    foreach my $featType (param('featuretype1'), param('featuretype2')) {
	&DeleteUnwantedChar(\$featType); 
	$self->insertFeatureType($featObj->feature_no, $featType);
    }
}

########################################################################
sub deleteFeatureType {
########################################################################
    my ($self, $featNo, $featType) = @_;
    my $featTypeObj = Feature_type->new(dbh=>$dbh,
				       feature_no=>$featNo,
				       feature_type=>$featType);
    eval { $featTypeObj->delete; };
    if ($@) {
	print "An error occurred when deleting feature_type '$featType' for feature_no = $featNo from database:$@", br;
	$dbh->rollback;
    }
    else {
	print "The feature_type '$featType' for feature_no = $featNo has been deleted from database.", br;
	$dbh->commit;
    }
}

########################################################################
sub insertFeatureType {
########################################################################
    my ($self, $featNo, $featType) = @_;
    eval {
	Feature_type->Insert(dbh=>$dbh,
			     binds=>{feature_no=>$featNo,
				     feature_type=>$featType});
    };
    if ($@) {
	print "An error occurred when inserting feature_type '$featType' for feature_no = $featNo into database:$@", br;
	$dbh->rollback;
    }
    else {
	print "The feature_type '$featType' for feature_no = $featNo has been inserted into database.", br;
	$dbh->commit;

        print "In order to create sequences please click ",
               a({-href=>$configUrl->dictyBaseCGIRoot."$dblink/curation/loadSeq.pl?user=$self->{'_user'}"},"here");

    }
}


########################################################################
sub updateCuratorNoteTable {
########################################################################
    my ($self, $featObj) = @_;
    my $note = param('note');
    if (!$note) { return; }
    my $idList = param('idList');
    my $isPublic = param('isPublic');
    if ($isPublic =~ /^Y/) { $isPublic = "Y"; }
    else { $isPublic = "N"; }
    &DeleteUnwantedChar(\$note);
    &DeleteUnwantedChar(\$idList);
    $idList =~ s/ +/ /g;
    $idList =~ s/, */\,/g;
    my $featNo = $featObj->feature_no;
    if ($idList !~ /Feature,${featNo}/i) {
    $idList .= " Feature,$featNo";
    }
    $idList =~ s/^ //;
    my $noteObj = Curator_note->new(dbh=>$dbh,
				    note=>$note,
				    is_public=>$isPublic);
    if (!$noteObj) {
	eval {
	    Curator_note->Insert(dbh=>$dbh,
				 literals=>{curator_note_no=>'CGM_DDB.cnno_seq.nextval'},
				 binds=>{note=>$note,
					 is_public=>$isPublic});
	};
	if ($@) {
	    print "An error occurred when inserting new curator_note '$note' into database:$@", br;
	    $dbh->rollback;
	    return;
	}
	else {
	    print "The new curator_note '$note' has been inserted into database.", br;
	    $dbh->commit;
	    $noteObj = Curator_note->new(dbh=>$dbh,
					 note=>$note,
					 is_public=>$isPublic);
	}
    }
    eval {
        Curator_note->InsertCuratorNoteLinkInfo(dbh=>$dbh,
			  idList=>$idList,
			  curator_note_no=>$noteObj->curator_note_no);
    };
    if ($@) {
	print "An error occurred when inserting info into curator_note link table:$@", br;
	$dbh->rollback;
    }
    else {
	print "The curator note info has been inserted into linking table(s).", br;
	$dbh->commit;
    }
}

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

########################################################################
sub err_report {
########################################################################
    my ($self, $err) = @_;
 
    &printStartPage($self->database, $self->title, $self->help);
    
    print b($err);
    
    &printEndPage;

    if ($dbh) { $dbh->disconnect; }
    exit;
}

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



















