=head1 NAME

iPE::Util::Overlap - Provides facilities for checking for overlaps in a set of intervals.  

=head1 DESCRIPTION

This is generally used as a sanity checker for input data in the parameter template.  You may insert any number of interval nodes into structure, and check for overlaps at any point.  

=head1 FUNCTIONS

=over 8

=cut

package iPE::Util::Overlap;

use iPE::Util::Overlap::Node;
#use base ("iPE::RedBlack");
use strict;

=item new ()

Creates a new empty pool of overlap nodes.

=cut
sub new {
    my $class = shift;
    my ($m) = @_;
    #my $this = $class->SUPER::new(@_);
    my $this = bless {}, $class;

    $this->{intervals_} = [];

    bless $this, $class;
}

=item nodes ()

Returns a reference to the array of intervals in this overlap group.

=cut
sub nodes { shift->{intervals_} }

#XXX this is deprecated
sub intervals { shift->{intervals_} }

=item insert(node)

Inserts a new node into the Overlap tree.  Node must be of type iPE::Overlap::Node.

=cut
sub insert {
    my ($this, $node) = @_;
    $this->check_ref($node);

    push (@{$this->{intervals_}}, $node);

    #$this->SUPER::insert($node->key, $node);
}

#old code for redblack trees.

#sub left_rotate {
    #my $this = shift;
    #my ($node) = @_;
    #$this->check_ref($node);
    #$this->SUPER::left_rotate(@_);
#
    #my $parent = $node->parent;
#
    #$parent->parent->update_max if defined $parent->parent;
    #$parent->update_max;
    #$node->update_max;
#}
#
#sub right_rotate {
    #my $this = shift;
    #my ($node) = @_;
    #$this->check_ref($node);
    #$this->SUPER::left_rotate(@_);
#
    #my $parent = $node->parent;
#
    #$parent->parent->update_max if defined $parent->parent;
    #$parent->update_max;
    #$node->update_max;
#}

=item find_overlap(node)

Check the tree for overlaps with the passed node.  If one is found, it returns the first node found that overlaps that node is returned.

=cut
sub find_overlap {
    my($this, $node) = @_;
    
# old code for redblack
    #my $x = $this->root;
#
    #while($x and $node->overlaps($x) == 0) {
        #if($x->left && 
                #iPE::Overlap::Node::cmp($x->left->max, $node->low) >= 0) { 
            #$x = $x->left;  
        #}
        #else { $x = $x->right; }
    #}

    for(@{$this->intervals}) {
        if($node->overlaps($_)) {return $_;}
    }

    return undef;
}

sub NODE_TYPE { "iPE::Util::Overlap::Node" }

sub check_ref {
    die ref($_[0])." node must be of type ".$_[0]->NODE_TYPE
        if (ref($_[1]) ne $_[0]->NODE_TYPE);
}

=head1 SEE ALSO

L<iPE::Util::Overlap::Node>

=head1 AUTHOR

Bob Zimmermann (rpz@cse.wustl.edu)

=cut

1;
