#!/opt/perl/bin/perl
use strict;
use Getopt::Long;
use GPS::StrUtil;
use GPS::Coords;
use GPS::DataTable;
use GPS::NetMaker;
use GPS::DATES;
use GPS::Defaults;
use File::Basename;
use Carp;
use Cwd;

my $progname = basename $0;
my $usage = <<EOT;
 ==================================================================
  $progname produces lists (networks ) containing name, lat and lon
  from a given list of sites and common sites.

  Usage:
  $progname -sites  sites_file_name [-csites common_sites_file_name] 
            [-nname net_name] [-outdir dir] 
            [-max_net nmax]  [-max_snet nsmax ]

  The input files should contain : name, lon, lat as their 
  first three fields in each line.
  
  on output:
  net_name is used as a prefix for all the generated networks.
  the resulting lists are saved in <local_dir/snets> if exists.
  otherwise the local dir will be used.
  Each file will contain the fields:
  name lon lat sub_net_name

  nmax  : maximum number of sites in a network (default 36)
  nsmax : maximum number of sites in a sub-network (default 33)
  
  by default, nets will be created with a total of 36 sites that 
  include 3 common sites in each subnet.

  Marcelo Santillan
  GPS Lab & PANGA facility
  Central Washington University.
  April 2006
 ===================================================================
EOT

my ($help  ,$args,   $fsites,
    $outdir,$fcsites,$prefix,
    $here,  $nname,  $max_snet,
    $max_net,$save,  $sfields,
    $cfields,$sfields_out,$cfields_out )=('')x15;
$sfields  = 'name,lon,lat';
$cfields  = 'name,lon,lat';
$sfields_out  = 'name,lon,lat';
$cfields_out  = 'name,lon,lat';
$max_net  = 36;
$max_snet = 33;
$here   = cwd();
$outdir = "$here/snets";
$args=@ARGV;


my ($date,$yyyy,$doy,$yy);

GetOptions ( 
     'sites=s'    => \$fsites,
     'date:s'     => \$date,
     'csites=s'   => \$fcsites,
     'sfields:s'  => \$sfields,
     'cfields:s'   => \$cfields,
     'sfields_out:s'  => \$sfields_out,
     'cfields_out:s'  => \$cfields_out,
     'nname:s'    => \$prefix,
     'max_net:i'  => \$max_net,
     'max_snet:i' => \$max_snet,
     'outdir:s'   => \$outdir,
     'help'       => \$help,
     'save!'       => \$save,

) || die "$progname: error in options\n $usage";


if ( ! $args || $help ) { die $usage; }

#if ( ! -d $outdir ) { die "dir $outdir doesn't exists\n"; }

if ( ! $prefix ) {
  ($prefix) = split /\./,basename $fsites;
}

my %par = get_defaults();

my %rnx=get_rnx_names($date);

$sfields = lc $sfields;
check_fields($sfields);
$cfields = lc $cfields;
check_fields($cfields);
$sfields_out = lc $sfields_out;
check_fields($sfields_out);
$cfields_out = lc $cfields_out;
check_fields($cfields_out);

my $sites = GPS::DataTable->new( file        => $fsites,
                            fields_in   => $sfields,
                            fields_out  => $sfields_out);


my $csites = {};

if ( $fcsites ) {
   $csites = GPS::DataTable->new( file        => $fcsites,
                             fields_in   => $cfields,
                             fields_out  => $cfields_out);
}
else {
  $max_snet = $max_net;
}

filter_sites( $date,$sites->{data} );
filter_sites( $date,$csites->{data} );


my $sn =GPS::NetMaker->new(  max_net  => $max_net , 
                         max_snet => $max_snet
                      );

print STDERR "# Making sub-nets from $fsites\n";
print STDERR "# with common sitesfrom $fcsites\n" if $fcsites;


$sn->make_nets( prefix       => $prefix,
                sites        => $sites->{data},
                common_sites => $csites->{data}
               );

#print STDERR "# Generated sub_nets: \n",
#             join "\n", map { $_ } $sn->get_names( sites => 1);
#print "\n";
my $sname;
foreach my $s ( $sn->get_names() ) {
  my @sites = $sn->sub_net($s);
  my %seen =();
  @sites =  grep { ! $seen{$_}++ } @sites; #$sn->sub_net($s);
  my $line = uc( $s) . lc (" @sites\n");
  print $line;
#  print $fh $line;
}


exit;
my $sname;
foreach my $s ( $sn->get_names() ) {
  print '#'.'='x30,"\n";
  print "# Sub-Net $s\n";
  $sname= "$s.list";
  $sn->print( sub_net => $s );
  $sn->print( sub_net => $s ,file => "$outdir/$sname" ) if $save;
}

sub filter_sites {
  my $date = shift;
  return if ! $date;
  my $data_in = shift;
  my $data = [];
  foreach my $h ( @{$data_in} ) {
    next if ! exists $rnx{lc $h->{name}};
    push @$data,$h;
  }
  @{$data_in} = @$data;
}

sub get_rnx_names {
  my $date = shift;
  
  return () if ! $date;
  
  my ($yyyy,$doy) = split(' ',get_date($date,'doy'));
  
  my $dir = "$par{RNX_DIR_ARCHIVE}/$yyyy/$doy";
  
  opendir(my $dh,$dir) or die "Couldn't open $dir $!\n";

  my (%sta,$site);

  foreach my $f ( grep { /^[a-z0-9_]{4}/ } readdir($dh) ) {
     $site = unpack('a4',$f);
     $sta{$site}=$f;    
  }
  
  return %sta;
}

sub check_fields {
   my @f =  split /,/, shift;
   my $ok = 0;
   my %cf;
   @cf{@f}=();
   if ( exists $cf{name} &&
        exists $cf{lon} &&
        exists $cf{lat} ) {
        $ok = 1;
  }
  die "field names : name lon lat,  must be present\n" if ! $ok;
}


