#!/usr/local/bin/perl
#	Title:	SpaceTrackTk
#	Author:	T. R. Wyant
#	Date:	07-Mar-2005
#	Remarks:
#		This Perl script provides a Perl/Tk interface to the
#		Astro::SpaceTrack package. Command arguments are passed to
#		the instantiated object, so that you can do things like
#		$ perl SpaceTrackTk 'set username me password secret'
#		to initialize your session.

use strict;
use warnings;

use Astro::SpaceTrack;
use Tk;

our $VERSION = '0.015';

my @pad = qw{-padx 5 -pady 5};

my $st = Astro::SpaceTrack->new (@ARGV);

my ($mw, $row, $col);
$row = $col = 0;
my ($user, $pwd, $rslt);

my $banner = !$st->get ('banner')->content;

sub banner {
my $mw = MainWindow->new (-title => 'Front Matter');
my $text = "SpaceTrackTk $VERSION" . $st->banner->content;
$text =~ s/^\s+//s;
$text =~ s/[\s\n]+$//s;
$mw->Label (-text => $text)->pack (-side => 'top', @pad);
$mw->Button (-text => 'OK', -command => sub {$mw->destroy})
    ->pack (-side => 'bottom', @pad);

MainLoop;

1;
}

unless ($st->get ('direct')->content || ($rslt = $st->login ()) && $rslt->is_success) {

    $banner ||= banner ();

    $user = $pwd = '';
    $mw = MainWindow->new (-title => 'Log in to Space Track');

    $mw->Label (-text => 'Username:')
	->grid (-row => $row, -column => $col++, -sticky => 'e', @pad);
    $mw->Entry (-relief => 'sunken', -textvariable => \$user)
	->grid (-row => $row, -column => $col++, -sticky => 'w', @pad);
    $row++; $col = 0;
    $mw->Label (-text => 'Password:')
	->grid (-row => $row, -column => $col++, -sticky => 'e', @pad);
    $mw->Entry (-relief => 'sunken', -textvariable => \$pwd, -show => '*')
	->grid (-row => $row, -column => $col++, -sticky => 'w', @pad);
    $row++; $col = 0;
    my $bf = $mw->Frame->grid (-row => $row, -column => 0, -columnspan => 2, -sticky => 'ew');
    $bf->Button (-text => 'Log in', -command => sub {
	$rslt = $st->login (direct => 0, username => $user, password => $pwd);
	$rslt->is_success and do {
	    $mw->destroy;
	    return;
	    };
	$mw->messageBox (-icon => 'error', -type => 'RetryCancel',
		-title => 'Login failure', -message => $rslt->status_line)
		eq 'Cancel' and do {
	    $mw->destroy;
	    return;
	    };
	})
	->grid (-row => 0, -column => $col++, @pad);
    $bf->Button (-text => 'Skip login', -command => sub {
	$st->set (direct => 1);
	$mw->destroy;
	})
	->grid (-row => 0, -column => $col++, @pad);

    MainLoop;

    }

exit unless $st->get ('direct')->content || $rslt && $rslt->is_success;

$banner ||= banner ();

my ($command, $current, $data, $label, $names);
$command = $data = $label = '';
$mw = MainWindow->new (-title => 'Retrieve Space Track data');

my %dsdata;
my %dslbl = (
    celestrak => 'Catalog name:',
    spacetrack => 'Catalog name:',
    file => 'Catalog file:',
    search_name => 'Name to search for:',
    search_id => 'International Designator(s):',
    retrieve => 'Satellite ID(s):',
    );
my $dsfile_widget = $mw->Frame;
$dsfile_widget->Entry (-relief => 'sunken', -textvariable => \$dsdata{file})
	->grid (-row => 0, -column => 0, -padx => 5);
$dsfile_widget->Button (-text => 'Find file ...', -command => sub {
	my $file = $mw->getOpenFile (-filetypes => [
		['Text files', '.txt', 'TEXT'],
		['All files', '*'],
		], -initialfile => $dsdata{$command},
		-defaultextension => '.txt');
	$dsdata{file} = $file if $file;
	})->grid (-row => 0, -column => 1, -padx => 5);
my %dswdgt = (
    celestrak => $mw->Optionmenu (-options => ($st->names ('celestrak'))[1],
	-variable => \$dsdata{celestrak}),
    spacetrack => $mw->Optionmenu (-options => ($st->names ('spacetrack'))[1],
	-variable => \$dsdata{spacetrack}),
    file => $dsfile_widget,
    search_name => $mw->Entry (-relief => 'sunken', -textvariable => \$dsdata{search_name}),
    search_id => $mw->Entry (-relief => 'sunken', -textvariable => \$dsdata{search_id}),
    retrieve => $mw->Entry (-relief => 'sunken', -textvariable => \$dsdata{retrieve}),
    );
my %dsxfrm = (
    retrieve => sub {(split '\s+', $_[0])},
    );
$row = $col = 0;
$mw->Label (-text => 'Object ID source:')
	->grid (-row => $row, -column => $col++, -sticky => 'e', @pad);
$mw->Optionmenu (-options =>
	([  ['Celestrak catalog' => 'celestrak'],
	    ['Space Track catalog' => 'spacetrack'],
	    ['Human Space Flight data' => 'spaceflight'],
	    ['Radio Amateur Satellite Corporation data' => 'amsat'],
	    ['Iridium Status' => 'iridium_status'],
	    ['Local file catalog' => 'file'],
	    ['Space Track name lookup' => 'search_name'],
	    ['Space Track international designator lookup' => 'search_id'],
	    ['Space Track satellite IDs' => 'retrieve'],
	    ],
	 [  ['Celestrak catalog' => 'celestrak'],
	    ['Iridium Status' => 'iridium_status'],
	    ['Human Space Flight data' => 'spaceflight'],
	    ['Radio Amateur Satellite Corporation data' => 'amsat'],
	    ],
	)[$st->get ('direct')->content ? 1 : 0],
    -variable => \$command, -command => sub {
	$current and $current->gridForget ();
	$label = $dslbl{$command};
	$current = $dswdgt{$command} or return;
	$current->grid (-row => 1, -column => 1, -sticky => 'w', @pad);
	})->grid (-row => $row, -column => $col++, -sticky => 'w', @pad);

$row++; $col = 0;
$label = $dslbl{$command};
$mw->Label (-textvariable => \$label)
	->grid (-row => $row, -column => $col++, -sticky => 'e', @pad);
$current = $dswdgt{$command};
$current->grid (-row => $row, -column => $col++, -sticky => 'w', @pad);

if ($st->get ('direct')->content) {
    $names = 0;
    $st->set (with_name => $names);
    }
  else {
    $row++; $col = 0;
    $mw->Label (-text => 'Include common names:')
	->grid (-row => $row, -column => $col++, -sticky => 'e', @pad);
    $mw->Checkbutton (-variable => \$names, -relief => 'flat', -command => sub {
	$st->set (with_name => $names);
	})
	->grid (-row => $row, -column => $col++, -sticky => 'w', @pad);
    $names = !!$st->get ('with_name')->content;
    }

$row++; $col = 0;
my $bf = $mw->Frame->grid (-row => $row, -column => 0, -columnspan => 2, -sticky => 'ew');
$bf->Button (-text => 'Exit', -command => sub {$mw->destroy})
    ->grid (-row => 0, -column => $col++, -sticky => 'ew', @pad);
$bf->Button (-text => 'View data ...', -command => sub {
	my $vw = $mw->Toplevel ();
	my $tx = $vw->Scrolled ('Text', -relief => 'sunken', -scrollbars => 'oe');
	$tx->pack (-expand => 1, -fill => 'both');
	$rslt = $st->$command ($dsxfrm{$command} ?
		($dsxfrm{$command}->($dsdata{$command})) :
		$dsdata{$command});
	if ($rslt->is_success) {
	    $tx->insert ('0.0', $rslt->content);
	    $vw->title ($dsdata{$command} ? "$command $dsdata{$command}" : $command);
	    }
	  else {
	    $mw->messageBox (-icon => 'error', -type => 'OK',
		-title => 'Data fetch error', -message => $rslt->status_line);
	    }
	})
	->grid (-row => 0, -column => $col++, -sticky => 'ew', @pad);
$bf->Button (-text => 'Save data ...', -command => sub {
	my $file = $mw->getSaveFile (-filetypes => [
		['Text files', '.txt', 'TEXT'],
		['All files', '*'],
		], -initialfile => $dsdata{$command},
		-defaultextension => '.txt');
	return unless defined $file && $file ne '';
	$rslt = $st->$command ($dsxfrm{$command} ?
		($dsxfrm{$command}->($dsdata{$command})) :
		$dsdata{$command});
	if ($rslt->is_success) {
	    my $fh;
	    $fh = FileHandle->new (">$file")
		and print $fh $rslt->content
		or $mw->messageBox (-icon => 'error', -type => 'OK',
		-title => 'File open error', -message => $!);
	    }
	  else {
	    $mw->messageBox (-icon => 'error', -type => 'OK',
		-title => 'Data fetch error', -message => $rslt->status_line);
	    }
	})
	->grid (-row => 0, -column => $col++, -sticky => 'ew', @pad);
##	->grid (-row => $row, -column => $col++, @pad);

MainLoop;

__END__

=head1 NAME

SpaceTrackTk - Perl/Tk application to fetch satellite orbit data.

=head1 SYNOPSIS

This application provides a windowed interface to the Astro::SpaceTrack
module, based on the Perl/Tk windowing system. All you do is issue the
command

 $ SpaceTrackTk

You will be presented with a splash screen, followed by a login window.
In order to get full functionality, you must have a Space Track
account. It is the username and password of this account that you enter
into the login screen.

You have the option to skip the login. This gives you reduced
functionality, since you are limited to the data provided by
redistributers known to Astro::SpaceTrack. The reduced functionality
is apparent in two ways:

* The Space Track sources do not appear in the "Object ID source" drop
list.

* The "Include common names" checkbox does not appear on the retrieval
window, since you get whatever the redistributer provides.

=head1 ENVIRONMENT

If SPACETRACK_OPT sets direct to 1, the login screen is skipped, and
the functionality is as though you skipped the login (i.e. reduced).
Otherwise, if a username and password are available from either
SPACETRACK_USER or SPACETRACK_OPT, you are logged in automatically
and the login screen is skipped.

Please see L<Astro::SpaceTrack> for the details.

=head1 MODIFICATIONS

 (no version) T. R. Wyant
   initial release.
 0.013 24-Nov-2005 T. R. Wyant
   Added version.
   Added support for direct-fetching of data.
   Added ability to skip login.
   Added POD.
 0.014 22-Feb-2006 T. R. Wyant
   Support iridium_status.
 0.015 30-May-2006 T. R. Wyant
   Support spaceflight and amsat.

=head1 ACKNOWLEDGMENTS

The author wishes to thank Dr. T. S. Kelso of
L<http://celestrak.com/> and the staff of L<http://www.space-track.org/>
(whose names are unfortunately unknown to me) for their co-operation,
assistance and encouragement in the development of the Astro::SpaceTrack
module.

=head1 AUTHOR

Thomas R. Wyant, III (F<wyant at cpan dot org>)

=head1 COPYRIGHT

Copyright 2005, 2006 by Thomas R. Wyant, III
(F<wyant at cpan dot org>). All rights reserved.

This script is free software; you can use it, redistribute it
and/or modify it under the same terms as Perl itself.

The data obtained by this script is subject to the Space
Track user agreement (L<http://www.space-track.org/perl/user_agreement.pl>).

This software is provided without any warranty of any kind, express or
implied. The author will not be liable for any damages of any sort
relating in any way to this software.

=cut
