package Lire::ReportSection;

use strict;

use vars qw( $VERSION );

use Lire::Report::Section;
use Lire::DataTypes qw/:special /;

use Carp;

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

=pod

=head1 NAME

Lire::ReportSection - API to report configuration's section

=head1 SYNOPSIS

    use Lire::ReportConfig;
    use Lire::ReportSection;

    my $report_cfg = new Lire::ReportConfig( "www" );
    my $section = new Lire::Section( "www", "General" );
    $report_cfg->add_section( $section );

=head1 DESCRIPTION

This class offers an object oriented API to report configuration's
section. It offers methods to access and modify the section's
attribute.

=head1 CONSTRUCTOR

=head2 new( $superservice, [$title] )

Creates a new Lire::Section object which will contains report
specifications of the $superservice superservice. The section's title
will be set to the value of $title.

=cut

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

    my ( $super, $title ) = @_;

    croak "invalid superservice: $super"
      unless check_superservice( $super );

    bless { superservice    => $super,
	    filters	    => [],
	    title	    => $title || "Section",
	    reports_by_key  => {},
	    reports	    => [],
	  }, $class;
}

=pod

=head1 OBJECT METHODS

=head2 superservice()

Returns this section's superservice.

=cut

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

    $self->{superservice};
}

=pod

=head2 title([$title])

Return's the current section's title.

When the $title parameter is used, it will set the section's title to
a new value.

=cut

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

    if ( defined $title ) {
	$self->{title} = $title;
    }

    $self->{title};
}

=pod 

=head2 filters()

Returns this section's filter specifications as an array of
Lire::FilterSpec objects. Those filter specifications will be used by
all of this section's report specifications in addition to the filter
specification they may already be using.


=cut

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

    return @{ $self->{filters} };
}

=pod 

=head2 add_filter($filter_spec)

Adds the $filter_spec filter specification to this section's list. The
$filter_spec parameter must be an instance of Lire::FilterSpec or one
of its descendants.

This method will die if the filter specification's schema isn't
compatible with this section's superservice.

=cut

sub add_filter {
    my ( $self, $filter_spec ) = @_;

    croak ( "filter_spec must be of type Lire::FilterSpec (not $filter_spec)" )
      unless UNIVERSAL::isa( $filter_spec, 'Lire::FilterSpec' );

    # Make sure all the report's schema are compatible
    # with with this filter
    my $schema = $filter_spec->schema->id;
    foreach my $r ( $self->reports ) {
	die "filter ", $filter_spec->id, "'s schema is incompatible ",
	  "with report ", $r->id, "\n"
	    unless $r->schema->is_schema_compatible( $schema );
    }
    push @{$self->{filters}},$filter_spec;
}

=pod 

=head2 reports()

Returns this section's report specifications as an array of
Lire::ReportSpec objects.

=cut

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

    return @{ $self->{reports} };
}

=pod 

=head2 add_report( $report_spec )

Adds the $report_spec report specification to this section. This
method will die if the report specification's schema isn't compatible
with this section's superservice.

=cut

sub add_report {
    my ( $self, $report ) = @_;

    croak "report must of type Lire::ReportSpec (not $report)"
      unless UNIVERSAL::isa( $report, "Lire::ReportSpec" );

    croak ( "report is of wrong superservice: ", $report->superservice ,
	    " != ", $self->superservice )
      if $self->superservice ne $report->superservice;

    # Make sure the report's schema is compatible
    # with all the filters' schema
    my $schema = $report->schema;
    foreach my $f ( $self->filters ) {
	die "report ", $report->id, "'s schema is incompatible with filter ",
	  $f->id, "\n"
	    unless $schema->is_schema_compatible( $f->schema->id );
    }
    push @{$self->{reports}},$report;
}

sub create_report_section {
    my ( $self, $report ) = @_;

    my $section = new Lire::Report::Section( $self->title );
    $report->add_section( $section );

    if ( $self->filters ) {
	my $desc = "<para>";
	if ( $self->filters == 1 ) {
	    my ($f) = $self->filters;
	    $desc .= "Applied filter in this section: " . 
	      $f->expanded_display_title;
	} else {
	    $desc .= "Filters applied in this section:\n" .
	      qq! <itemizedlist spacing="compact">\n!;

	    foreach my $filter ( $self->filters ) {
		$desc .= " <listitem>\n  <para>" .
		  $filter->expanded_display_title . "</para>\n </listitem>\n";
	    }
	    $desc .= " </itemizedlist>\n";
	}
	$desc .= "</para>\n";
	$section->description( undef, $desc );
    }

    foreach my $spec ( $self->reports ) {
	my $subreport = $spec->create_subreport( $report );
	$section->add_subreport( $subreport );
    }

    return $section;
}

# keep perl happy
1;

__END__

=pod

=head1 SEE ALSO

Lire::ReportConfig(3pm) Lire::ReportSpec(3pm) Lire::FilterSpec(3pm)
Lire::Report::Section(3pm)

=head1 VERSION

$Id: ReportSection.pm,v 1.5 2002/05/21 18:25:41 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
