=head1 NAME

CFX5::Output::MeshStyle - output in the format used by the meshers

=head1 SYNOPSIS

  use CFX5::Output;

=head1 DESCRIPTION

The C<CFX5::Output::MeshStyle> class is an alternative output class
for CFX-5 perl scripts using L<CFX5::Output>.

=cut

package CFX5::Output::MeshStyle;
@ISA=qw(CFX5::Output::Terminal);
use strict;

use CFX5::Output::Terminal;

use CFX5::ExitRoutines;

=head2 STANDARD METHODS

=head3 init

The C<init> routine here reads the C<CFX_OUTPUT> environment variable,
and uses it to set up the list of output types to process or ignore.

=cut

sub init {
  my $self=shift;
  my $rv=$self->SUPER::init(@_);

  print qq(CFX_PROGRAM_START "$CFX5::Output::Prog"\n);

  CFX5::ExitRoutines::push_tidyup(sub { $self->program_exit(@_); });

  return $rv;
}

sub program_exit {
  my $self=shift;
  my $is_fail=shift;

  my $succfail=($is_fail ? 'FAILURE' : 'SUCCESS');

  print qq(CFX_PROGRAM_END $succfail "$CFX5::Output::Prog"\n);

  1;
}

=head3 output

This version of the C<output> function uses the on/off settings from
C<set_verbosity> to decide whether to output a given message or not.
Word wrapping is done to the value of the configuration record
C<CFX5_TERMINAL_WIDTH>, or 75 by default; verbatim lines (such as
filenames) are not wrapped.

=cut

sub output {
  my $self=shift;
  my $type=shift;
  my $severity=shift;
  my $title=shift;
  my $text=join('',@_);

  $self->internal_error("Unknown output type $type") 
    unless exists $self->{settings}{$type};
  
  return unless $self->{settings}{$type};

  my %typestring=(
                  internal => 'INTERNAL',
                  abort => 'FATAL',
                  error => 'ERROR',
                  warn => 'WARNING'
                 );
  if ($typestring{$type}) {
    my $routine=$self->caller_sum(1);
    print <<"EOF";
CFX_ERROR_START $typestring{$type}
CFX_ERROR_PROGRAM "$CFX5::Output::Prog"
CFX_ERROR_SUBROUTINE "$routine"
EOF
    print $self->text_to_show($title,$text);
    print "CFX_ERROR_END\n";
  } else {
    # if it's not one we can signal through Richard's error format,
    # just delegate to the standard output style
    return $self->SUPER::output($type, $severity, $title, $text);
  }

  return 1;
}

sub call_level() {
  $_[0]->SUPER::call_level() + 1;
}

=head2 CUSTOM METHODS

=head3 set_verbosity

C<set_verbosity> determines which messages are displayed to the screen
during a run. It should be called with one or more arguments, from the
following list:

=over

=item warn

Warnings. These are displayed by default.

=item info

Informational messages, displayed by L<_note> and L<_info>. These are
off by default, but should be switched on if the configuration
variable C<VERBOSE> is set.

=item moreinfo

This does not correspond to a function, but is used by some other
modules. It's meaning, roughly, is that where a script would normally
give output when C<info> is set, that output should be made more complete.

=item trace

Display a trace of program execution, including when new processes are
spawned or large functions invoked. This is off by default.

=item debug

Display any other information which the programmer thought might be
useful for debugging. This is off by default.

=item noI<keyword>

Turn off I<keyword>

=back

The verbosity is initialised from the environment variable CFX_OUTPUT
when the program starts.

=cut '

sub set_verbosity {
  my $self=shift;
  my $p;
  for $p (map { split(/[, ]/) } @_) {
    my $val=1;
    if ($p =~ m/^no(.*)/) {
      $p=$1;
      $val=0;
    }
    $self->warn("Setting unrecognised output parameter $p")
      unless exists $self->{settings}{$p};
    $self->{settings}{$p}=$val;
  }
}

=head3 query_verbosity

  if (query_verbosity('moreinfo')) {
    _info("This is some more info");
  }

Returns TRUE if the requested level is set, or FALSE (0)
otherwise. Note that queries of the "noI<level>" forms are not
allowed.

If the requested level is not known, returns undef.

=cut

sub query_verbosity {
  my $self=shift;
  my $level=shift;
  return $self->{settings}{$level};
}


1;
