=head1 NAME

  CFX5::ChangeLog - Object representing a file change-log

=head1 SYNOPSIS

=head1 DESCRIPTION

$Id$

=cut

package CFX5::ChangeLog;

use strict;
use CFX5::DefFile;
use CFX5::Simulation::Util qw (GetDataSet);
use CFX5::FileStat;
use CFX5::Output qw(:all);
use CFX5::TimeDate qw(timedatestamp);

=head2 new

  my $changelog = CFX5::ChangeLog->new($filename,'FRED/CHANGELOG');

Constructor. Creates a new ChangeLog object.
If a file is specified, the new object is initialized from it.
The dataset signature specified (in whole or part) will be used.

=cut

sub new
{
  my $this = shift;
  my $class = ref($this) || $this;
  my $self = {
               changelog  => undef,
               maxentries => 512,
               what       => 'G/CHANGELOG',
               where      => 'EVERY',
               when       => 0,
	     };
  bless $self, $class;

  my $filename = shift;

  for my $key (qw(what where when))
  {
    $self->{$key} = shift if (@_);
  }

  if (defined $filename) { $self->ReadFromFile($filename) }

  return $self;
}

=head2 ReadFromFile

  $changelog->ReadFromFile($filename);

Read log entries from specified file

=cut

sub ReadFromFile
{
  my $self = shift;
  my $filename = shift;

  my @entries = GetDataSet($filename, $self->{what}, $self->{where}, $self->{when});

  for my $entry (@entries)
  {
    $self->AddEntry($entry);
  }

  return 1;
}

=head2 WriteToFile

  $changelog->WriteToFile($filename);

Write log entries to specified file

=cut

sub WriteToFile
{
  my $self = shift;
  my $filename = shift;

  my $ds = new CFX5::DefFile::DataSet();

  $ds->header(what     => $self->{what});
  $ds->header(where    => $self->{where});
  $ds->header(when     => $self->{when});
  $ds->header(number   => scalar(@{$self->{changelog}}));
  $ds->header(datatype => "STRI");

  $ds->data(@{$self->{changelog}});

  unless (CFX5::FileStat::test_e $filename)
  {
    _error("WriteToFile failed - file does not exist");
    return 0;
  }

  my $io = CFX5::DefFile->new($filename);

  unless ($io->write_dataset($ds))
  {
    _error("WriteToFile failed - dataset write filed");
    return 0;
  }

  return 1;
}

=head2 show

  $changelog->show();

Print log contents to standard output

=cut

sub show
{
  my $self = shift;

  printf "\nContents of change log:\n";
  printf "No.      HH:MM:SS    DD MMM YYYY   Action performed\n";

  my $i = 0;
  for my $entry (@{$self->{changelog}})
  {
    $i++;
    printf "%3d : %s\n", $i, $entry;
  }
}

=head2 AddEntry

  $changelog->AddEntry($entry);

Add entry to log. Do not allow the log to grow beyond maxentries.

=cut

sub AddEntry
{
  my $self = shift;
  my $entry = shift;

  if ($entry)
  {
    push @{$self->{changelog}}, $entry;
    my $nentry = scalar(@{$self->{changelog}});
    if ($nentry > $self->{maxentries})
    {
      splice(@{$self->{changelog}},0,$nentry-$self->{maxentries});
    }
  }
}

=head2 AddDatedEntry

  $changelog->AddDatedEntry($entry);

Add entry to log with date time prepended.

=cut

sub AddDatedEntry
{
  my $self = shift;
  my $entry = shift;

  my $tdstamp = timedatestamp();
  $self->AddEntry(sprintf "%s : %s",$tdstamp,$entry);
}

1;
