#!/usr/bin/perl -w
use strict;
use List::Util qw(sum);
use Getopt::Long;

###
#This script is used to locate P-element insertions according to alignments in SAM file.
#Usage: perl $0 [options] -i in.sam -o insertion.out
#Shuo Zhang
#History: 2015-11-10; 2015-11-12; 2016-05-17
###

my $read1_len=30; #default mapped read2 lenght: 30bp 
my $read2_len=30;  # default mapped read2 length: 30bp
my $infile;
my $outfile;
my $mapped_read;
GetOptions ( 'read1_len:i' => \$read1_len, 'read2_len:i' => \$read2_len, 'infile=s' => \$infile, 'outfile=s' => \$outfile, 'mapped_read:s' => \$mapped_read) or die ("Error in command line arguments\n");
my %insertion;
my %read;
#requirement for read1
open IN,'<', $infile or die "Cannot open the input file:$!";
while(my $line = <IN>){
	chomp($line);
	my @sam=split /\t/,$line;
	my (@cigar_m)=$sam[5]=~/(\d+)M/g;
	my $aln_ln=sum(@cigar_m);
	if ($sam[1]=~/1$/ and $aln_ln >=$read1_len){	# require mapped length of read1 to be at least 90bp and filter low mapping quality alignment
	$read{$sam[0]}=1;
	}
}
close IN;

#requirement for read2
open IN,'<', $infile or die "Cannot open the input file:$!";
while(my $line = <IN>){
        chomp($line);
        my @sam=split /\t/,$line;
	next unless exists $read{$sam[0]};
	if ($sam[1]=~/1$/){next;}
	if ($sam[1]=~/2$/){
		my (@cigar_m)=$sam[5]=~/(\d+)M/g;
                my $aln_ln=sum(@cigar_m);
		#my $rate=$aln_ln/($seq_len-54);
		delete $read{$sam[0]} unless (defined $aln_ln and $aln_ln >= $read2_len);
	}
}
close IN;

if (defined $mapped_read){
	open READ,'>',$mapped_read or die "Cannot open the mapped_read output file\n";
	foreach my $key (sort keys %read){
		print READ "$key\n";
	}
	close READ;
}
		
		
open IN,'<', $infile or die "Cannot open the input file:$!";
while(my $line = <IN>){
	chomp($line);
	my @sam=split /\t/,$line;
	next if $sam[1]=~/2$/;
	if (exists $read{$sam[0]}){
		my $strand="sense";
		if ($sam[1] =~/R/){
			my $coor = $sam[3] + 7; #breakpoint
			${${$insertion{$sam[2]}}{$coor}}[0]++;
			${${$insertion{$sam[2]}}{$coor}}[1]++;
			}
		elsif ($sam[1] =~/r/){
			$strand="antisense";
                    	my (@cigar_m)=$sam[5]=~/(\d+)M/g;
                    	my (@cigar_d)=$sam[5]=~/(\d+)D/g;
                    	#my (@cigar_s)=$sam[5]=~/(\d+)S/g;
                   	#my (@cigar_i)=$sam[5]=~/(\d+)I/g;
                    	my $aln_ln=sum(@cigar_m,@cigar_d);
                   	my $coor=$sam[3]+$aln_ln-1;
			${${$insertion{$sam[2]}}{$coor}}[0]++;
			${${$insertion{$sam[2]}}{$coor}}[2]++;
		}
		else { die "wrong sam file";} 
	}
}
close IN;

###formatted print
open OUT,'>',$outfile or die "Cannot open the output file:$!";
print OUT "chromosome\tlocation\treads_support\tstrand\n";
foreach my $ele (sort keys %insertion){
	my @ele= keys %{$insertion{$ele}};
	my @ele_sorted = sort {$a <=> $b} @ele;
	foreach my $site (@ele_sorted ){	
		my $num = ${${$insertion{$ele}}{$site}}[0];
		my $strand;
		if (defined ${${$insertion{$ele}}{$site}}[1] and ${${$insertion{$ele}}{$site}}[0] == ${${$insertion{$ele}}{$site}}[1]){ $strand = "sense";print OUT "$ele\t$site\t$num\t$strand\n"} 
		elsif (defined ${${$insertion{$ele}}{$site}}[2] and ${${$insertion{$ele}}{$site}}[0] == ${${$insertion{$ele}}{$site}}[2]){ $strand = "antisense";print OUT "$ele\t$site\t$num\t$strand\n"}
		else {print OUT "$ele\t$site\t${${$insertion{$ele}}{$site}}[1]\tsense\n"; print OUT "$ele\t$site\t${${$insertion{$ele}}{$site}}[2]\tantisense\n";}
	}
}
close OUT;
close IN;

