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

use strict;
use Apache::Request;
use Template;
use Gramene::Page;
use Gramene::Protein::EditProteinDB;
use Gramene::Gene::GeneDB;
use Gramene::Gene::GeneCurationDB;


use constant DETAIL_TEMPLATE => 'protein_editing.tmpl';
use constant ERROR_TEMPLATE  => 'protein_editing_error.tmpl';
use constant SEARCH_TEMPLATE => 'protein_editing_entry.tmpl';

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

my %args = $apr->args;

my @evn_codes = qw[IC IDA IEA IEP IMP IGI IPI ISS IAGP NAS NOT NR RCA SM TAS];
my $term_types = [
    'Biological Process',
    'Cellular Component',
    'Molecular Function',
    'Trait',
    'Plant Structure',
    'Plant Growth and Development Stage',
    #'Cereal Plant Growth Stage',
    'Enviroment',
    'Taxonomy'
];



eval {

    $template =
      Template->new(
        { INCLUDE_PATH => '/usr/local/gramene/templates/protein', } );

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

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

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

    my $input_acc = $apr->param('acc');
    my $input_id  = $apr->param('id');

    my ( $id, $acc );

    if ($input_acc) {
        $id = $db->get_protein_id($input_acc);
        ( $acc = $input_acc ) =~ tr/a-z/A-Z/ if $id;

        # print DEBUG "id=$id\tacc=$acc\n";
    }

    if ($input_id) {
        $acc = $db->get_protein_acc($input_id);
        $id = $input_id if $acc;
    }

    if ( $acc || $id ) {    #protein found

        my $xref_dbnames  = $db->get_all_xref_dbnames();
        my $feature_types = $db->get_all_feature_type_names();
	my @all_species = $db->get_all_species;


        # get the protein info

        my $name = $db->get_name($id);

        my $synonym_arrRef = $db->get_synonyms($id);

        my $ec_arrRef = $db->get_ecs($id);

        my $gene_name_arrRef = $db->get_gene_names($id);

	my $organism = $db->get_organism($id);
	my $selected_species_id = $organism->{'species_id'};
	my @cultivars = $db->get_all_species_cultivar($selected_species_id);


        my $asso_arrRef = $db->get_associations($id);  #ref to  an array of hash


        my $gene_asso_arrRef =
          $db->get_gene_associations($id);           #ref to  an array of hash

        my $feature_arrRef = $db->get_features($id);

        my $pub_comment     = $db->get_public_comment($id)  || '';
        my $curator_comment = $db->get_curator_comment($id) || '';

        #processing name editing

        if ( $apr->param('update_name') ) {
            my $v_name = $apr->param('name');
            $db->update_name( $id, $v_name );

            $name = $db->get_name($id);
        }

        if ( $apr->param('del_synonyms') ) {
            my @synonyms = $apr->param('synonym');
            if ( @synonyms && scalar(@synonyms) > 0 ) {
                $db->delete_synonyms($id, \@synonyms );
                $synonym_arrRef = $db->get_synonyms($id);
            }
        }

        if ( $apr->param('add_synonym') ) {
            my $synonym = $apr->param('new_synonym');
            $db->add_synonym( $id, $synonym );
            $synonym_arrRef = $db->get_synonyms($id);
        }

        if ( $apr->param('del_ecs') ) {
            my @ecs_id = $apr->param('ec');
            if ( @ecs_id && scalar(@ecs_id) > 0 ) {

		# check and update ec in gene db
		my $gene_asso_arrRef = $db->get_gene_associations($id);
		if($gene_asso_arrRef){
		    my @ecs;
		    foreach my $ec_id (@ecs_id){
			my $dbx = $db->get_dbxref_by_objectxref_id($ec_id);
			my $ec = $dbx->{'xref_key'};
			push @ecs, $ec;
		    }

		    my $gene_ec_dbx_id = $db_gene_edit->get_dbxref_id('E.C. Number(s)');
		    foreach my $gene_assoc (@$gene_asso_arrRef){
			my $gene_acc = $gene_assoc->{'gene_accession'};
			my $gene_id  = $db_gene->get_gene_id ($gene_acc);
			if($gene_id){
			    foreach my $ec (@ecs){
				$db_gene_edit->delete_gene_dbxref($gene_id,$gene_ec_dbx_id,$ec);
			    }
			}
		    }
		}

		# in protein db
                $db->delete_ecs( \@ecs_id );
                $ec_arrRef = $db->get_ecs($id);
            }
        }

        if ( $apr->param('add_ec') ) {
            my $ec = $apr->param('new_ec');
            $db->add_ec( $id, $ec );
            $ec_arrRef = $db->get_ecs($id);

	    # check and update ec in gene db
	    my $gene_asso_arrRef = $db->get_gene_associations($id);
	    if($gene_asso_arrRef){
		foreach my $gene_assoc (@$gene_asso_arrRef){
		    my $gene_acc = $gene_assoc->{'gene_accession'};
		    my $gene_id  = $db_gene->get_gene_id ($gene_acc);
		    if($gene_id){
			my $dbx_id = $db_gene_edit->get_dbxref_id('E.C. Number(s)');
			$db_gene_edit->add_gene_dbxrefs($gene_id, $dbx_id, $ec, {} );
		    }
		}
	    }

        }

        if ( $apr->param('del_gene_names') ) {
            my @gene_names = $apr->param('gene_name');
            if ( @gene_names && scalar(@gene_names) > 0 ) {
                $db->delete_gene_names($id, \@gene_names );
                $gene_name_arrRef = $db->get_gene_names($id);
            }
        }

        if ( $apr->param('add_gene_name') ) {
            my $gene_name = $apr->param('new_gene_name');
            $db->add_gene_name( $id, $gene_name );
            $gene_name_arrRef = $db->get_gene_names($id);
        }
	
	if ( $apr->param('select_spe')){
	    $selected_species_id = $apr->param('select_spe');
	    @cultivars = $db->get_all_species_cultivar($selected_species_id);
	}
	if ($apr->param('update_cultivar')){
	    $selected_species_id = $apr->param('select_spe');
	    my $cul_id = $apr->param('select_cul');
	    $db->update_organism($id,$selected_species_id,$cul_id);
	    $organism = $db->get_organism($id);
	    @cultivars = $db->get_all_species_cultivar($selected_species_id);
	}


        if ( $apr->param('del_assoc') ) {
            my $assoc_id = $apr->param('assoc_id');
	    my $term_acc = $apr->param('term_acc');
            $db->delete_associations($assoc_id);
            $asso_arrRef = $db->get_associations($id);
 
	    # check and update assoc in gene db
	    my $gene_asso_arrRef = $db->get_gene_associations($id);
	    if($gene_asso_arrRef){
		foreach my $gene_assoc (@$gene_asso_arrRef){
		    my $gene_acc = $gene_assoc->{'gene_accession'};
		    my $gene_id  = $db_gene->get_gene_id ($gene_acc);
		    if($gene_id){
			my @proteins = $db_gene->get_gene_xref_vals_by_xdb('gene', $gene_id, 'Gramene Protein');
			my $delete_flag = 1;
			# check wheter other proteins have the term associated
			foreach my $protein_acc (@proteins){
			    next if $protein_acc eq $acc;
			    my $protein_id = $db->get_protein_id($protein_acc);
			    my $gp_assoc_id = $db->get_association_id($protein_id,$term_acc);
			    if($gp_assoc_id){
				$delete_flag = 0 ; # can't delete term association in gene_db
				last;
			    }
			}

			if($delete_flag){
			    $db_gene_edit->delete_gene_ontology_associations($gene_id,[$term_acc],{});
			}
		    }
		}
	    }
        
        }

        if ( $apr->param('del_evn') ) {
            my $evn_id = $apr->param('evn_id');
            $db->delete_evidence($evn_id);
            $asso_arrRef = $db->get_associations($id);
        }

	if ($apr->param('update_evn')){
	    my $evn_id = $apr->param('evn_id');
	    my $new_evn_code = $apr->param('evn_code');
	    $db->update_evidence_code($evn_id,$new_evn_code);
	    $asso_arrRef = $db->get_associations($id);
	}

        if ( $apr->param('add_evn') ) {
            my $assoc_id    = $apr->param('assoc_id');
            my $xref_dbname = $apr->param('xref_dbname');
            my $xref_key    = $apr->param('xref_key');
            my $evn_code    = $apr->param('evn_code');

            $db->add_evidence($id, $assoc_id, $xref_dbname, $xref_key, $evn_code );
            $asso_arrRef = $db->get_associations($id);
        }

	if($apr->param('del_evn_dbx')){
	    my @evn_dbx_id = $apr->param('evn_dbx');
	    my $evn_id = $apr->param('evn_id');
	    $db->delete_evidence_dbxref(\@evn_dbx_id,$evn_id);
            $asso_arrRef = $db->get_associations($id);
	}

	if($apr->param('add_evn_dbx')){
	    my $evn_id = $apr->param('evn_id');
	    my $xref_dbname = $apr->param('xref_dbname');
            my $xref_key    = $apr->param('xref_key');
	    $db->add_evidence_dbxref($evn_id,$xref_dbname, $xref_key);
	    $asso_arrRef = $db->get_associations($id);
	}


        if ( $apr->param('add_assoc') ) {
            my $term_acc = $apr->param('new_go');
            my $term_type = $apr->param('term_type');

            my $xref_dbname = $apr->param('xref_dbname');
            my $xref_key    = $apr->param('xref_key');
            my $evn_code    = $apr->param('evn_code');

            my $assoc_id = $db->add_association( $id, $term_acc,$term_type);
            $db->add_evidence($id, $assoc_id, $xref_dbname, $xref_key, $evn_code );

            $asso_arrRef = $db->get_associations($id);
        
	    # check and update assoc in gene db
	    my $gene_asso_arrRef = $db->get_gene_associations($id);
	    if($gene_asso_arrRef){
		foreach my $gene_assoc (@$gene_asso_arrRef){
		    my $gene_acc = $gene_assoc->{'gene_accession'};
		    my $gene_id  = $db_gene->get_gene_id ($gene_acc);
		    if($gene_id){
			$db_gene_edit->add_gene_ontology_associations($gene_id,$term_type,$term_acc,{});
		    }

		}

	    }
        }

        if ( $apr->param('add_gene_assoc') ) {
            my $gene_acc = $apr->param('new_gene_acc');
            $db->add_gene_association( $id, $gene_acc );
            $gene_asso_arrRef = $db->get_gene_associations($id);
        }
        if ( $apr->param('del_gene_assoc') ) {
            my @assoc_ids = $apr->param('association_id');
            if ( @assoc_ids && scalar(@assoc_ids) > 0 ) {
                $db->delete_gene_association( \@assoc_ids );
                $gene_asso_arrRef = $db->get_gene_associations($id);
            }
        }

        if ( $apr->param('del_feature') ) {
            my $feature_id = $apr->param('feature_id');
            $db->delete_feature($feature_id);
            $feature_arrRef = $db->get_features($id);
        }

        if ( $apr->param('update_feature') ) {
            my $feature_id   = $apr->param('feature_id');
            my $feature_type = $apr->param('feature_type');
            my $from_pos     = $apr->param('from');
            my $to_pos       = $apr->param('to');
            my $xref_dbname  = $apr->param('xref_dbname');
            my $xref_key     = $apr->param('xref_key');
            $db->update_feature( $feature_id, $id, $feature_type,, $from_pos,
                $to_pos, $xref_dbname, $xref_key );
            $feature_arrRef = $db->get_features($id);

        }

        if ( $apr->param('add_feature') ) {
            my $feature_type = $apr->param('feature_type');
            my $from_pos     = $apr->param('from');
            my $to_pos       = $apr->param('to');
            my $xref_dbname  = $apr->param('xref_dbname');
            my $xref_key     = $apr->param('xref_key');
            $db->add_feature( $id, $feature_type,, $from_pos, $to_pos,
                $xref_dbname, $xref_key );
            $feature_arrRef = $db->get_features($id);

        }

        if ( $apr->param('del_all_feature') ) {
            $db->delete_all_features($id);
            $feature_arrRef = $db->get_features($id);
        }

        if ( $apr->param('update_pub_com') ) {
            my $comments = $apr->param('pub_comments');
            $db->update_public_comment( $id, $comments );
            $pub_comment = $db->get_public_comment($id);
        }
        if ( $apr->param('update_curator_com') ) {
            my $comments = $apr->param('curator_comments');
            $db->update_curator_comment( $id, $comments );
            $curator_comment = $db->get_curator_comment($id);
        }

        my $protein = {
            id                  => $id,
            acc                 => $acc,
            name                => $name,
            synonyms            => $synonym_arrRef,
            ecs                 => $ec_arrRef,
            gene_names          => $gene_name_arrRef,
	    all_species		=> \@all_species,
	    selected_species_id => $selected_species_id, # to decide cultivars
	    cultivars		=> \@cultivars,
	    organism		=> $organism,
            associations        => $asso_arrRef,
            gene_associations => $gene_asso_arrRef,
            xref_dbnames        => $xref_dbnames,
	    term_types          => $term_types,
            evn_codes           => \@evn_codes,
            features            => $feature_arrRef,
            feature_types       => $feature_types,
            pub_comment         => $pub_comment,
            curator_comment     => $curator_comment
        };

        $template->process(
            DETAIL_TEMPLATE,
            {
                gramene_page => $page,
                apr          => $apr,
                protein      => $protein
            },
            \$html
          )
          or $html = $template->error;

    }
    else {
        my $show_header      = 1;
        my $search_not_found = 1 if ( $input_acc || $input_id );

        $template->process(
            SEARCH_TEMPLATE,
            {
                gramene_page     => $page,
                apr              => $apr,
                show_header      => $show_header,
                search_no_result => $search_not_found
            },
            \$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";
    }
}

if ( defined $db ) {
    $db->terminate_database;
}

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

#close(DEBUG);
