#!/usr/bin/perl -w

use FindBin;
use lib "$FindBin::Bin/..";
use General::FileSystem;
use POSIX;

chdir($FindBin::Bin) || die "Can't chmod $FindBin::Bin: $!\n";

my $functable_src = "../../fvwm/functable.c";
my $content_ref = load_file($functable_src);
die "No commands found, so Commands.pm is not generated.\n" unless $content_ref;

my $command_entries_code = "";
foreach my $entry ($$content_ref =~
	m{(?:/\* )?CMD_ENT\(\s*(?:"|PRE_).*?\),(?: \*/)?.*?/\* .*?- .*? \*/}sg)
{
	my ($name, $flags, $cursor, $name2, $descr) = $entry =~ m{
		,
		.*? CMD_(\w+) ,
		.*? ,
		.*? ([\w\s|]+?) ,
		.*? (?:CRS_)?(\w+)
		.*? \) ,
		.*? /\*\s (?:(.+)\s)? -\s (.*?) \s\*/
	}xs;
	$name = $name2 if $name2;
	my $window = $flags =~ FUNC_NEEDS_WINDOW? 1: 0;
	$cursor = "" if $cursor eq "0";
	$command_entries_code .=
		"\t{\n\t\tname => '$name',\n\t\tcursor => '$cursor',\n" .
		"\t\twindow => $window,\n\t\tdescr => q{$descr},\n\t},\n";
}

my $version = `egrep '^VERSION = |^VERSIONINFO = ' Makefile | cut -d"=" -f2 \\
	| perl -pe 's/^ //;s/\\n//'`;
my $time = time;

my $output = <<ENDOUTPUT;
# Autogenerated from the fvwm sources.

package FVWM::Commands;

use vars qw(\$VERS \$TIME \@LIST);

\$VERS = '$version';
\$TIME = $time;

\@LIST = (
$command_entries_code);

1;

__END__

=head1 NAME

FVWM::Commands - lists all available fvwm commands

=head1 DESCRIPTION

This class is autogenerated from the fvwm sources.

It may be used to get a list of all available fvwm commands including the
command name, its short description and some other command properties.

=head1 USAGE

    use lib `fvwm-perllib dir`;
    use FVWM::Commands;
    use POSIX;

    my \$date = strftime("%d-%b-%Y", gmtime(\$FVWM::Commands::TIME));
    my \$version = \$FVWM::Commands::VERS;
    print "The recognized commands for fvwm \$version as of \$date:\\n\\n";
    foreach my \$command (\@FVWM::Commands::LIST) {
        printf "  %-21s - %s\\n", \$command->{name}, \$command->{descr};
    }

=head1 PUBLIC CONSTANTS

=over 4

=item \$VERS

The fvwm version number at the generation time like "2.6.0" plus the info
that may indicate that this is not a final version, but a cvs snapshot.

=item \$TIME

The unix time of the command list generation.

Example:

    print "The fvwm command list found on your system was generated "
        . (time() - \$FVWM::Commands::TIME) / 86400 . " days ago\\n";

=item \@LIST

The command list that is an array of hashes with keys I<name>, I<cursor>,
I<descr> (string) and I<window> (boolean).

I<name> may be special, like "+", "#" and "*".  Other names usually contain
only isalpha characters, like B<Move>, B<SendToModule>.

I<cursor> may be either empty or the cursor context used in B<CursorStyle>
(like "SELECT" or "MOVE"), associated with the command.

I<descr> is a short one line description of the command.

I<window> is true for commands that need a window.

Example:

    # get command names only
    \@command_names = map { \$_->{name} } \@FVWM::Commands::LIST;

=back

=head1 AUTHOR

Mikhael Goikhman <migo\@homemail.com>.

=head1 SEE ALSO

For more information about the commands themselves, see fvwm(1).

=cut
ENDOUTPUT

# ---------------------------------
print "Creating Commands.pm\n";
save_file("Commands.pm", \$output);

# ---------------------------------
print "Testing  Commands.pm\n";
eval qq{
	use lib '$FindBin::Bin/..';
	use FVWM::Commands;
};
die $@ if $@;
$FVWM::Commands::TIME ||= 0;  # avoid "used once" warning

my $date = strftime("%d-%b-%Y", gmtime($FVWM::Commands::TIME));
my $cmds = "The recognized commands for fvwm $version as of $date:\n\n";
foreach my $command (@FVWM::Commands::LIST = @FVWM::Commands::LIST) {
	$cmds .= sprintf "  %-21s - %s\n", $command->{name}, $command->{descr};
}

# ---------------------------------
print "Creating ../../docs/COMMANDS\n";
save_file("../../docs/COMMANDS", \$cmds);
