#!/usr/bin/perl -w

# # # # # # # # # # # # # # # # # # # # # # # 
# ATUALIZA ARQUIVO DE ORF
# Fasta/$mtg/ORFs/n/$orfFile
# Fasta/$mtg/ORFs/p/$orfFile
# 
# ATUALIZA TABELAS
# orf
# 	-start
# 	-end
# 	-length
# 	-frame (RECALCULAR)
# 	-bases (RECALCULAR)
# 
# rbs
# 	-start
# 
# startCodons
# 	-orfStart 
# 
# 
# ATUALIZA BLAST
#	-deleta registro banco
# 	-deleta relatorio
# 	-roda blast (runOrfsBlast.pl) 
# # # # # # # # # # # # # # # # # # # # # # # #

use Bio::Seq;
use Bio::SeqIO;
use DBI;
use DBD::mysql;

use strict;

our $DB_NAME;
our $DB_HOST;
our $DB_USER;
our $DB_PASS;
require '../lib/config.pl';

my $mtg = shift;
my $contigId = shift;
my $orfId = shift;
my $newStart = shift;
my $end = shift;

my $dbh = DBI->connect("DBI:mysql:$DB_NAME:$DB_HOST",$DB_USER,$DB_PASS,{RaiseError => 1});

atualizaInfoOrf($dbh, $mtg, $contigId, $orfId, $newStart, $end);

# atualizaResultadoBlast($dbh, $mtg, $orfId);

exit 0;
# # # # # # # 
# FUNCOES
# # # # # # # 

#### Atualiza aquivos Fasta e tabelas 'orf', 'rbs' e 'startCodons'
sub atualizaInfoOrf{
	my ($dbh, $mtg, $contigId, $orfId, $newStart, $end) = @_;

	my $contigFile = "../Fasta/$mtg/Contigs/n/Contig$contigId.fas";

	my $contigSeq = Bio::SeqIO->new(-file => "<".$contigFile,
					-format => "fasta");
	$contigSeq = $contigSeq->next_seq();

	my $length;
	my $strand;
	my $newOrfSeq;

	#### FORWARD STRAND
	if ($newStart < $end){
		$length = $end - $newStart + 1;
		$strand = 1;
		$newOrfSeq = $contigSeq->subseq($newStart, $end);
	}
	#### REVERSE STRAND
	else{
		$length = $newStart - $end + 1;
		$strand = -1;
		$newOrfSeq = Bio::Seq->new(-seq => $contigSeq->subseq($end, $newStart),
					   -alphabet => "dna");
		$newOrfSeq = $newOrfSeq->revcom->seq;
	}

	my $aaSeq = Bio::PrimarySeq->new ('-seq' => $newOrfSeq);
	my $ptSeq = $aaSeq->translate();

	my $aaFile = "../Fasta/$mtg/ORFs/n/ORF$orfId.fas";
	my $ptFile = "../Fasta/$mtg/ORFs/p/ORF$orfId.fas";

	my $fna = Bio::SeqIO->new('-file' =>">$aaFile", '-format' => 'fasta');
	my $fpt = Bio::SeqIO->new('-file' =>">$ptFile", '-format' => 'fasta');
	
	$aaSeq->display_id("$orfId.n");
	$fna->write_seq($aaSeq);
	
	$ptSeq->display_id("$orfId.p");
	$fpt->write_seq($ptSeq);

	

	my ($bases_a,$bases_c,$bases_t,$bases_g) = calculaNumBases($newOrfSeq);
	my $frame = getFrame($newStart, $strand);

	my $updateOrfTable = "
		UPDATE	orf
		SET
			start=$newStart,
			end=$end,
			length=$length,
			frame='$frame',
			bases_a=$bases_a,
			bases_c=$bases_c,
			bases_t=$bases_t,
			bases_g=$bases_g
		WHERE
			idMontagem=\'$mtg\'	AND
			id=\'$orfId\'
	";
	$dbh->do($updateOrfTable);

	my $updateRbsTable = "
		UPDATE	rbs
		SET
			start=$newStart
		WHERE
			idMontagem=\'$mtg\'	AND
			id=\'$orfId\'
	";
	$dbh->do($updateRbsTable);

	my $updateStartCodonsTable = "
		UPDATE	startCodons
		SET
			orfStart=$newStart
		WHERE
			idMontagem=\'$mtg\'	AND
			idOrf=\'$orfId\'
	";
	$dbh->do($updateStartCodonsTable);
}

sub calculaNumBases{
	my ($seq) = @_;

	my %hash = ('A' => 0, 'C' => 1 , 'T' => 2, 'G' => 3, 'N' => 99);
	my @array = (0,0,0,0);
	my @nt = split(//, $seq);

	foreach my $base (@nt){
		if ($base =~ /A/i || $base =~ /C/i || $base =~ /G/i || $base =~ /T/i){
			$array[$hash{$base}]++;
		}
	}

	return @array;
}

sub getFrame{
	my ($start, $strand) = @_;

	my $frame;
	if ($strand == 1){
		$frame = $start % 3;
		if ($frame == 0){
			$frame = 3;
		}
		$frame = "F".$frame;
	}else{
		$frame = $start % 3;
		if ($frame == 2){
			$frame = 3;
		}elsif ($frame == 0){
			$frame = 2;
		}
		$frame = "R$frame";
	}

	return $frame;
}


#### ARRUMAR ####
#### ARRUMAR ####
#### ARRUMAR ####
#### ARRUMAR ####
#### ARRUMAR ####

sub atualizaResultadoBlast{
	my ($dbh, $mtg, $orfId) = @_;

	my $orfFile = "../Fasta/$mtg/ORFs/p/ORF$orfId.fas";
	my $blastOutDir = "../BlastReports/$mtg";

	unless (-d $blastOutDir){
		mkdir $blastOutDir;
	}

	system("perl deletaOrfsBlast.pl $DB_NAME $mtg $orfId");

	system("perl runOrfsBlast.pl $DB_NAME $mtg $orfFile ../BlastDatabases/nr nr $blastOutDir");
	system("perl runOrfsBlastCOG.pl $DB_NAME $mtg $orfFile $blastOutDir");
	system("perl runOrfsBlastPFAM.pl $DB_NAME $mtg $orfFile $blastOutDir");
}
