#!/usr/bin/perl -w

use Getopt::Long;
use Data::Dumper;

our($opt_outfile,$opt_help,$opt_fps);
GetOptions("help","f=i","t=s","fps=i","outfile=s");
print_help() && exit(0) if (defined $opt_help);
$source=shift         || die "You must Enter a source file!\n";
$outfile=$opt_outfile ||$source;

$f=$opt_f if (defined $opt_f);
$t=$opt_t if (defined $opt_t);
$fps=$opt_fps  || 25;
$frame_rate=int 1000/$fps;
my $ref_tempo;

if ($f) {
	$frames=$f;
	$ref_tempo=&to_tempo($frames,$frame_rate);
	@tempo=@{$ref_tempo};
}

if ($t) {
	@tempo=split(/:/,$t);
	&normalizar_time(\@tempo);
	$frames=&to_frames(\@tempo,$frame_rate);
}

die "Nao definiu tempo\n" unless defined $frames;

############################################
# ver qual a extensao (tipo do ficheiro)
@ext=split(/\./,$source);
$e=pop @ext;
if (lc($e) eq "sub") {
	my $result=&alterar_sub($source,$frames);
	&print_to_file($outfile,$result);
}
elsif (lc($e) eq "srt") {
	my $result=&alterar_srt($source,\@tempo);
	&print_to_file($outfile,$result);
}
else { die "Formato de legendas nao suportado\n";
}
#############################################

sub normalizar_time
{
	my $total;
	my $tam;
	$ref_array=shift;
	$tam=@{$ref_array};
	
	# Passar todos os valores a negtivo se for o caso;

	$p=$ref_array->[0];

	if ($p<0)
		{
			for($i=1;$i<$tam;$i++)
			{
				$ref_array->[$i]="-".$ref_array->[$i];
			}
		}
	
	# Completar Tempo

	while ($tam<4)
	{
		unshift @{$ref_array}, 0;
		$tam=@{$ref_array};
	}
}	
		
sub to_frames
{
	my $time=shift;
	my $fr=shift;
	my $tot_mseg;

	$tot_mseg=(3600*$time->[0]+60*$time->[1]+$time->[2])*1000 +$time->[3];

	my $total_frames=int $tot_mseg / $fr;
 	return $total_frames;	
}
sub print_array
{
	$a=shift;
	for(@{$a}) { print "$_:"; }
	print "\n";
}

sub to_tempo
{
	my $total_frames=shift;
	my $fr=shift;
	my $total_mseg;
	my $menos=0;
	my @tempo;
	
	if ($total_frames<0) 
	{
		$total_frames*=-1;
		$menos=1;
	}
	
	$total_mseg=$total_frames*$fr;
	$ms=$total_mseg % 1000;
	$seg=int $total_mseg /1000;
	$min=int $seg/60;
	$seg=$seg % 60;
	$hora=int $min / 60;
	$min=$min % 60;
	
	unshift @tempo , $ms;
	unshift @tempo , $seg;
	unshift @tempo , $min;
	unshift @tempo , $hora;
	
	if ($menos==1)
	{
		for ($i=0;$i<4;$i++)
		{
			$tempo[$i]="-".$tempo[$i];
		}
	}
	
	return \@tempo;
}



sub alterar_srt
{

	my $resultado="";
	my $file=shift;
	my $ref_array=shift;

	my @tempo=@{$ref_array};
	open (A,$file);
	while (<A>)
	{
		if ($_=~/(\d{2}):(\d{2}):(\d{2}),(\d{3}) --> (\d{2}):(\d{2}):(\d{2}),(\d{3})/)
		{
			my @n_tempo_i=();
			my @n_tempo_f=();
			my @all=();
			push(@n_tempo_i,$1,$2,$3,$4);
			push(@n_tempo_f,$5,$6,$7,$8);

			for ($i=0;$i<4;$i++)
			{
				$n_tempo_i[$i]+=$tempo[$i];
				$n_tempo_f[$i]+=$tempo[$i];
			}
			
			push @all,\@n_tempo_i;
			push @all,\@n_tempo_f;

			for ($i=0;$i<2;$i++)
			{
				if ($all[$i]->[3]<0)
				{
					$all[$i]->[2]--;
					$all[$i]->[3]+=1000;
				}
				if ($all[$i]->[3]>999)
				{
					$all[$i]->[2]++;
					$all[$i]->[3]-=1000;
				}
				if ($all[$i]->[2]<0)
				{
					$all[$i]->[1]--;
					$all[$i]->[2]+=60;
				}
				if($all[$i]->[2]>59)
				{
					$all[$i]->[1]++;
					$all[$i]->[2]-=60;
				}
				if($all[$i]->[1]<0)
				{
					$all[$i]->[0]--;
					$all[$i]->[1]+=60;
				}
				if($all[$i]->[1]>59)
				{
					$all[$i]->[0]++;
					$all[$i]->[1]-=60;
				}

				while(length($all[$i]->[0])<2)
				{
					$all[$i]->[0]="0".$all[$i]->[0];
				}
				while(length($all[$i]->[1])<2)
				{
					$all[$i]->[1]="0".$all[$i]->[1];
				}
				while(length($all[$i]->[2])<2)
				{
					$all[$i]->[2]="0".$all[$i]->[2];
				}
				while(length($all[$i]->[3])<3)
				{
					$all[$i]->[3]="0".$all[$i]->[3];
				}
			}
			$a=$all[0];
			$b=$all[1];
			$_="$a->[0]:$a->[1]:$a->[2],$a->[3] --> $b->[0]:$b->[1]:$b->[2],$b->[3]\n";
					
		}
		$resultado.=$_;
	}
	close(A);
	return $resultado;
}

sub alterar_sub
{
	my $fich=shift;
	my $frames=shift;
	my $frame_i;
	my $frame_f;
	open(A,"$fich") || die "$fich - ficheiro nao existente!\n";
	while (<A>)
	{
		if ($_=~/\{(\d+)\}\{(\d+)\}(.*)/)
		{
			$frame_i=$1+$frames;
			$frame_f=$2+$frames;
		}
		
		$_="{$frame_i}{$frame_f}$3\n";
		$resultado.=$_;
	}
	return $resultado;

}

sub print_to_file
{
	my $fich=shift;
	my $res=shift;
	open (A,">$fich") or die("cant create $fich\n");
	print A $res;
        close A;
}

sub print_help
{   print << "FIM";
alterar_legendas.pl - Script para alterar o tempo em que as legendas 
 aparecem nos filmes.

Uso:perl alterar_legendas.pl <ficheiro> [opcoes]

OPCOES:
 -t=tempo   - tempo que deseja acrescentar ou retirar as legendas
 -f=frames  - frames que deseja acrescentar ou retirar ao aparecimento das 
            legendas
 -fps=FPS    - Numero de frames por segundo em que o filme foi codificado 
            (se nao usar esta opcao, o valor por defeito e 25)
 -outfile=FILE - Ficheiro de outpu, se esta opcao nao for especificada o 
            output sera redirecionado para o ficheiro original

EXEMPLO:
perl alterar_legendas.pl aaa.srt -t=-2:340  - Assim as legendas 
  aparecerao 2 segundos e 340 milisegundos antes.
	
perl alterar_legendas.pl aaa.srt -t=1:0:100 - Assim as legendas 
  apareceram 1 minuto e 100 milisegundos depois.

perl alterar_legendas.pl aaa.srt -f=200     - Assim as legendas 
  aparecerao 200 frames depois.

NOTA:
Esta script so suporta 2 tipos de ficheiros (.srt , .sub) e e necessario 
que as extensoes dos ficheiros sejam correspondentes ao tipo de ficheiro.
FIM
}
