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

use strict;
use Apache::Request;
use Template;

use Gramene::Page;
use Gramene::Utils 'commify';
use Gramene::Mutant::MutantCurationDB;



use constant CURATION_ENTRY_TEMPLATE => 'mutant_curation_entry.tmpl';
use constant CURATION_TEMPLATE    => 'mutant_curation.tmpl';
use constant EDITING_TEMPLATE =>'mutant_edit.tmpl';
use constant ERROR_TEMPLATE     => 'mutant_error.tmpl';



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

$db = Gramene::Mutant::MutantCurationDB->new(); 
$db->connect_to_db();

my $all_species = $db->get_all_species();
my $all_dbxrefs = $db->get_all_dbxrefs();

my $term_types={
                     2=>'GO Biological process',
                     3=>'GO Cellular component',
                     4=>'GO Molecular function',
                     5=>'Trait',
                     6=>'Anatomy',
                     7=>'Growth stage',
		     9=>'Environment'
                };


my $chromosomes_by_species;


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

my $acc;

if($apr->param('acc')){
  $acc = process_acc($apr->param('acc')); #clean the acc
 # $apr->param('acc')=$acc;
}

unless($gene_id){
  
   $gene_id = $db->get_gene_id($acc) if $acc;
}

eval{

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

 if($acc){ 
   if($gene_id){  # editing gene in db


     unless($apr->param('save_to_db')){ # this param in curation new mutant form only
       my $gene_obj;
       my $edit_result={};


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

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

       # a hashref      
       $gene_obj->{'ontologys'} = $db->get_gene_ontology_association($gene_id);
        
       $gene_obj->{'dbxrefs'} = $db->get_gene_dbxrefs($gene_id);# a hashref
       
       $gene_obj->{'curation_note'} = $db->get_gene_curation_note($gene_id);
       
       $chromosomes_by_species= $db->get_chromosomes_by_species($gene_obj->{'species_id'});


       ####
       
       if($apr->param('update_obsolete')){
           my $new_status = 1 - $gene_obj->{'is_obsolete'};  # switch status between 1 and 0
          
           $db->update_gene_simple_field('is_obsolete',$gene_id,$new_status,$edit_result);
           $gene_obj->{'is_obsolete'} = $db->get_gene_simple_field('is_obsolete',$gene_id);
       }


       if($apr->param('add_syn')){
	   my $new_syn = $apr->param('new_syn');
           $new_syn =~s/^\s+|\s+$//g;
           my $sym = $gene_obj->{'symbol'};
           my $nm = $gene_obj->{'name'};
          
           $db->add_gene_synonym($gene_id,$new_syn,$edit_result);
	   $gene_obj->{'synonyms'}= $db->get_gene_synonyms($gene_id);
           
      }

       if($apr->param('update_symbol')){
	   my $new_symbol_id = $apr->param('symbol');
           my $old_symbol_id = $gene_obj->{'symbol_id'};
           #my $old_symbol = $gene_obj->{'symbol'};
           #my $name_id = $gene_obj->{'name_id'};

           unless($new_symbol_id == $old_symbol_id){
              $db->update_gene_synonym('symbol_id',$gene_id,$old_symbol_id,$new_symbol_id,$edit_result); 
                            
               unless($edit_result->{'error'}){
   	         $gene_obj->{'symbol_id'} = $new_symbol_id;
                 $gene_obj->{'symbol'} = $db->get_synonym_name($new_symbol_id);
                 $gene_obj->{'synonyms'} = $db->get_gene_synonyms($gene_id);
               }
	   }
       }

       if($apr->param('update_name')){
           my $new_name_id = $apr->param('name');
           my $old_name_id = $gene_obj->{'name_id'};
           #my $name_id = $gene_obj->{'name_id'};

           unless($new_name_id == $old_name_id){
              $db->update_gene_synonym('name_id',$gene_id,$old_name_id,$new_name_id,$edit_result);

	      unless($edit_result->{'error'}){
		  $gene_obj->{'name_id'} = $new_name_id;
		  $gene_obj->{'name'} = $db->get_synonym_name($new_name_id);
		  $gene_obj->{'synonyms'} = $db->get_gene_synonyms($gene_id);
	      }
	  }
       }

         
       if($apr->param('del_synonym')){
	   my $syn_id = $apr->param('synonym');
           $db->delete_gene_synonym($gene_id,$syn_id,$edit_result);
           $gene_obj->{'synonyms'} = $db->get_gene_synonyms($gene_id);
       }

       if($apr->param('update_species') || $apr->param('species')){
           my $spe_id = $apr->param('species');
           $chromosomes_by_species= $db->get_chromosomes_by_species($apr->param('species'));
           unless($spe_id == $gene_obj->{'species_id'}){
	       $db->update_gene_simple_field('species_id',$gene_id,$spe_id,$edit_result);
	       $gene_obj->{'species_id'} =  $db->get_gene_simple_field('species_id',$gene_id);
               #chromosome depends  on species,if species update, chromosome should be updated too.
               my $chr='';
               #$db->update_gene_simple_field('chromosome',$gene_id,$chr,$edit_result);
               $gene_obj->{'chromosome'} = $chr;         
           }
       }

       if($apr->param('update_chr') || defined $apr->param('chromosome')){
           my $chr = $apr->param('chromosome') || '';
           $chr =~s/^\s+|\s+$//g;
	   my $chr_id = $db->get_chromosome_id($chr,$gene_obj->{'species_id'}) || '';
           $db->update_gene_simple_field('chromosome_id',$gene_id,$chr_id,$edit_result);
	   $gene_obj->{'chromosome'} = $chr;
           #$gene_obj->{'chromosome'} = $db->get_gene_simple_field('chromosome',$gene_id);
       }


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

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

       if($apr->param('add_dbxref')){
	   my $dbxref_val=$apr->param('new_dbxref');
           my $dbx_id = $apr->param('new_dbxref_id');
           
           if($dbxref_val){
             $dbxref_val =~s/^\s+|\s+$//g;
             $db->add_new_gene_dbxref($gene_id,$dbx_id,$dbxref_val,$edit_result);
             #update the dbxref cache of gene_obj
             my $dbx_hashref = $db->get_gene_dbxrefs_by_field('dbxref_id',$dbx_id,$gene_id);
             foreach my $db_name (keys %{$dbx_hashref}){
		 $gene_obj->{'dbxrefs'}->{$db_name} = $dbx_hashref->{$db_name};
             }  
	   }
       }

       if($apr->param('del_dbxref')){
           foreach my $dbx (@$all_dbxrefs){
	       my $dbx_name = $dbx->{'dbxref_name'};
               my $dbx_id = $dbx->{'dbxref_id'};
               if($apr->param("dbxref_$dbx_name")){
		 my @dbx_vals = $apr->param("dbxref_$dbx_name");
                 if(@dbx_vals){
                   $db->delete_gene_dbxref(\@dbx_vals,$edit_result);
		   my $dbx_hashref = $db->get_gene_dbxrefs_by_field('dbxref_id',$dbx_id,$gene_id);
	           if($dbx_hashref){                  
                      foreach my $db_name (keys %{$dbx_hashref}){
                        $gene_obj->{'dbxrefs'}->{$db_name} = $dbx_hashref->{$db_name};
                      }
		   }else{ # no this dbxref in dbxref_to_object
		       delete($gene_obj->{'dbxrefs'}->{$dbx_name});
                   }
                 } 
                 last;
               } 
           }          

       }

       if($apr->param('add_term')){
	   my $term_acc = $apr->param('new_term');
           my $term_type = $apr->param('ontology_type_id');
           if($term_acc && $term_type){
              $db->add_gene_ontology_terms($gene_id,$term_type,$term_acc,$edit_result);
              $gene_obj->{'ontologys'}->{$term_type}=$db->get_gene_ontology_association_by_type($gene_id,$term_type);
 
           }
       }

       if($apr->param('del_term')){
	   foreach my $type (keys %{$term_types}){
	       if($apr->param("ontology_$type")){
		   my @terms = $apr->param("ontology_$type");
                   if(@terms){
		      $db->delete_gene_ontology_terms($gene_id,\@terms,$edit_result);
                      my $termRef=$db->get_gene_ontology_association_by_type($gene_id,$type);
                      if(scalar(@$termRef)>0){
			  $gene_obj->{'ontologys'}->{$type}=$termRef;
                      }else{
                          delete( $gene_obj->{'ontologys'}->{$type});
                      }
                   }
                   last;
               } 
           }

       }
        
       if($apr->param('update_curation_note')){
	   my $note = $apr->param('curation_note');
           $note =~s/^\s+|\s+$//g;
           if($note){
              if($gene_obj->{'curation_note'}){
                 $db->update_gene_curation_note($gene_id,$note,$edit_result);         
	      }else{
		  $db->add_gene_curation_note($gene_id,$note,$edit_result);
              }       
	  }else{
	      $db->delete_gene_curation_note($gene_id);
          }
          $gene_obj->{'curation_note'} = $db->get_gene_curation_note($gene_id);
        }
 

          $template->process(
             EDITING_TEMPLATE,
	     {
                gramene_page  => $page,
                stylesheet    => $page->stylesheet,
                apr           => $apr,
                gene          => $gene_obj,
                all_species   => $all_species,
                all_dbxrefs   => $all_dbxrefs,
                ontology_types =>$term_types,
                chromosomes_by_species => $chromosomes_by_species,
                edit_result   => $edit_result,
                title         => "Mutant Editing"
                },
            \$html
	    ) or $html = $template->error;
   }

  }else{ # curate new mutant

     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_mutant(\%args);
         if($temp_gene && $curation_result->{'ok'}){
             $acc =~s/GR:00//;    
             unlink("./TEMP_GENE/Gene_$acc.txt") or die "$!"; # delete the temp file
         } 
       } 

       if($args{"save_to_file"}){

           $acc =~s/GR:00//;           
                                                                                
  	   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'}="GR:00$acc";
       }


     }
    if(defined $apr->param('species')){ #user select species

       $chromosomes_by_species= $db->get_chromosomes_by_species($apr->param('species'));
       $temp_gene->{'species'} = $apr->param('species');
       $temp_gene->{'chromosome'} = '';

    }else{ # no species,try use temp_gene's species to display chr field
      if($temp_gene->{'species'}){
          $chromosomes_by_species = $db->get_chromosomes_by_species($temp_gene->{'species'});

      }
    }

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

  } 
  }else{

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



 }

 
};

if ( my $err = $@ ) {
    if ( $template ) {
        $template->process( 
            ERROR_TEMPLATE,
            {
                gramene_page  => $page,
                stylesheet    => $page->stylesheet,
                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:00//;

  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 process_acc{
    my $acc = shift;
    $acc =~s/^\s+|\s+$//g;    
    if($acc){
       $acc =~s/GR://i;
       $acc =~s/^0+//g;
                                                                                
       $acc ='GR:00'.$acc;
   }
    return $acc;
}
 
