package Sequence::LociUtil;
BEGIN{ push(@INC, $ENV{LOCAL_PERL_MODULES}); }
use Carp;
use warnings;
use strict;
use Sequence::Locus;

###################################################
sub getMergedLoci {
    my $loci = shift;
    my $mergedLoci = [];
    my $seqID2loci = getSeqIDToLoci( $loci );
    foreach my $seqID (sort keys %$seqID2loci){
	my $curLoci = $seqID2loci->{$seqID};
	my $sortedLoci = sortLociByStart($curLoci);
	my $curMergedLoci = getMergedLociFromSortedLoci( $sortedLoci );
	push( @$mergedLoci, @$curMergedLoci );
    }
    return $mergedLoci;
}

sub getSeqIDToLoci {
    my $loci = shift;
    my $seqID2loci = {};
    foreach my $locus (@$loci){
	my $seqID = $locus->getSeqID();
	if( $seqID2loci->{$seqID} ){
	    push( @{$seqID2loci->{$seqID}}, $locus );
	} else {
	    $seqID2loci->{$seqID} = [$locus];
	}
    }
    return $seqID2loci;
}

sub sortLociByStart {
    my $loci = shift;
    my @sortedLoci = sort{ $a->getStart() <=> $b->getStart() } @$loci;
    return \@sortedLoci;
}

sub getMergedLociFromSortedLoci {
    my $loci = shift;
    my $mergedLoci = [];
    my $curLocus = $loci->[0];
    for( my $i=1 ; $i<scalar(@$loci) ; ++$i ){
	my $locus = $loci->[$i];
	if( $curLocus->isOverlap($locus) ){
	    $curLocus->merge($locus);
	} else {
	    push( @$mergedLoci, $curLocus );
	    $curLocus = $locus;
	}
    }
    push( @$mergedLoci, $curLocus );
    return $mergedLoci;
}

sub selectBySeqID {
    my $loci = shift;
    my $seqID = shift;
    my $selectedLoci = [];
    foreach my $locus (@$loci){
	if( $locus->getSeqID() eq $seqID ){
	    push(@$selectedLoci, $locus);
	}
    }
    return $selectedLoci;
}

sub getTotalLength {
    my $loci = shift;
    my $totalLength = 0;
    foreach my $locus (@$loci){
	$totalLength += $locus->getLength();
    }
    return $totalLength;
}



1;
