package Lire::Report::Section;

use strict;

use vars qw/ $VERSION @ISA /;

use Lire::XMLUtils qw/xml_encode/;

use Carp;

BEGIN {
    ($VERSION)	= '$Revision: 1.2 $' =~ m!Revision: ([.\d]+)!;
}

=pod

=head1 NAME

Lire::Section - Interface to the content of the section's element.

=head1 SYNOPSIS

    my $section = Lire::ReportParser::ReportBuilder( "report.xml" );
    
    foreach my $s ( $report->sections ) {
	print "Section: '", $s->title, "' has ", scalar $s->subreports(),
	    " subreports in it\n";
    }

=head1 DESCRIPTION

This class offers an API to the section's elements of a Lire report.

=head1 CONSTRUCTOR

=head2 new( [$title] )

Creates a new Lire::Report::Section. The section's title will be set
to the $title parameter if present.

=cut

sub new {
    my $proto = shift;
    my $class = ref $proto || $proto;

    my ( $title ) = @_;

    bless { 
	    title	 => $title || "Untitled",
	    subreports	 => [],
	    descriptions => [],
	  }, $class;
}

=pod

=head1 OBJECT METHODS

=head2 title( [$title] )

Returns the section's title, if it has one. The section's title will
be changed $title if that parameter is set.

=cut

sub title {
    $_[0]{title} = $_[1] if defined $_[1];
    $_[0]{title};
}

=pod

=head2 target_users()

Returns the user class supported by the descriptions of this section. 

=cut

sub target_users {
    my ( $self ) = @_;

    return map { $_->{name} } @{$self->{descriptions}};
}

=pod

=head2 description( [$target_user], [$description] )

Returns the description for a particular class of user. This should be
one of the values returned by target_users(). If the $target_user
parameter is missing or the requested class isn't available, the
'default' description will be returned. That's the first one that
appears in the XML file. 

The description is encoded in DocBook XML.

If the $description parameter is set, this method will set the
$target_user description to this new value. If the $description
parameter is undef, that description will be removed.

=cut

sub description {
    my ( $self, $target_user, $new_desc ) = @_;

    my $desc_idx = 0;
    if ( defined $target_user ) {
	# Look for that target_user or use the first one
	my $i	    = 0;
	foreach my $d ( @{$self->{descriptions}} ) {
	    if ($d->{name} eq $target_user) {
		$desc_idx	= $i;
		last;
	    }
	    $i++
	}
	# $desc_idx defaults to 0
    } # else $desc_idx defaults to 0

    # Mutator
    if ( @_ == 3 ) {
	if ( defined $target_user && $desc_idx == 0 ) {
	    # Check that $desc_idx is really target_user and not just the
	    # default one
	    unless ( defined $self->{descriptions}[0]{name} && 
		     $target_user eq $self->{descriptions}[0]{name} ) 
	    {
		push @{$self->{descriptions}}, { name => $target_user, };
		$desc_idx = $#{$self->{descriptions}};
	    }
	}
	if ( defined $new_desc ) {
	    $self->{descriptions}[$desc_idx]{desc} = $new_desc;
	} else {
	    splice @{$self->{descriptions}}, $desc_idx, 1;
	    return undef;
	}
    }

    $self->{descriptions}[$desc_idx]{desc};
}

=pod

=head2 subreports()

Returns the subreport's included in that section. This will be an array of
Lire::Report::Subreport objects.

=cut

sub subreports {
    @{$_[0]{subreports}};
}


=pod

=head2 add_subreport( $subreport )

Adds a subreport to this report. The $subreport parameter should be a
Lire::Report::Subreport object.

=cut

sub add_subreport {
    my ( $self, $subreport ) = @_;

    croak ( "section should be of type Lire::Report::Subreport (not $subreport)" )
      unless UNIVERSAL::isa( $subreport, "Lire::Report::Subreport" );

    push @{$self->{subreports}}, $subreport; 
}

=pod

=head2 subreports_by_type( $type )

Returns all the subreports in this section of a the type $type. The
subreport's type is the id of the report specification used to compute
the reports. The subreports are returned as an array of
Lire::Report::Subreport objects.

=cut

sub subreports_by_type {
    my ( $self, $type ) = @_;

    grep { $_->type eq $type } $self->subreports;
}

sub write_report {
    my ( $self, $fh, $indent ) = @_;

    $fh ||= *STDOUT;
    my $pfx = ' ' x $indent;

    print $fh qq"$pfx<lire:section>\n";

    print $fh "$pfx <lire:title>", xml_encode( $self->{title} ), 
      "</lire:title>\n\n";

    foreach my $desc ( @{$self->{descriptions}} ) {
	print $fh "$pfx <lire:description";
	print $fh qq! target-user="$desc->{name}"! 
	  if defined $desc->{name};
	print $fh ">$desc->{desc}</lire:description>\n";
    }
    print $fh "\n" if @{$self->{descriptions}};

    foreach my $r ( $self->subreports ) {
	$r->write_report( $fh, $indent + 1 );
    }

    print $fh "$pfx</lire:section>\n";
}

# keep perl happy
1;

__END__

=pod

=head1 SEE ALSO

Lire::ReportParser::ReportBuilder(3pm) Lire::Report(3pm)
Lire::Report::Subreport(3pm) Lire::Report::Entry(3pm)
Lire::Report::Group(3pm)

=head1 VERSION

$Id: Section.pm,v 1.2 2002/05/21 18:24:18 flacoste Exp $

=head1 COPYRIGHT

Copyright (C) 2002 Stichting LogReport Foundation LogReport@LogReport.org

This file is part of Lire.

Lire is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program (see COPYING); if not, check with
http://www.gnu.org/copyleft/gpl.html or write to the Free Software 
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.

=head1 AUTHOR

Francis J. Lacoste <flacoste@logreport.org>

=cut
