#!/usr/local/bin/perl -w

use strict;
use Apache::Request;
use Template;
use CGI 'unescape';
use Gramene::Page;
use Gramene::Utils 'commify';
use Gramene::Gene::GeneCurationDB;
use Gramene::Protein::EditProteinDB;
use Gramene::Gene::GeneDB;

use constant {
    CURATION_ENTRY_TEMPLATE => 'gene_curation_entry.tmpl',
    CURATION_TEMPLATE       => 'gene_curation.tmpl',
    EDITING_TEMPLATE        => 'gene_edit.tmpl',
    UTIL_TEMPLATE        => 'gene_util.tmpl',
    ERROR_TEMPLATE          => 'gene_error.tmpl',

    GENE_ACCESSION_PREFIX => 'GR:',
    GENE_ACCESSION_LENGTH => 7,

    PROTEIN_XREF_DB => 'Gramene Protein',
};

my $apr  = Apache::Request->new( Apache->request );
my $page = Gramene::Page->new($apr);
my ( $template, $html, $db, $db_get, $db_protein, $pager );



$db = Gramene::Gene::GeneCurationDB->new();
$db->connect_to_db();

$db_get = Gramene::Gene::GeneDB->new();
$db_get->connect_to_db();

$db_protein = Gramene::Protein::EditProteinDB->new();
$db_protein->connect_to_db();


my $all_species = $db_get->get_all_species();
my $all_dbxrefs = $db_get->get_all_dbxrefs();
my $all_gene_types = $db_get->get_all_gene_types();
my $gene_interaction_types = $db_get->get_all_gene_interaction_types();
my $has_phenotype = [ 'yes', 'no', 'N/A' ];
my $interaction_object_classes = [ 'DNA', 'RNA', 'protein', 'gene'];
my @evidence_codes = qw[IC IDA IEA IEP IMP IGI IPI ISS IAGP NAS NOT NR RCA SM TAS];


my $ordered_term_type_fields = [
    'Trait',
    'Plant Structure',
    'Plant Growth and Development Stage',
    'Cereal Plant Growth Stage',
    'Cellular Component',
    'Molecular Function',
    'Biological Process',
    'Enviroment'
];


# search field maps to term_type in database
my %search_term_fields = (
    'to' => 'Trait',
    'anatomy' =>'Plant Structure',
    'po_growth_stage' => 'Plant Growth and Development Stage',
    'growth_stage' => 'Cereal Plant Growth Stage',
    'go_component' => 'Cellular Component',
    'go_function' => 'Molecular Function',
    'go_process' =>  'Biological Process',
    'eo' => 'Enviroment'
);

my %edit_actions = (
    'add_dbxref' => \&add_gene_dbxref,
    'add_term' => \&add_gene_ontology_association,
    'add_synonym' => \&add_gene_synonym,
    'add_map_pos' => \&add_gene_map_position,
    'add_interaction' => \&add_gene_interaction,
    'add_interaction_evidence' => \&add_gene_interaction_evidence,
    'del_dbxref' => \&delete_gene_dbxref,
    'del_synonym' => \&delete_gene_synonym,
    'del_term' => \&delete_gene_ontology_association,
    'del_map_pos' => \&delete_gene_map_position,
    'del_interaction' => \&delete_gene_interaction,
    'del_interaction_evidence' => \&delete_gene_interaction_evidence,
    'update_symbol' => \&update_gene_symbol,
    'update_name' => \&update_gene_name,
    'update_status' => \&update_gene_status,
    'update_species' => \&update_gene_species,
    'update_gene_type' => \&update_gene_type,
    'update_has_phenotype' => \&update_gene_has_phenotype,
    'update_chromosome' => \&update_gene_chromosome,
    'update_description' => \&update_gene_description,
    'update_map_pos' => \&update_gene_map_position,
    'update_interaction' => \&update_gene_interaction,
    'update_interaction_evidence' => \&update_gene_interaction_evidence,
    'update_comment' => \&update_gene_public_curation_comment,
    'update_curation_note' => \&update_gene_internal_curation_comment,
    'merge_gene' => \&merge_genes,
);

my %utils = (
    dbxref => \&util_dbxref,
    gene_type => \&util_gene_type,
    species => \&util_species
);

my $util_query = $apr->param('util');
my $gene_id = $apr->param('gene_id');    # internal use only
my $acc;

if ( $apr->param('acc') ) { 
    #clean the acc
    $acc = process_accession( 
			      GENE_ACCESSION_PREFIX,
			      GENE_ACCESSION_LENGTH, 
			      $apr->param('acc')
			    );   
}

unless ($gene_id) {

    $gene_id = $db_get->get_gene_id($acc) if $acc;
}

eval {

    $template = Template->new(
        {
            INCLUDE_PATH => '/usr/local/gramene/templates/genes',
            PRE_CHOMP    => 1,
            POST_CHOMP   => 1,
            TRIM         => 1,
            FILTERS      => { commify => \&Gramene::Utils::commify }

        }
    );

    if ($acc){ # gene 
	if($gene_id){ # gene in db
	    unless($apr->param('save_to_db')){ # this param in curation new gene form only
	

		my $obj_type = 'gene';
		my $gene_obj = &get_gene_object($db_get,$gene_id,$obj_type);

		my $edit_result={};




		#### edit gene fields
		foreach my $param ($apr->param){
		    if(exists $edit_actions{$param}){
			my $method = $edit_actions{$param};
			$method->($apr, $db, $db_get, $db_protein,PROTEIN_XREF_DB, $obj_type, $gene_obj, $edit_result);
			last;
		    }
		}
	


		$template->process(
		    EDITING_TEMPLATE, {
			gramene_page  => $page,
			apr           => $apr,
			gene          => $gene_obj,
			all_species   => $all_species,
			all_dbxrefs   => $all_dbxrefs,
			all_gene_types => $all_gene_types,
			gene_interaction_types => $gene_interaction_types,
			evidence_codes => \@evidence_codes,
			interaction_object_classes => $interaction_object_classes,
			has_phenotype => $has_phenotype,
			ordered_term_type_fields => $ordered_term_type_fields,
			edit_result   => $edit_result,
			title         => "Gene Editing"
		    },
		\$html
		) or $html = $template->error;
	   }
	}else{ # new gene entry
		    
	    my $curation_result;
	    my $temp_gene;

	    my %args = $apr->args;        

	    $temp_gene = get_the_temp_gene($acc);

	    if(%args){
		if($args{"save_to_db"}){
		     $curation_result = $db->load_gene(\%args, \%search_term_fields);
		     if($temp_gene && $curation_result->{'ok'}){
			 $acc =~s/GR:0+//;    
			 unlink("./TEMP_GENE/Gene_$acc.txt") or die "$!"; # delete the temp file
		     } 
		     if($curation_result->{'ok'}){

			# check and update protein to gene and ontology association in protein DB


			my $gene_acc = $args{'acc'};
			my $gene_id = $db_get->get_gene_id($gene_acc) ;

			my $gene_obj = &get_gene_object($db_get, $gene_id, 'gene');

			my $gene_name = $gene_obj->{'name'};
			my $gene_desc = $gene_obj->{'description'};
			my $gene_symbol = $gene_obj->{'symbol'};

			my $protein_xref_db = PROTEIN_XREF_DB;
			my @protein_ids = &get_protein_ids($gene_obj, $db_protein,$protein_xref_db);


			if(@protein_ids){ # update protein db fields, import fields from protein

			    &update_protein_gene_association_in_protein_db($db, $db_protein, $gene_acc, $curation_result, \@protein_ids);


			    # export the gene-onto to protein db
			    my $gene_terms = $db_get->get_ontology_association('gene',$gene_id);
			    foreach my $term_type (keys %$gene_terms){
				my $terms = $gene_terms->{$term_type};
				foreach my $term (@$terms){
				    my $term_acc = $term->{'term_accession'};
				    &update_protein_ontology_associations($db, $db_protein, $gene_id, \@protein_ids, $term_acc, $term_type);
				}
			    }


			     # in gene db
			     &update_gene_ontology_association_from_protein_xrefs($db, $db_protein, $gene_id, $curation_result, \@protein_ids);


			    # in protein db
			    &update_protein_public_comment($db_protein, $gene_acc, $gene_desc, \@protein_ids);



			    &update_protein_name($db_protein, $gene_name, \@protein_ids);
			    &update_protein_symbol($db_protein, $gene_symbol, \@protein_ids);


			    # import ec from protein db
			    &update_gene_ecs_from_protein_ecs($db, $db_protein, $gene_id, $curation_result, \@protein_ids);

			    # export ecs to protein db
			    my $ecs_obj = $gene_obj->{'dbxrefs'}->{'E.C. Number(s)'};
			    my @ecs = values %$ecs_obj;
			    &update_protein_ecs($db_protein, \@ecs,\@protein_ids);

			}


		     }
		}elsif($args{"save_to_file"}){
		    $acc =~s/GR:0+//;
		    my $temp_file = "./TEMP_GENE/Gene_$acc.txt";
		    open(TEMP, ">$temp_file") or die "$!";
		    foreach my $param ($apr->param){
			print TEMP $param, "=", $apr->param($param),"\n";
		    }
		    close(TEMP);
		    $curation_result->{'temp'}= process_accession( 
			      GENE_ACCESSION_PREFIX,
			      GENE_ACCESSION_LENGTH, 
			      $acc
			    );   
		}
	    }

	    $template->process( 
		     CURATION_TEMPLATE,
		    {
			gramene_page  => $page,
			apr           => $apr,
			species       => $all_species,
			dbxrefs       => $all_dbxrefs,
			gene_types    => $all_gene_types,
			has_phenotype => $has_phenotype,
			acc           => $acc,   
			temp_gene     => $temp_gene,
			curation_result=>$curation_result, 
			title         => "Gene Curation"
		    },
		    \$html
	    ) or $html = $template->error;

	}
	
    }elsif(defined $util_query){
	my $util = {};
	if($util_query && $utils{$util_query}){
	    $utils{$util_query}->($apr, $db, $db_get, $util);
	}

	$template->process(
	    UTIL_TEMPLATE,
	    {
		gramene_page  => $page,
		apr           => $apr,
		util	      => $util
	    },
	    \$html
	) or $html = $template->error;
       	
    
    }else { #  gene curation entry page

        $template->process(
            CURATION_ENTRY_TEMPLATE,
            {
                gramene_page => $page,
                apr          => $apr,
                title        => "Gene Curation"
            },
            \$html
          )
          or $html = $template->error;

    }

};

if ( my $err = $@ ) {
    if ($template) {
        $template->process(
            ERROR_TEMPLATE,
            {
                gramene_page  => $page,
                error_message => $err,
            },
            \$html
          )
          or $html = $template->error;
    }
    else {
        $html = "Error: $err";
    }
}

$apr->content_type('text/html');
$apr->send_http_header;
$apr->print($html);




# -----------------------------------------------

sub get_the_temp_gene {

    my ($acc) = @_;

    $acc =~ s/^GR:0+//;

    my $temp_obj;
    my ($temp_file) = glob("./TEMP_GENE/*_$acc.txt");
    if ($temp_file) {
        open( TEMP, "<$temp_file" ) or die "$!";
        while (<TEMP>) {
            chomp;
            /^(.*)=(.*)$/;
            $temp_obj->{$1} = $2;
        }
        close(TEMP);
    }

    return $temp_obj;
}


#-----------------------------------------------
sub get_gene_object{
    my ($db_get, $gene_id, $obj_type) = @_;

    my $gene_obj;


    $gene_obj = $db_get->get_gene_general_info($gene_id);     

    # get the gene_type from get_gene_general_info, but we want # gene_type_id so:
    $gene_obj->{'gene_type_id'} = $db_get->get_gene_simple_field('gene_type_id',$gene_id);

    $gene_obj->{'synonyms'}= $db_get->get_gene_synonyms($gene_id); # a hashref


    # an array of hashref
    $gene_obj->{'map_positions'} = $db_get->get_gene_map_position($gene_id);

    $gene_obj->{'gene_interactions'} = $db_get->get_gene_interactions($gene_id);

    # a hashref      
    $gene_obj->{'ontologys'} = $db_get->get_ontology_association($obj_type, $gene_id);
    $gene_obj->{'dbxrefs'} = $db_get->get_object_all_dbxrefs($obj_type,$gene_id);# a hashref


    return $gene_obj;

}

# -----------------------------------------------


sub process_accession {

    my ($prefix, $length,$acc) = @_;
    $acc =~s/^$prefix//;
    $acc =~s/^0+//;

    my $str_len = length($acc);
    my $num = $length - $str_len;
    for my $i (1 .. $num){
	$acc = '0'.$acc;
    }

    $acc = $prefix.$acc;
    return $acc;

}

# -----------------------------------------------

sub update_gene_status{
    my($apr, $db, $db_get, $db_protein, $protein_xref_db, $obj_type,  $gene_obj, $edit_result) = @_;

    my $gene_id = $gene_obj->{'gene_id'};
    my $new_status = 1 - $gene_obj->{'is_obsolete'};  # switch status between 1
    $db->update_gene_simple_field('is_obsolete', $new_status, $gene_id, $edit_result);
    $gene_obj->{'is_obsolete'} = $db_get->get_gene_simple_field('is_obsolete',$gene_id);
}

# -----------------------------------------------

sub update_gene_symbol{
    &update_gene_symbol_or_name(@_,'symbol');
    &check_and_update_protein_symbol(@_);
}
    

# -----------------------------------------------

sub update_gene_name{
    &update_gene_symbol_or_name(@_,'name');
    &check_and_update_protein_name(@_);
}

# -----------------------------------------------

sub update_gene_symbol_or_name{
    my($apr, $db, $db_get, $db_protein, $protein_xref_db, $obj_type,  $gene_obj, $edit_result, $field) = @_;

    my $gene_id = $gene_obj->{'gene_id'};
    my $new_symbol = $apr->param($field);
    # in template the symbol, name and synonym fields in selection are escaped
    # because the quota in <option value="
    $new_symbol = unescape($new_symbol);   
    my $old_symbol = $gene_obj->{$field};
    unless($new_symbol eq $old_symbol){
	$db->update_gene_simple_field($field, $new_symbol, $gene_id, $edit_result);

	unless($edit_result->{'error'}){
	    $db->add_gene_synonyms($gene_id,$old_symbol,$edit_result);
	    $db->delete_gene_synonym($gene_id,$new_symbol,$edit_result);
	    $gene_obj->{'synonyms'} = $db_get->get_gene_synonyms($gene_id);
	}
	$gene_obj->{$field} = $db_get->get_gene_simple_field($field,$gene_id);
    }
}

# -----------------------------------------------

sub add_gene_synonym{
    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result) = @_;

    my $gene_id = $gene_obj->{'gene_id'};
    my $new_syns = $apr->param('new_syn');
    $db->add_gene_synonyms($gene_id,$new_syns,$edit_result);
    $gene_obj->{'synonyms'}= $db_get->get_gene_synonyms($gene_id);
}


# -----------------------------------------------

sub delete_gene_synonym{
    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result) = @_;

    my $gene_id = $gene_obj->{'gene_id'};
    my $syn = $apr->param('synonym');
    $syn = unescape($syn);
    $db->delete_gene_synonym($gene_id,$syn,$edit_result);
    $gene_obj->{'synonyms'} = $db_get->get_gene_synonyms($gene_id);
}


# -----------------------------------------------

sub update_gene_simple_fields{
    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result, $field) = @_;

    my $gene_id = $gene_obj->{'gene_id'};
    my $val = $apr->param($field);
    $val =~s/^\s+|\s+$//g;
    $db->update_gene_simple_field($field, $val, $gene_id, $edit_result);
    $gene_obj->{$field} = $db_get->get_gene_simple_field($field,$gene_id);

}

sub update_gene_species{
    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result) = @_;


    &update_gene_simple_fields(@_, 'species_id');
    my $spe_id = $gene_obj->{'species_id'};

    #add the species obj to gene obj
    $gene_obj->{'species'} = $db_get->get_species($spe_id);

    #delete the species_id to avoid update two places
    delete $gene_obj->{'species_id'};
}



sub update_gene_type{
    &update_gene_simple_fields(@_, 'gene_type_id');
}

sub update_gene_has_phenotype{
    &update_gene_simple_fields(@_, 'has_phenotype');
}


sub update_gene_chromosome{
    &update_gene_simple_fields(@_, 'chromosome');
}

sub update_gene_description{
    &update_gene_simple_fields(@_, 'description');
    &check_and_update_protein_comment(@_);
}


sub update_gene_public_curation_comment{
    &update_gene_simple_fields(@_, 'public_curation_comment');
}

sub update_gene_internal_curation_comment{
    &update_gene_simple_fields(@_, 'internal_curation_comment');
}

# -----------------------------------------------
sub delete_gene_dbxref{

    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result) = @_;

    my $gene_id = $gene_obj->{'gene_id'};
    my $gene_acc = $gene_obj->{'accession'};
    my $db_name = $apr->param('xdb_name');	
    my @dbxrefs = $apr->param('dbxref');

    if(@dbxrefs){


	if($db_name eq 'E.C. Number(s)'){
	    &check_and_delete_protein_ecs($gene_obj,$db_protein,$protein_xref_db,\@dbxrefs);
	}

	# delete the protein association in protein db if has
	# also delete the ontology associations brought by those proteins in gene db
	if($db_name eq $protein_xref_db){

	    my %g_terms;
	    my $protein_onto_assoc = 0;
	    my %del_proteins;
	    my @proteins;

	    foreach my $dbx_id (@dbxrefs){
		my $protein_acc = $db_get->get_xref_object($dbx_id);
		my $protein_id = $db_protein->get_protein_id($protein_acc);
		if($protein_id){
		    $del_proteins{$protein_acc} = $protein_id;

		    # update the protein comment field
		    my $gene_desc = ''; # remove the gene_desc from protein comment
		    &update_protein_public_comment($db_protein, $gene_acc, $gene_desc, [$protein_id]);

		}
	    }
	    
	    # the ontology associations of associated proteins in gene db excluding the del_proteins
	    @proteins = $db_get->get_gene_xref_vals_by_xdb($obj_type,$gene_id, $protein_xref_db);
	    foreach my $protein (@proteins){
		next if $del_proteins{$protein};
		my $protein_id = $db_protein->get_protein_id($protein);
		if($protein_id){
		    my $associations = $db_protein->get_associations($protein_id);
		    foreach my $assoc (@$associations){
			my $term_acc = $assoc->{'term_accession'};
			$g_terms{$term_acc}->{$protein_id} = $assoc->{'association_id'};
		    }
		}
	    }

	    # delete protein-gene association in protein db
	    # check and delete onto associations coming from deleted proteins in
	    # gene db
	    foreach my $protein_acc (keys %del_proteins){
		my $protein_id = $del_proteins{$protein_acc};
		$db_protein->delete_gene_association_by_acc( $protein_id,$gene_obj->{'accession'});

		my $associations = $db_protein->get_associations($protein_id);
		foreach my $assoc (@$associations){
		    my $term_acc = $assoc->{'term_accession'};
		    # delete onto only when no other protein associated
		    unless(%g_terms && exists $g_terms{$term_acc}){
			 $db->delete_gene_ontology_associations($gene_id, [$term_acc],$edit_result);
			 $protein_onto_assoc = 1;

		    }
		}
	    }

	    if($protein_onto_assoc){ # update ontology assoc
		$gene_obj->{'ontologys'} = $db_get->get_ontology_association($obj_type, $gene_id);
	    }
	}


	# delete dbxref
	$db->delete_gene_dbxrefs(\@dbxrefs,$edit_result);
	$gene_obj->{'dbxrefs'} = $db_get->get_object_all_dbxrefs($obj_type,$gene_id);# a hashref
	
    }
}


# -----------------------------------------------
sub add_gene_dbxref{
    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result) = @_;
    my $gene_id = $gene_obj->{'gene_id'};
    my $gene_acc = $gene_obj->{'accession'};
    my $gene_desc = $gene_obj->{'description'};

    my $dbxref_vals=$apr->param('new_dbxref');
    my $dbx = $apr->param('dbxref');
    my ($dbx_id, $db_name) = ($dbx=~/(\d+)_(.+)/); # dbxref_id plus '_' plus dbxref_name as value
    if($dbxref_vals){
	$db->add_gene_dbxrefs($gene_id,$dbx_id,$dbxref_vals,$edit_result);
	$gene_obj->{'dbxrefs'} = $db_get->get_object_all_dbxrefs($obj_type,$gene_id);# a hashref

	# for update the protein-gene association in protein db
	# also bring the protein-ontology association to gene db
	if($db_name eq $protein_xref_db){
	    my @protein_accs = $db->process_delimited_values(',',$dbxref_vals);
	    my @protein_ids;
	    foreach my $protein_acc (@protein_accs){
		my $protein_id = $db_protein->get_protein_id($protein_acc);
		push @protein_ids, $protein_id if $protein_id;
	    }
	    
	    my $update_onto = 0;
	    my $update_ec = 0;

	    if(@protein_ids){
		&update_protein_gene_association_in_protein_db($db, $db_protein, $gene_obj->{'accession'}, $edit_result, \@protein_ids);

		# export the gene-onto to protein db
		my $gene_terms = $gene_obj->{'ontologys'};
		foreach my $term_type (keys %$gene_terms){
		    my $terms = $gene_terms->{$term_type};
		    foreach my $term (@$terms){
			my $term_acc = $term->{'term_accession'};
			&update_protein_ontology_associations($db, $db_protein, $gene_id, \@protein_ids, $term_acc, $term_type);
		    }
		}



		# import protein-onto to gene db
		$update_onto = &update_gene_ontology_association_from_protein_xrefs($db, $db_protein, $gene_id, $edit_result, \@protein_ids);


		# export ecs to protein db
		my $ecs_obj = $gene_obj->{'dbxrefs'}->{'E.C. Number(s)'};
		my @ecs = values %$ecs_obj;
		&update_protein_ecs($db_protein, \@ecs,\@protein_ids);

		# import ecs to gene db
		$update_ec = &update_gene_ecs_from_protein_ecs($db, $db_protein, $gene_id, $edit_result, \@protein_ids);


		&update_protein_public_comment($db_protein, $gene_acc, $gene_desc, \@protein_ids);


	    }
	    if($update_onto){ # update ontology assoc
		$gene_obj->{'ontologys'} = $db_get->get_ontology_association($obj_type, $gene_id);
	    }

	    if($update_ec){ 
		$gene_obj->{'dbxrefs'} = $db_get->get_object_all_dbxrefs($obj_type,$gene_id);
	    }

	}


	if($db_name eq 'E.C. Number(s)'){
	    my @ecs = $db->process_delimited_values(',',$dbxref_vals);
	    &check_and_update_protein_ecs($gene_obj,$db_protein,$protein_xref_db,\@ecs);
	}
    } #
}



# -----------------------------------------------
sub delete_gene_ontology_association{

    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result) = @_;

    my $gene_id = $gene_obj->{'gene_id'};
    my $gene_acc = $gene_obj->{'accession'};
    
    my @terms = $apr->param('term_acc');
    if(@terms){
	$db->delete_gene_ontology_associations($gene_id, \@terms,$edit_result);

	my $term_type = $apr->param('term_type');
	$gene_obj->{'ontologys'} = $db_get->get_ontology_association($obj_type, $gene_id);

	# check and update protein ontology association in protein DB
	my $proteins = $gene_obj->{'dbxrefs'}->{$protein_xref_db};
	if($proteins){
	    my $evn_code = 'NOT';
	    my $ic_evn_code = 'IC';
	    my $protein_dbx = 'gramene.literature';
	    my $protein_dbx_val = '11089';
	    my $protein_evn_dbxref_id = $db_protein->get_dbxref_id($protein_dbx,$protein_dbx_val);

	    my @protein_ids;
	    # get all protein associations 
	    foreach my $protein (values %$proteins){
		my $protein_id = $db_protein->get_protein_id($protein);
		push @protein_ids, $protein_id;
	    }

	    if(@protein_ids){

		foreach my $g_term (@terms){
		    foreach my $p_id (@protein_ids){
			my $assoc_id = $db_protein->get_association_id($p_id,$g_term);
			if($assoc_id){
			    my $evn_id = $db_protein->get_evidence_id($ic_evn_code, $assoc_id, $protein_evn_dbxref_id);
			    if($evn_id){ # update 'IC' to 'NOT'
				$db_protein->update_evidence($evn_code, $assoc_id, $protein_evn_dbxref_id, $evn_id);
			    }else{ # flag to 'NOT' in protein db
				$db_protein->add_evidence($p_id, $assoc_id, $protein_dbx, $protein_dbx_val, $evn_code);
			    }
			}
		    }
		}



	    }
	}

    }

}



# -----------------------------------------------
sub add_gene_ontology_association{
    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result) = @_;
    my $gene_id = $gene_obj->{'gene_id'};

    my $term_acc = $apr->param('new_term');
    my $term_type = $apr->param('ontology_type');
    if($term_acc && $term_type){
	$db->add_gene_ontology_associations($gene_id,$term_type,$term_acc,$edit_result);
	$gene_obj->{'ontologys'} = $db_get->get_ontology_association($obj_type, $gene_id);

	# check and update protein ontology association in protein DB
	my $proteins = $gene_obj->{'dbxrefs'}->{$protein_xref_db};
	if($proteins){
	    my @protein_accs = values %$proteins;
	    my @protein_ids;
	    foreach my $protein_acc (@protein_accs){
		my $protein_id = $db_protein->get_protein_id($protein_acc);
		push @protein_ids, $protein_id if $protein_id;
	    }
			

	    &update_protein_ontology_associations($db, $db_protein, $gene_id, \@protein_ids, $term_acc, $term_type);

    
	}

    }
}

# -----------------------------------------------


sub util_dbxref {
    my ($apr, $db, $db_get, $util) = @_;

    # selected xref_db
    if($apr->param('xref_db')){
	my $xref_db = $db_get->get_xref_db($apr->param('xref_db'));
	$util->{'xref_db'} = $xref_db if $xref_db;
    }

    # update
    if($apr->param('update_dbxref')){
	my $dbx_id = $apr->param('xdb_id');
	my $dbx_name = $apr->param('xdb_name');
	my $dbx_url = $apr->param('xdb_url');
	if($dbx_id && $dbx_name && $dbx_url){
	    $db->update_dbxref_source($dbx_id, $dbx_name, $dbx_url);
	}
	
    }

    # add
    if($apr->param('add_dbxref')){
	my $dbx_name = $apr->param('xdb_name');
	my $dbx_url = $apr->param('xdb_url');
	if($dbx_name && $dbx_url){
	    $db->add_dbxref_source($dbx_name, $dbx_url);
	}
    

    }
	
    my $all_xref_dbs = $db_get->get_all_dbxrefs;
    $util->{'xref_dbs'} = $all_xref_dbs;


    # default selected xref_db
    unless($apr->param('xref_db')){
	$util->{'xref_db'} = $all_xref_dbs->[0];
    }
}


# ----------------------------------

sub util_species {
    my ($apr, $db, $db_get, $util) = @_;

    # select species 
    if($apr->param('select_spe')){
	my $species = $db_get->get_species($apr->param('select_spe'));
	$util->{'species'} = $species if $species;
    }

    # update
    if($apr->param('update_species')){
	my $spe_id = $apr->param('species_id');
	my $genus = $apr->param('spe_genus');
	my $spe = $apr->param('spe_species');
	my $name = $apr->param('spe_name');
	my $taxid = $apr->param('spe_taxid');
	my $gr_taxid = $apr->param('gr_spe_taxid');
	if($genus || $spe || $name || $taxid || $gr_taxid){
	    $db->update_species($spe_id, $genus, $spe, $name, $taxid, $gr_taxid);
	}
    }

    # add
    if($apr->param('add_species')){
	my $genus = $apr->param('spe_genus');
	my $spe = $apr->param('spe_species');
	my $name = $apr->param('spe_name');
	my $taxid = $apr->param('spe_taxid');
	my $gr_taxid = $apr->param('gr_spe_taxid');
	if($genus || $spe || $name || $taxid || $gr_taxid){
	    $db->add_species($genus, $spe, $name, $taxid, $gr_taxid);
	}
    

    }
	
    my $all_species = $db_get->get_all_species;
    $util->{'all_species'} = $all_species;


    #default selected species 
    unless($apr->param('select_spe')){
	$util->{'species'} = $all_species->[0];
    }
}




# -----------------------------------------------


sub util_gene_type {
    my ($apr, $db, $db_get, $util) = @_;

    # selected xref_db
    if($apr->param('select_gene_type')){
	my $gene_type = $db_get->get_gene_type($apr->param('select_gene_type'));
	$util->{'gene_type'} = $gene_type if $gene_type;
    }

    # update
    if($apr->param('update_gene_type')){
	my $type_id = $apr->param('gene_type_id');
	my $type = $apr->param('gene_type');
	if($type_id && $type){
	    $db->update_gene_type($type_id, $type );
	}
	
    }

    # add
    if($apr->param('add_gene_type')){
	my $type = $apr->param('gene_type');
	if($type){
	    $db->add_gene_type($type);
	}
    }
	
    my $all_gene_types = $db_get->get_all_gene_types;
    $util->{'gene_types'} = $all_gene_types;


    # default selected xref_db
    unless($apr->param('select_gene_type')){
	$util->{'gene_type'} = $all_gene_types->[0];
    }
}

sub update_protein_gene_association_in_protein_db{
    my($db, $db_protein, $gene_acc, $edit_result, $protein_ids) = @_;

    foreach my $protein_id (@$protein_ids){
	$db_protein->add_gene_association( $protein_id,$gene_acc);
    }

}

sub update_gene_ontology_association_from_protein_xrefs{
    my($db, $db_protein, $gene_id, $edit_result, $protein_ids) = @_;
    my $update_onto;
    foreach my $protein_id (@$protein_ids){
	my $assocs = $db_protein->get_associations($protein_id);
	foreach my $assoc (@$assocs){
	    $update_onto = 1;
	    my $term_acc = $assoc->{'term_accession'};
	    my $term_type = $assoc->{'term_type'};
	    $db->add_gene_ontology_associations($gene_id, $term_type, $term_acc, $edit_result);

	}
	
    }
    return $update_onto;
}


sub update_protein_ontology_associations{
    my($db, $db_protein, $gene_id, $protein_ids, $term_acc, $term_type) = @_;

    my $evn_code = 'IC';
    my $protein_dbx = 'gramene.literature';
    my $protein_dbx_val = '11089';
    my %p_terms;
    # get all protein associations 
    foreach my $protein_id (@$protein_ids){
	my $associations = $db_protein->get_associations($protein_id);
	foreach my $assoc (@$associations){
	    my $term_acc = $assoc->{'term_accession'};
	    $p_terms{$term_acc}->{$protein_id} = $assoc->{'association_id'};
	    
	}
    }

    if(@$protein_ids){

	my @g_terms = $db->process_delimited_values(',', $term_acc);
	foreach my $g_term (@g_terms){
	    my $assocs = $p_terms{$g_term} if %p_terms;
	    if($assocs){ # add evn only for existed assocs in protein db
		foreach my $p_id (keys %$assocs){
		    my $assoc_id = $assocs->{$p_id};
		    $db_protein->add_evidence($p_id, $assoc_id, $protein_dbx, $protein_dbx_val, $evn_code);
		}

	    }else{ # new ontology assoc in protein
		foreach my $p_id (@$protein_ids){
		    my $assoc_id = $db_protein->add_association($p_id,$g_term,$term_type);
		    $db_protein->add_evidence($p_id, $assoc_id, $protein_dbx, $protein_dbx_val, $evn_code);

		}

	    }

	}
    }
	

}



sub update_protein_symbol{
    my ($db_protein, $gene_symbol, $protein_ids) = @_;
    return unless $gene_symbol;

    foreach my $protein_id (@$protein_ids){
	my $protein_symbol = $db_protein->get_symbol($protein_id);

	if($gene_symbol ne $protein_symbol){
	    #use gene symbol to replace protein symbol
	    $db_protein->update_symbol($protein_id,$gene_symbol);

	    # delete the synonym
	    $db_protein->delete_synonyms($protein_id,[$gene_symbol]);

	    #protein symbol become protein synonym
	    $db_protein->add_synonym($protein_id, $protein_symbol);
	}
    }

}


sub check_and_update_protein_symbol{

    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result ) = @_;

    my $symbol = $gene_obj->{'symbol'};

    my @protein_ids = &get_protein_ids($gene_obj,$db_protein,$protein_xref_db);

    if(@protein_ids){

	&update_protein_symbol($db_protein, $symbol, \@protein_ids);

    }
}

sub update_protein_name{
    my ($db_protein, $gene_name, $protein_ids) = @_;
    return unless $gene_name;

    foreach my $protein_id (@$protein_ids){
	my $protein_name = $db_protein->get_name($protein_id);

	if($gene_name ne $protein_name){
	    #use gene name to replace protein name
	    $db_protein->update_name($protein_id,$gene_name);

	    # delete the synonym
	    $db_protein->delete_synonyms($protein_id,[$gene_name]);

	    #protein name become protein synonym
	    $db_protein->add_synonym($protein_id, $protein_name);
	}
    }

}


sub check_and_update_protein_name{

    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result ) = @_;

    my $name = $gene_obj->{'name'};

    my @protein_ids = &get_protein_ids($gene_obj,$db_protein,$protein_xref_db);

    if(@protein_ids){

	&update_protein_name($db_protein, $name, \@protein_ids);

    }
}



sub update_protein_public_comment{
    my ($db_protein, $gene_acc, $gene_desc, $protein_ids) = @_;
    if($gene_desc eq 'under curation'){
	return;
    }
    foreach my $protein_id (@$protein_ids){
	my $protein_comment = $db_protein->get_public_comment($protein_id);
	my $new_comment;
	if($protein_comment){
	    # remove the old comment from gene
	    if($protein_comment =~/\s<br>.+\(Imported from Gene $gene_acc\)/){
		$protein_comment =~s/\s<br>.+\(Imported from Gene $gene_acc\)//;
		$new_comment = $protein_comment;
	    }
	    unless($protein_comment =~/$gene_desc/){
		$new_comment = "$protein_comment <br>$gene_desc (Imported from Gene $gene_acc)" if $gene_desc;
	    }
	}else{
	    $new_comment = " <br>$gene_desc (Imported from Gene $gene_acc)" if $gene_desc;
	}
	if(defined $new_comment){
	    $db_protein->update_public_comment($protein_id, $new_comment);
	}
    }

}

sub check_and_update_protein_comment{

    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result ) = @_;

    my @protein_ids = &get_protein_ids($gene_obj,$db_protein,$protein_xref_db);

    if(@protein_ids){
	my $gene_acc = $gene_obj->{'accession'};
	my $gene_desc = $gene_obj->{'description'};
	&update_protein_public_comment($db_protein, $gene_acc, $gene_desc, \@protein_ids);

    }
}


sub check_and_delete_protein_ecs{
    my ($gene_obj,$db_protein,$protein_xref_db,$ecs_dbx) = @_;

    my @protein_ids = &get_protein_ids($gene_obj,$db_protein,$protein_xref_db);

    if(@protein_ids){
	my @ecs;
	foreach my $dbx_id (@$ecs_dbx){
	    my $ec = $gene_obj->{'dbxrefs'}->{'E.C. Number(s)'}->{$dbx_id};
	    push @ecs, $ec;
	}

	foreach my $gp_id (@protein_ids){
	    foreach my $ec (@ecs){
		$db_protein->delete_ec($gp_id,$ec);
	    }
	}
    }

}

sub check_and_update_protein_ecs{
    my ($gene_obj,$db_protein,$protein_xref_db,$ecs) = @_;

    my @protein_ids = &get_protein_ids($gene_obj,$db_protein,$protein_xref_db);

    if(@protein_ids){
	&update_protein_ecs($db_protein, $ecs, \@protein_ids);

    }
}

sub update_protein_ecs{
    my ($db_protein, $ecs,$protein_ids)=@_;

    foreach my $protein_id (@$protein_ids){
	foreach my $ec (@$ecs){
	    $db_protein->add_ec($protein_id,$ec);
	}
    }
}
    


sub update_gene_ecs_from_protein_ecs{
    my ($db, $db_protein, $gene_id, $edit_result, $protein_ids) = @_;
    my $update_ec;
    my %uniq_ecs;
    my @all_ecs;
    foreach my $protein_id (@$protein_ids){
	my $ecs = $db_protein->get_ecs($protein_id);
	foreach my $ec (@$ecs){
	    push @all_ecs, $ec->{'ec'};
	}
    }

    my %uniq_ecs = map { $_ => 1 } @all_ecs;

    my $final_ecs = join(',',keys %uniq_ecs);

    if(scalar(keys %uniq_ecs) > 0){
	my $dbx_id = $db->get_dbxref_id('E.C. Number(s)');
	$db->add_gene_dbxrefs($gene_id, $dbx_id, $final_ecs, $edit_result );
	$update_ec = 1;
    }

    return $update_ec;
}

# ---------------------

sub add_gene_map_position{
    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result) = @_;

    my $gene_id = $gene_obj->{'gene_id'};
    my $gene_acc = $gene_obj->{'accession'};
    my $map_acc = $apr->param('cmap_map_acc');
    my $map_start = $apr->param('map_start');
    my $map_stop = $apr->param('map_stop');
    $db->add_map_position($gene_id,$gene_acc,$map_acc,$map_start,$map_stop,$edit_result);
    $gene_obj->{'map_positions'} = $db_get->get_gene_map_position($gene_id);
}



# ---------------------

sub update_gene_map_position{
    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result) = @_;

    my $gene_id = $gene_obj->{'gene_id'};
    my $map_pos_id = $apr->param('map_position_id');
    my $map_start = $apr->param('map_start');
    my $map_stop = $apr->param('map_stop');
    $db->update_map_position($map_pos_id,$map_start,$map_stop,$edit_result);
    $gene_obj->{'map_positions'} = $db_get->get_gene_map_position($gene_id);
}


# ---------------------

sub delete_gene_map_position{
    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result) = @_;

    my $gene_id = $gene_obj->{'gene_id'};
    my $map_pos_id = $apr->param('map_position_id');
    $db->delete_map_position($map_pos_id,$edit_result);
    $gene_obj->{'map_positions'} = $db_get->get_gene_map_position($gene_id);
}

# ----------------------
sub update_gene_interaction{
    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result) = @_;

    my $gene_id = $gene_obj->{'gene_id'};
    my $interaction_id = $apr->param('interaction_id');
    my $g1_obj_class = $apr->param('g1_obj_class');
    my $g2_obj_class = $apr->param('g2_obj_class');
    my $interaction_type_id = $apr->param('interaction_type');
    $db->update_gene_interaction($interaction_id,$g1_obj_class,$interaction_type_id,$g2_obj_class,$edit_result);
    unless($edit_result->{'error'}){
	$gene_obj->{'gene_interactions'} = $db_get->get_gene_interactions($gene_id);
    }
}

# -------------------------

sub delete_gene_interaction{
    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result) = @_;

    my $interaction_id = $apr->param('interaction_id');
    $db->delete_gene_interaction($interaction_id,$edit_result);
    $gene_obj->{'gene_interactions'} = $db_get->get_gene_interactions($gene_id);
}

sub update_gene_interaction{
    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result) = @_;

    my $gene_id = $gene_obj->{'gene_id'};
    my $interaction_id = $apr->param('interaction_id');
    my $g1_obj_class = $apr->param('g1_obj_class');
    my $g2_obj_class = $apr->param('g2_obj_class');
    my $interaction_type_id = $apr->param('interaction_type');
    $db->update_gene_interaction($interaction_id,$g1_obj_class,$interaction_type_id,$g2_obj_class,$edit_result);
    unless($edit_result->{'error'}){
	$gene_obj->{'gene_interactions'} = $db_get->get_gene_interactions($gene_id);
    }
}


# ----------------------
sub add_gene_interaction{
    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result) = @_;

    my $gene_id = $gene_obj->{'gene_id'};
    my $g1_obj_class = $apr->param('g1_obj_class');
    my $interaction_type_id = $apr->param('interaction_type');
    my $g2_obj_class = $apr->param('g2_obj_class');
    my $evn_code = $apr->param('evn_code');
    my $comment = $apr->param('action_comment');

    my $dbxref_val=$apr->param('new_dbxref');
    my $dbx = $apr->param('dbxref');
    my ($dbx_id, $db_name) = ($dbx=~/(\d+)_(.+)/); # dbxref_id plus '_' plus dbxref_name as value

    my $g2_obj_acc = process_accession( 
			      GENE_ACCESSION_PREFIX,
			      GENE_ACCESSION_LENGTH, 
			      $apr->param('g2_obj_acc')
			      );


    my $g2_gene_id = $db_get->get_gene_id($g2_obj_acc) if $g2_obj_acc;
    unless($g2_gene_id){
	push (@{ $edit_result->{'error'} },"The gene 2 object $g2_obj_acc is not in gene db");
	return;
    }

    $db->add_gene_interaction($gene_id,$g1_obj_class,$interaction_type_id,$g2_gene_id,$g2_obj_class,$evn_code,$comment,$dbx_id,$dbxref_val,$edit_result);
    
    unless($edit_result->{'error'}){
	$gene_obj->{'gene_interactions'} = $db_get->get_gene_interactions($gene_id);
    }
}

# ----------------------
sub update_gene_interaction_evidence{
    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result) = @_;

    my $gene_id = $gene_obj->{'gene_id'};
    my $interaction_evn_id = $apr->param('interaction_evn_id');
    my $evn_code = $apr->param('evn_code');
    my $comment = $apr->param('action_comment');
    $db->update_gene_interaction_evidence($interaction_evn_id,$evn_code,$comment,$edit_result);
    unless($edit_result->{'error'}){
	$gene_obj->{'gene_interactions'} = $db_get->get_gene_interactions($gene_id);
    }
}


# -------------------------

sub delete_gene_interaction_evidence{
    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result) = @_;

    my $interaction_evn_id = $apr->param('interaction_evn_id');
    my $dbxref_to_object_id = $apr->param('dbx_to_obj_id');
    $db->delete_gene_interaction_evidence($interaction_evn_id,$dbxref_to_object_id,$edit_result);
    $gene_obj->{'gene_interactions'} = $db_get->get_gene_interactions($gene_id);
}


# ----------------------
sub add_gene_interaction_evidence{
    my($apr, $db, $db_get, $db_protein,$protein_xref_db, $obj_type,  $gene_obj, $edit_result) = @_;

    my $gene_id = $gene_obj->{'gene_id'};
    my $interaction_id = $apr->param('interaction_id');
    my $evn_code = $apr->param('evn_code');
    my $comment = $apr->param('action_comment');

    my $dbxref_val=$apr->param('new_dbxref');
    my $dbx = $apr->param('dbxref');
    my ($dbx_id, $db_name) = ($dbx=~/(\d+)_(.+)/); # dbxref_id plus '_' plus dbxref_name as value

    $db->add_gene_interaction_evidence($interaction_id,$evn_code,$comment,$dbx_id,$dbxref_val,$edit_result);
    
    unless($edit_result->{'error'}){
	$gene_obj->{'gene_interactions'} = $db_get->get_gene_interactions($gene_id);
    }
}


sub get_protein_ids{
    my ($gene_obj, $db_protein,$protein_xref_db) = @_;

    my $proteins = $gene_obj->{'dbxrefs'}->{$protein_xref_db};
    my @protein_ids;
    if($proteins){
	my @protein_accs = values %$proteins;
	foreach my $protein_acc (@protein_accs){
	    my $protein_id = $db_protein->get_protein_id($protein_acc);
	    push @protein_ids, $protein_id if $protein_id;
	}
    }

    return @protein_ids;
}


sub merge_genes{
    my($apr, $db, $db_get, $db_protein, $protein_xref_db, $obj_type,  $gene_obj, $edit_result) = @_;

    my $gene_id = $gene_obj->{'gene_id'};

    # 
    my $main_gene_acc = process_accession( 
			      GENE_ACCESSION_PREFIX,
			      GENE_ACCESSION_LENGTH, 
			      $apr->param('main_gene')
			      );

			    
    my $main_gene_id = $db_get->get_gene_id($main_gene_acc) if $main_gene_acc;
    unless($main_gene_id){
	push (@{ $edit_result->{'error'} },"The primary gene $main_gene_acc is not in gene db");
	return;
    }


    # gene's acc, symbol, name,synonyms become main gene's synonym
    my $acc = $gene_obj->{'accession'};
    my $symbol = $gene_obj->{'symbol'};
    my $name = $gene_obj->{'name'};
    my $synonyms = $gene_obj->{'synonyms'};
    my $new_synonyms = join(',',($acc,$symbol,$name,@$synonyms));
    $db->add_gene_synonyms($main_gene_id,$new_synonyms,$edit_result);

    # merge description, comment to main gene's comment 
    my $description = $gene_obj->{'description'}; 
    my $pub_comment = $gene_obj->{'public_curation_comment'};
    my $private_comment = $gene_obj->{'internal_curation_comment'};

    my $new_comment = '';
    if($description){
	$new_comment .=$description;
    }
    if($pub_comment){
	$new_comment .= $pub_comment;
    }
    if($new_comment){
	my $main_gene_comment =
	$db_get->get_gene_simple_field('public_curation_comment',$main_gene_id) || '';
	$main_gene_comment = $main_gene_comment."<br>$new_comment";
	$db->update_gene_simple_field('public_curation_comment',$new_comment,$main_gene_id,$edit_result);
    }
    if($private_comment){
	my $main_gene_note = $db_get->get_gene_simple_field('internal_curation_comment',$main_gene_id) || '';
	$main_gene_note .= "<br>$private_comment";
	$db->update_gene_simple_field('internal_curation_comment',$new_comment,$main_gene_id,$edit_result);
    }
	
    # merge ontology associations
    my $terms = $db_get->get_ontology_association($obj_type, $gene_id);
    foreach my $term_type (keys %$terms){
	my @term_accs;
	foreach my $term (@{$terms->{$term_type}}){
	    my $term_acc = $term->{'term_accession'};
	    push @term_accs, $term_acc;
	}
	my $new_term_accs = join(',',@term_accs);
	$db->add_gene_ontology_associations($main_gene_id,$term_type,$new_term_accs,$edit_result);
    }

    my $dbxrefs = $db_get->get_object_all_dbxrefs($obj_type,$gene_id);
    foreach my $db_name (keys %$dbxrefs){
	my @db_vals;
	foreach my $dbx_obj_id (keys %{$dbxrefs->{$db_name}}){
	    my $db_val = $dbxrefs->{$db_name}->{$dbx_obj_id};
	    push @db_vals, $db_val;
	}
	my $dbx_id = $db_get->get_dbxref_id($db_name);
	my $dbxref_vals = join(',',@db_vals);
	$db->add_gene_dbxrefs($main_gene_id,$dbx_id,$dbxref_vals,$edit_result);
    }

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

    # update the obsolete gene status
    my $new_status = 1;  # make it obsolete
    $db->update_gene_simple_field('is_obsolete', $new_status, $gene_id, $edit_result);
    $gene_obj->{'is_obsolete'} = $db_get->get_gene_simple_field('is_obsolete',$gene_id);
   
   $pub_comment ||='';
   my $note = "This gene $acc was made obsolete. It has been merged into Gene $main_gene_acc.";
   unless($pub_comment =~/$note/){
	$pub_comment = $note.' '.$pub_comment;
	$db->update_gene_simple_field('public_curation_comment',$pub_comment,$gene_id, $edit_result);
	$gene_obj->{'public_curation_comment'} = $db_get->get_gene_simple_field('public_curation_comment',$gene_id);
    }


}

