#!/usr/local/bin/perl
# -*-Perl-*- 
#######################################################################
# This software has been created by Genome Research Limited (GRL).    # 
# GRL hereby grants permission to use, copy, modify and distribute    # 
# this software and its documentation for non-commercial purposes     # 
# without fee at the user's own risk on the basis set out below.      #
# GRL neither undertakes nor accepts any duty whether contractual or  # 
# otherwise in connection with the software, its use or the use of    # 
# any derivative, and makes no representations or warranties, express #
# or implied, concerning the software, its suitability, fitness for   #
# a particular purpose or non-infringement.                           #
# In no event shall the authors of the software or GRL be responsible # 
# or liable for any loss or damage whatsoever arising in any way      # 
# directly or indirectly out of the use of this software or its       # 
# derivatives, even if advised of the possibility of such damage.     #
# Our software can be freely distributed under the conditions set out # 
# above, and must contain this copyright notice.                      #
#######################################################################
# 
# $Id: Uncovered.pm,v 1.1 1997/06/09 15:45:29 rmd Exp $
# $Log: Uncovered.pm,v $
# Revision 1.1  1997/06/09  15:45:29  rmd
# Initial revision
#
#

package Uncovered;

use Carp;
use strict;

############################################################
############################################################
###  Routines to determine uncovered regions in sequences, contigs
############################################################
############################################################

sub new {
    my ($type, $from, $to) = @_;
    my ($c1, $c2);
    if ($from <= $to) {
	($c1, $c2) = ($from, $to);
    } else {
	($c1, $c2) = ($to, $from);
    }
    my $self = {uncovered => [[$c1, $c2]]};
    return bless $self, $type;
}

sub dump {
    my ($self, $file) = @_;
    confess "Wrong type" unless ref $self;
    my $n = scalar(@{$self->{uncovered}});
    print $file "$n uncovered regions\n";
    my $region;
    foreach $region (@{$self->{uncovered}}) {
	print $file "  $region->[0] $region->[1]\n";
    }
}

sub cover {
    my ($self, $from, $to) = @_;
    confess "Wrong type" unless ref $self;
    my ($c1, $c2);
    if ($from <= $to) {
	($c1, $c2) = ($from, $to);
    } else {
	($c1, $c2) = ($to, $from);
    }
    my $i;
    my $uncovered = $self->{uncovered};
    for ($i = 0; $i <= $#{${uncovered}}; $i++) {
	if ($c2 < $uncovered->[$i]->[0]) {
	    last;
	} elsif ($c1 <= $uncovered->[$i]->[0] && $c2 < $uncovered->[$i]->[1]) {
	    $uncovered->[$i]->[0] = $c2+1;
	} elsif ($c1 <= $uncovered->[$i]->[0]) {
	    splice(@{$uncovered},$i,1); $i--;
	} elsif ($c2 < $uncovered->[$i]->[1]) {
	    splice(@{$uncovered},$i,0,[$uncovered->[$i]->[0],$uncovered->[$i]->[1]]);
	    $uncovered->[$i]->[1] = $c1-1;
	    $i++;
	    $uncovered->[$i]->[0] = $c2+1;
	} elsif ($c1 <= $uncovered->[$i]->[1]) {
	    $uncovered->[$i]->[1] = $c1-1;
	} else {
	    # no action
	}	
    }
}

sub getNumRegions {
    my ($self) = @_;
    confess "Wrong type" unless ref $self;
    return scalar(@{$self->{uncovered}});
}

sub getRegion {
    my ($self, $regionNum) = @_;
    confess "Wrong type" unless ref $self;
    return @{$self->{uncovered}->[$regionNum]};
}

# Iterators

sub getFirstRegion {
    my ($self) = @_;
    confess "Wrong type" unless ref $self;
    $self->{regionNum} = 0;
    return $self->getNextRegion;
}

sub getNextRegion {
    my ($self) = @_;
    confess "Wrong type" unless ref $self;
    return undef unless $self->{regionNum} < scalar(@{$self->{uncovered}});
    return $self->{uncovered}->[$self->{regionNum}++];
}

1;
