#!/usr/bin/perl -w

package SPARCplug;

use strict;
use Tk;
use Tk::Widget;
use Tk::NoteBook;
use File::Basename;
use Getopt::Long;
use Cwd qw(chdir getcwd abs_path);;

BEGIN {
	my ( $filename, $directoryPath ) = fileparse($0);
	push @INC, $directoryPath;
}

use MListbox;
require "BufferedSelect.pm";
require "configuration.pl";
require "run_calibrations.pl";
require "read_fits.pl";
require "dfits_fitsort.pl";
require "parallelProcessing.pl";

configure();
our %rawfitsheader;
our $maxNumberProcesses=6;

printUsage() if $#ARGV == 0 && $ARGV[0] eq "?";
print "Command line arguments: ", join (" ",@ARGV),"\n";
our $option_errors = "";
$SIG{__WARN__} = sub{print "Caught warning: $_[0]"; $option_errors .= $_[0];};
my (%options);
&GetOptions(
	\%options,
	'raw_file_directory|raw-file-directory|rawfiledirectory|raw=s',
	'cal_directory|cal-directory|caldirectory|calibrationdirectory|cal=s',
	'working_directory|working-directory|workingdirectory|wd=s',
	'filename_pattern|filename-pattern|filenamepattern|pattern=s',
	'steps=s',
	'bands=s',
	'angles=s',
	'all',
	'fits_check',
	'help|?',
);
$SIG{__WARN__} = 'DEFAULT';

$option_errors .= "No plain arguments are allowed: " . join (" ",@ARGV) . "\n"
		if !($#ARGV == -1 || ($#ARGV == 0 && $ARGV[0] eq "?"));

$option_errors .= "Missing cal_directory option which is required\n"
		if ! defined($options{"cal_directory"});
		
if ($option_errors ne "") {
	print "\nError: Cannot parse the command line\n";
	print "\n$option_errors\n";
	printUsage();
}
printUsage() if $options{"help"} || ($#ARGV == 0 && $ARGV[0] eq "?");

our ( $filepattern, $raw_file_directory, $working_directory, $cal_directory , $fits_check);
$filepattern        = 'KMOS_*.fits';
$working_directory  = getcwd();
$raw_file_directory = getcwd();
$cal_directory      = "";
$fits_check			= 0;
my $steps           = 'ALL';
my $bands           = 'ALL';
my $angles          = 'ALL';
my $all				= 0;
$filepattern        = $options{"filename_pattern"}
							if defined($options{"filename_pattern"});
$raw_file_directory = abs_path($options{"raw_file_directory"})
							if defined($options{"raw_file_directory"});
$working_directory  = abs_path($options{"working_directory"})
							if defined($options{"working_directory"});
$cal_directory      = abs_path($options{"cal_directory"})
							if defined($options{"cal_directory"});
$fits_check         = $options{"fits_check"}
							if defined($options{"fits_check"});
$steps				= uc($options{"steps"})
							if defined($options{"steps"});
$bands				= uc($options{"bands"})
							if defined($options{"bands"});
$angles				= uc($options{"angles"})
							if defined($options{"angles"});
$all         		= $options{"all"}
							if defined($options{"all"});
												
my $check_messages = "";
$check_messages .= "raw_file_directory $raw_file_directory does not exist\n"
			if ! -e $raw_file_directory;
$check_messages .= "raw_file_directory $raw_file_directory is not a directory\n"
			if -e $raw_file_directory && ! -d $raw_file_directory;
$check_messages .= "cal_directory $cal_directory does not exist\n"
			if ! -e $cal_directory;
$check_messages .= "cal_directory $cal_directory is not a directory\n"
			if -e $cal_directory && ! -d $cal_directory;
$check_messages .= "working_directory $working_directory does not exist\n"
			if ! -e $working_directory;
$check_messages .= "working_directory $working_directory is not a directory\n"
			if -e $working_directory && ! -d $working_directory;

my ( @fcheck_list, $fcheck_cmd, $FCHECK);
if (-d $raw_file_directory) {
	@fcheck_list = ();
	$fcheck_cmd = "ls $raw_file_directory/" . $filepattern;
	open($FCHECK, "-|", $fcheck_cmd);
	@fcheck_list = <$FCHECK>;
	close $FCHECK;
	$check_messages .= "raw_file_directory $raw_file_directory holds no $filepattern files\n"
			if $#fcheck_list == -1;
}
if (-d $cal_directory) {
	@fcheck_list = ();
	$fcheck_cmd = "ls $cal_directory/*.fits";
	open($FCHECK, "-|", $fcheck_cmd);
	@fcheck_list = <$FCHECK>;
	close $FCHECK;
	$check_messages .= "cal_directory $cal_directory holds no FITS files\n"
			if $#fcheck_list == -1;
}
if ($check_messages ne "") {
	print "\nError: Initial setup checks failed\n$check_messages";
	exit 2;
}

$raw_file_directory .= '/' if substr($raw_file_directory,-1) ne "/";
$working_directory  .= '/' if substr($working_directory,-1) ne "/";
$cal_directory      .= '/' if substr($cal_directory,-1) ne "/";
chdir($working_directory);

printf "Working directory:                         %s\n", $working_directory;
printf "Directory holding raw detector frames:     %s\n", $raw_file_directory;
printf "Directory holding \"static\" cal files:      %s\n", $cal_directory;
printf "File name pattern for raw detector frames: %s\n", $filepattern;

our %raw_headers;
%raw_headers = scan_fits_files( $raw_file_directory . $filepattern, 
							\%rawfitsheader, $fits_check);
printf "Found %d valid raw files\n", scalar( keys %raw_headers );

our $esorex_msg_level = "info";
run_calibrations($steps,$bands,$angles,$all);

print "done\n";
exit(0);

sub printUsage {
	my $basename = basename( $0, "" );
	print "
This is a script to automatically run the calibration recipes.

Synopsis: $basename ?
          $basename -help
          $basename -cal_directory=dir [-options]
          
Options:  -help (or a single argument \"?\")
                Print this help maessage.

          -cal_directory=dir   (required)
                Aliases: cal-directory, caldirectory, calibrationdirectory
                Use \"dir\" to locate calibration files. The current working
                directory is used too.

          -raw_file_directory=dir  (optional, defaults to current working directory)
                Aliases: raw-file-directory, rawfiledirectory
                Use \"dir\" to locate FITS files containing raw detector images.

          -working_directory=dir   (optional, defaults to current working directory)
                Aliases: working-directory, workingdirectory
                Use \"dir\" to store output files. This directory is also searched
                for calibration files.

          -filename_pattern=pat    (optional, defaults to 'KMOS_*.fits')
                Aliases: filename-pattern, filenamepattern, pattern
                This is the file name pattern to match  FITS files containing
                raw detector images.
                
           -check              (optional, default is not set)
                Checks the raw detector images FITS files for proper structure.
                This takes some time but it will be only done during startup.
                The failed files will be listed with the detected errors.

Notes:
	- All options can abbreviated as long as the name is still unique.
	- All options can also start with two hyphens \"--\".
	- All directory specification are relative to the current directory at
	  startup not to the specified \"working_directory\" option.
";
	exit  1;
}

sub printError {
	my $msg = shift(@_);
	print "\aERROR: $msg\n";
}
