package Lire::ReportParser::AsciiWriter;

use strict;

use vars qw/ $VERSION @ISA /;

use Lire::ReportParser::DocBookFormatter;

use Lire::Program qw/ :msg /;
use Text::Wrap qw/ wrap /;

BEGIN {
    ($VERSION)	= '$Revision: 1.24 $' =~ m!Revision: ([.\d]+)!;
    @ISA = qw/ Lire::ReportParser::DocBookFormatter /;
}

sub new {
    my $proto = shift;
    my $class = ref $proto || $proto;
    my $self  = $class->SUPER::new( @_ );

    my %args = @_;
    $self->{columns}	    = $args{columns} || 72;
    $self->{max_name_len}   = $args{max_name_length} || 180;
    $self->{max_line_len}   = $args{max_line_length} || 64;
    $self;
}

sub report_start {
    my $self = shift;
    $self->SUPER::report_start( @_ );
    $self->{print_timespan} = 1;
}

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

    if ( $self->{print_timespan} ) {
	my $date = $self->current_date;
	my $timespan = $self->current_timespan;

	print "Report generated: ", $date->{date}, "\n"
	  if $date;
	if ( $timespan ) {
	    print "Reporting on period:\n";
	    print $timespan->{timespan}, "\n\n";
	}

	$self->{print_timespan} = 0;
    }
}

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

    # Trim the title
    $title =~ s/^\s*//;
    $title =~ s/\s*$//;
    if ($self->in_element( "lire:section" ) ) {
	# Section's title
	my $len = length $title;
	if ( $len > $self->{columns} - 12 ) {
	    local $Text::Wrap::columns = $self->{columns} - 12;
	    print wrap( "    ", "    ", $title ), "\n";
	    print "    ", "-" x ($self->{columns} - 12), "\n\n";
	} else {
	    my $pad = int( ($self->{columns} - $len) / 2);
	    print ' ' x $pad, $title, "\n", ' ' x $pad, '-' x $len, "\n\n";
	}
    } else {
	local $Text::Wrap::columns = $self->{columns} - 12;
	print wrap( "  ", "  ", $title ), "\n\n";
    }
}

sub section_end {
    my ( $self ) = shift;

    print "  No subreports were generated for this section.\n\n"
      if ( ! $self->current_section_subreport_count);

    $self->SUPER::section_end( @_ );
}

sub subreport_start {
    my ( $self ) = shift;

    $self->SUPER::subreport_start( @_ );
    $self->{printed_description} = 0;
}

sub subreport_end {
    my ( $self ) = shift;

    $self->SUPER::subreport_end( @_ );
    print "\n";
}

sub table_end {
    my ( $self ) = shift;

    print "  No content in report.\n" if ( ! $self->current_table_entry_count);

    $self->SUPER::table_end( @_ );

    # Reset
    $self->{extra_nl} = 0;
}

sub group_start {
    my $self = shift;

    $self->SUPER::group_start( @_ );

    # Unnecessary when a subgroup is started
    $self->{extra_nl} = 0;
}

sub entry_start {
    my ( $self ) = shift;

    # Output newline when multiple names were printed
    # in the last entry
    print "\n" if $self->{extra_nl};
    $self->SUPER::entry_start( @_ );
    $self->{last_name} = [];
    $self->{extra_nl} = 0;
}

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

    push @{$self->{last_name}}, $name->{content};
}

sub print_long_name {
    my ( $pre, $name, $value, $crop_len ) = @_;

    my $rest = undef;
    if ( length $name > $crop_len ) {
	my $cropped_name = substr( $name, 0, $crop_len - 1 ) . "\\";
	print $pre, " ", $cropped_name;
	$rest = substr( $name, $crop_len - 1 );
    } else {
	print $pre, " ", sprintf( "%-${crop_len}s", $name );
    }
    print " ", $value if defined $value;
    print "\n";

    $pre .= "  " if defined $value; # First line
    print_long_name( $pre, $rest, undef, $crop_len - 3 )
      if defined $rest;
}

# FIXME: Doesn't handle multiple values.
sub handle_value {
    my ( $self, $value_rec ) = @_;

    my $value = $value_rec->{content};
    my $names = $self->{last_name};
    my $max_name_len = 0;
    for  ( my $i=0; $i < @$names; $i++ ) {
	my $name = $names->[$i];

	# Crop names longer than MAX_NAME_LENGTH
	if ( length $name > $self->{max_name_len} ) {
	    $name = $names->[$i]  =
	      substr( $name, 0, $self->{max_name_len} ) . "[...]"
	}

	$max_name_len = length $name
	  if length $name > $max_name_len;
    }
    my $level = $self->current_group_level();

    my $pre = "  " x ($level + 1);
    if ( length($pre) + $max_name_len + length($value) + 3
	 > $self->{max_line_len})
    {
	my $crop_len = $self->{max_line_len} -
	  (2 + length($pre) + length($value) );

	print_long_name( $pre, $names->[0], $value, $crop_len );
	if ( @$names > 1 ) {
	    foreach my $name (@{$names}[1..$#$names]) {
		print_long_name( $pre, $name, undef, $crop_len );
	    }
	    $self->{extra_nl} = 1;
	}
    } else {
	my $dots = ($level > 0 || length $value == 0 ) ? " " : ".";
	$dots x= $self->{max_line_len} - ( $max_name_len + length($value) +
					   length($pre) + 3 );

	print $pre, " ", sprintf( "%-${max_name_len}s", $names->[0]),
	  " ",  $dots, " ",  $value, "\n";
	if ( @$names > 1 ) {
	    foreach my $name (@{$names}[1..$#$names]) {
		print $pre, " ", sprintf( "%-${max_name_len}s", $name), "\n";
	    }
	    $self->{extra_nl} = 1;
	}
    }

}

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

    print $description;
}

# keep perl happy
1;

__END__

=pod

=head1 NAME

Lire::ReportParser::AsciiWriter - Lire::ReportParser processor that formats the report in ASCII

=head1 SYNOPSIS

    use Lire::ReportParser::AsciiWriter;

    my $parser = new Lire::ReportParser::AsciiWriter;

    eval { $parser->parsefile( "report.xml" ) };
    print "Parse failed: $@" if $@;

=head1 DESCRIPTION

This is a Lire::ReportParser processor which will print the Lire XML
Report in ASCII on STDOUT.

Its constructor takes the following parameters:

=over 4

=item columns

The number of columsn for which the report should be formatted. Defaults
to 72.

=item max_name_length

The maximum number of characters that will be kept in name element.
Defaults to 180.

=item max_line_length

The maximum number of characters to have one a single line. Defaults
to 64.

=item target-user

Audience for which the description should be printed. Defaults to
C<sysadmin>.

=item userlevel

In description, the maximum level of elements that will be displayed.
Defaults to C<normal> (i.e. C<advanced> elements aren't formatted.

=back

=head1 SEE ALSO

Lire::ReportParser(3pm) Lire::DocBookFormatter(3pm)

=head1 VERSION

$Id: AsciiWriter.pm,v 1.24 2002/07/28 19:29:17 flacoste Exp $

=head1 COPYRIGHT

Copyright (C) 2001-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
