The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#perl -MFile::Slurp -MXML::Simple -MData::Dumper -e'print scalar Dumper ( XMLin( read_file(shift @ARGV).""))' 

use warnings;
use strict;
use Term::ANSIScreen;
use Text::Autoformat;
use YAML;
use File::Slurp;
use XML::Simple;
use Term::ReadKey;
use Data::Dumper;
         use File::Temp qw/ tempfile tempdir /;
my @tags = qw(doc install core plugin security view t-discard backward-compatiblity-problem u-pubsub r-crud e-testing);

my %tags = map { substr($_,0,1) => $_ } @tags;
my $mode = shift @ARGV;
my ($source,$dest);
if ($mode eq '--generate') {
     $source = shift @ARGV;
     $dest = shift @ARGV;

}
elsif ($mode eq '--edit') {
     $source = shift @ARGV;
     $dest = shift @ARGV;

}

unless ($source && -f $source && $dest) { die "$0 --generate SOURCEFILE DESTFILE\n or \n$0 --edit SOURCEFILE DESTFILE" }


my $data = XMLin(read_file($source)."");


if ($mode eq '--edit') {

foreach my $entry (@{$data->{'logentry'}}) {
   my %entries; 
    foreach my $entry (@{$data->{'logentry'}}) {
        push @{$entries{$entry->{section}||'uncategorized'}}, $entry;
    }
    foreach my $key ( keys %entries) {
        foreach my $entry (@{$entries{$key}}){ 
    act_on($entry);
    }
    }
}

    do_quit();
} elsif ($mode eq '--generate') {
   my %entries; 
    foreach my $entry (@{$data->{'logentry'}}) {
        push @{$entries{$entry->{section}||'uncategorized'}}, $entry;
    }

    foreach my $key ( keys %entries) {
    my $title = $key;
    $title =~ s/^\w\-//;
        print uc($key)."\n";
        print "=" x length($key) ;
        print "\n\n";

        foreach my $entry (@{$entries{$key}}){ 

        format_entry($entry) ;
        print "\n";
        }
    }

}

sub act_on {
    my $entry = shift;

    my $console = Term::ANSIScreen->new;
    while (1) {
    my $command = '';
    while (!$command) {
        $console->Cls;
            $console->Cursor(1,1);


        if (!$entry->{'edited_msg'} && ref($entry->{msg})) { $entry->{'edited_msg'} = Dumper($entry->{'msg'}); }
        format_entry ($entry => 1);
    
    
        my $in = getchar();


        if ($in eq 's') {
            return;
        } 
        elsif ($in eq 'c') { $command = 'chomp'; }
        elsif ($in eq 'e') { $command = 'edit'; }
        elsif ($in eq 'q') { $command = 'quit'; }
        elsif ($in eq 't') { $command = 'tag' }
        elsif ($in eq ' ') {
            return
        }
    }
    if ($command eq 'tag') {
        tag($entry);
    }
    elsif ( $command eq 'write' ) {
        warn "Writing";
    } elsif ( $command eq 'chomp' ) {
        my $msg = ( $entry->{'edited_msg'} || $entry->{'msg'} );
        my @lines = split( "\n", $msg );
        shift @lines;
        $entry->{'edited_msg'} = join( "\n", @lines );
    } elsif ( $command eq 'edit' ) {
        warn "Chomping";
        my ( $fh, $filename ) = tempfile();
        print $fh ( $entry->{'edited_msg'} || $entry->{'msg'} ) || die $!;
        close $fh;
        system( ( $ENV{EDITOR} || 'vi' ), $filename );
        $entry->{'edited_msg'} = read_file($filename);
    } elsif ($command eq 'quit') {

        do_quit();
    }

    }

}

sub tag {
    my $entry = shift;
    my $tag;
    print "Valid tags are: " . join( ', ', @tags ) . "\n";
    while ( !$tag ) {
        my $key = getchar();
        return if ( $key eq  ' ' );
        print "You picked " . $key . "\n";
        if ( $tags{$key} ) {
            $tag = $tags{$key};
            print "You tagged it $tag\n";
        } else {
            print "NO. THAT IS NOT A VALID TAG\n";

        }
    }
    $entry->{section} = $tag;

}

sub do_quit {
my $out;
    open( $out, ">$dest" );

    print $out XMLout($data,  NoAttr => 1 );
    close($out);
    exit;

}

sub getchar {

    ReadMode 4;
        my $key = ReadKey(0);
            ReadMode 0;

    return $key
            }


sub format_entry {
    my $entry = shift;
    my $verbose = shift ||0; 
        if  ($verbose ) {
      print "r".$entry->{revision}." - ";
      print $entry->{'section'} || "UNCATEGORIZED - HIT 't'";   
      print "\n".("="x60)."\n";
      }

     my $msg = ( $entry->{'edited_msg'} || $entry->{'msg'});

    if ($msg =~ /^[\s\*]*\w/) {
        $msg =~ s/^[\s\*]*/ * /;
    }

        $msg =~  s/\n+$//g;
     $msg .= " - ".$entry->{'author'}."\n";


     $msg =   autoformat ($msg,  { left=>0, right=>78 });
        $msg =~  s/\n+$//g;
      print $msg."\n";
        if  ($verbose ) {

        print YAML::Dump( $entry->{'paths'});
        print "\n";
    }
}