$VERSION = "0.02";
package News::Overview::Entry;
our $VERSION = "0.02";     

# -*- Perl -*-          # Fri Oct 10 11:29:51 CDT 2003 
#############################################################################
# Written by Tim Skirvin <tskirvin@killfile.org>.  Copyright 2003, Tim
# Skirvin.  Redistribution terms are below.
#############################################################################

=head1 NAME

News::Overview::Entry - an object for storing specific overview information 

=head1 SYNOPSIS

  use News::Overview::Entry;
  use News::Overview;
  
  my $article = new News::Article;
  # Populate News::Article somehow; 
  
  # Create a new News::Overview::Entry object
  my $msgid = $article->header('message-id');
  my @refs = split(/\s+/, $article->header('references') || "");
  my %other; 
  foreach ( News::Overview->defaults ) { 
    $other{$_} = $article->header($_) || "";
  }
  my $entry = News::Overview::Entry->new($msgid, \@refs, %other);

See below for more specific information about related functions.

=head1 DESCRIPTION

News::Overview::Entry is an object meant to hold overview information
about a single news article - that is, the minimal information necessary
to sort the article with other articles, as used by XOVER in the NNTP
specification.  It is primarily a helper class for use with
News::Overview; see that manual page for more information.

 
=head1 USAGE 

All of this object's usage is contained within its functions.

=cut

###############################################################################
### main() ####################################################################
###############################################################################

use strict;
use Date::Parse;

=head2 Basic functions 

=over 4

=item new ( MSGID [, REFERENCES, OTHER] ) 

Creates a new News::Overview::Entry object.  C<MSGID> is the Message-ID of
the object, and is required (the function will return undef if it's not
present).  

C<REFERENCES> is an arrayref that contains the message-IDs of the entry's
parents.  C<OTHER> is a hash of other information about the article, which
are stored in the entry.  

=cut

sub new {
  my ($proto, $msgid, $refs, %other) = @_;
  return undef unless $msgid;
  $refs ||= [];
  my $class = ref($proto) || $proto;
  my $self = {
	ID	 =>     $msgid,
        Values   =>     {
		'Message-ID'	=> $msgid,
		'References'	=> join(" ", reverse @{$refs}),
		%other
		 	},
	Parent   => 	(@{$refs})[0] || undef,
        Children =>     {},
 	References =>   $refs,
             };
  bless $self, $class;
  $$self{Values}->{Newsgroups} = join(',', $self->newsgroups);
  $self;
}

=item id () 

Returns the associated message-ID of the Entry. 

=cut

sub id       { shift->{ID} || "" }

=item parent () 

Returns the Entry's parent's message-ID, or undef if there isn't one.
This is currently defined as "the last item in References".  This isn't
currently being used, and may change to something else.

=cut

sub parent   { shift->{Parent} || undef }

=item children () 

Returns all of the children of the current Entry; each returned item is
another News::Article::Entry object.  Note that no children exist until
they are added with add_child().

=cut

sub children { 
  my @array = values %{shift->{Children}};
  wantarray ? @array : \@array;
}

=item value ( FIELD ) 

Returns the value of the information stired in C<FIELD> within the Entry.  

=cut

sub value { my ($self, $field) = @_; $self->values->{$field} || ""; }

=item values ( )

Returns a hashref containing all of the keys and values of the information
associated with the Entry.  

=cut

sub values   { shift->{Values} }

=back

=head2 Additional Information 

These functions offer additional information about the Entry, generally by
parsing the above information.  

=over 4 

=item depth () 

Returns the "depth" of the Entry, ie the number references above the
article.  A parent article (one with no References) is depth 0.
  
=cut

sub depth    { ( scalar @{shift->{References}} ) || 0 }

=item time ( )

Returns the time, in seconds since the epoch, that the Entry says it was
posted at (generated by parsing the Date header; will default to 0).  

This information is cached for later use within the item.

=cut

sub time {
  my $self = shift;  
  unless ($$self{Time}) { $$self{Time} = str2time($self->values->{Date}) }
  $$self{Time};
}

=item newsgroups () 

Returns the newsgroups associated with the entry, either by parsing the
Newsgroups field or Xref.  Returns an array of associated newsgroups.

=cut

sub newsgroups {
  my ($self) = @_;
  if       (my $groups = $self->value('Newsgroups') ) { 
    my (@groups) = split(/\s+/, $groups); 
    return @groups;
  } elsif ( my $xref = $self->value('Xref') ) { 
    my ($server, @groups) = split(/\s+/, $xref); 
    map { s/:.*//g } @groups;
    return @groups;
  } else { 
    return ();
  }
}

=back

=head2 Manipulation Functions

Besides new(), these functions are the only ones that actually modify the
Entry in a notable way.  

=over 4

=item add_child ( CHILDREN )

Add children to the given item, each of which is a News::Overview::Entry
object.  These are later accessed with children().  This is useful for
threading.  

Returns the number of children that were successfully added.

=cut

sub add_child {
  my ($self, @children) = @_;
  my $start = scalar $self->children;
  foreach (@children) { $$self{Children}->{$_->id} = $_; }
  ( scalar $self->children ) - $start;
}

=head1 REQUIREMENTS

News::Overview, Date::Parse

=head1 SEE ALSO

B<News::Overview>

=head1 TODO

Use the parent() bit effectively.  Make "pseudo-Entries", to make entries
for articles that don't exist, to make threading more accurate.

=head1 AUTHOR

Tim Skirvin <tskirvin@killfile.org>

=head1 COPYRIGHT

Copyright 2003 by Tim Skirvin <tskirvin@killfile.org>.  This code may be
distributed under the same terms as Perl itself.

=cut

1;

###############################################################################
### Version History ###########################################################
###############################################################################
# v0.01b	Fri Oct 10 11:29:51 CDT 2003 
### First commented version (above date indicates the start of the comments).
# v0.12         Thu Apr 22 13:19:25 CDT 2004 
### No real changes; internal code layout.
