#!/usr/bin/env perl

use strict;
use warnings;

# given an RA and DEC lookup find the LAP stack images

# XXX: consider making these options these could be made options I guess

my $tess_id = 'RINGS.V3';
my $label = 'LAP.ThreePi.20110809';

use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
use Pod::Usage qw( pod2usage );
use DBI;
use PS::IPP::Config 1.01 qw( :standard );

my $ipprc =  PS::IPP::Config->new();
my $dbh = getDBHandle();


my ($requested_filter, $no_display, $skycell_id, $verbose, $ra, $dec, $convolved);


GetOptions(
    'filter|f=s'    => \$requested_filter,
    'convolved'     => \$convolved,
    'no-display|n'  => \$no_display,
    'skycell_id=s'  => \$skycell_id,
    'verbose|v'     => \$verbose,
) or pod2usage( 2 );

pod2usage( -msg => '<ra> and <dec> or --skycell_id is required', -exitval => 2)
    unless defined $skycell_id or scalar @ARGV == 2;

$ra = shift;
$dec = shift;

my $extension;
if ($convolved) {
    $extension = 'fits';
} else {
    $extension = 'unconv.fits';
}

# run whichimage to find a list of skycells containing the given coordinates
my $whichimage_output = `whichimage --listchipcoords --tess_id $tess_id $ra $dec`;

print $whichimage_output if $verbose;

my @results = split "\n", $whichimage_output;

die "whichimage returned no output\n" if scalar @results == 0;

my $query = "SELECT skycell_id, filter, stack_id, quality, path_base
    FROM stackRun join stackSumSkyfile USING(stack_id) 
    WHERE stackRun.state ='full' AND label = '$label' AND skycell_id = ?";

if ($requested_filter) {
    $requested_filter .= '%' if length($requested_filter) == 1;
}
$query .= " AND filter LIKE '$requested_filter'" if defined $requested_filter;

# This will "sort of" put the sets of images for skycells that were processed multiple times
# in temporal order
$query .= "ORDER BY stack_id";

my $stmt = $dbh->prepare($query) or die $dbh->errstr;

# @files will contain the list of skycells found in order of skycell_id, filter.
# These will be displayed in this order so that the image frames are in order of increasing bandpass
my @files = ();

# give each filter an index value
my %index = ( 'g.00000' => 0, 'r.00000' => 1, 'i.00000', => 2, 'z.00000' => 3, 'y.00000' =>4 );
my $num_filters = scalar keys %index;

my $total_files = 0;
my $skycells = 0;
# loop over the list of skycells returned by whichimage
foreach (split "\n", $whichimage_output) {
    chomp;
    my ($radeg, $decdeg, undef, $skycell, $x, $y) = split " ";
    print "$skycell $radeg $decdeg\n" if $verbose;
    $stmt->execute($skycell) or die $stmt->errstr;
    my $files_found = 0;
    while (my $f = $stmt->fetchrow_hashref()) {
        next if $f->{quality};
        my $filter = $f->{filter};
        my $stack_id = $f->{stack_id};
        my $path_base = $f->{path_base};
        # save the skycell coordinates so we can pan efficiently below
        $f->{X} = $x;
        $f->{Y} = $y;

        # Find where this filter goes in the array
        my $i = $index{$filter};
        if (!defined $i) {
            print STDERR "stack_id $stack_id has unknown filter $filter! Skipping\n";
            next;
        }
        # if multiple skycells match the coordinates bump the index
        $i += $skycells * $num_filters;
        $files[$i] = $f;
        $files_found++;
    }
    if ($files_found) {
        $total_files += $files_found;
        $skycells++;
    }
}

if (!$total_files) {
    print "no files found\n";
    exit 1;
}


if (!$no_display) {
    # estimate of image size for the case where we have 5 frames
    my $imagesize = 680;
    # my $panargs = "-pan to $ra $dec wcs fk5";
    my @args;
    foreach my $f (@files) {
        next if ! $f;
        my $filename = $f->{path_base} . ".$extension";
        my $resolved = $ipprc->file_resolve($filename);
        next if !$resolved;
        my $panargs = "-pan to $f->{X} $f->{Y}";

        my $xlabel = $f->{X} + $imagesize / 2;
        my $ylabel = $f->{Y} + $imagesize / 2;
        # The following is an attempt put the filter name in the image using a region with text a label.
        # I couldn't make this work. The circle would appear but without the text
        # my $label = " -regions command  'circle($xlabel,$ylabel,1)' # text={ $f->{filter} }";

        # This didn't work either. Generates an X Errror "RenderBadPicture (invalid Picture parameter)"
        # we could easily create a temporary region file and load that with -regions filename
        my $label = " -regions command  text $xlabel $ylabel {$f->{filter}}";
        # $panargs .= $label;

        push @args, ($resolved, $panargs);
    }
    my $ds9cmd = "ds9 -geom 1024x1024 @args";
    print "$ds9cmd\n" if $verbose;
    system $ds9cmd;
} else {
    foreach my $f (@files) {
        next if !$f;
        print "$f->{skycell_id} $f->{stack_id} $f->{filter} $f->{path_base}\n";
    }
}

exit 0;

#############################################################################

sub getDBHandle {
    my $dbuser = metadataLookupStr($ipprc->{_siteConfig}, "DBUSER");
    my $dbpassword = metadataLookupStr($ipprc->{_siteConfig}, "DBPASSWORD");
    my $dbserver = metadataLookupStr($ipprc->{_siteConfig}, "DBSERVER");
    my $dbname = 'gpc1';

    die "database configuration set up" unless defined($dbserver) and defined($dbuser)
        and defined($dbpassword) and defined($dbname);

    my $dsn = "DBI:mysql:host=$dbserver;database=$dbname";

    my $dbh = DBI->connect($dsn, $dbuser, $dbpassword) 
        or die "Cannot connect to database.\n";

    return $dbh;
}

