#!/usr/local/bin/perl

eval 'exec /usr/local/bin/perl  -S $0 ${1+"$@"}'
  if 0;    # not running under some shell

use strict;
local $^W = 1;

use Getopt::Std;
use lib ( qw| ./blib ./blib/lib | );
use ExtUtils::ModuleMaker;
use ExtUtils::ModuleMaker::Licenses::Standard;
use ExtUtils::ModuleMaker::Licenses::Local;

use Data::Dumper;

use vars qw (%opts $VERSION %destinations %messages);

$VERSION = 0.33;

########## BEGIN DECLARATIONS ##########

#!#!#!#!#
##   3 ##
my %Author_Menu = (
    N => [ 'Name        ', 'NAME' ],
    C => [ 'CPAN ID     ', 'CPANID' ],
    O => [ 'Organization', 'ORGANIZATION' ],
    W => [ 'Website     ', 'WEBSITE' ],
    E => [ 'Email       ', 'EMAIL' ],
);

#!#!#!#!#
##   5 ##
my %Directives_Menu = (
    C => [ 'Compact        ', 'COMPACT' ],
    P => [ 'Permissions    ', 'PERMISSIONS' ],
    V => [ 'Verbose        ', 'VERBOSE' ],
    D => [ 'Include POD    ', 'NEED_POD' ],
    N => [ 'Include new    ', 'NEED_NEW_METHOD' ],
    H => [ 'History in POD ', 'CHANGES_IN_POD' ],
);

#!#!#!#!#
##   6 ##
my %Flagged =
  ( ( map { $_ => 0 } qw (0 N F) ), ( map { $_ => 1 } qw (1 Y T) ), );

#!#!#!#!#
##   8 ##
my $License_Standard = ExtUtils::ModuleMaker::Licenses::Standard->interact();
my $License_Local    = ExtUtils::ModuleMaker::Licenses::Local->interact();
my @lic              = (
    (
        map { [ $_, $License_Standard->{$_} ] }
          sort { $License_Standard->{$a} cmp $License_Standard->{$b} }
          keys( %{$License_Standard} )
    ),
    (
        map { [ $_, $License_Local->{$_} ] }
          sort { $License_Standard->{$a} cmp $License_Standard->{$b} }
          keys( %{$License_Local} )
    ),
);

#!#!#!#!#
##  11 ##
my %Build_Menu = (
    E => 'ExtUtils::MakeMaker',
    B => 'Module::Build',
    P => 'Module::Build and proxy Makefile.PL',
);

#!#!#!#!#
##  17 ##
%destinations = (
    'Main Menu' => {
        A => 'Author Menu',
        L => 'License Menu',
        D => 'Directives_Menu',
        B => 'Build Menu',
        Q => 'done',
    },
    'Author Menu' => {
        R => 'Main Menu',
        Q => 'done',
    },
    Directives_Menu => {
        R => 'Main Menu',
        Q => 'done',
    },
    'License Menu' => {
        C => 'Copyright_Display',
        L => 'License_Display',
        R => 'Main Menu',
        Q => 'done',
        P => 'License Menu',
    },
    'Build Menu' => {
        R => 'Main Menu',
        Q => 'done',
    },
);

#!#!#!#!#
##  18 ##
%messages = (

    #---------------------------------------------------------------------

    'Main Menu' => <<EOF,
modulemaker: Main Menu

    Feature              Current Value
N - Name of module       '##name##'
S - Abstract             '##abstract##'
A - Author information
L - License              '##license##'
D - Directives
B - Build system         '##build##'
G - Generate module

Q - Quit program

Please choose which feature you would like to edit: 
EOF
    #---------------------------------------------------------------------

    'Author Menu' => <<EOF,
modulemaker: Author Menu

    Feature       Current Value
##Data Here##

R - Return to main menu

Please choose which feature you would like to edit:
EOF

    #---------------------------------------------------------------------

    Directives_Menu => <<EOF,
modulemaker: Directives Menu

    Feature           Current Value
##Data Here##

R - Return to main menu

Please choose which feature you would like to edit:
EOF

    #---------------------------------------------------------------------

    'License Menu' => <<EOF,
modulemaker: License Menu

ModuleMaker provides many licenes to choose from, many of them approved by opensource.org.

        License Name
##Licenses Here##

# - Enter the number of the license you want to use
C - Display the Copyright
L - Display the License
R - Return to main menu

Please choose which license you would like to use:
EOF

    #---------------------------------------------------------------------

    License_Display => <<EOF,
Here is the current license:

##License Here##

C - Display the Copyright
L - Display the License
P - Pick a different license
R - Return to main menu

Please choose which license you would like to use:
EOF

    #---------------------------------------------------------------------

    Copyright_Display => <<EOF,
Here is the current copyright:

##Copyright Here##

C - Display the Copyright
L - Display the License
P - Pick a different license
R - Return to main menu

Please choose which license you would like to use:
EOF

    #---------------------------------------------------------------------

    Build_Menu => <<EOF,
Here is the current build system:

##Build Here##

E - ExtUtils::MakeMaker
B - Module::Build
P - Module::Build and proxy Makefile.PL
R - Return to main menu

Please choose which build system you would like to use:
EOF

    #---------------------------------------------------------------------
);

########## END DECLARATIONS ##########

########## BEGIN STATEMENTS ##########

#!#!#!#!#
##  19 ##
getopts( "bdhCIPVcn:a:v:l:u:p:o:w:e:", \%opts );
die Usage() if ( $opts{h} );

my $where = 'Main Menu';
my $MOD   = ExtUtils::ModuleMaker->new(
    COMPACT        => ( ( $opts{c} ) ? 1 : 0 ),
    VERBOSE        => ( ( $opts{V} ) ? 1 : 0 ),
    CHANGES_IN_POD => ( ( $opts{C} ) ? 1 : 0 ),
    NEED_POD       => ( ( $opts{P} ) ? 0 : 1 ),
    INTERACTIVE    => ( ( $opts{I} ) ? 0 : 1 ),
    ( ( $opts{n} ) ? ( NAME         => $opts{n} ) : () ),
    ( ( $opts{a} ) ? ( ABSTRACT     => $opts{a} ) : () ),
    ( ( $opts{b} ) ? ( BUILD_SYSTEM => $opts{b} ) : () ),
    ( ( $opts{v} ) ? ( VERSION      => $opts{v} ) : () ),
    ( ( $opts{l} ) ? ( LICENSE      => $opts{l} ) : () ),
    ( ( $opts{u} ) ? ( AUTHOR       => { NAME         => $opts{u} } ) : () ),
    ( ( $opts{p} ) ? ( AUTHOR       => { CPANID       => $opts{p} } ) : () ),
    ( ( $opts{o} ) ? ( AUTHOR       => { ORGANIZATION => $opts{o} } ) : () ),
    ( ( $opts{w} ) ? ( AUTHOR       => { WEBSITE      => $opts{w} } ) : () ),
    ( ( $opts{e} ) ? ( AUTHOR       => { EMAIL        => $opts{e} } ) : () ),
    USAGE_MESSAGE => Usage(),
);

if ( $MOD->{INTERACTIVE} ) {
    while () {
        if ( $where eq 'done' ) {
            last;
        } elsif ( $where eq 'Module Name' ) {
        } elsif ( $where eq 'Abstract' ) {
        } elsif ( $where eq 'Main Menu' ) {
            $where = Main_Menu($MOD);
        } elsif ( $where eq 'License Menu' ) {
            $where = License_Menu($MOD);
        } elsif ( $where eq 'Author Menu' ) {
            $where = Author_Menu($MOD);
        } elsif ( $where eq 'License_Display' ) {
            $where = License_Display($MOD);
        } elsif ( $where eq 'Copyright_Display' ) {
            $where = Copyright_Display($MOD);
        } elsif ( $where eq 'Directives_Menu' ) {
            $where = Directives_Menu($MOD);
        } elsif ( $where eq 'Build Menu' ) {
            $where = Build_Menu($MOD);
        } else {
            $where = Main_Menu($MOD);
        }
    }
}
else {
    $MOD->complete_build();
}

print "\n------------------------\n\nGood bye.\n\n";

########## END STATEMENTS ##########

########## BEGIN SUBROUTINES ##########

#!#!#!#!#
##   2 ##
sub Main_Menu {
    my $MOD = shift;

    my $string = $messages{'Main Menu'};
    defined $MOD->{NAME} 
	? $string =~ s|##name##|$MOD->{NAME}|
	: $string =~ s|##name##||;
    $string =~ s|##abstract##|$MOD->{ABSTRACT}|;
    $string =~ s|##license##|$MOD->{LICENSE}|;
    $string =~ s|##build##|$MOD->{BUILD_SYSTEM}|;

    my $response = Question_User( $string, 'menu' );

    return ( $destinations{'Main Menu'}{$response} )
      if ( exists $destinations{'Main Menu'}{$response} );

    if ( $response eq 'G' ) {
          $MOD->{AUTHOR}{COMPOSITE} =
              "\t"
               . join( "\n\t",
                  $MOD->{AUTHOR}{NAME},
                  ( $MOD->{AUTHOR}{CPANID} ) ? "CPAN ID: $MOD->{AUTHOR}{CPANID}" : (),
                  ( $MOD->{AUTHOR}{ORGANIZATION} ) ? "$MOD->{AUTHOR}{ORGANIZATION}" : (),
                  $MOD->{AUTHOR}{EMAIL}, $MOD->{AUTHOR}{WEBSITE},
          );
        $MOD->complete_build();
        print "Module files generated\n";
    }
    elsif ( $response eq 'N' ) {
        my $value =
          Question_User( "Please enter a new value for Primary Module Name",
            'data' );
        $MOD->{NAME} = $value;
    }
    elsif ( $response eq 'S' ) {
        my $value =
          Question_User( "Please enter a 44-character max Abstract for this extension",
            'data' );
        $MOD->{ABSTRACT} = $value;
    }
    elsif ( $response eq 'V' ) {
        $MOD->verify_values();
        print "Module verification done\n";
    }
    return ('Main Menu');
}

#!#!#!#!#
##   4 ##
sub Author_Menu {
    my $MOD = shift;

    my $string = $messages{'Author Menu'};
    my $stuff  = join(
        "\n",
        map {
            "$_ - $Author_Menu{$_}[0]  '"
              . $MOD->{AUTHOR}{ $Author_Menu{$_}[1] } . "'"
          } qw (N C O W E)
    );
    $string =~ s|##Data Here##|$stuff|;

    my $response = Question_User( $string, 'menu' );
    return ( $destinations{'Author Menu'}{$response} )
      if ( exists $destinations{'Author Menu'}{$response} );
    return ('Author Menu') unless ( exists( $Author_Menu{$response} ) );

    my $value =
      Question_User( "Please enter a new value for $Author_Menu{$response}[0]",
        'data' );
    $MOD->{AUTHOR}{ $Author_Menu{$response}[1] } = $value;

    return ('Author Menu');
}

#!#!#!#!#
##   7 ##
sub Directives_Menu {
    my $MOD = shift;

    my $string = $messages{Directives_Menu};
    my $stuff  = join(
        "\n",
        (
            map {
                "$_ - $Directives_Menu{$_}[0]  '"
                  . $MOD->{ $Directives_Menu{$_}[1] } . "'"
              } qw (C V D N H)
        ),
        "P - $Directives_Menu{P}[0]  '"
          . sprintf(
            "%04o - %d",
            $MOD->{ $Directives_Menu{P}[1] },
            $MOD->{ $Directives_Menu{P}[1] }
          )
          . "'",
    );
    $string =~ s|##Data Here##|$stuff|;

    my $response = Question_User( $string, 'menu' );
    return ( $destinations{Directives_Menu}{$response} )
      if ( exists $destinations{Directives_Menu}{$response} );
    return ('Directives_Menu') unless ( exists( $Directives_Menu{$response} ) );

    if ( $response eq 'P' ) {
        my $value =
          Question_User(
            "Please enter a new value for $Directives_Menu{$response}[0]",
            'data' );
        $value = oct($value) if ( $value =~ /^0/ );
        $MOD->{ $Directives_Menu{$response}[1] } = $value if ( $value <= 0777 );
    }
    else {
        my $value = Question_User(
            "Please enter a new value for $Directives_Menu{$response}[0],"
              . " (0,No,False  || 1,Yes,True)",
            'menu'
        );
        $value = $Flagged{$value};
        $MOD->{ $Directives_Menu{$response}[1] } = $Flagged{$value}
          if ( exists $Flagged{$value} );
    }

    return ('Directives_Menu');
}

#!#!#!#!#
##   9 ##
sub License_Menu {
    my $MOD = shift;

    my $string   = $messages{'License Menu'};
    my $ct       = 1;
    my $licenses = join(
        "\n",
        map {
                $ct++ . ( ( $MOD->{LICENSE} eq $_->[0] ) ? '***' : '' ) . "\t"
              . $_->[1]
          } @lic
    );
    $string =~ s|##Licenses Here##|$licenses|;

    my $response = Question_User( $string, 'license', scalar(@lic) );
    return ( $destinations{'License Menu'}{$response} )
      if ( exists $destinations{'License Menu'}{$response} );

    if ( $lic[ $response - 1 ] ) {
        $MOD->{LICENSE} = $lic[ $response - 1 ][0];
    }
    $MOD->initialize_license();

    return ('License Menu');
}

#!#!#!#!#
##  10 ##
sub License_Display {
    my $MOD = shift;

    my $string = $messages{License_Display};
    $string =~ s|##License Here##|$MOD->{LicenseParts}{LICENSETEXT}|;

    my $response = Question_User( $string, 'menu' );
    return ( $destinations{'License Menu'}{$response} )
      if ( exists $destinations{'License Menu'}{$response} );
    return ('License Menu');
}

#!#!#!#!#
##  12 ##
sub Build_Menu {
    my $MOD = shift;

    my $string = $messages{Build_Menu};
    $string =~ s|##Build Here##|$MOD->{BUILD_SYSTEM}|;

    my $response = Question_User( $string, 'menu' );
    return ( $destinations{'Build Menu'}{$response} )
      if ( exists $destinations{'Build Menu'}{$response} );

    $MOD->{BUILD_SYSTEM} = $Build_Menu{$response}
      if exists $Build_Menu{$response};

    return ('Build Menu');
}

#!#!#!#!#
##  13 ##
sub Copyright_Display {
    my $MOD = shift;

    my $string = $messages{Copyright_Display};
    $string =~ s|##Copyright Here##|$MOD->{LicenseParts}{COPYRIGHT}|;

    my $response = Question_User( $string, 'menu' );
    return ( $destinations{'License Menu'}{$response} )
      if ( exists $destinations{'License Menu'}{$response} );
    return ('License Menu');
}

#!#!#!#!#
##  14 ##
sub Question_User {
    my ( $question, $flavor, $feature ) = @_;

    print "\n------------------------\n\n", $question, "\n";
    my $answer = <>;

    if ( $flavor eq 'menu' ) {
        $answer =~ m/^(.)/;
        $answer = uc($1);
    }
    elsif ( $flavor eq 'data' ) {
        chomp($answer);
    }
    elsif ( $flavor eq 'license' ) {
        chomp($answer);
        unless ( $answer =~ m/^\d+/ ) {
            $answer =~ m/^(.)/;
            $answer = uc($1);
        }
        elsif ( ( $answer < 1 ) || ( $feature < $answer ) ) {
            $answer = 'P';
        }
    }

    print "You entered '$answer'\n";
    return ($answer);
}

#!#!#!#!#
##  16 ##
sub Usage {
    my $message = <<ENDOFUSAGE;
modulemaker [-CIPVch] [-v version] [-n module_name] [-a abstract]
        [-u author_name] [-p author_CPAN_ID] [-o organization]
        [-w author_website] [-e author_e-mail]
        [-l license_name] [-b build_system]

Currently Supported Features
    -a   Specify (in quotes) an abstract for this extension
    -b   Specify a build system for this extension
    -c   Flag for compact base directory name
    -C   Omit creating the Changes file, add HISTORY heading to stub POD
    -e   Specify author's e-mail address
    -h   Display this help message
    -I   Disable INTERACTIVE mode, the command line arguments better be complete
    -l   Specify a license for this extension
    -n   Specify a name to use for the extension (required)
    -o   Specify (in quotes) author's organization
    -p   Specify author's CPAN ID
    -P   Omit the stub POD section
    -u   Specify (in quotes) author's name
    -v   Specify a version number for this extension
    -V   Flag for verbose messages during module creation
    -w   Specify author's web site

modulemaker version: $VERSION
ExtUtils::ModuleMaker version: $ExtUtils::ModuleMaker::VERSION
ENDOFUSAGE

    return ($message);
}

########## END SUBROUTINES ##########

################### DOCUMENTATION ################### 

#!#!#!#!#
##   1 ##

=head1 NAME

modulemaker - interactive interface to ExtUtils::ModuleMaker

=head1 USAGE

=head2 Easy

At the command-prompt, simply call:

    % modulemaker

... and answer each question.

=head2 Not So Easy, But More Geeky

At the command-prompt, call C<modulemaker> with as many options as you can type correctly:

    modulemaker [-CIPVch] [-v version] [-n module_name] [-a abstract]
        [-u author_name] [-p author_CPAN_ID] [-o organization]
        [-w author_website] [-e author_e-mail]
        [-l license_name] [-b build_system]

Currently Supported Features

=over 4

=item * -a

Specify (in quotes) an abstract for this extension

=item * -b

Specify a build system for this extension

=item * -c

Flag for compact base directory name

=item * -C

Omit creating the Changes file, add HISTORY heading to stub POD

=item * -e

Specify author's e-mail address

=item * -h

Display this help message

=item * -I

Disable INTERACTIVE mode, the command line arguments better be complete

=item * -l

Specify a license for this extension

=item * -n

Specify a name to use for the extension (required)

=item * -o

Specify (in quotes) author's organization

=item * -p

Specify author's CPAN ID

=item * -P

Omit the stub POD section

=item * -u

Specify (in quotes) author's name

=item * -v

Specify a version number for this extension

=item * -V

Flag for verbose messages during module creation

=item * -w

Specify author's web site

=back

=head1 AUTHOR

ExtUtils::ModuleMaker was originally written in 2001-02 by R. Geoffrey Avery
(modulemaker [at] PlatypiVentures [dot] com).  Since version 0.33 (July
2005) it has been maintained by James E. Keenan (jkeenan [at] cpan [dot]
org).

=head1 COPYRIGHT

Copyright (c) 2001-2002 R. Geoffrey Avery. All rights reserved.
This program is free software; you can redistribute
it and/or modify it under the same terms as Perl itself.

The full text of the license can be found in the
LICENSE file included with this module.

=head1 SEE ALSO

F<ExtUtils::ModuleMaker>, F<perlnewmod>, F<h2xs>, F<ExtUtils::MakeMaker>.

=cut

