#!/opt/perl/bin/perl 
use strict;
use GPS::DATES qw(get_date yy2y);
use GPS::Geodesy;
use Cwd;
use Carp;
use File::Basename;
use Getopt::Long;

my $progname = basename $0;
my $usage = <<EOT;
  $progname extract information from the rinex file and 
  generates GIPSY station info files.
Usage:
  
  
  $progname -site site [-outdir outdir]
  
  uses first_rnx to get the rinex file ( see first_rnx )
  
  
  $progname -rnx rinexfile [-outdir outdir]

  outdir : output directory (default current dir.)

Output: 
   files:  sta_pos.tmp
           sta_id.tmp
           sta_svec.tmp
           sta_rcvr.tmp
           sta_loc.tmp
   stdout: meta-data info
EOT
my $here = cwd();
my $args = @ARGV;
my ($help,$rnx,$year) = ('')x3;
my $outdir = $here;
#my $teqc = '/home/gnet/processing/bin/Linux86/teqc';
my $teqc = 'teqc';
my $site = '';
my  ($do_pos,$do_id,$do_svec,$do_rcvr,$do_coords)=('')x5;
#Get command line options
GetOptions( "site:s"   => \$site,
            "year:s"   => \$year,
            "rnx:s"    => \$rnx,
            "outdir:s" => \$outdir,
            'dir:s'    => \$outdir,
            'nopos'     => sub { $do_pos='-nopos'},
            'noid'      => sub { $do_id ='-noid'},
            'nosvec'    => sub { $do_svec='-nosvec'},
            'norcvr'    => sub { $do_rcvr='-norcvr'},
            'nocoords'  => sub { $do_coords='-nocoords'},
      	     help   => \$help,
	   ) || die "error in options";


if ( ! $args ) { die "$usage\n" };
if (  $help ) {  print "$usage\n";exit; }
if ( $site )  {
   $site = lc $site;
   $rnx = `first_rnx $site $year`; chomp $rnx;
}
if ( ! -e $rnx ) { 
  croak "$rnx not found $!\n"; 
}

my ( $doy,$yy) = (0,0);
   ( $site,$doy,$yy) = unpack("A4A3x2A2",basename($rnx));

my $yyyy = yy2y($yy);

my $brdc = "brdc${doy}0.${yy}n";

if ( ! -e $brdc ) { system("get_brdc -date $yyyy,$doy"); }
my $mcmd = "$do_pos $do_id $do_svec $do_rcvr $do_coords";
open(META,"| mk_meta -dir $outdir $mcmd") or croak "couldn't open mk_meta $!\n";

if ( $rnx =~ /\d\d[d](\.Z|)$/i ) {
   system("crz2rnx", $rnx);
   $rnx = glob("$site$doy*${yy}o"); #`crz2rnx -echo $rnx`; 
}
# print get_pos($rnx,$brdc);
 my $SITE=uc $site;
 my @m; 
 push  @m, "new meta data file $rnx: $site $yyyy $doy\n";
	  
 @m = grep ! /(latitude|longitude|elevation)/,
           `(teqc -plot +meta -O.mo $SITE $rnx) 2> /dev/null`;
 push @m , get_pos($rnx,$brdc);
 
 my @sta_name= grep /(4-char station code|station name)/,@m;
 
 @m = (@sta_name,grep !/(4-char station code|station name)/, @m); 

# print @m;
 @m = trans_meta(\@m);
 print @m;
 
 print META @m;


sub get_pos {
   my $rnx  = shift;
   my $brdc = shift;
   my @m;
   
   my ($x,$y,$z) = split ' ', (grep /APPROX POSITION XYZ/,`head -200 $rnx`)[0];
 
  if ( sqrt($x*$x+$y*$y+$z*$z) < 6378136.3 ) {
    my @o = `teqc +qc +ap +quiet -nav $brdc $rnx`; chomp @o;
    ($x,$y,$z) =  split(' ',(map { s/:(.*)\(m\)//;$1 } grep { /\(xyz\)/ } @o)[0]);
  }
  
  push @m, "APPROX POSITION XYZ        : $x $y $z\n";
  
  return @m
} 

sub trans_meta {
 
 my $aref = shift;
 my %conv = (
      'site network'        => 'Site Network',
      '4-char station code' => '4 CH ID',
      'station name' => 'Name',
      'antenna id number' => 'Ant S/N',
      'antenna type' => 'Ant Model',
      'radome' => 'Radome' ,
      'antenna latitude (deg)' => 'Latitude',
      'antenna longitude (deg)' => 'Longitude',
      'antenna elevation (m)' => 'Elevation',
      'antenna height (m)'    => 'Ant Height',
      'receiver id number'    => 'Rx S/N',
      'receiver type'         => 'Rx Model',
      'receiver firmware'   => 'Firmware',
      'rx software version'   => 'Firmware',
     # 'trans date  time'   => 'Date',
      'start date  time'   => 'Date',
      'r start date  time'   => 'Date',
      'r program'            => 'comment',
      'approx position xyz'  => 'XYZ',
#      'antenna wgs 84 (xyz)' => 'XYZ',
      'antenna wgs 84 (geo)' => 'Lat Lon',
      'wgs 84 height'        => 'Elevation'
    );
	

   my @lines;

   push @lines,"\n*****************\n";

   foreach my $l ( @$aref ) {   
     my %out = ();
     chomp $l;
     my ($k,$v);
     if ( $l =~ /^(.*?):(.*)$/ ) {
       #($k,$v) = split(/(\s+|):\s+/,$l);
       ($k,$v) = ($1,$2);
     }
     #}else {
     #  ( $k,$v ) = unpack("a27a*",$l);
     #}
     $v =~ s/(\(m\)|m)//g;
     $v =~ s/ deg//g;
     $v = trim($v);
     $k =~ s/(&|:)//g;
     $k = lc $k;
     $k=trim($k);
     next  if ! exists $conv{$k};
     if ( $k =~ /4-char station code/ ) {
         $out{$conv{$k}} = uc $v;
     }elsif ( $k eq 'antenna type' ) {
         my ($a,$d)=unpack("a16a4",$v);
         $out{$conv{$k}}=$a;
         $out{$conv{radome}}=$d;
     } elsif ( $k =~ /r start date/) {
         my ($y,$m,$d)= split(/-/, unpack("A10",$v));
	 $out{Date} = "$m/$d/$y";
     } elsif ( $k eq 'antenna wgs 84 (geo)' ) {
          my ($lat,$lon)  = split ' ', $v;
	      $out{Latitude}  = $lat; 
	      $out{Longitude} = $lon;
     } elsif ( $k =~ /wgs 84 height/ ) {
          $out{Elevation} = $v;
     #} elsif ( $k eq 'antenna wgs 84 (xyz)' ) {
     } elsif ( $k eq 'approx position xyz' ) {
         my ($x,$y,$z) = split ' ', $v ;
         $out{'Ant X'} = $x;	 
         $out{'Ant Y'} = $y;	 
         $out{'Ant Z'} = $z;	 
         my ($lat,$lon,$h ) = xyz2llh($x,$y,$z);
	     $out{Latitude}  = $lat; 
	     $out{Longitude} = $lon;
         $out{Elevation} = $h;
     } else {
       if ( ! $out{$conv{$k}} ) {
         $out{$conv{$k}}=$v ;
       }
     }
     push @lines, ( map {"$_\: $out{$_}\n" } keys %out );
   }
   my ($st,$city,undef,undef,$reg) = get_info_from_comments();
   my $metadata = qq{
Site Network: $reg 
IERS Domes: N/A
State: $st
City: $city
   }; 
   push @lines,$metadata;
   push @lines,"\n*****************\n";
        
   return @lines 
}
sub get_info_from_comments {
  open(my $fh , $rnx) or croak "couldn't open $rnx $!\n";
  my ($st,$city,$reg,$lon,$lat)=('')x4;
  while ( <$fh> ) {
    last if /END OF HEADER/ || $. > 500 ;
    next if ! /COMMENT/;
    last if /End of DB comments/i;
    s/COMMENT//;
    s/\s+$//;
    s/^\s+//;
    next unless length;
    if ( /_([a-zA-Z\d]+)_([a-zA-Z]{2})_\d{4}_\w+$/ ) {
      $city = $1;
      $st = $2;
    }
    if ( /Monument location/i ) {
      s/Monument location://;
      ($lat,$lon) = split ' ',$_;
    } 
  }
  $reg = get_region($st,$lon,$lat);
  return ( $st,$city,$lon,$lat,$reg)
}
sub is_nucleus { 
  my $site = uc shift;
  my $nucleus = 1;
  if ( $site =~ /(P\d{3}|A[BCV]\d{2}|RG\d{2})/ ) { $nucleus = 0; }

  return $nucleus
}
sub get_region {
   my $state = uc pack 'a2', shift;
   my ($lon,$lat) = @_;
   my %region = (
      CS => 'SC',
      CN => 'NC',
      CA => 'CA',
      WA => 'PN',
      OR => 'PN',
      AK => 'AK',
      ID => 'BR',
      NV => 'BR',
      AZ => 'BR',
      NM => 'RM',
      CO => 'RM',
      WY => 'RM',
      MN => 'RM',
      KS => 'RM',
      TX => 'RM',
      NE => 'RM',
      SD => 'RM',
      ND => 'RM',
      WI => 'RM',
   );

   my $reg =  exists $region{$state} ? $region{$state} : 'RM';
   $lon = $lon < 0 ? $lon+360 : $lon;
   #not quite true, but good enough.
   if ( $state eq 'CA' ) {
     $reg = $lat >= 36 && $lon <= 240 ? 'NC' : 'SC';
   }
   if ( is_nucleus($site) ) { $reg = "Nucleus $reg"; }
   return $reg
}

sub trim {
   my $s = shift;
   $s =~ s/^\s+//g;
   $s =~ s/\s+$//g;
   return $s
}





