###########################################################################################################################
#	
#	"Collect_span-tick_Tracks.pl"
#	
#	--Collect track lines from specified "...bw<+-|+>TRACKS.txt" Files into span-20 and tick-5p Files.  
#	
#	--Also set priorities acc to ( span ? 0 : n*100 ) + <INPUT File #>*10 + ( POS ? 0 : 1 ) 
#	
#	
#	... Possible improvements:  
#		Generalize span-20 to span-<#> 
#	
#	
#	-- David A Harmin, HMS, Mon 2 Dec 2013 
#	
#	
#	
###########################################################################################################################

use strict; 
use warnings; 

use Carp; 


my $n_ = 5; 

my $USAGE = <<"#";  


	perl  Collect_span_tick_Tracks.pl  <OUTPUT baseFile name>  <INPUT baseFile name>  <Sample sub names ...>  

where 
		<OUTPUT baseFile name> = "...-----..."  ($n_ or more dashes to be replaced by 'span-20' and 'tick-5p') 

		<INPUT  baseFile name> = "...-----..."  ($n_ or more dashes to be replaced by the following strings ...) 

		<Sample sub names ...> = <ws-separated list of one or more Sample names to be substituted> 

#


my ( $CR, $TAB, $BAR, ) = ( "\n", "\t", q{|}, ); 

# Open a file for OUTPUT and return its filehandle, stored in a variable, for assignment to a hash of filehandles:  
# Expects 1 arg = OUTPUT File name; returns the opened filehandle.  
sub open_OUT { 
	my $fnm = shift; 
	return undef  unless $fnm; 
	open my $FH, '>', $fnm  or  croak "\nCan't open OUTPUT File \"$fnm\"!"; 
	return $FH; 
} 


#----------------------------------------------------------------------------------------------------------


# Expect track lines themselves to end with bigWig File names of the form 
#		"...<sample>..._<GNM+SPL|SPL>__...__<span-20|tick-5p>__<POS|NEG>.bw"  
#   with <sample> replacing '-----'. 
# 
# INPUT track-line Files should have names of the form "...<sample>..." 
#   with each <sample> replacing '-----' in the given INPUT baseFile name. 
# 
# OUTPUT track-line Files will have names of the form "...<Source>,<Track type>__(<sample1,sample2,...>)..." 
#   with everything btwn the ellipses replacing '-----' in the given OUTPUT baseFile name.  

my @Sources = qw(  GNM+SPL  ); 

my @Track_types = qw(  span-20  tick-5p  ); 

my @Strands = qw(  POS  NEG  );  

my @fmts = map { my $x=$_; $x=~s/\+/\\+/; $x } map { join $BAR, @$_ } ( \@Sources, \@Track_types, \@Strands ); 
my $TRACK_fmt = '^track .*?priority=\\d+.*?bigDataUrl=\\".*?-----.*?_(FMT0)__.*?__(FMT1)__(FMT2)\\.bw\\"\s*$'; 

my $baseFile_fmt = qr/^(.*?)-{$n_,}(.*)$/; 

my %pri_Trk = (  'span-20' => 0,  'tick-5p' => 100  ); 
my %pri_Str = (  POS => 1,  NEG => 2  ); 
my %pri_smp = (); 


#----------------------------------------------------------------------------------------------------------


croak $USAGE  unless  @ARGV >= 3; 

my ( $OUT_baseFile, $IN_baseFile, @samples ) = @ARGV ;  
print	"\n\n\$OUT_baseFile = \"$OUT_baseFile\"\n\n\$IN_baseFile = \"$IN_baseFile\"\n\n\@samples = [ ", 
	( join ', ', @samples ), " ]\n\n";   
croak $USAGE  unless  $IN_baseFile =~ /$baseFile_fmt/  &&  $OUT_baseFile =~ /$baseFile_fmt/; 


my %IN_Files = map { my $s=$_;  ( my $f = $IN_baseFile ) =~ s/$baseFile_fmt/$1$s$2/; $s => $f  } @samples; 
my $n_samples = @samples; 
print	"\n$n_samples \%IN_Files = \n", ( join $CR, map { sprintf "% 15s:   \"%s\"", $_, $IN_Files{$_} } @samples ), $CR, $CR; 
$pri_smp{ $samples[$_] } = $_*10  for (0..$#samples); 
$pri_Trk{'tick-5p'} += 10*( $n_samples - $n_samples % 10 )  if $n_samples >= 10; 

my %OUT_Files = map { 
	my $src = $_;  
	my $ss = join ',', @samples; 
	$src => { map { 
		my $trk = $_; 
		( my $f = $OUT_baseFile ) =~ s/$baseFile_fmt/$1$src,${_}__($ss)$2/;  
		$trk => $f 
	} @Track_types } 
} @Sources; 
print "\n\%OUT_Files = \n", ( map { my $src=$_; map { sprintf "\t%s\n", $OUT_Files{$src}{$_} } @Track_types } @Sources ), $CR; 


#----------------------------------------------------------------------------------------------------------


my ( $n_OUT, $n_IN_File ) = ( 0, 0 ); 

my %OUT_ = map { $_ => { map { $_ => {} } @Track_types } } @Sources; 
for my $src ( @Sources ) {  for my $trk ( @Track_types ) {  
	$OUT_{$src}{$trk} = open_OUT( $OUT_Files{$src}{$trk} ); 
	print { $OUT_{$src}{$trk} }	$CR; 
}  }  

for my $sample ( @samples ) { 
	( my $sample_fmt = $TRACK_fmt ) =~ s/-{$n_,}/$sample/; 
	$sample_fmt =~ s/FMT$_/$fmts[$_]/  for (0..2); 
	my $n_used = 0;   
	
	my $IN_File = $IN_Files{$sample}; 
	open IN, '<', $IN_File  or  croak  "Can't open INPUT File \"$IN_File\"!"; 
	print	"\nINPUT File \"$IN_File\" ... \n"; 
	
	while ( my $line = <IN> ) { 
		chomp $line; 
		next  if  $line =~ /^\s*$/  ||  $line !~ /$sample_fmt/; 
		my ( $src, $trk, $str ) = ( $1, $2, $3 ); 
		my $pri = $pri_Trk{$trk} + $pri_smp{$sample} + $pri_Str{$str}; 
		$line =~ s/(priority=)(\d+)/$1$pri/; 
		print { $OUT_{$src}{$trk} }	$CR, $line, $CR; 
		++$n_used;  ++$n_OUT; 
	} 
	
	close( IN )  or  croak  "Can't close INPUT File \"$IN_File\"!"; 
	if( $n_used ) { 
		for my $src ( @Sources ) {  for my $trk ( @Track_types ) {  print { $OUT_{$src}{$trk} } $CR;  }  }  
	} 
	++$n_IN_File;  
} 

for my $src ( @Sources ) {  
	for my $trk ( @Track_types ) {  
		print { $OUT_{$src}{$trk} }	$CR, $CR; 
		close( $OUT_{$src}{$trk} )  or  croak  "Can't close OUTPUT File \"$OUT_Files{$src}{$trk}\"!"; 
	}  
}  


#----------------------------------------------------------------------------------------------------------


print	"\n\n\n>=====[  DONE!  ]-------(  Total $n_OUT track lines OUTPUT from INPUT Files for Samples [ " 
	. ( join ', ', @samples ). " ]=====<\n\n"; 


###########################################################################################################################
