#!/usr/bin/perl --
# =============================================================-------
# -------------------------------------
#
# file name: saros
# Copyright (C) 2003-2004 Sebastian Harl
#
# -------------------------------------
# =============================================================-------
#
# This program is free software; you can redistribute it and/or 
# modify it under the terms of the GNU General Public License as 
# published by the Free Software Foundation; either version 2 of 
# the License, or (at your option) any later version. 
#
# This program is distributed in the hope that it will be 
# useful, but WITHOUT ANY WARRANTY; without even the implied 
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
# PURPOSE. See the GNU General Public License for more details. 
#
# You should have received a copy of the GNU General Public 
# License along with this program; if not, write to the Free 
# Software Foundation, Inc., 59 Temple Place, Suite 330, 
# Boston, MA 02111-1307, USA.
#
# program info:
# Saros - calculation of the occurance of solar eclipses
# A mathematics work written by Sebastian Harl
# Adam-Kraft-Gymnasium Schwabach
# Class of 2003
#
# =============================================================-------
#
# HISTORY & CHANGELOG:
# --------------------
# 
# v 1.0		official 'facharbeit' release
# v 1.1		display central line graphically
# v 1.1.01	error log replaces general log, save report as 
# 		text-file
# v 1.1.02	180 bug fixed!
# v 1.1.03	status bar added
# v 1.1.04	gif images replaced with jpeg and png images, 
# 		save report as pdf
# v 1.1.05	save central line as jpeg or png
# v 1.2		a lot of code cleanup and removal of unnecessary 
# 		files
#
# =============================================================-------

# -------------------------------------
# these are globale variables you might
# have to adjust for your environment:

  # world map image file:
  my $worldmapimagefile = '/usr/share/saros/images/world.jpg';
  # base name for language file:
  my $langfile_base = '/usr/share/saros/lang.';

# =====================================
# you should not need to edit anything
# below this line!!
# =====================================
  
# -------------------------------------
# loading modules
  use warnings;
  use strict;

  use vars qw($nojpeg $nogd $nopdf);
  BEGIN {
	  $nojpeg = "false";
	  $nogd = "false";
	  $nopdf = "false";
  }
  
  use Tk;
  require Tk::Menu;
  require Tk::Radiobutton;
  require Tk::Checkbutton;
  require Tk::DialogBox;
  require Tk::Canvas;
  require Tk::ROText;
  
  eval "require Tk::JPEG";
  if ($@) {
	# Tk::JPEG not found!
	print STDERR "-saros: Tk/JPEG.pm not found!\n";
	print STDERR "\tCentral line can not be displayed graphically.\n";
	$nojpeg = "true";
  }

  use Math::Trig qw/ asin atan tan /;

  eval "use GD";
  if ($@) {
	# GD not found!
	print STDERR "-saros: GD.pm not found!\n";
	print STDERR "\tCannot save image of central line.\n";
	$nogd = "true";
  }
  eval "use PDF::API2";
  if ($@) {
	# PDF::API2 not found!
	print STDERR "-saros: PDF/API2.pm not found!\n";
	print STDERR "\tCannot save PDF report of a solar eclipse.\n";
	$nopdf = "true";
  }

# end loading modules
# -------------------------------------

# -------------------------------------
# defining globale variables
  my $VERSION = "1.2";
  # user home directory:
  my $user_home = $ENV{HOME};
  # saros user directory:
  my $user_dir = "$user_home/.saros/";
  my $conffile = $user_dir . 'saros.conf';
  my $coordscachefile = $user_dir . 'coords.db';
  my ($mw, $mb, $language);
  # top, left, right and bottom frame for main screen
  my ($top_f, $left_f, $right_f, $bottom_f);
  # status bar
  my ($status, $status_msg);
  # input fields in top frame
  my ($interval_lbl, $to_lbl, $from_entry, $to_entry, $submit_bttn);
  # list field for possible solar eclipse dates in left frame
  my ($nm_ls);
  # output field in right frame
  my ($out_text, $out_c);
  # input data
  my ($from_year, $to_year);
  # hash to store newmoon dates and each related 'beta'
  my %NM_data;
  my $pi = 3.1415926535;
  my $pihalf = $pi / 2;	
  my $pi3half = 3 * $pi / 2;
  my $pi2 = 2 * $pi;
  # some astronomic constants (see my 'facharbeit' for details)
  my $D1 = 1236.853086;
  my $D0 = 0.827361;
  # menubar buttons
  my ($mb_file, $mb_settings, $mb_help);
  # hash to store language data
  my %lang;
# end defining globale variables
# -------------------------------------

&init;			# initialize program

MainLoop;



# -------------------------------------
# Subs

# initialize program
# i.e. create main-window, menu, read config.
sub init {
	&createmw;

	my $configtest = &configcheck;		# check for main config 
	if ( $configtest eq "notconfigured" ) {
		&editconfig('firststart');
	}

	&getlang;		# get language information

	&createmenu;		# creating menubar
	&init2;
} # sub init

# set up widgets in main window
# NOTE: do not merge init and init2!! we're gonna need init2 later!!
sub init2 {	
	# -----------------------------
	# bindings
	$mw->bind('<Control-Key-q>' => \&quit);
	$mw->bind('<Control-Key-i>' => \&info); 
	$mw->bind('<Control-Key-z>' => \&displaygraphic);
	$mw->bind('<Control-Key-s>' => \&saveouttext);

	$top_f = $mw->Frame(
			-borderwidth => 1,
			-relief => 'groove',
			);

	$left_f = $mw->Frame(
			-borderwidth => 1,
			-relief => 'groove',
			);

	$right_f = $mw->Frame(
			-borderwidth => 1,
			-relief => 'groove',
			);

	$bottom_f = $mw->Frame(	
			-borderwidth => 0,
			-relief => 'flat',
			);

	$top_f->grid('-', 
			-sticky => 'nsew', 
			-padx => 0, 
			-pady => 0);
	$left_f->grid($right_f, 
			-sticky => 'nsew', 
			-padx => 0, 
			-pady => 0);
	$bottom_f->grid('-', 
			-sticky => 'nsew', 
			-padx => 0, 
			-pady => 0);

	# second row fills entire left-over space
	$mw->gridRowconfigure(1, -weight => 1);
	# second column is three times as wide as first column
	$mw->gridColumnconfigure(0, -weight => 3);
	$mw->gridColumnconfigure(1, -weight => 7);

	# -----------------------------
	# creating widgets in top_f
	  $interval_lbl = $top_f->Label(
			-text => "$lang{'interval_lbl'}",
			)->pack(
				-side => 'left',
				-padx => 10,
				-pady => 10,
			);
	  $from_entry = $top_f->Entry(
			-textvariable => \$from_year,
			)->pack(
				-side => 'left',
				-pady => 10,
			);
	  $to_lbl = $top_f->Label(
			-text => "$lang{'to_lbl'}",
			)->pack(
				-side => 'left',
				-padx => 10,
				-pady => 10,
			);
	  $to_entry = $top_f->Entry(
			-textvariable => \$to_year,
			)->pack(
				-side => 'left',
				-pady => 10,
			);
	  $submit_bttn = $top_f->Button(
			-text => 'OK',
			-command => \&newmoon,
			)->pack(
				-side => 'left',
				-padx => 10,
				-pady => 10,
			);
	# end top_f
	# -----------------------------

	# -----------------------------
	# creating widgets in left_f
	  $nm_ls =  $left_f->Scrolled(
			'Listbox',
			-scrollbars => 'se',
			-relief => 'flat',
			-selectmode => 'single',
			-height => 3,
			-width => 4,
	 		)->pack(
				-expand => 1,
				-fill => 'both',
			);
	  $nm_ls->bind("<Button-1>" => sub {
			my $NM_date = $nm_ls->get($nm_ls->curselection());
			&calcoord($NM_date);
	  });
	# end left_f
	# -----------------------------

	# -----------------------------
	# creating widgets in right_f
	  $out_text = $right_f->Scrolled(
			'ROText',
			-scrollbars => 'se',
			-background => 'white',
			-relief => 'flat',
			-height => 3,
			-width => 4,
			-wrap => 'none',
			)->pack(
				-expand => 1,
				-fill => 'both',
				);
	  $out_text->insert('end', 
			  "Saros $VERSION\n$lang{'out_text_intro'}\n\n\n");
	  $out_text->see('end');
	  $mw->update;
	# end right_f
	# -----------------------------

	# -----------------------------
	# creating widgets in bottom_f
	  $status = $bottom_f->Label(
				-anchor => 'w',
				-textvariable => \$status_msg,
				-padx => 5,
				-font => ['Arial', '8'],
				-relief => 'sunken',
				)->pack(
					-expand => 1,
					-fill => 'both',
				);
	# end bottom_f
	# -----------------------------

	$mw->update();
}


# you should check out my 'facharbeit' if you want to understand
# the algorithms in the following sections!!

sub newmoon {
	my $header = sprintf "  %6s %6s %6s %9s %9s\n", 
			"$lang{'day'}", 
			"$lang{'month'}", 
			"$lang{'year'}", 
			"$lang{'hour'}", 
			"$lang{'beta'}";
	if ( ($from_year or $from_year eq '0') 
			and ($to_year or $to_year eq '0') 
			and ($from_year =~ /^-?\d+$/) 
			and ($to_year =~ /^-?\d+$/) ) {
		if ( $to_year < $from_year ) {
			# invalid interval
			$out_text->insert('end', 
					"ERROR: $lang{'fromltto_year'}\n\n");
			$out_text->see('end');
			return;
		}
		$nm_ls->delete(0, 'end');
		$out_text->insert('end', 
				"\t$lang{'newmoon'} $from_year - $to_year\n" .
				"\t===========================\n\n");
		$out_text->insert('end', $header);
		$out_text->see('end');
	} else {
		# invalid number:
		$out_text->insert('end', 
				"ERROR: $lang{'yearnovalidnumber'}\n\n");
		$out_text->see('end');
		return;
	}

	# note: multiplication is needed to force interpretation as
	# integers (otherwise, we'll get problems if $to_year is zero)
	for (($from_year * 1) .. ($to_year * 1)) {
		&newmoon_one_year($_);
	}
	$out_text->insert('end', "\n\n");	# insert two newlines
	$out_text->see('end');

	$status_msg = "$lang{'newmoon'} $from_year - $to_year";
}

# calculate dates for the newmoons in a specified year
sub newmoon_one_year {
	my $calc_year = shift;
	my ($tNM, $day, $month, $year, $hour, $beta);

	for ( 0..13 ) {
		$tNM = (int($D1 * ($calc_year - 2000)/100) + $_ - $D0);
		$tNM /= $D1;

		# do twice for higher acuracy
		for (0..1) {
			my ($lM, $lS, $D, $F);
			my ($DeltalambdaM, $DeltalambdaS);

			# mittlere Anomalie des Mondes
			$lM = &chopdigits(0.374897 + 1325.552410 * $tNM);
			$lM *= $pi2;
			
			# mittlerer Anomalie der Sonne
			$lS = $pi2 * &chopdigits(0.993133 + 99.997361 * $tNM);

			# mittlere Differenz Lnge Mond-Sonne
			$D = (&chopdigits(0.5 + $D0 + $D1 * $tNM) - 0.5);
			$D *= $pi2;

			# Knotenabstand
			$F = $pi2 * &chopdigits(0.259086 + 1342.227825*$tNM);

			# Delta lambda von Mond und Sonne
			$DeltalambdaM = 22640*sin($lM) - 4586*sin($lM-2*$D) 
					+ 2370*sin(2*$D) + 769*sin(2*$lM) 
					- 668*sin($lS) - 412*sin(2*$F) 
					- 212*sin(2*$lM-2*$D) 
					- 206*sin($lM+$lS-2*$D) 
					+ 192*sin($lM+2*$D) 
					- 165*sin($lS-2*$D) - 125*sin($D) 
					- 110*sin($lM+$lS) + 148*sin($lM-$lS) 
					- 55*sin(2*$F-2*$D);
			$DeltalambdaM /= (3600 * 360);
			$DeltalambdaS = 6893*sin($lS) 
					+ 72*sin(2*$lS);
			$DeltalambdaS /= (3600*360);

			# improve tNM
			$tNM -= ($D / $pi2 + ($DeltalambdaM - $DeltalambdaS)) 
					/ $D1;

			# ekl. Breite beta von Mond
			if ( $_ == "1" ) {
				$beta = 18520*sin($F+$DeltalambdaM * $pi2);
				$beta -= 526*sin($F-2*$D);
				$beta /= 3600;
			}
		}

		# convert tNM from centuries since J2000 to normal date
		my ($conv_dat_0, $conv_dat_1, $conv_dat_2);
		my ($conv_dat_3, $conv_dat_4);

		my $JD_tNM = 36525 * $tNM + 2451545;
		my $JD0_tNM = int($JD_tNM+0.5);
		# consider calender reform
		if ($JD0_tNM < 2299161) {
			$conv_dat_1 = $JD0_tNM + 1524;
		}
		else {
			$conv_dat_0 = int(($JD0_tNM-1867216.25)/36524.25);
			$conv_dat_1 = $JD0_tNM 
					+ ($conv_dat_0 - int($conv_dat_0/4)) 
					+ 1525;
		}
		$conv_dat_2 = int(($conv_dat_1 - 122.1)/365.25);
		$conv_dat_3 = 365 * $conv_dat_2 + int($conv_dat_2/4);
		$conv_dat_4 = int(($conv_dat_1 - $conv_dat_3)/30.6001);

		$day = int($conv_dat_1-$conv_dat_3+0.5) 
				- int(30.6001 * $conv_dat_4);
		$month = $conv_dat_4 - 1 - 12*int($conv_dat_4/14);
		$year = $conv_dat_2 - 4715 - int((7 + $month)/10);
		$hour = 24 * ($JD_tNM + 0.5 - $JD0_tNM);

		my $newmoondate = sprintf "  %6s %6s %6s %9.5f % 9.5f", 
				$day, $month, $year, $hour, $beta;
		if ( $year == $calc_year ) {
			if ( $beta < 1.58 and $beta > -1.58 ) {
				# solar eclipse is possible
				$nm_ls->insert('end', "$day $month $year");
				$out_text->insert('end', 
						"$newmoondate -> " .
						"$lang{'sofipossible'}\n");
				$NM_data{"$day $month $year"} = "$tNM";
			} else {
				$out_text->insert('end', "$newmoondate\n");
			}
		}
	}
}
	

# calculate geographic coordinates of central line
sub calcoord {
	my $NM_date = shift;
	my $ext_NM_date = $NM_data{"$NM_date"};

	$out_text->insert('end', 
			"\t$lang{'calcoord_header'} $NM_date\n" .
			"\t===============================================" .
			"===========\n\n");
	my $calcoord_out_text_header = 
			sprintf "  %12s %10s %17s  %8s %8s          \n\n", 
			$lang{'date'}, 'UT', $lang{'phase'}, 
			$lang{'geo_laenge'}, $lang{'geo_breite'};
	$out_text->insert('end', $calcoord_out_text_header);

	my ($time, $Lambda_S, $beta_S, $Lambda_M, $beta_M);
	my (@geo_laengen, @geo_breiten, @days, @months, @years);
	my (@h_m_times, @phases);
	
	# Abstand der Sonne von der Erde (mittl.) [km]
	my $mS = 149600000;
	# Abstand des Mondes von der Erde (mittl.) [km]
	my $mM = 384400;
	my $r_M = 1738;			# radius moon [km]
	my $r_S = 696000;		# radius sun [km]
	my $r_E = 6371;			# radius earth [km]
	my $qday = 0.25 / 36525;	# quarter of a day in centuries
	my $Delta_t = 5 / (60 * 24 * 36525); # Schrittweite (5min in Jhd.)

	# Suchzeitraum bestimmen: 1/2 Tag um Neumond
	my $start_time = $ext_NM_date - $qday;
	my $end_time = $ext_NM_date + $qday;

	my $geo_laenge_0;
	# Suchzeitraum schrittweise durchlaufen
	for ( $time=$start_time; $time<=$end_time; $time+=$Delta_t ) {		
		# coordinates of sun and moon
		# sun:
		  # mittl. Anomalie Sonne [rad]
		  my $lS = &chopdigits(0.9931266 + 99.9973604 * $time);		
		  $lS *= $pi2;
		  
		  # ['']
		  my $Deltalambda_S = 6893 * sin($lS) + 72 * sin(2*$lS) 
			  	+ 6.4 * sin($pi2 *(0.6983 + 0.0561 * $time)) 
				+ 1.87 * sin($pi2*(0.5764 + 0.4174 * $time)) 
				+ 0.27 * sin($pi2 * (0.4189 + 0.3306 * $time)) 
				+ 0.2 * sin($pi2 * (0.3581 + 2.4814 * $time));
		  
		  # []
		  $Lambda_S = 282.94031 + $lS * 360 / $pi2;
		  $Lambda_S += (6191.2 * $time + 1.1 * $time * $time 
			  	+ $Deltalambda_S) / 3600;

		  # []
		  $beta_S = 0;
		  
		# moon:
		  # mittl. Anomalie des Mondes [rad]
		  my $lM = &chopdigits(0.374897 + 1325.552410 * $time);
		  $lM *= $pi2;
		  
		  # [r]
		  my $L0 = &chopdigits(0.606433 + 1336.855225 * $time 
				  - 3.1389e-6 * $time *$time);
		  # Knotenabstand [rad]
		  my $F = $pi2 * &chopdigits(0.259086 + 1342.227825*$time);
		  # mittl. Diff. Lnge Mond-Sonne [rad]
		  my $D = $pi2 * (&chopdigits(0.5 + $D0 + $D1 * $time) - 0.5);
		  # [rad]
		  my $S = $pi2 * &chopdigits(3.14e-4 * sin(2*$F) 
				  + 4.17e-4 * sin($lS));
		  # ['']
		  my $N = -526 * sin($F - 2*$D) + 44 * sin($F + $lM - 2*$D) 
			  	- 31 * sin($F - $lM - 2*$D);

		  # [r]
		  my $Deltalambda_M = &chopdigits((22640*sin($lM) 
				  - 4586*sin($lM-2*$D) + 2370*sin(2*$D) 
				  + 769*sin(2*$lM) - 668*sin($lS) 
				  - 412*sin(2*$F) - 212*sin(2*$lM-2*$D) 
				  - 206*sin($lM+$lS-2*$D) + 192*sin($lM+2*$D) 
				  - 165*sin($lS-2*$D) - 125*sin($D) 
				  - 110*sin($lM+$lS) + 148*sin($lM-$lS) 
				  - 55*sin(2*$F-2*$D))/(3600 * 360));

		  # ekl. Lnge []
		  $Lambda_M = ($L0 + $Deltalambda_M)*360;

		  # ekl. Breite []
		  $beta_M = 18520 * sin($F + $Deltalambda_M*$pi2 + $S) + $N;
		  $beta_M /= 3600;

		# Umrechnung in kartesische Koordinaten und dann in quatoriale
		  # moon:
		  my $beta_M_rad = $beta_M * $pi2 / 360;
		  my $Lambda_M_rad = $Lambda_M * $pi2 / 360;
		  my $cosbeta_M = cos($beta_M_rad);

		  # x1-coords. (ekl.) [km]
		  my $moon1ekl = $mM * $cosbeta_M * cos($Lambda_M_rad);
		  # x2-coords. (ekl.) [km]
		  my $moon2ekl = $mM * $cosbeta_M * sin($Lambda_M_rad);
		  # x3-coords. (ekl.) [km]
		  my $moon3ekl = $mM * sin($beta_M_rad);

		  # Ekliptikschiefe zum Zeitpunkt
		  # [rad]
		  my $eklschiefe = $pi2 * (0.065109142 - 3.613e-5 * $time);
		  my $coseklschiefe = cos($eklschiefe);
		  my $sineklschiefe = sin($eklschiefe);

		  # x1-coords. (qu.) [km]
		  my $moon1 = $moon1ekl;
		  # x2-coords. (qu.) [km]
		  my $moon2 = $moon2ekl * $coseklschiefe 
			  	- $moon3ekl * $sineklschiefe;
		  # x3-coords. (qu.) [km]
		  my $moon3 = $moon2ekl * $sineklschiefe 
			  	+ $moon3ekl * $coseklschiefe;

		  # sun:
		  my $beta_S_rad = $beta_S * $pi2 / 360;
		  my $Lambda_S_rad = $Lambda_S * $pi2 / 360;
		  my $cosbeta_S = cos($beta_S_rad);

		  # x1-coords. (ekl.) [km]
		  my $sun1ekl = $mS * $cosbeta_S * cos($Lambda_S_rad);
		  # x2-coords. (ekl.) [km]
		  my $sun2ekl = $mS * $cosbeta_S * sin($Lambda_S_rad);
		  # x3-coords. (ekl.) [km]
		  my $sun3ekl = $mS * sin($beta_S_rad);

		  # x1-coords. (qu.) [km]
		  my $sun1 = $sun1ekl;
		  # x2-coords. (qu.) [km]
		  my $sun2 = $sun2ekl * $coseklschiefe 
			  	- $sun3ekl * $sineklschiefe;
		  # x3-coords. (qu.) [km]
		  my $sun3 = $sun2ekl * $sineklschiefe 
			  	+ $sun3ekl * $coseklschiefe;

		# Berechnung der Schattendurchmesser im Abstand d0
		  # Einheitsvektor e
		  my $betragMSMM = sqrt(($moon1-$sun1)*($moon1-$sun1) 
				  + ($moon2-$sun2)*($moon2-$sun2) 
				  + ($moon3-$sun3)*($moon3-$sun3));
		  my $e1 = ($moon1-$sun1)/$betragMSMM;	# x1-Koord.
		  my $e2 = ($moon2-$sun2)/$betragMSMM;	# x2-Koord.
		  my $e3 = ($moon3-$sun3)/$betragMSMM;	# x3-Koord.

		  # distance d0
		  my $d0 = -($moon1*$e1 + $moon2*$e2 + $moon3*$e3);

		  # radius of penumbra
		  my $rHd0 = (($r_M*$betragMSMM)/($r_M + $r_S) + $d0) 
			  	* tan(asin(($r_M + $r_S)/$betragMSMM));

		  # radius of umbra
		  my $rKd0 = (($r_M*$betragMSMM)/($r_S - $r_M) - $d0) 
			  	* tan(asin(($r_S - $r_M)/$betragMSMM));
		  if ( $rKd0 < 0 ) {
			$rKd0 = -$rKd0;
		  }

		  # Abstand p0
		  my $p0 = sqrt($r_E*$r_E - ($d0*$d0 
				  - ($moon1*$moon1 + $moon2*$moon2 
				  + $moon3*$moon3) + $r_E*$r_E)) 
			  	  - $r_E;
		my $phase;
		# Phasen bestimmen
		  if ( $p0 < $rHd0 and $p0 > $rKd0 ) {
			$phase = "$lang{'partial'}";
		  } elsif ( $p0 <= $rKd0 and $p0 >= 0 ) {
			$phase = "$lang{'noncentral'}";
		  } elsif ( $p0 < $rKd0 ) {
			$phase = "$lang{'central'}";
		  } else {
			$phase = "noeclipse";
		  }

		# geographic coords for central phase & output
		my ($alpha, $delta, $geo_laenge, $geo_breite) = (0,0,0,0);

		unless ( $phase eq "noeclipse" ) {
			# Berechnung von d
			# Determinante > 0 ?
			my $d_test = $d0*$d0 - $moon1*$moon1 - $moon2*$moon2 
					- $moon3*$moon3 + $r_E*$r_E;
			if ( $d_test > 0 ) {
				$phase = "$lang{'central'}";
			}
			
			# calculate central line
			if ( $phase eq "$lang{'central'}" ) {
				my $d = $d0 - sqrt($d0*$d0 - $moon1*$moon1 
						- $moon2*$moon2 
						- $moon3*$moon3 + $r_E*$r_E);

				# x1-coord. schnittpunkt [qu.]
				my $p1 = $moon1 + $d * $e1;
				# x2-coord. schnittpunkt [qu.]
				my $p2 = $moon2 + $d * $e2;
				# x3-coord. schnittpunkt [qu.]
				my $p3 = $moon3 + $d * $e3;

				$alpha = atan($p2/$p1);
				$delta = atan($p3/(sqrt($p1*$p1 + $p2*$p2)));

				# fix for 180 bug 

				# -2pi < $alpha < 2pi
				$alpha = $pi2 * (&chopdigits($alpha / $pi2));
				# $alpha > 0 => 0 < $alpha < 2pi
				$alpha += $pi2 if ( $alpha < 0 );

				# quadrant in welchem alpha liegt
				my $quad;
				if ( $p1 > 0 ) {
					if ( $p2 > 0 ) {
						$quad = "first";
					} elsif ( $p2 < 0 ) {
						$quad = "fourth";
					} elsif ( $p2 == 0 ) {
						$quad = "x-plus";
					}
				} elsif ( $p1 < 0 ) {
					if ( $p2 > 0 ) {
						$quad = "second";
					} elsif ( $p2 < 0 ) {
						$quad = "third";
					} elsif ( $p2 == 0 ) {
						$quad = "x-minus";
					}
				} elsif ( $p1 == 0 ) {
					if ( $p2 > 0 ) {
						$quad = "y-plus";
					} elsif ( $p2 < 0 ) {
						$quad = "y-minus";
					} elsif ( $p2 == 0 ) {
						$quad = "error";
					}
				}

				if ( $quad eq "first" ) {
					$alpha = &checkquad("0", "$pihalf", 
							"$alpha");
				} elsif ( $quad eq "second" ) {
					$alpha = &checkquad("$pihalf", $pi, 
							"$alpha");
				} elsif ( $quad eq "third" ) {
					$alpha = &checkquad($pi, "$pi3half", 
							"$alpha");
				} elsif ( $quad eq "fourth" ) {
					$alpha = &checkquad("$pi3half", 
							"$pi2", "$alpha");
				} elsif ( $quad eq "x-plus" ) {
					$alpha = 0;
				} elsif ( $quad eq "x-minus" ) {
					$alpha = $pi;
				} elsif ( $quad eq "y-plus" ) {
					$alpha = $pihalf;
				} elsif ( $quad eq "y-minus" ) {
					$alpha = $pi3half;
				}


				# geographic coords
				  my $MJD = 36525 * $time + 51544.5;
				  my $UT = (&chopdigits($MJD)) * 24;
				  my $T = ($MJD - $UT/24 - 51544.5)/36525;
				  my $Theta = 6.697374558 + 1.0027379093*$UT 
					  	+ 2400.051337*$T 
						+ (0.093104*$T*$T 
						- 0.0000062*$T*$T*$T)/3600;
				$geo_laenge = 15*$Theta - $alpha * 360 / $pi2;
				$geo_laenge = 360 * (&chopdigits($geo_laenge 
						/ 360 ));
				$geo_breite = $delta * 360 
						/ $pi2 + 0.1924*sin(2*$delta);
			} else {
				$geo_laenge = "---";
				$geo_breite = "---";
			}

			push @geo_laengen, $geo_laenge;
			push @geo_breiten, $geo_breite;

			# Zeitkonvertierung
			my ($conv_dat_0, $conv_dat_1, $conv_dat_2);
			my ($conv_dat_3, $conv_dat_4);
			my ($day, $month, $year, $hour, $h_m_time);

			my $JD_time = 36525 * $time + 2451545;
			my $JD0_time = int($JD_time+0.5);
			if ($JD0_time < 2299161) {
				$conv_dat_1 = $JD0_time + 1524;
			}
			else {
				$conv_dat_0 = int(($JD0_time-1867216.25) 
						/ 36524.25);
				$conv_dat_1 = $JD0_time + ($conv_dat_0 
						- int($conv_dat_0/4)) + 1525;
			}
			$conv_dat_2 = int(($conv_dat_1 - 122.1)/365.25);
			$conv_dat_3 = 365 * $conv_dat_2 + int($conv_dat_2/4);
			$conv_dat_4 = int(($conv_dat_1 
					- $conv_dat_3)/30.6001);

			$day = int($conv_dat_1-$conv_dat_3+0.5) 
					- int (30.6001 * $conv_dat_4);
			$month = $conv_dat_4 - 1 - 12*int($conv_dat_4/14);
			$year = $conv_dat_2 - 4715 - int((7 + $month)/10);
			$hour = 24 * ($JD_time + 0.5 - $JD0_time);
			my $mins = &chopdigits($hour);
			$mins *= 60;
			$mins = int($mins);
			$mins = "0" . $mins if ( $mins < 10 );
			my $hours = int($hour);
			$hours = "0" . $hours if ( $hours < 10 );
			$h_m_time = "$hours:$mins";

			push @days, $day;
			push @months, $month;
			push @years, $year;
			push @h_m_times, $h_m_time;
			push @phases, $phase;
		}
	}
	open (COORDS, ">$coordscachefile") or $out_text->insert('end', 
			"$coordscachefile $lang{'couldntopen'}: $!\n" .
			"$lang{'datanotwrittennographic'}\n\n");
	print COORDS "$NM_date\n";
	for ( 0..$#geo_laengen ) {
		my $output = sprintf "  %4s %4s %6s %7s %17s % 8.6s % 8.6s\n", 
				$days[$_], $months[$_], $years[$_], 
				$h_m_times[$_], $phases[$_], 
				$geo_laengen[$_], $geo_breiten[$_];
		$out_text->insert('end', $output);

		# Caching coords for graphic display
		print COORDS "$geo_laengen[$_]*$geo_breiten[$_]\n" 
				if ( $phases[$_] eq "$lang{'central'}" );
	}
	close (COORDS);

	if ( @geo_laengen == 0 ) {
		$out_text->insert('end', "$lang{'noeclipse'}");
	}

	$out_text->insert('end', "\n\n");
	$out_text->see('end');

	$status_msg = "$lang{'calcoord_header'} $NM_date";
}

# displays world map with central line of last calculated solar eclipse
sub displaygraphic {
	if ("true" eq $nojpeg) {
		$status_msg = "Can not display central-line: Tk/JPEG.pm " .
			"is missing!";
		return 1;
	}

	my @coords;
	unless (-e "$coordscachefile") {
		return;
	}
	if ( -s "$coordscachefile" > 100 ) {
		open (READCOORDS, "<$coordscachefile");
		@coords = <READCOORDS>;
		chomp @coords;
		close (READCOORDS);
	} elsif ( -s "$coordscachefile" > 2 ) {
		$out_text->insert('end', 
				"ERROR: $lang{'cache-nocentralphase'}\n\n");
		return;
	} else {
		$out_text->insert('end', 
				"ERROR: $lang{'couldntopencoordscache'}\n\n");
		return;
	}

	my $centrallinedate = $coords[0];
	$centrallinedate = join '.', (split / /, $centrallinedate);
	my $mwgeometry = $mw->geometry();
	my @mwgeometry = split /\+/, $mwgeometry;

	my $tl = $mw->Toplevel(
			-title => "$lang{'centrallinetitle'}$centrallinedate",
			);

	my $tlgeometry = '540x420+' . ($mwgeometry[1] + 30) . '+' . 
			($mwgeometry[2] + 50);
	$tl->geometry("$tlgeometry");
	
	my $worldmapcanvas = $tl->Canvas(
		-height => '420',
		-width => '540',
		)->pack();

	$worldmapcanvas->createImage(
				0, 0,
				-anchor => 'nw',
				-image => $tl->Photo(
						-format => 'jpeg',
						-file => "$worldmapimagefile",
						),
				);

	$worldmapcanvas->CanvasBind('<Shift-Button-1>', 
			sub { $tl->destroy; });

	for ( 1..$#coords ) {
		my @xycoords = split /\*/, $coords[$_];
		my $xcoord = $xycoords[0];
		my $ycoord = $xycoords[1];
		if ( $ycoord < 80 ) {
			while ( $xcoord > 180 ) {
				$xcoord -= 360;
			}
			while ( $xcoord < -180 ) {
				$xcoord += 360;
			}
			$xcoord = 270 - (($xcoord / 180) * 270);

			$ycoord = log (tan (($pi / 4) 
					+ ($ycoord * $pi2 / 720)));
			$ycoord = $ycoord * 540 / $pi2;
			$ycoord = 210 - $ycoord;

			# radius:
			my $r = 2;
			$worldmapcanvas->createOval(
					$xcoord - $r, $ycoord - $r,
					$xcoord + $r, $ycoord + $r,
					-fill => 'blue',
					-outline => 'blue',
					);
		}
	}
}

sub checkquad {
	my $lower = shift;
	my $upper = shift;
	my $alpha = shift;

	if ( $alpha > $upper ) {
		$alpha -= $pihalf while ( $alpha > $upper );
	} elsif ( $alpha < $lower ) {
		$alpha += $pihalf while ( $alpha < $lower );
	}

	return $alpha;
}

sub saveasimage {
	if ("true" eq $nogd) {
		$status_msg = "Can not save image: GD.pm is missing!";
		return 1;
	}
	# ---------------------------------------
	# this sub is still in develop state!!!!
	# TODO: create dialog to configure output (jpeg: quality; 
	# gray-scale, ...); lang-support
	#

	my $imagetype = shift;

	my $save_file = $mw->getSaveFile(
				-defaultextension => "\.$imagetype",
				-filetypes => [
					  [uc($imagetype), "\.$imagetype"],
					],
				);

	unless ($save_file) {
		return;
	}

	unless ( open (WORLDMAP, "<", "$worldmapimagefile") ) {
		$out_text->insert('end', 
				"ERROR: $save_file " .
				"$lang{'cannot_open_save_file'} $!");
		$out_text->see('end');
		return;
	}
	my $worldimage = newFromJpeg GD::Image(\*WORLDMAP);
	close (WORLDMAP);

	unless ( open (COORDS, "<", "$coordscachefile") ) {
		$out_text->insert('end', 
				"ERROR: there's no central line to be safed!");
		$out_text->see('end');
		return;
	}
	my @coords = <COORDS>;
	close(COORDS);

	my $blue = $worldimage->colorAllocate(0, 0, 255);

	for ( 1..$#coords ) {
		my @xycoords = split /\*/, $coords[$_];
		my $xcoord = $xycoords[0];
		my $ycoord = $xycoords[1];
		if ( $ycoord > -80 and $ycoord < 80 ) {
			while ( $xcoord > 180 ) {
				$xcoord -= 360;
			}
			while ( $xcoord < -180 ) {
				$xcoord += 360;
			}
			$xcoord = 270 - (($xcoord / 180) * 270);

			$ycoord = log(tan (($pi / 4) 
					+ ($ycoord * $pi2 / 720)));
			$ycoord = $ycoord * 540 / $pi2;
			$ycoord = 210 - $ycoord;

			$worldimage->arc($xcoord, $ycoord, 
					1, 1, 0, 360, 
					$blue);
			$worldimage->arc($xcoord, $ycoord, 
					3, 3, 0, 360, 
					$blue);
			$worldimage->arc($xcoord, $ycoord, 
					5, 5, 0, 360, 
					$blue);
		}
	}
	
	my $centrallinedate = $coords[0];
	$centrallinedate = join '.', (split / /, $centrallinedate);
	chomp $centrallinedate;

	my $black = $worldimage->colorAllocate(0, 0, 0);

#	my $logtime = &gettime;
#	$worldimage->string('gdGiantFont', 10, 5, 
#			"$lang{'centrallinetitle'}$centrallinedate", $black);
#	$worldimage->string('gdSmallFont', 4, 379, 
#			"This file was created by SAROS $logtime", $black);
#	$worldimage->string('gdSmallFont', 4, 392, 
#			"SAROS is published under the terms of the GNU " .
#			"General Public License 2", $black);
#	$worldimage->string('gdSmallFont', 4, 405, 
#			"Copyright (C) 2003 Sebastian Harl - " .
#			"World map created with GMT [gmt.soest.hawaii.edu]", 
#			$black);

	unless (open (SAVE_IMAGE, ">", "$save_file")) {
		$out_text->insert('end', 
				"ERROR: image ($imagetype) could not " .
				"be saved: $!");
		return;
	}
	binmode(SAVE_IMAGE);
	print SAVE_IMAGE $worldimage->jpeg(75) if ( $imagetype eq "jpg");
	print SAVE_IMAGE $worldimage->png() if ( $imagetype eq "png");
	close (SAVE_IMAGE);

	$status_msg = "$save_file$lang{'filesaved'}";
}

sub saveastext {

	# ---------------------------------------
	# this sub is still in develop state!!!!
	# TODO: create dialog to format output (which texts to include, etc.)
	#	|--> maybe save last coords to var/coords.txt 
	#	=> choose between all text or last eclipse

	my $save_file = $mw->getSaveFile(
			-filetypes => [
				['Text files', '.*'],
			],
		);

	unless ($save_file) {
		return;
	}
	
	open (SAVE_FILE, ">", "$save_file") or $out_text->insert('end', 
			"ERROR: $save_file " .
			"$lang{'cannot_open_save_file'} $!");
	my $logtime = &gettime;
	print SAVE_FILE "This file was created by SAROS $VERSION " .
			"$logtime\n\n";
	print SAVE_FILE "SAROS is published under the terms of " .
			"the GNU General Public License 2.\n";
	print SAVE_FILE "Copyright (C) 2003 Sebastian Harl\n\n\n";

	unless ( open (COORDS, "<", "$coordscachefile") ) {
		$out_text->insert('end', 
				"ERROR: there's no central line to be safed!");
		$out_text->see('end');
		return;
	}
	my @coords = <COORDS>;
	close(COORDS);

	my $centrallinedate = $coords[0];
	$centrallinedate = join '.', (split / /, $centrallinedate);

	print SAVE_FILE "$lang{'solar_eclipse_path'}: $centrallinedate\n\n";

	my $k = 0;

	for ( 1..$#coords ) {
		my ($westcoord, $northcoord) = split /\*/, $coords[$k+1];
		$coords[$k+1] = sprintf "%+08.4fw %+08.4fn\n", 
				($westcoord, $northcoord);
		print SAVE_FILE "$coords[$k+1]";
		$k++;
	}

	close (SAVE_FILE);

	$status_msg = "$save_file$lang{'filesaved'}";
}

sub saveaspdf {
	if ("true" eq $nopdf) {
		$status_msg = "Can not save PDF file: PDF/API2.pm is " .
			"missing!";
		return 1;
	}

	# ---------------------------------------
	# this sub is still in develop state!!!!
	# TODO: lang-variables, dialog to configure output
	#

	my $save_file = $mw->getSaveFile(
				-defaultextension => '.pdf',
				-filetypes => [
					  ['PDF (Portable Document Format)',	
					  		'.pdf'],
					],
				);

	unless ($save_file) {
		return;
	}

	unless ( open (COORDS, "<", "$coordscachefile") ) {
		$out_text->insert('end', 
				"ERROR: there's no central line to be safed!");
		$out_text->see('end');
		return;
	}
	my @coords = <COORDS>;
	close(COORDS);

	my $centrallinedate = $coords[0];
	$centrallinedate = join '.', (split / /, $centrallinedate);

	my $pdf = PDF::API2->new;
	my $page = $pdf->page();
	$page->mediabox(595, 842);

	my $header_text1 = $page->text();
	$header_text1->translate(72, 770);
	$header_text1->font($pdf->corefont('Courier-Bold', 1), 18);
	$header_text1->text("$lang{'solar_eclipse_path'}: $centrallinedate");

	my $gfx = $page->gfx();		# creating gfx-obj for image

	my $world_image = $pdf->image("$worldmapimagefile");
	$gfx->image($world_image, 72, 440, 0.7);

	for ( 1..$#coords ) {
		my @xycoords = split /\*/, $coords[$_];
		my $xcoord = $xycoords[0];
		my $ycoord = $xycoords[1];
		if ( $ycoord > -80 and $ycoord < 80 ) {
			while ( $xcoord > 180 ) {
				$xcoord -= 360;
			}
			while ( $xcoord < -180 ) {
				$xcoord += 360;
			}
			# NOTE: this is a really bad hack, since we're 
			# using the old values for $xcoord and $ycoord
			# to calculate the new values!!
			$xcoord	= -(($xcoord / 180) * 270 * 0.7);
			$xcoord += 72 + 0.7 * 270;

			$ycoord = log(tan(($pi / 4) + ($ycoord * $pi2 / 720)));
			$ycoord = 0.7 * $ycoord * 540 / $pi2;
			$ycoord = 440 + 0.7 * 210 + $ycoord;

			my $gfx2 = $page->gfx();
			$gfx2->strokecolor("#0000FF");
			$gfx2->fillcolor("#0000FF");
			$gfx2->circle($xcoord, $ycoord, 1);

			$gfx2->fillstroke;
		}
	}

	my $ytext = 400;
	my $xtext = 72;
	my $k = 0;
	my $l = 0;

	for ( 1..$#coords ) {
		my ($westcoord, $northcoord) = split /\*/, $coords[$k+1];
		$coords[$k+1] = sprintf "%+08.4fw %+08.4fn", 
				($westcoord, $northcoord);
		last if ( $k > 61 );
		$coords[$k+1] = '...' if ( $k == 61 and $coords[$k+2] );
		my ${info_text} = $page->text();
		$xtext = 252 if ( $k > 30 );
		${info_text}->translate($xtext, $ytext-(($k > 30)?$l++:$k)*10);
		${info_text}->font($pdf->corefont('Courier', 1), 8);
		${info_text}->text("$coords[$k+1]");
		$k++;
	}

	my $logtime = &gettime;

	my $footer_text1 = $page->text();
	$footer_text1->translate(72, 72);
	$footer_text1->font($pdf->corefont('Courier', 1), 8);
	$footer_text1->text("This file was created by SAROS $VERSION $logtime");

	my $footer_text2 = $page->text();
	$footer_text2->translate(72, 62);
	$footer_text2->font($pdf->corefont('Courier', 1), 8);
	$footer_text2->text('SAROS is published under the terms of the ' .
			'GNU General Public License 2');

	my $footer_text3 = $page->text();
	$footer_text3->translate(72, 52);
	$footer_text3->font($pdf->corefont('Courier', 1), 8);
	$footer_text3->text('Copyright (C) 2003 Sebastian Harl - World ' .
			'map created with GMT [gmt.soest.hawaii.edu]');

	unless ( open (SAVE_PDF, ">", "$save_file") ) {
		$out_text->insert('end', "ERROR: pdf could not be saved: $!");
		return;
	}
	binmode(SAVE_PDF);
	print SAVE_PDF $pdf->stringify();
	$pdf->end;
	close (SAVE_PDF);

	$status_msg = "$save_file$lang{'filesaved'}";
}

sub chopdigits {		# get digits of number
  my $arg = $_[0];
  $arg -= int($arg);
  $arg += 1 if ($arg < 0);

  return $arg;
}

sub createmw {			# creating mainwindow
	$mw = MainWindow->new(
				-title => " Saros",
				);

	$mw->geometry('550x400+100+80');

	# call sub quit on delete of mainwindow
	$mw->protocol('WM_DELETE_WINDOW', \&quit);	

	$mw->configure(
		-menu => $mb = $mw->Menu(),
		);

	$mw->update;
}

sub getlang {			# reading lang config file
	my $langfile = $langfile_base . $language;
	if ( open (LANG, "<$langfile") )
	{
		$/ = "\n<-->\n";	# setting line seperator
		my @lang = <LANG>;
		chomp @lang;
		%lang = @lang;		# converting array into hash 
					# (label => language string)
		$/ = "\n";		# setting line seperator to default
		close (LANG);
	}
	else
	{
		my $logtime = &gettime;
		print STDERR "-saros: Could not open $langfile: " .
				"${!}\n\tMaybe you did not specify a valid " .
				"language.\n\tCannot run program without " .
				"information from that file.\n\tI'm aborting " .
				"now!\n";
		exit 0;
	}
}

sub createmenu {		# create menubar
	$mb_file = $mb->cascade(
			-label => "$lang{'menu_file'}",		# file button
			-tearoff => 0,
			-menuitems =>
				[
				  ['command', "$lang{'menu_file_graph'}", 
				  		-command => \&displaygraphic, 
						-accelerator => 'Strg-z   '],
				  '',
				  ['cascade', "$lang{'save_image_as'}", 
				  		-tearoff => 0, -menuitems =>
				    [
					['command', "JPEG", 
						-command => [ \&saveasimage, 
								'jpg']],
					['command', "PNG", 
						-command => [ \&saveasimage, 
								'png']],
				    ]
				  ],
				  ['cascade', "$lang{'save_report_as'}", 
				  		-tearoff => 0, -menuitems =>
				    [
					['command', "PDF", 
						-command => \&saveaspdf],
					['command', "TEXT", 
						-command => \&saveastext],
				    ]
				  ],
				  '',
				  ['command', "$lang{'menu_file_quit'}", 
				  		-command => \&quit, 
						-accelerator => 'Strg-q   '],
				],
			);

	my $file_menu = $mb->entrycget(
			"$lang{'menu_file'}",
			-menu,
			);
	$file_menu->entryconfigure(
			"$lang{'menu_file_graph'}",
			-state => 'disabled',
			) if ("true" eq $nojpeg);
	$file_menu->entryconfigure(
			"$lang{'save_image_as'}",
			-state => 'disabled',
			) if ("true" eq $nogd);
	my $save_report_menu = $file_menu->entrycget(
			"$lang{'save_report_as'}",
			-menu,
			);
	$save_report_menu->entryconfigure(
			"PDF",
			-state => 'disabled',
			) if ("true" eq $nopdf);

	$mb_settings = $mb->cascade(
			-label => "$lang{'menu_settings'}",
			-tearoff => 0,
			-menuitems =>
				[
				  ['command', "$lang{'menu_settings_language'}",
				  -command => [\&editconfig, 'edit']],	
				],
			);

	$mb_help = $mb->cascade(
			-label => "$lang{'menu_qm'}",
			-tearoff => 0,
			-menuitems =>
				[
				  ['command', "$lang{'menu_qm_info'}", 
						-command => \&info, 
						-accelerator => 
							'Strg-i   '],
				],
			);
}



sub configcheck {
	if ( -e "$conffile" )
	{
		unless ( open (RCONFIG, "<$conffile") ) {
			my $logtime = &gettime;
			print STDERR "-saros: Can't open Config File: " .
					"$!\n\tCannot run program without " .
					"information from that file.\n" .
					"\tI'm aborting now!\n";
			exit 0;
		}
		my @config_lines = <RCONFIG>;
		close (RCONFIG);

		if ( ($config_lines[0] eq "de\n") 
				or ($config_lines[0] eq "en\n") )
		{
			$language = $config_lines[0];
		}
		else
		{
			return "notconfigured";
		}
	}
	else
	{
		return "notconfigured";
	}
	chomp $language;
}

sub editconfig {		# change main config file
	if ((-e $user_dir) and !(-d $user_dir)) {
		print STDERR "-saros: $user_dir exists but is no directory!\n";
	}

	unless (-e $user_dir) {
		if (mkdir("$user_dir", 0755)) {
			# force permissions to be 0755 ...
			chmod(0755, "$user_dir");
		} else {
			print STDERR "-saros: Could not create $user_dir " .
					"directory: $!!\nI'm aborting now!\n";
			exit 1;
		}
	}

	my (@config_lines, $redrawmw);
	my $check = shift;
	unless ( $check eq 'firststart' )
	{
		unless ( open (RCONFIG, "<$conffile") ) {
			my $logtime = &gettime;
			print STDERR "-saros: Can't open Config File: " .
					"$!\n\tCannot run program without " .
					"information form that file.\nI'm " .
					"aborting now!\n";
			exit 0;
		}
		@config_lines = <RCONFIG>;
		close (RCONFIG);
	}

	my $dlgbox = $mw->DialogBox(
				-title => 'Saros konfigurieren/Configure Saros',
				-buttons => ['OK', 'Cancel'],
				-default_button => 'OK',
				);
	$dlgbox->add('Label', -text => "Bitte whlen Sie die gewnschte " .
			"Sprache.\nPlease select your prefered language.\n"
			)->pack();
	$dlgbox->add('Radiobutton', -text => 'Deutsch', 
			-variable => \$language, -value => 'de')->pack();
	$dlgbox->add('Radiobutton', -text => 'English', 
			-variable => \$language, -value => 'en')->pack();
	$dlgbox->add('Label', -text => "\n")->pack();
	unless ( $check eq 'firststart' )
	{
		$redrawmw = 1;
		$dlgbox->add('Checkbutton', 
				-text => "Fenster neuzeichnen\nRedraw window", 
				-variable => \$redrawmw)->pack();
	}
	my $answer = $dlgbox->Show();
	if ( ($answer eq 'OK') and $language )
	{
		$config_lines[0] = "$language\n";
		my $logtime = &gettime;
		open (WCONFIG, ">$conffile") 
				or print STDERR "-saros: Can't write to " .
				"Config File: $!\n\tInformation not saved!\n";
		print WCONFIG "@config_lines";
		close (WCONFIG);
	}
	elsif ( ! $language )
	{
		&editconfig($check);
	}
	elsif ( ($answer eq 'Cancel') and ($check eq 'firststart') )
	{
		&editconfig($check);
	}
	elsif ( $answer eq 'Cancel' )
	{
		return;
	}

	if ( $redrawmw )
	{
		$mw->destroy();
		&createmw;
		&getlang;
		&createmenu;
		&init2;
	}
}

sub info {		# show info-box
	my $mwgeometry = $mw->geometry();
	my @mwgeometry = split /\+/, $mwgeometry;

	my $tl = $mw->Toplevel(
			-title => "Saros Info",
			);

	my $tlgeometry = '+' . ($mwgeometry[1] + 50) . '+' . 
			($mwgeometry[2] + 50);
	$tl->geometry("$tlgeometry");

	$tl->Label(
			-justify => 'left',
			-padx => 10,
			-pady => 10,
			-wraplength => 400,
			-text => "Saros Version $VERSION\n\nSaros lets ".
				"you calculate solar eclipses.\n\n" .
				"Copyright (C) 2003-2004 Sebastian Harl " .
				"<sh\@tokkee.de>\n\nSaros is free " .
				"software; you can redistribute it and/or " .
				"modify it under the terms of the GNU " .
				"General Public License as published by " .
				"the Free Software Foundation; either " .
				"version 2 of the License, or (at your " .
				"option) any later version.\n\nSaros is " .
				"distributed in the hope that it will be " .
				"useful, but WITHOUT ANY WARRANTY; " .
				"without even the implied warranty of " .
				"MERCHANTABILITY or FITNESS FOR A " .
				"PARTICULAR PURPOSE. See the GNU " .
				"General Public License for more details\n\n" .
				"You should have received a copy of the " .
				"GNU General Public Licnese along with " .
				"Saros; if not, write to the Free Software " .
				"Foundation, Inc., 59 Temple Place, Suite " .
				"330, Boston, MA 02111-1307, USA.",
		)->pack();
	$tl->Button(
			-text => "Close",
			-command => sub { $tl->destroy(); },
		)->pack();
}

sub gettime {		# get time of program start (-> log file)
	my ($sec, $min, $hour, $day, $month, 
			$year, $wday, $yday, $dstime) = localtime(time);

	$year += 1900;
	$month += 1;

	for ($sec, $min, $hour, $day, $month) {
		$_ = "0" . $_ if ( $_ < 10 );
	}

	return "[$year-$month-${day}_$hour:$min:$sec]";
}

sub quit {		# destroy created mainwindows and exit
	$mw->destroy();
	exit 0;
}



