#!/usr/local/SunOS/bin/perl
#
$perldir = "/usr/local/lib/perl5";
push(@INC, "$perldir");
require Time::Local;
#
# This script generates a report of gaps, overlaps, etc.
#
# Usage: cat sync file > goatreport.pl (tol) (-j) (-c) (-o) (-g)
#
# where:
#
# tol is a numeric tolerance in seconds
# -j indicates output Julian day format
# -c indicates output continuous
# -o indicates output overlaps
# -g indicates output gaps
# -s silent - status set to nonzero if there is anything to be reported
 
$jflag = 0;
$tol = 0;
$gapchecked = 0;
$overlapchecked = 0;
$continuouschecked = 0;
$silent = 0;
$i = 0;
while ($i <= $#ARGV) {
        if ("$ARGV[$i]" eq "-j") { $jflag = 1; }
        elsif ("$ARGV[$i]" eq "-o") { $overlapchecked = 1; }
        elsif ("$ARGV[$i]" eq "-c") { $continuouschecked = 1; }
        elsif ("$ARGV[$i]" eq "-g") { $gapchecked = 1; }
        elsif ("$ARGV[$i]" eq "-s") { $silent = 1; }
        else { $tol = $ARGV[$i];}
	$i++;
}

$count=0;

&do_timetable();

exit($count == 0 ? 0 : 1);

sub timediff() {

	local ($year, $mon, $mday) = ();
	local ($hours, $min, $sec) = ();
	local ($time1, $time2)=();

	my ($yyyymmdd1, $hhmmss1, $yyyymmdd2, $hhmmss2) = @_;

	($hours, $min, $sec) = split (':', $hhmmss1);
	$sec = int ($sec);

	($year, $mon, $mday) = split ('-', $yyyymmdd1);

	$mon--;
	$year -= 1900;
	$time1 = Time::Local::timegm($sec, $min, $hours, $mday, $mon, $year);

	($hours, $min, $sec) = split (':', $hhmmss2);
	$sec = int ($sec);

	($year, $mon, $mday) = split ('-', $yyyymmdd2);

	$mon--;
	$year -= 1900;
	$time2 = Time::Local::timegm($sec, $min, $hours, $mday, $mon, $year);

	return ($time1 - $time2);

}
sub hhmmss
{
        local ($seconds) = @_ ;
	local ($hours, $minutes, $timestr)=();

	$hours = int ($seconds/3600);
	$seconds -= $hours*3600;
	$minutes = int ($seconds/60);
	$seconds -= $minutes*60;
	$timestr = sprintf ("%02d:%02d:%02d", $hours, $minutes, $seconds);
	
	return ($timestr);
}

sub do_timetable { 

	local ($infile,$network,$station,$location,$channel)=(); 
	local ($name, $oldname)=();
	local ($yyyymmdd1,$hhmmss1,$yyyymmdd2,$hhmmss2,$xyyyymmdd,$xhhmmss)=();
	local ($yyyymmdd3,$hhmmss3,$yyyymmdd4,$hhmmss4)=();
	local ($tdiff, $absdiff, $duration)=();
	local ($date1, $date2, $date3, $date4)=();
	local $recsize = 0;

	$found = 0;

	#skip first line
	while(<STDIN>) {
		if (!($_ =~ /|/)) {
                        print "$infile is not a valid Sync File.";
                        exit(0);
                }
                last;
        }


	if (!$silent) {
		print "GOAT Report\n";
		if ($gapchecked) { print "g) indicates gap\n"; }
		if ($overlapchecked) { print "o) indicates overlap\n"; }
		if ($continuouschecked) { print "c) indicates continuous\n"; }
		print "(tolerance has been set to $tol)\n\n";
		print "   NE.STAT.LO.CHA\tSTARTTIME\t\tENDTIME\t\tDURATION\n";
	}
	
	while(<STDIN>) {
		($network, $station, $location, $channel, $date1, $date2, $max_drift) = split(/[\t|]/);
		if ("$date2" eq "") { next; }
		$location =~ s/\s//g;
		if ($location eq "") { $location = "__" }
		($yyyymmdd1, $hhmmss1) = &synctoqc($date1);
		$gmttime1 = &gettimegm($yyyymmdd1,$hhmmss1); 

		($yyyymmdd2, $hhmmss2) = &synctoqc($date2);
		$gmttime2 = &gettimegm($yyyymmdd2,$hhmmss2); 

		last;
	}

	$name = "$network.$station.$location.$channel";
	if ($continuouschecked) {
		$cstartyy = $yyyymmdd1;
		$cstarthh = $hhmmss1;
		if (!$silent) {
			$printname = $name;
                       	$printname =~ s/__//;
			print "c) $printname \t$yyyymmdd1 $hhmmss1 ";
		}
	}

	while (<STDIN>){

		$recsize = length $_;

		($network, $station, $location, $channel,
			$date3, $date4, $max_drift) = split(/[\t|]/);
		if ("$date4" eq "") { next; }
		if ($location eq "") { $location = "__"; }

		($yyyymmdd3, $hhmmss3) = &synctoqc($date3);
		$gmttime = &gettimegm($yyyymmdd3,$hhmmss3); 
		($yyyymmdd4, $hhmmss4) = &synctoqc($date4);
		$gmttime = &gettimegm($yyyymmdd4,$hhmmss4); 

		$oldname = $name;
		$name = "$network.$station.$location.$channel";

		if ("$name" ne "$oldname") { 

			# end old continuous
			if ($continuouschecked) {
				if ($silent) { $count++; }
				else {
					$absdiff = abs( 
					&timediff($cstartyy, $cstarthh, $yyyymmdd2, $hhmmss2)); 
					$duration = &hhmmss($absdiff);
					$printme1 = &getprinttime($yyyymmdd2,$hhmmss2);
					print "\t$printme1\t$duration\n";
				}
		
			}

			# starting another net/sta/location/chan

			if  ($gapchecked &&
			("$currchan" eq "" || "$currchan" lt "$name")) { 
				$gmttime = &gettimegm($yyyymmdd3,$hhmmss3); 
			}

			# start new continuous
			if ($continuouschecked) {
				$cstartyy = $yyyymmdd3;
				$cstarthh = $hhmmss3;
				if (!$silent) {
					$printname = $name;
                                	$printname =~ s/__//;
					$printme1 = &getprinttime($yyyymmdd3,$hhmmss3);
					print "c) $printname \t$printme1 ";
				}

			}

			$yyyymmdd1 = $yyyymmdd3;
			$hhmmss1 = $hhmmss3;
			$yyyymmdd2 = $yyyymmdd4;
			$hhmmss2 = $hhmmss4;

			next; 

		}

		$tdiff = &timediff($yyyymmdd2, $hhmmss2, $yyyymmdd3, $hhmmss3); 
		$sample_tol = 0;
                if ($usesamp && ("$sample_rate" ne "")) {
                    	$sample_tol = 1/($sample_rate*2);
                }

		if (abs($tdiff) > $tol + $sample_tol) {
			# end old continuous
			if ($continuouschecked) {
				if ($silent) { $count++; }
				else {
					$absdiff = abs( 
				&timediff($cstartyy, $cstarthh, $yyyymmdd2, $hhmmss2)); 
					$duration = &hhmmss($absdiff);
					$printme1 = &getprinttime($yyyymmdd2,$hhmmss2);
					print "\t$printme1\t$duration\n";
				}
			}

			if ($tdiff > 0) { 
				if ($overlapchecked) {
					if ($silent) { $count++; }
					else {
						$printname = $name;
                                        	$printname =~ s/__//;
						$absdiff = abs($tdiff);
						$duration = &hhmmss($absdiff);
						$printme1 = &getprinttime($yyyymmdd3,$hhmmss3);
						$printme2 = &getprinttime($yyyymmdd2,$hhmmss2);
						print "o) $printname \t$printme1\t$printme2\t$duration\n";
					}
				}	
			} else { 
				if ($gapchecked) {
					if ($silent) { $count++; }
					else {
						$printname = $name;
                                        	$printname =~ s/__//;
						$absdiff = abs($tdiff);
						$duration = &hhmmss($absdiff);
						$printme1 = &getprinttime($yyyymmdd2,$hhmmss2);
						$printme2 = &getprinttime($yyyymmdd3,$hhmmss3);
						print "g) $printname \t$printme1\t$printme2\t$duration\n";
					}
				}
			}
			
			# start new continuous	
			if ($continuouschecked) {
				$cstartyy = $yyyymmdd3;
				$cstarthh = $hhmmss3;
				if (!$silent) {
					$printname = $name;
                                       	$printname =~ s/__//;
					$printme1 = &getprinttime($yyyymmdd3,$hhmmss3);
					print "c) $printname \t$printme1 ";
				}
			}
		}

		$yyyymmdd1 = $yyyymmdd3;
		$hhmmss1 = $hhmmss3;
		$yyyymmdd2 = $yyyymmdd4;
		$hhmmss2 = $hhmmss4;

	}

	# end continuous
	if ($continuouschecked) {
		if ($silent) { $count++; }
		else {
			$absdiff = abs( 
				&timediff($cstartyy, $cstarthh, $yyyymmdd2, $hhmmss2)); 
			$duration = &hhmmss($absdiff);
			$printme1 = &getprinttime($yyyymmdd2,$hhmmss2);
			print "\t$printme1\t$duration\n";
		}
	}
}


sub gettimegm() {

	local ($mon, $year, $hours, $min, $sec) = ();
	my ($yyyymmdd, $hhmmss) = @_;

	($hours, $min, $sec) = split (':', $hhmmss);
	$sec = int ($sec);

	($year, $mon, $mday) = split ('-', $yyyymmdd);

	$mon--;
	$year -= 1900;

	$time = Time::Local::timegm($sec, $min, $hours, $mday, $mon, $year);

	return ($time);

}

sub getprinttime() {

	my ($yyyymmdd, $hhmmss) = @_;
	local ($mon, $year, $hours, $min, $sec) = ();

	if ($jflag != 0) {
		($hours, $min, $sec) = split (':', $hhmmss);
		$sec = int ($sec);

		($year, $mon, $mday) = split ('-', $yyyymmdd);

		$mon--;
		$year -= 1900;

		$time = Time::Local::timegm($sec, $min, $hours, $mday, $mon, $year);
		($sec, $min, $hours, $mday, $mon, $year, $wday, $yday, $isdst) =
                	gmtime($time);

		$yday++;
		$year += 1900;

                $yyyymmdd = sprintf("%04d,%03d", $year, $yday);
        }

        return ("$yyyymmdd $hhmmss");

}

sub jdatetoepoch ()
{

	local ($mon, $year, $hours, $min, $sec) = ();
	local $time;
	
	my ($jday, $year) = @_;

	($mon, $mday) = &get_month_mday ($year, $jday);

	$mon--;
	$year -= 1900;

	$sec = 0;
	$min = 0;
	$hours = 0;
	$time = Time::Local::timegm($sec, $min, $hours, $mday, $mon, $year);

	return ($time);

}

sub synctoqc ()
{

        local ($yyyymmdd, $hhmmss) = ();
        local ($mon, $mday, $year, $hours, $min, $sec) = ();
        local ($time, $wday, $yday, $isdst) = ();

        my ($date) = @_;

        ($year, $yday, $hhmmss) = split (/[, ]/, $date, 3);
  	if ("$hhmmss" eq "") { $hhmmss = "00:00:00"; }
        ($hours, $min, $sec) = split(':', $hhmmss);
	($month, $mday) = &get_month_mday($year,$yday);

        $mon--;
        $yday--;
        $year -= 1900;
        $time = Time::Local::timegm($sec, $min, $hours, $mday, $mon, $year);
        ($sec, $min, $hours, $mday, $mon, $year, $wday, $yday, $isdst) = gmtime($time);
        $year += 1900;
        $mon++;

	$yyyymmdd = sprintf("%04d-%02d-%02d", $year,$mon,$mday);

        return ($yyyymmdd, $hhmmss);

}


sub get_month_mday {

	local @days_in_month = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
	local $isleap = 0;
	local $mday = 0;

	my ($year, $yday) = @_;
	
	if (!($year%4) && ($year%100 || !($year%400))) {
                $days_in_month[1] = 29;
        }

	$mon = 0;
	$mday = $yday;

	while ($mday > $days_in_month[$mon]) {
		$mday -= $days_in_month[$mon];
		$mon++;
	}

	$mon++;

	return ($mon, $mday);
}
