#!perl
use 5.010;
use strict;
use warnings;
use Getopt::Long;

# Compiles the constellations into include/tks/tks_cons.h: Roman's (1987)
# table of the IAU boundaries of 1930 in the B1875.0 frame (CDS VI/42,
# data.dat), in its order, and the 88 names and genitives transcribed from
# the IAU Style Manual's Table 11 (iau-table11.tsv). Shipped so a reader can
# regenerate the table; never installed.
#
#     perl tools/conscompile --dir ../plan_time_keeper_sky/sources/constellations

my ($dir, $out) = ('', 'include/tks/tks_cons.h');
GetOptions('dir=s' => \$dir, 'out=s' => \$out) or die "usage: conscompile --dir <directory> [--out <header>]\n";
die "conscompile: --dir <directory> is needed\n" unless $dir;

my (@names, %index);
open my $nf, '<', "$dir/iau-table11.tsv" or die "conscompile: $dir/iau-table11.tsv: $!\n";
while (<$nf>) {
    next if /^#/ || !/\S/;
    chomp;
    my @f = split /\t/;
    die "conscompile: iau-table11.tsv line $.: three columns wanted\n" unless @f == 3;
    $index{ $f[0] } = scalar @names;
    push @names, \@f;
}
close $nf;
die "conscompile: " . scalar(@names) . " constellations, not 88\n" unless @names == 88;

my @rows;
open my $df, '<', "$dir/vi42-data.dat" or die "conscompile: $dir/vi42-data.dat: $!\n";
while (my $line = <$df>) {
    chomp $line;
    my ($lo, $hi, $dec, $con) = split ' ', $line;
    die "conscompile: data.dat line $.: '$line'\n" unless defined $con && exists $index{$con};
    push @rows, [$lo, $hi, $dec, $index{$con}];
}
close $df;
die "conscompile: " . scalar(@rows) . " boundary rows, not 357\n" unless @rows == 357;

open my $oh, '>', $out or die "conscompile: $out: $!\n";
my $n = @rows;
print $oh <<"EOT";
#ifndef TKS_CONS_H
#define TKS_CONS_H

/* Generated by tools/conscompile. The IAU constellation boundaries of 1930
 * (Delporte) in Roman's (1987) form (CDS VI/42): $n bands, each a lower
 * declination and a range of right ascension in the B1875.0 frame, in the
 * order they are to be tried; and the 88 constellations' IAU abbreviations,
 * names and genitives (the IAU Style Manual, 1989, Table 11). Do not edit:
 * regenerate. */

#define TKS_CONS_ROWS $n
#define TKS_CONSTELLATIONS 88

typedef struct tks_cons_row {
    double ra_lo, ra_hi, dec_lo;    /* hours, hours, degrees; B1875.0 */
    int    con;                     /* an index into tks_cons_names */
} tks_cons_row;

static const char *const tks_cons_names[TKS_CONSTELLATIONS][3] = {
EOT
printf $oh "    { \"%s\", \"%s\", \"%s\" },\n", @$_ for @names;
print $oh "};\n\nstatic const tks_cons_row tks_cons_rows[TKS_CONS_ROWS] = {\n";
printf $oh "    { %s, %s, %s, %d },\n", @$_ for @rows;
print $oh "};\n\n#endif\n";
close $oh;
printf "%s: %d bands, %d constellations\n", $out, $n, scalar @names;
