#!/usr/bin/perl

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

#
# Do a perl check for version >= 5.005.  See 'gpt-translate-interpreter' should you
# need to alter the invocation path to a valid perl interpreter in the GPT front-end
# programs.
#

if ( ! ( defined eval "require 5.005" ) )
{
    die "GPT requires at least Perl version 5.005";
}

my $gpath = $ENV{GPT_LOCATION};
if (!defined($gpath))
{
  $gpath = $ENV{GLOBUS_LOCATION};

}
if (!defined($gpath))
{
   die "GPT_LOCATION or GLOBUS_LOCATION needs to be set before running this script"
}

@INC = ("$gpath/lib/perl", "$gpath/lib/perl/$Config{'archname'}", @INC);

if ( ! ( defined eval "require Grid::GPT::GPTObject" ) )
{
    die("$gpath does not appear to hold a valid GPT installation\n");
}

require Pod::Usage;

my $help;
my $version;
GetOptions('help' => \$help,'version' => \$version)
  or Pod::Usage::pod2usage(1);

Pod::Usage::pod2usage(0) if $help;
require Grid::GPT::GPTIdentity;
Grid::GPT::GPTIdentity::print_gpt_version() if defined $version;

require Grid::GPT::Widgets::Dependency;
require Grid::GPT::Widgets::Setup;
require Grid::GPT::V1::DependencyIndexes;
require Grid::GPT::Widgets::ManagedHList;
use Tk;
use Tk::Menubutton;
require Tk::BrowseEntry;
require Tk::HList;
require Grid::GPT::V1::Package;
use strict;
use Getopt::Long;

# sub pod2usage {
#   my $ex = shift;
#   print "gpt_edit [-help] [source_metadatafile]\n";
#   exit $ex;
# }


my $srcfile = shift;

my ($name, $major, $minor, $age, $depindexes, $description, $group, $stability);
my $pkg = new Grid::GPT::V1::Package;

my $main = MainWindow->new(-title => "GPT Packaging Metadata");
my $f = $main->Frame(-width => 100)->pack();
my $nf = $f->Frame->pack();
my $nlabel = $nf->Label(-text => "Name:", -justify => 'left')->pack(-side => 'left');
my $n = $nf->Entry( -relief => 'sunken', 
                    -width => 40, 
                    -textvariable => \$name)->pack();
my $def = $f->Frame->pack();
my $delabel = $def->Label(-text => "Description:", -justify => 'left')->pack();
my $de = $def->Entry( -relief => 'sunken', 
                    -width => 100, 
                    -textvariable => \$description)->pack();
my $fgf = $f->Frame->pack();
my $fglabel = $fgf->Label(-text => "Functional Group:", -justify => 'left')->pack();
my $fg = $fgf->Entry( -relief => 'sunken', 
                    -width => 100, 
                    -textvariable => \$group)->pack();
my $verf = $f->Frame->pack();
my $mjlabel = $verf->Label(-text => "Major Version:", 
                           -justify => 'left')->pack(-side => 'left');
my $mj = $verf->Entry( -relief => 'sunken', 
                    -width => 4, 
                    -textvariable => \$major)->pack(-side => 'left');

my $milabel = $verf->Label(-text => "Minor Version:", 
                           -justify => 'left')->pack(-side => 'left');
my $mi = $verf->Entry( -relief => 'sunken', 
                    -width => 4, 
                    -textvariable => \$minor)->pack(-side => 'left');

my $aglabel = $verf->Label(-text => "Version Age:", 
                           -justify => 'left')->pack(-side => 'left');
my $ag = $verf->Entry( -relief => 'sunken', 
                    -width => 4, 
                    -textvariable => \$age)->pack(-side => 'left');

my $vsf = $f->Frame->pack();
my $vslabel = $vsf->Label(-text => "Version Stability:", 
                          -justify => 'left')->pack(side => 'left');
my $p = $vsf->BrowseEntry( -relief => 'sunken', 
                         -width => 16,
                         -choices => ['experimental', 'alpha', 'beta', 'stable'],
                         -textvariable => \$stability)->pack(-side => 'left');

my $vl = $f->Label(-text => "Dependencies")->pack(-side => 'top');

my @dep_headers = ('Name', 'compile', 'pgm_link', 'lib_link', 
                   'data_runtime', 'doc_runtime','pgm_runtime',
                   'lib_runtime');

my $deps_widget = new Grid::GPT::Widgets::ManagedHList(-parent => $f,
                                                       -headers => \@dep_headers,
                                                       -width => 100, 
                                                       -height => 8,
                                                       -edit => sub { edit(0,shift,shift); },
                                                       -fill => \&fill_dep_content,
                                                      );


my $setupf = $f->Frame->pack(-side => 'left');

my $sl = $f->Label(-text => "Needed Setup Packages")->pack(-side => 'top');

my @setup_headers = ('Name', 'Package Type');

my $setup_widget = new Grid::GPT::Widgets::ManagedHList(-headers => \@setup_headers,
                                                        -width => 50, 
                                                        -height => 8,
                                                        -edit => sub { edit(1,shift,shift); },
                                                        -fill => \&fill_setup_content,
                                                        -parent =>$f,
                                                       );
my $b3 = $setupf->Button(-text =>'Add Dependency', -command => sub { $deps_widget->edit(); },
                         -width => 15)->pack();
my $sb3 = $setupf->Button(-text =>'Add Setup Package', -command => sub { $setup_widget->edit(); },
                          -width => 15)->pack();
my $sb2 = $setupf->Button(-text =>'Quit', -command => \&quitme, 
                          -width => 15)->pack();
my $sb1 = $setupf->Button(-text =>'Save & Quit', -command => \&done, 
                          -width => 15)->pack();

if (defined($srcfile)) {
  $pkg->read_metadata_file($srcfile);
  $name = $pkg->{'Name'};
  $description = $pkg->{'Description'};
  $group = $pkg->{'Functional_Group'};
  $stability = $pkg->{'Version_Stability'};
  $depindexes = 
    Grid::GPT::V1::DependencyIndexes::create_indexes($pkg->{'Source_Dependencies'});
  $major = $pkg->{'Version'}->{'major'};
  $minor = $pkg->{'Version'}->{'minor'};
  $age = $pkg->{'Version'}->{'age'};
  my $setup = $pkg->{'Source_Setup_Dependencies'};
  for my $d (sort keys %{$depindexes->{'name'}}) {
    $deps_widget->add($d);
  }

  for my $s (@$setup) {
    $setup_widget->add($s);
  }
}

my $deps_window = new Grid::GPT::Widgets::Dependency(parent => $main, 
                                              indexes => $depindexes);

my $setup_window = new Grid::GPT::Widgets::Setup(parent => $main);


MainLoop;

sub update {

}

sub fill_dep_content {
  my ($deps) = @_;
  my %depcontents = ('compile',"",
                     'Name',"",
                     'pgm_link',"",
                     'lib_link',"", 
                     'data_runtime', "", 
                     'doc_runtime',"", 
                     'pgm_runtime',"", 
                     'lib_runtime',"");
  if (defined($deps)) {
    my $name = $depcontents{'Name'} = $deps;
    for my $d (@{$depindexes->{'name'}->{$name}}) {
      if ($d->{'type'} !~ m!runtime!) {
        $depcontents{$d->{'type'}} = "X";
      } else {
        if ($depcontents{$d->{'type'}} eq "") {
          $depcontents{$d->{'type'}} = $d->{'pkg_type'} 
        } else {
          $depcontents{$d->{'type'}} .= ", $d->{'pkg_type'}" 
        }
      }
    }
  }
  return \%depcontents;
}

sub edit {
  my ($setup, $func, $entry) = @_;
  my $selection;
  my ($window);

  if ($setup) {
    $window = $setup_window;
  } else {
    $window = $deps_window;
  }

  if (defined ($entry)) {
    $window->display($func, $entry);
  } else {
    $window->display($func);
  }

}

sub fill_setup_content {
  my ($stp) = @_;
  my %setup_contents = ('Name',"",
                     'Package Type',"");
  my $newitem = 0;
  
  if (defined($stp)) {
    $setup_contents{'Name'} = $stp->{'name'};
    $setup_contents{'Package Type'} = $stp->{'type'};
  }

  return \%setup_contents;
}


sub done {
   $pkg->{'Name'} = $name;
   $pkg->{'Description'} = $description;
   $pkg->{'Functional_Group'} = $group;
   $pkg->{'Version_Stability'} = $stability;

   $pkg->{'Source_Dependencies'} = 
     $depindexes->export_hash_of_hashes('name');

   my @setup;
   for my $s (sort keys %{$setup_widget->{'objs'}}) {
     push @setup, $setup_widget->{'objs'}->{$s};
   }

   $pkg->{'Source_Setup_Dependencies'} = \@setup;

   $pkg->{'Version'}->{'major'} = $major;
   $pkg->{'Version'}->{'minor'} = $minor;
   $pkg->{'Version'}->{'age'} = $age;
   $pkg->output_metadata_file($srcfile);
   quitme();
}

sub quitme { 

exit;
}

=head1 NAME

B<gpt_edit> - GUI to edit source package metadata files

=head1 SYNOPSIS

gpt_edit source_package_metadata_file

=head1 DESCRIPTION

B<gpt_edit> is a GUI that can be used to edit source package metadata
files.  The script requires the B<Perl Tk> libraries.



=head1 The Main Window

Here you can edit the name and version of the package and manage the
dependencies.  The version is an "aging" version type discussed in
B<Version>.  The dependency table summarizes the dependencies.  The
descriptions of the dependency types are found in B<SourceDependency>.
Those dependencies marked with an B<X> have their package types
assumed.  The other dependencies list the package types. Double clicking on a dependency row will bring up the Dependency Window.

=over 4

=item Add Dependency

Brings up an empty Dependency Window.

=item Quit

Exits B<gpt_edit> without saving any changes.

=item Save & Quit

Saves the changes and exits B<gpt_edit>.

=back

=head1 Dependency Window

The Dependency Window lets you edit the dependencies to one
package. The window contains the following:

=over 4

=item Name

The name of the dependent package.

=item Build Dependencies

This a selectable list of dependencies to the package during the time
your package is being built.  Select the one that best describes the
build relationship.


=item Runtime Dependencies

This is a set of buttons that allows you to pinpoint runtime
relationships between your binary packages and the binary packages
produced by the dependent package.

=item Version List Table

This is a selectable list of all of the versions of the dependent
package that your package is compatible with.  Version types are
detailed in B<Version>.  Double click on a row to edit a version
requirement using the Version Window.


=item Done

Press this button when you are done with editing the dependency.

=item Add Version

Press this button to add a version requirement using the Version
Window.

=back


=head1 Version Window

This window allows you to add a version requirement. See B<Version>
for an explanation of the fields.

=head1 SEE ALSO

Version(3) Package(3) SourceDependency(3) 

=head1 AUTHOR

Michael Bletzinger E<lt>mbletzin.ncsa.uiuc.eduE<gt> and Eric Blau
E<lt>eblau.ncsa.uiuc.eduE<gt>

=cut



