#!/usr/local/bin/perl

use strict;
use Time::Local;
require "arglib.pl";

my $settings=&parseArgs(@ARGV);
&initSettings($settings);
&showSettings($settings);
$settings->{START_TS}=&toTimestamp($settings->{START});
$settings->{END_TS}=&toTimestamp($settings->{END});
&clip($settings);
exit 1;


sub showSettings {
  my ($settings)=@_;
  printf STDERR "Settings:\n\n";
  printf STDERR "Date format: YYYYMMDDHHMMSS\n\n";
  foreach my $key (sort keys %$settings) {
    printf STDERR "  %-20s = %s\n",$key,$settings->{$key};
  }
  printf STDERR "\n";
}


sub initSettings {
  my ($settings)=@_;
  $settings->{START}="" unless defined $settings->{START};
  $settings->{END}="" unless defined $settings->{END};
  $settings->{INPUT}="in.dat" unless defined $settings->{INPUT};
  $settings->{OUTPUT}="out.dat" unless defined $settings->{OUTPUT};
  $settings->{DEBUG}="1" unless defined $settings->{DEBUG};
  return $settings;
}


sub toTimestamp {
  my ($str)=@_;
  return -1 if length($str)<1;
  die 'Invalid timestamp "'.$str.'".' unless $str=~/^(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/;
  my ($year,$mon,$day,$hh,$mm,$ss)=($1,$2,$3,$4,$5,$6);
  my $ts = timegm($ss, $mm, $hh, $day, $mon-1, $year); 
}


sub clip {
  my ($s)=@_;
  open IN,$s->{INPUT} or die "Cannot open ".$s->{INPUT}." for reading.";
  binmode IN;
  open OUT,">".$s->{OUTPUT} or die "Cannot open ".$s->{OUTPUT}." for writing.";
  binmode OUT;
  my $buf;
  read IN,$buf,4;
  print OUT $buf;
  my $framesize=unpack "L",$buf;
  printf STDERR "FRAMESIZE: %d\n",$framesize if $s->{DEBUG};
  return unless $framesize>0;
  my $previousInRange=0;
  my $firstTS = undef;
  my $lastTS = undef;
  while (1) {
    my $bytesRead = read IN,$buf,4;
    last unless $bytesRead==4;
    my $ts=unpack "L",$buf;
    $firstTS=$ts unless defined $firstTS;
    $lastTS=$ts;
    my $inRange = &inRange($s,$ts);
    print OUT $buf if $inRange or $previousInRange;
    $bytesRead=read IN,$buf,$framesize;
    print OUT $buf if $inRange;
    $previousInRange=$inRange;
  }
  printf STDERR "RANGE:     %s - %s\n",scalar gmtime $firstTS,scalar gmtime $lastTS;
  close IN;
  close OUT;
}


sub inRange {
  my ($s,$ts)=@_;
  return 0 if $s->{START_TS}>0 and $ts<$s->{START_TS};
  return 0 if $s->{END_TS}>0 and $ts>$s->{END_TS};
  return 1;
}

