#!/usr/bin/perl

use strict;
use warnings;

my $seq;
my @score = ();
my $finestra = $ARGV[0];
my $fitxerseq= $ARGV[1];
my %resultats;
#llegir la seqüencia d'un fitxer i posar-lo a una variable tota seguida

$seq = &llegir_seq($fitxerseq);

#calcular g+c en cada finestre que anem recorrent i col·locar-ho a un array

@score = &gc_finestres($seq,$finestra); ######posem entre parèntesi en la funció les variables globals que necessitem per la funció.


#donem els resultats

&printa_score(\@score,$finestra);


exit(0);

#definim les funcions

sub llegir_seq() {

    print STDERR "## Llegint SEQUENCIA....\n";

    my $seq = "";
    my $header = "";
    my $sequencia = $_[0]; ########és el primer component que passa per la funció $_[0] es refereix a $fitxerseq que hem indicat al costat de la funció entre parèntesi en el programa.Aquesta variable ara l'estem enregistrant a $sequencia

    if (!open(SEQ,"<$sequencia")) {
	print STDERR " no puc obrir $sequencia\n";
	exit(1);
    };

    $header = <SEQ>;

    while (<SEQ>) {
	chomp($_);
	$_ =~ s/\s+//go;
	$seq .= $_; 
    };

    close (SEQ);

    return $seq;

} # llegir_seq

sub gc_finestres() {

    print STDERR "## Calculant SCORES....\n";

    my $seq = $_[0]; ####és el primer component que passa per la funció. $_[0] es refereix a $seq que hem indicat al costat de la funció entre parèntesi en el programa.Aquesta variable ara l'estem enregistrant a $seq dins la funció
    my $finestra = $_[1]; ####és el segon component que passa per la funció. $_[1] es refereix a $finestra que hem indicat al costat de la funció entre parèntesi en el programa.Aquesta variable ara l'estem enregistrant a $finestra dins la funció

    my $i=0;
    my $long=length($seq);

    my @score = ();

    #################farem un while dins un altre el primer while tallara la seq de 1000 en 1000 i el segon de dins, per una seq de 1000 anira nt x nt llegint i omplint el hash.contarem les c+g/ per 1000 i ho guardarem a un element d'un array @score.###########    

    while ($i<$long) {

	my $seq_finestra; ####aqui hi enregistrem les finestres de 1000
	my %gc_hash;
	my $z; ########serveix per anar tirant endavant de nt a nt dins finestra 1000

	$seq_finestra=substr($seq,$i,$finestra);
	
	$z = 0;
	
	############inicialitzam el hash a 0  
	
	%gc_hash = ("A" => 0,
		    "C" => 0,
		    "G" => 0,
		    "T" => 0);

	while ($z < $finestra) { 
	    

	    my $nt = substr($seq_finestra, $z, 1); 

	    last if $nt eq ''; ####acaba de contar nt quan el que agafis sigui res, i surt.(ho posem per la última finestra a recorrer ja que té menys de 1000nt.

	    $nt = uc($nt); ####Tots els nucleòtids que agafis, si ni a en minúscules passa-ho a majúscules
	    
	    $gc_hash{$nt} = $gc_hash{$nt} + 1;

	    $z = $z + 1;

	} #####en aquest while secundari hem omplert el hash
	########abans de tancar la clau del primer while hem de posar resultat del hash per 1000nt en un element del vector @score.
	
	
	my $sumaCG = (($gc_hash{'G'} + $gc_hash{'C'}) / $finestra);
	
	######### ara declarem el array @score on emmagatzarem a cada un dels elements del array la proporció de CG de cada sequencia finestra############
	
        push @score, $sumaCG; ####push és la manera d'anar omplint l'array una suma rera una altre
	
	$i = $i + $finestra;
	
    }

    return @score; #####el return l'usem per tal que en aquest cas l'array omplert es passi a la següent funció ja que el necessita.

}


sub printa_score() {

    print STDERR "## Imprimint SCORES....\n";

    my @score = @{$_[0]};

    my $finestra = $_[1];

    my $long = scalar(@score);
 
    my $cordmitja = ($finestra/2);

    my $n = 0;

    while ($n < $long){

	printf STDOUT "%d %.3f\n", $cordmitja, $score[$n];
	
	$cordmitja = $cordmitja + $finestra;
	
	$n = $n + 1;

    }

} # printa_score








