#!/usr/bin/perl -w
#use strict;

my $debug = 0;

use Astro::Coord;
use Astro::Time;
use PGPLOT;
use Getopt::Long;

my $obslat = -35.40; #Observatory latitude (deg);
my $obslong = 148.8541944; #Observatory longitude (deg);
my $el_limit = 8.0;
my $vers;

my ($start_year,$start_day, $start_ut);
my ($stop_year,$stop_day, $stop_ut);
my $title;

my $title_ch = 1.0;
my $default_ch = 1.0;
my $date_ch = 0.6;
my $ant_avail_ch = 0.5;
my $expt_label_ch = 0.8;
my $LST_colour = 14;


my $dev = "?";
GetOptions('device=s'=>\$dev);

if (@ARGV!=2) {
  die "\nUsage: sched_release_map.pl antenna_avail.txt schedule.txt\n\n";
}

my $year = undef;

# read in schedule
get_sched($ARGV[1]);
# read in constraints
get_ant_times($ARGV[0]);
my $do_small = 0;
my $landscape = 1;
if ($#ARGV == 2) {
  $landscape = $ARGV[2];
}
if ($#ARGV == 3) {
  $landscape = $ARGV[2];
  $do_small = $ARGV[3];
}
my @antenna;

my $start_mjd = dayno2mjd($start_day, $start_year);
my $stop_mjd = dayno2mjd($stop_day, $stop_year);

# calculate the UT of LST = 0, 6, 12, 18 on each day
for ($i = $start_day-1; $i <= $stop_day+1; $i++) {
  $mjd = lst2mjd(0.0, $i, $start_year, ($obslong/360.0));
  ($d,$m,$y,$ut) = mjd2cal($mjd);
  $lst0[$i] = $ut*24.0;
  
  $mjd = lst2mjd(0.25, $i, $start_year, ($obslong/360.0));
  ($d,$m,$y,$ut) = mjd2cal($mjd);
  $lst6[$i] = $ut*24.0;

  $mjd = lst2mjd(0.5, $i, $start_year, ($obslong/360.0));
  ($d,$m,$y,$ut) = mjd2cal($mjd);
  $lst12[$i] = $ut*24.0;

  $mjd = lst2mjd(0.75, $i, $start_year, ($obslong/360.0));
  ($d,$m,$y,$ut) = mjd2cal($mjd);
  $lst18[$i] = $ut*24.0;
}
my ($ymin, $ymax) = ($start_day, $stop_day+1);

my $device = pgopen($dev);
if ($do_small) {
  if ($landscape) {
    pgpap(5.0,0.709);
  } else {
    pgpap(5.0,1.409);
  }
} else {
  if ($landscape) {
#    pgpap(29.6/2.54,0.709);
  } else {
    pgpap(21.0/2.54,1.409);
  }
}
pgscr(0,1.0,1.0,1.0);
pgscr(1,0.0,0.0,0.0);
pgsvp(0.01,0.99,0.8,1.0);
pgswin(0.0,1.0,0.0,1.0);
pgsch($title_ch);
pgptxt(0.5, 0.5, 0.0,0.5,"$title $vers");
pgsch($default_ch);
# date column
pgsvp(0.0,0.095,0.1,0.8);
pgswin(0.0,1.0,$ymax-0.5,$ymin-0.5);
# separate days with a horizontal line
pgsci(1);
for ($i = $start_day+0.5; $i <= $stop_day+1; $i++) {
    pgmove(0.0, $i);
    pgdraw(24.0, $i);
}
pgslw(1.0);
pgsci(4);
pgbox('BC',0.0,0,'BC',0.0,0);
#pglabel('UT','Day Number','');
#use DateTime;
#my ($d, $m,$dt,$day_abbr,$mon_abbr);
my ($d, $day, $month,$dt,$dow,$mStr);
pgsch($date_ch);
for ($mjd = $start_mjd; $mjd <= $stop_mjd; $mjd++) {
  ($day,$month) = mjd2cal($mjd);
  $dow = mjd2weekdaystr($mjd);
  ($d) = mjd2dayno($mjd);
  $mstr = month2str($month);

    pgtext (0.05, $d-0.2, "Day $d");
    pgtext (0.05, $d+0.2, "$dow $mstr $day");
}

pgsch($default_ch);
##############################################
# main window
pgsvp(0.1,0.99,0.1,0.8);
pgswin(0.0,24.0,$ymax-0.5,$ymin-0.5);
pgsci(1);

# draw a grey box for every second hour
# define a light grey
pgshls(99, 1.0, 0.9, 0.0);
for ($i = 0; $i < 24; $i = $i + 2) {
    pgsci(99);
    pgrect($i, $i+1,$ymin-0.5,$ymax-0.5);
}

# separate days with a horizontal line
pgsci(1);
for ($i = $start_day+0.5; $i <= $stop_day; $i++) {
    pgmove(0.0, $i);
    pgdraw(24.0, $i);
}
# draw start and stop times
pgsci(1);
pgslw(10.0);
pgsci(3);
pgmove($start_ut,$start_day-0.5);
pgdraw($start_ut,$start_day+0.5);
pgsci(2);
pgmove($stop_ut,$stop_day-0.5);
pgdraw($stop_ut,$stop_day+0.5);

# CJP - not sure what this does
#pgsci(2);
#pgmove($break_start_ut,$break_start_day-0.5);
#pgdraw($break_start_ut,$break_start_day+0.5);
#pgsci(3);
#pgmove($break_stop_ut,$break_stop_day-0.5);
#pgdraw($break_stop_ut,$break_stop_day+0.5);


pgslw(1.0);
pgsci(4);
pgbox('BCN',0.0,0,'BC',0.0,0);

#Don't label UT this way so as to add AEST. pge 20/7/07 
#pglabel('UT','','');

pgsci($LST_colour);
pgmove($lst0[$start_day-1],$start_day-1);
for ($i = $start_day; $i <= $stop_day+1; $i++) {
    if ($lst0[$i] <= $lst0[$i-1]) {
	pgdraw($lst0[$i], $i);
    } else {
	pgmove($lst0[$i], $i);
    }
}
pgsls(2);
pgmove($lst6[$start_day-1],$start_day-1);
for ($i = $start_day; $i <= $stop_day+1; $i++) {
    if ($lst6[$i] <= $lst6[$i-1]) {
	pgdraw($lst6[$i], $i);
    } else {
	pgmove($lst6[$i], $i);
    }
}
pgmove($lst12[$start_day-1],$start_day-1);
for ($i = $start_day; $i <= $stop_day+1; $i++) {
    if ($lst12[$i] <= $lst12[$i-1]) {
	pgdraw($lst12[$i], $i);
    } else {
	pgmove($lst12[$i], $i);
    }
}
pgmove($lst18[$start_day-1],$start_day-1);
for ($i = $start_day; $i <= $stop_day+1; $i++) {
    if ($lst18[$i] <= $lst18[$i-1]) {
	pgdraw($lst18[$i], $i);
    } else {
	pgmove($lst18[$i], $i);
    }
}

pgptxt(12.0, $ymin-4.0*(($ymax - $ymin)/100)-0.5, 0.0,0.5,"LST at Tid");
pgptxt($lst0[$start_day-1], $ymin-(($ymax - $ymin)/100)-0.5, 0.0,0.5,"0");
pgptxt($lst6[$start_day-1], $ymin-(($ymax - $ymin)/100)-0.5, 0.0,0.5,"6");
pgptxt($lst12[$start_day-1], $ymin-(($ymax - $ymin)/100)-0.5, 0.0,0.5,"12");
pgptxt($lst18[$start_day-1], $ymin-(($ymax - $ymin)/100)-0.5, 0.0,0.5,"18");

pgsci(4);
pgptxt(12.0, $ymax+4.0*(($ymax - $ymin)/100)-0.5, 0.0,0.5,"UT");

pgsci(2);
pgptxt(12.0, $ymax+14.0*(($ymax - $ymin)/100)-0.5, 0.0,0.5,"AEST");
pgptxt(10, $ymax+14.0*(($ymax - $ymin)/100)-0.5, 0.0,0.5,"20");
pgptxt(16, $ymax+14.0*(($ymax - $ymin)/100)-0.5, 0.0,0.5,"2");
pgptxt(22.0, $ymax+14.0*(($ymax - $ymin)/100)-0.5, 0.0,0.5,"8");
pgptxt(0.0, $ymax+14.0*(($ymax - $ymin)/100)-0.5, 0.0,0.5,"10");
pgptxt(4.0, $ymax+14.0*(($ymax - $ymin)/100)-0.5, 0.0,0.5,"14");
#pgptxt($lst0[$start_day-1], $ymin-(($ymax - $ymin)/100)-0.5, 0.0,0.5,"0");
#pgptxt($lst6[$start_day-1], $ymin-(($ymax - $ymin)/100)-0.5, 0.0,0.5,"6");
#pgptxt($lst12[$start_day-1], $ymin-(($ymax - $ymin)/100)-0.5, 0.0,0.5,"12");
#pgptxt($lst18[$start_day-1], $ymin-(($ymax - $ymin)/100)-0.5, 0.0,0.5,"18");


#pgswin(0.0,24.0,$ymax,$ymin);

pgsls(1);
pgsci(2);

my $off_a = 0.2;
my $off_b = 0.4;
my $offset = $off_a;
my $last_a =  $ant[0];
for ($i = 0; $i <= $#start_d; $i++) {
  if ($stop_d[$i]<$start_day || $start_d[$i]>$stop_day) {
    my $str = sprintf("%s %d/%s", $label[$i], $start_d[$i], $start_h[$i]);
    next;
  }

  if ($ant[$i] ne $last_a) {
    if ($offset eq $off_a) {
      $offset = $off_b;
    } else {
      $offset = $off_a;
    }

    $last_a = $ant[$i];
  }

  my $hoff = 1;
  while ($ant[$i] =~ /^~/) {
    $hoff += 0.75;
    $ant[$i] =~ s/^~//;
  }

  pgsci(12);
  if ($stop_h[$i] > $start_h[$i]) {
    pgslw(1);
    draw_bar($start_h[$i], $start_d[$i]+$offset);
    pgsls(4);
    pgmove($start_h[$i], $start_d[$i]+$offset);
    pgdraw($stop_h[$i], $start_d[$i]+$offset);
    pgsls(1);
    draw_bar($stop_h[$i], $start_d[$i]+$offset);
    pgslw(1);
    pgsch($ant_avail_ch);
    pgptxt($start_h[$i]+$hoff, $start_d[$i]+($offset-0.05), 0.0, 0, $label[$i]);
    pgsch($default_ch);
  } else {
    pgslw(1);
    draw_bar($start_h[$i], $start_d[$i]+$offset);
    pgsls(4);
    pgmove($start_h[$i], $start_d[$i]+$offset);
    pgdraw(24.0, $start_d[$i]+$offset);
    pgmove(0.0, $start_d[$i]+1.0+$offset);
    pgdraw($stop_h[$i], $start_d[$i]+1.0+$offset);
    pgsls(1);
    draw_bar($stop_h[$i], $start_d[$i]+1.0+$offset);
    pgslw(1);
    pgsch($ant_avail_ch);
    pgptxt((24+$start_h[$i])/2.0, $start_d[$i]+$offset-0.1, 0.0, 0.5, $label[$i]);
    pgptxt($stop_h[$i]/2.0, $stop_d[$i]+$offset-0.1, 0.0, 0.5, $label[$i]);
    pgsch($default_ch);
  }
}
pgsci(2);
pgsch($expt_label_ch);
$offset = -0.05;
$texth = -0.2;
for ($i = 0; $i <= $#start_day; $i++) {
    if (($stop_ut[$i] > $start_ut[$i]) && ($start_day[$i] == $stop_day[$i])){
	pgslw(5);
	pgmove($start_ut[$i], $start_day[$i]);
	pgdraw($stop_ut[$i], $start_day[$i]);
	pgslw(2);
	pgsci(4);
	if (($stop_ut[$i] - $start_ut[$i]) < 4.0) {
	  if (($stop_ut[$i] - $start_ut[$i]) < 2.0) {
	    pgsch(0.7);
	  } else {
	    pgsch($expt_label_ch);
	  }
	  pgptxt(($start_ut[$i]+$stop_ut[$i])/2.0, $stop_day[$i]+$offset+$texth, 0.0, 0.5, $code[$i]);
	} else {
	  pgptxt(($start_ut[$i]+$stop_ut[$i])/2.0, $start_day[$i]+$offset+$texth, 
		 0.0, 0.5, $plabel1[$i]);
	  pgptxt(($start_ut[$i]+$stop_ut[$i])/2.0, $start_day[$i]+$offset, 
		 0.0, 0.5, $plabel2[$i]);
	}
	pgsci(2);
	draw_bar($start_ut[$i], $start_day[$i]);
	draw_bar($stop_ut[$i], $stop_day[$i]);
	pgsch($expt_label_ch);
    } else {
      pgslw(5);
	pgmove($start_ut[$i], $start_day[$i]);
	draw_bar($start_ut[$i], $start_day[$i]);
	pgdraw(24.0, $start_day[$i]);
	$day = $start_day[$i] + 1.0;
	while ($day < $stop_day[$i]) {
	    pgmove(0.0, $day);
	    pgdraw(24.0, $day);
	    pgslw(2);
	    pgsci(4);
	    pgptxt(12.0, $day+$offset+$texth, 0.0, 0.5, $plabel1[$i]);
	    pgptxt(12.0, $day+$offset, 0.0, 0.5, $plabel2[$i]);
	    pgsci(2);
	    pgslw(5);
	    $day++;
	}
	pgmove(0.0, $stop_day[$i]);
	pgdraw($stop_ut[$i], $stop_day[$i]);
	draw_bar($stop_ut[$i], $stop_day[$i]);
	pgslw(2);
	pgsci(4);
	if ($stop_ut[$i] > (24.0 - $start_ut[$i])) {
	    pgptxt($stop_ut[$i]/2.0, $stop_day[$i]+$offset+$texth, 0.0, 0.5, $plabel1[$i]);
	    pgptxt($stop_ut[$i]/2.0, $stop_day[$i]+$offset, 0.0, 0.5, $plabel2[$i]);
	    if ((24.0 - $start_ut[$i]) >= 2.0) {
	      pgptxt(($start_ut[$i]+24)/2.0, $start_day[$i]+$offset+$texth, 
		     0.0, 0.5, $code[$i]);
	    }
	} else {

	    pgptxt(($start_ut[$i]+24)/2.0, $start_day[$i]+$offset+$texth, 
		   0.0, 0.5, $plabel1[$i]);
	    pgptxt(($start_ut[$i]+24)/2.0, $start_day[$i]+$offset, 
		   0.0, 0.5, $plabel2[$i]);
	    if ($stop_ut[$i] >= 2.0) {
	      pgptxt($stop_ut[$i]/2.0, $stop_day[$i]+$offset+$texth, 0.0, 1.0, $code[$i]);
	    }

	}
	pgsci(2);
    }
#    pgsch($default_ch);
}

pgclos();

sub draw_bar {
    my ($x, $y) = @_;
    my $ofs = 0.1;
    pgmove($x, $y - $ofs);
    pgdraw($x, $y + $ofs);
    pgmove($x, $y);
}

#($rise, $set) = rise($rat,$dect,($obslat/360.0), ($el_limit/360.0));
#if ($rise eq 'Circumpolar') {

#############################################################
sub minmax {
  # takes an array and provides the minimum and maximum. If
  # $expand_fac is > 0, decrease $min and increase $max by 
  # $expand_fac * ($max - $min).
  my ($arr_ref, $expand_fac) = @_;
  my @sorted = sort numerically (@$arr_ref);
  my $min = $sorted[0];
  my $max = $sorted[$#sorted];

  if ($expand_fac > 0.0) {
    my $fact = $expand_fac * ($max - $min);
    $max = $max + $fact;
    $min = $min - $fact;
  }
  return ($min, $max);
}
#-------------------------------------------------------------------------
sub numerically { $a <=> $b; }
#-------------------------------------------------------------------------

sub date2dayno($$) {
  my ($date, $year) = @_;
  if ($date =~ /(\d+)\/(\d+)/) {
    $_[0] = cal2dayno($1, $2, $year);
  }
}

sub get_ant_times {
  my ($time_file) = @_;
  open (SRC, $time_file) || die "couldn't open file: $!\n";
  while (<SRC>) {
    s/\#.*$//; # Remove comments
    next if (/^\s*$/); # Skip blank line

    ($antenna, $d1, $t1, $d2, $t2) = split;
    #print "DATA = $antenna, $d1, $t1, $d2, $t2\n";
    date2dayno($d1,$year);
    date2dayno($d2,$year);
    
    $antenna =~ s/_/ /g;
    push @ant, $antenna;
    push @start_d, $d1;
    push @start_h, (substr($t1,0,2) + substr($t1,2,2)/60.0);
    while ($d2 > $d1) {
      push @stop_d, $d1;
      push @stop_h, 24.0;
      #	        push @label, "$antenna $d1/$t1 - $d2/$t2";
      push @label, "$antenna";
      $d1++;
      push @ant, $antenna;
      push @start_d, $d1;
      push @start_h, 0.0;
    }
    push @stop_d, $d2;
    push @stop_h, (substr($t2,0,2) + substr($t2,2,2)/60.0);
    #	    push @label, "$antenna $d1/$t1 - $d2/$t2";
    $antenna =~ s/^~+//;
    push @label, "$antenna";
  }
  close SRC;
}

sub get_sched {
  my ($file) = @_;
  my $baseDay = 0;
  open (SRC, $file) || die "couldn't open file: $!\n";
  while (<SRC>) {
    if (/^\#/) {
      # comments
    } elsif (/^\s*$/) {
      # blank line
    } elsif (/^\s*Version/) {
      chop;
      $vers = $_;
    } elsif (/^\s*Start/i) {
      my $dummy;
      ($dummy, $start_year,$start_day, $start_ut) = split;
      $start_day += $baseDay;
      $start_ut = str2turn($start_ut,'H') * 24;
      $year = $start_year;
    } elsif (/^\s*Stop/i) {
      my $dummy;
      ($dummy, $stop_year,$stop_day, $stop_ut) = split;
      $stop_day += $baseDay;
      $stop_ut = str2turn($stop_ut,'H') * 24;
    } elsif (/^\s*basedate\s+(\d+)/i) {
      $baseDay = $1;
    } else {
      ($code, $band, $ants, $d1, $t1, $d2, $t2, $comment) = split;
      $d1 += $baseDay;
      $d2 += $baseDay;
      $comment =~ s/_/ /g;
      $band =~ s/_/ /g;
      push @start_day, $d1;
      push @start_ut, (substr($t1,0,2) + substr($t1,2,2)/60.0);
      push @stop_ut, (substr($t2,0,2) + substr($t2,2,2)/60.0);
      push @stop_day, $d2;
      push @plabel1, "$code $band";
      push @plabel2, "$ants $comment";
      push @code, "$code";
    }
  }
  close SRC;
  $title = "LBA Schedule for $start_year day $start_day to $stop_day.";
}

