#!/usr/bin/perl

require '../lib/config.pl';

use Bio::Seq;
use Bio::SeqIO;
use Bio::SeqFeature::Generic;
use Bio::SeqIO::genbank;
use DBI;
use DBD::mysql;


my ($DB_NAME, $mtg, $contig, $ini, $fim, $inFile, $outFile) = @ARGV;

my $seq_in = Bio::SeqIO->new(-file => "<".$inFile,
     	                     -format => "fasta");

my $inseq = $seq_in->next_seq;

my $dbh = DBI->connect("DBI:mysql:$DB_NAME:$DB_HOST",$DB_USER,$DB_PASS,{RaiseError => 1});
$q = "SELECT tam FROM contig WHERE idMontagem=\'$mtg\' AND id=\'$contig\'";

$n = $dbh->selectrow_hashref($q, { Slice => {} });
if ($ini < $fim){
	$start = $ini;
	if ($fim > $n->{'tam'}){
		$end = $n->{'tam'};
	}else{
		$end = $fim;
	}
}else{
	$start = 1;
	$end = $n->{'tam'};
}

$inseq = Bio::Seq->new(-seq => $inseq->subseq($start, $end),
			-alphabet => "dna");

my $SRCfeat = new Bio::SeqFeature::Generic ( 
				-start => $start - ($start - 1), -end => $end - ($start - 1),
				-primary => 'source',
				-tag    => {
					mol_type	=> "genomic DNA",
					} );
$inseq->add_SeqFeature($SRCfeat);

$SQLregion = '';
if ($ini < $fim){
	$SQLregion = "AND start >= $start AND start <= $end AND end <= $end AND end >= $start";
	$TRNAregion = "AND begin >= $start AND begin <= $end AND end <= $end AND end >= $start";
}

my $q = "SELECT * FROM orf WHERE idMontagem=\'$mtg\' AND contigId=\'$contig\' $SQLregion ORDER BY start ASC";
my $n = $dbh->selectall_arrayref($q, { Slice => {} });

my ($tRNA, $tRNAfeat);
$q = "SELECT * FROM tRNA WHERE contigId=\'$contig\' and idMontagem=\'$mtg\' $TRNAregion ORDER BY begin";
$tRNA = $dbh->selectall_arrayref($q, { Slice => {} });
my $t=0;

foreach ( @$n ) {
	my ($rbs, $RBSfeat, $CDSfeat);

	$q = "SELECT * FROM anotacao WHERE idMontagem=\'$mtg\' AND id='$_->{id}'";
	$orf = $dbh->selectrow_hashref($q, { Slice => {} });
	
 	if ($orf->{validation} >= 0){
		# coloca o tRNA intercalado com as ORFs vizinhas
		for (;$t<@$tRNA;){
			if ($tRNA->[$t]->{begin} < $_->{start}){
				if ($tRNA->[$t]->{begin} <= $tRNA->[$t]->{end}){
					$tRNAstart = $tRNA->[$t]->{begin} - ($start - 1);
					$tRNAend = $tRNA->[$t]->{end} - ($start - 1);
					$tRNAstrand = 1;
				}else{
					$tRNAstart = $tRNA->[$t]->{end} - ($start - 1);
					$tRNAend = $tRNA->[$t]->{begin} - ($start - 1);
					$tRNAstrand = -1;
				}
			
				$tRNAfeat = Bio::SeqFeature::Generic->new(
						-start		=> $tRNAstart, 
						-end		=> $tRNAend,
						-strand		=> $tRNAstrand,
						-primary	=> 'tRNA',
						-tag		=> {
								product => "tRNA-".$tRNA->[$t]->{type}
								}
						);
				$inseq->add_SeqFeature($tRNAfeat);
				$t++;
			}else{
				last;
			}
		}
		
		$q = "SELECT status FROM validation WHERE code='$orf->{validation}'";
		$vld = $dbh->selectrow_hashref($q, { Slice => {} });
		$validation = lc $vld->{status};

		$frameshift = $orf->{frameshift} ? 'yes' : 'no';

		$q = "SELECT * FROM rbs WHERE idMontagem=\'$mtg\' AND id='$_->{id}' AND pattern!='---'";
		$rbs = $dbh->selectrow_hashref($q, { Slice => {} });

		$q = "SELECT * FROM anotacao WHERE idMontagem=\'$mtg\' AND id='$_->{id}'";
		$cds = $dbh->selectrow_hashref($q, { Slice => {} });

		$addRBS = 0;
		if (scalar(keys %{$rbs}) > 0 and $rbs->{position} > 0){
			$addRBS = 1;
		}

		if ($_->{frame} =~ /F/){
			$GENEstrand=1;
			$orfSeq = Bio::Seq->new(-seq => $inseq->subseq($_->{start} - ($start - 1), $_->{end} - ($start - 1)),
						-alphabet => "dna");
			$translation =  $orfSeq->translate->seq;
		}else{
			$GENEstrand=-1;
			$orfSeq = Bio::Seq->new(-seq => $inseq->subseq($_->{end} - ($start - 1), $_->{start} - ($start - 1)),
						-alphabet => "dna");
			$translation = $orfSeq->revcom->translate->seq;
		}

		if ($orf->{orfName}){
			$orfName = $orf->{orfName};
		}else{
			$orfName = $orf->{id};
		}

		if ($addRBS > 0){
			$RBSstart = $rbs->{position};
			$count = ($rbs->{pattern} =~ tr/[ACGT]//);
			$RBSend = $RBSstart + ($GENEstrand)*$count - $GENEstrand;

			if ($GENEstrand == -1){
				$tmp = $RBSstart;
				$RBSstart = $RBSend;
				$RBSend = $tmp;
			}
	
			$RBSfeat = Bio::SeqFeature::Generic->new(
				-primary	=> 'RBS',
				-start		=> $RBSstart - ($start - 1),
				-end		=> $RBSend - ($start - 1),
				-strand		=> $GENEstrand,
				-tag		=> {
						gene => $orfName,
						}
				);
		}

		if ($GENEstrand == -1){
			$GENEstart = $_->{end} - ($start - 1);
			$GENEend = $_->{start} - ($start - 1);
		}else{
			$GENEstart = $_->{start} - ($start - 1);
			$GENEend = $_->{end} - ($start - 1);
		}
		my $GENEfeat = Bio::SeqFeature::Generic->new(
			-primary	=> 'gene',
			-start		=> $GENEstart, 
			-end		=> $GENEend,
			-strand		=> $GENEstrand,
			-tag		=> {
# 					note => "score = $_->{gene_score} note = '$orf->{note}'",
					gene => $orfName,
					locus_tag => $cds->{id}
					}
			);
		
		$cds->{product} =~ s/\r\n/ /g;
		$cds->{function} =~ s/\r\n/ /g;
		
		$cogId = $cds->{COGid};
		
# 		print $cds->{product}."\n---\n";
		$annotator = $cds->{anotador};
		$reviewer = $cds->{revisor};

		my $CDSfeat = Bio::SeqFeature::Generic->new(
			-start		=> $GENEstart, 
			-end		=> $GENEend,
			-strand		=> $GENEstrand,
			-primary	=> 'CDS',
			-tag		=> {
					product => $cds->{product},
					function => $cds->{function},
					gene => $orfName,
					locus_tag => $cds->{id},
					translation => $translation,
					validation => $validation,
					cogNumber => $cogId,
					frameshift => $frameshift, 
					annotator => $annotator,
					reviewer => $reviewer
					}
			);

		$q = "SELECT EC_number, EC_number2 FROM anotacao WHERE idMontagem=\'$mtg\' AND id=\'$_->{id}\'";

		my $ECnumbers = $dbh->selectrow_hashref($q, { Slice => {} });

		foreach my $key (sort keys %{$ECnumbers}){
			if ($ECnumbers->{$key} =~ /\d/g){
				$CDSfeat->add_tag_value($key, $ECnumbers->{$key});
			}
		}

		if ($addRBS > 0){
			$inseq->add_SeqFeature($RBSfeat);
		}
		$inseq->add_SeqFeature($GENEfeat);
		$inseq->add_SeqFeature($CDSfeat);
 	}

}

# tRNAs que comecam depois da ultima ORF
for (;$t<@$tRNA;){
	if ($tRNA->[$t]->{begin} <= $tRNA->[$t]->{end}){
		$tRNAstart = $tRNA->[$t]->{begin} - ($start - 1);
		$tRNAend = $tRNA->[$t]->{end} - ($start - 1);
		$tRNAstrand = 1;
	}else{
		$tRNAstart = $tRNA->[$t]->{end} - ($start - 1);
		$tRNAend = $tRNA->[$t]->{begin} - ($start - 1);
		$tRNAstrand = -1;
	}

	$tRNAfeat = Bio::SeqFeature::Generic->new(
			-start		=> $tRNAstart, 
			-end		=> $tRNAend,
			-strand		=> $tRNAstrand,
			-primary	=> 'tRNA',
			-tag		=> {
					product => "tRNA-".$tRNA->[$t]->{type}
					}
			);
	$inseq->add_SeqFeature($tRNAfeat);
	$t++;

}

my $seq_out = Bio::SeqIO->new(-file   => ">$outFile",
			      -format => "GenBank");
$seq_out->write_seq($inseq);


