#!/usr/bin/perl -w
# NAME: cnthgt.pl
# AIM: *** VERY SPECIALISED *** Just count some HGT files in a folder...
# 12/11/2014 - Add a little moe information about what is being seen...
# 21/05/2014 - Initial cut
use strict;
use warnings;
use File::Basename;  # split path ($name,$dir,$ext) = fileparse($file [, qr/\.[^.]*/] )
use Cwd;
my $os = $^O;
my $perl_dir = '/home/geoff/bin';
my $PATH_SEP = '/';
my $temp_dir = '/tmp';
if ($os =~ /win/i) {
    $perl_dir = 'C:\GTools\perl';
    $temp_dir = $perl_dir;
    $PATH_SEP = "\\";
}
unshift(@INC, $perl_dir);
require 'lib_utils.pl' or die "Unable to load 'lib_utils.pl' Check paths in \@INC...\n";
# log file stuff
our ($LF);
my $pgmname = $0;
if ($pgmname =~ /(\\|\/)/) {
    my @tmpsp = split(/(\\|\/)/,$pgmname);
    $pgmname = $tmpsp[-1];
}
my $outfile = $temp_dir.$PATH_SEP."temp.$pgmname.txt";
open_log($outfile);

# user variables
my $VERS = "0.0.2 2014-01-13";
my $load_log = 0;
my $verbosity = 0;
my $out_file = '';
#my $in_dir = 'F:\data\dem3\usgs';
my $in_dir = '';
my $add_ranges = 1;
my $add_missed = 1;
my $max_line = 140;

# ### DEBUG ###
my $debug_on = 0;
my $def_file = 'F:\data\dem3\hgt';
my $miss_out = $temp_dir.$PATH_SEP."tempmiss.txt";

### program variables
my @warnings = ();
my $cwd = cwd();

sub VERB1() { return $verbosity >= 1; }
sub VERB2() { return $verbosity >= 2; }
sub VERB5() { return $verbosity >= 5; }
sub VERB9() { return $verbosity >= 9; }

sub show_warnings($) {
    my ($val) = @_;
    if (@warnings) {
        prt( "\nGot ".scalar @warnings." WARNINGS...\n" );
        foreach my $itm (@warnings) {
           prt("$itm\n");
        }
        prt("\n");
    } else {
        prt( "\nNo warnings issued.\n\n" ) if (VERB9());
    }
}

sub pgm_exit($$) {
    my ($val,$msg) = @_;
    if (length($msg)) {
        $msg .= "\n" if (!($msg =~ /\n$/));
        prt($msg);
    }
    show_warnings($val);
    close_log($outfile,$load_log);
    exit($val);
}


sub prtw($) {
   my ($tx) = shift;
   $tx =~ s/\n$//;
   prt("$tx\n");
   push(@warnings,$tx);
}

sub process_in_file($) {
    my ($inf) = @_;
    if (! open INF, "<$inf") {
        pgm_exit(1,"ERROR: Unable to open file [$inf]\n"); 
    }
    my @lines = <INF>;
    close INF;
    my $lncnt = scalar @lines;
    prt("Processing $lncnt lines, from [$inf]...\n");
    my ($line,$inc,$lnn);
    $lnn = 0;
    foreach $line (@lines) {
        chomp $line;
        $lnn++;
        if ($line =~ /\s*#\s*include\s+(.+)$/) {
            $inc = $1;
            prt("$lnn: $inc\n");
        }
    }
}

sub process_in_dir() {
    my $dir = $in_dir;
    if (! -d $in_dir) {
        prt("Input directory $dir does NOT exist!\n");
        return;
    }
    if (! opendir(DIR,$dir)) {
        prt("Unable to open directory $dir!\n");
        return;
    }
    my @files = readdir(DIR);
    closedir(DIR);
    my $cnt = scalar @files;
    prt("Got $cnt items from a readdir $dir\n");
    my ($file,$ff,$scnt);
    ut_fix_directory(\$dir);
    my @hgt = ();
    my %hgthash = ();
    my @check = ();
    my $txtcnt = 0;
    my $batcnt = 0;
    my $gifcnt = 0;
    my $zipcnt = 0;
    my $dbcnt = 0;
    foreach $file (@files) {
        next if ($file eq '.');
        next if ($file eq '..');

        $ff = $dir.$file;
        if (-f $ff) {
            $file = uc($file);  # deal ONLY in UPPER CASE
            if ($file =~ /^[NS]\d+[EW]\d+\.HGT$/) {
                push(@hgt,$file);
                $hgthash{$file} = 1;
            } elsif ($file =~ /\.TXT$/) {
                $txtcnt++;  # skip text
            } elsif ($file =~ /\.BAT$/) {
                $batcnt++;
            } elsif ($file =~ /\.DB$/) {
                $dbcnt++;
            } elsif ($file =~ /\.GIF$/) {
                $gifcnt++;
            } elsif ($file =~ /\.ZIP$/) {
                $zipcnt++;
            } else {
                push(@check,$file);
            }
        } elsif (-d $ff) {
            # ignore dirs
        } else {
            prt("WHAT IS THIS $ff - *** FIX ME ***\n");
            exit(1);
        }
    }
    prt("Skipped $txtcnt TXT, $batcnt BAT, $gifcnt GIF, $zipcnt ZIP and $dbcnt DB file\n");
    $scnt = scalar @check;
    if ($scnt) {
        prt("Skipping $scnt files...\n");
        prt(join(" ",@check)."\n");
    }
    # =============================================
    # deal with list if HGT files
    # =============================================
    my $hcnt = scalar @hgt;
    prt("Got $hcnt .hgt N|S file to process...\n");
    my ($ns,$lat,$ew,$lon,$ll);
    my %latlon = ();
    foreach $file (@hgt) {
        if ($file =~ /^(N|S)(\d+)(E|W)(\d+)\.HGT$/) {
            $ns = $1;
            $lat = $2;
            $ew = $3;
            $lon = $4;
            $lat *= -1 if ($ns eq 'S');
            $lon *= -1 if ($ew eq 'W');
            $ll = "$lat,$lon";
            $latlon{$ll} = 1;
        } else {
            prt("Fix regex - failed on [$file]\n");
            return;
        }
    }

    my @arr = keys %latlon;
    my $llcnt = scalar @arr;
    my $maxcnt = 0;
# 08/06/2012  09:49         2,884,802 N00E006.hgt
# 23/11/2012  16:21         2,884,802 N00E173.hgt
# 29/09/2012  23:58         2,884,802 N00W050.hgt
# 23/10/2012  19:09         2,884,802 N83W078.hgt
# 08/06/2012  13:34         2,884,802 S01E006.hgt
# 29/10/2012  19:54         2,884,802 S06E176.hgt
# 24/08/2012  19:52         2,884,802 S06W036.hgt
# 28/02/2009  10:01         2,884,802 S90W180.hgt
    my @missed = ();
    my %missll = ();
    my %ascii = (); # list found
    my ($aline,$loc);
    my ($tlat,$tlon);
    for ($lat = -90; $lat < 90; $lat++) {
        $aline = ' ' x 361;
        $loc = 0;
        for ($lon = -180; $lon < 180; $lon++) {
            $maxcnt++;
            $tlat = $lat;
            $tlon = $lon;
            $ns = 'N';
            if ($tlat < 0) {
                $ns = 'S';
                $tlat *= -1;
            }
            $ew = 'E';
            if ($tlon < 0) {
                $ew = 'W';
                $tlon *= -1;
            }
            $tlat = "0$tlat" if (length($tlat) < 2);
            $tlon = "00$tlon" if (length($tlon) < 2);
            $tlon = "0$tlon" if (length($tlon) < 3);
            $file = $ns.$tlat.$ew.$tlon.".HGT";
            if (!defined $hgthash{$file}) {
                push(@missed,$file);
                $ll = "$lat,$lon";
                $missll{$ll} = 1;
            } else {
                # add a '.' for the HGT found
                $aline = substr($aline,0,$loc).'.'.substr($aline,($loc+1));
            }
            $loc++;
        }
        $ascii{$lat} = $aline;  # for each LAT -90 to < 90
    }

    @missed = sort @missed;
    my $mcnt = scalar @missed;
    my $pct = (($mcnt / $maxcnt) * 100);
    $pct = (int($pct * 10)) / 10;
    $scnt = ($maxcnt - $llcnt);
    my $msg = "Got $llcnt lat,lon pairs, on a maximum of $maxcnt pairs, missing $mcnt ($scnt) $pct percent\n";
    prt($msg);
    $msg .= "from scan of directory [$dir]\n";
    $tlon = 90 - 1;
    $tlat = -90;
    if ($add_ranges) {
        # from North, head south
        for ($lat = 90-1; $lat >= -90; $lat--) {
            $aline = $ascii{$lat};
            if ($aline =~ /^\s+$/) {
                # all space
            } else {
                $tlon = $lat + 1;
                last;
            }
        }
        $msg .= "No HGT in latitude range 89 to $tlon\n";
        # from South head North
        for ($lat = -90; $lat < 90; $lat++) {
            $aline = $ascii{$lat};
            if ($aline =~ /^\s+$/) {
                # all space
            } else {
                $tlat = $lat -1;
                last;
            }
        }
        $msg .= "No HGT in latitude range -90 to $tlat\n";
    }
    ################## generate ASCII map #######################
    #############################################################
    $msg .= "ASCII graph where '.' represents a HGT file found, a 'blank' where none.\n";
    for ($lat = $tlon; $lat >= $tlat; $lat--) {
        $ff = sprintf("%3d",$lat);
        if ($add_ranges) {
            if ($lat == $tlat) {
                $aline = '=' x 361;
                $msg .= "$ff $aline $ff \n";
            }
        }
        if (defined $ascii{$lat}) {
            $aline = $ascii{$lat};
        } else {
            $aline = ' ' x 361;
        }
        ###$msg .= $ascii{$lat}."\n";
        $msg .= "$ff $aline $ff\n";
        if ($add_ranges) {
            if ($lat == $tlon) {
                $aline = '=' x 361;
                $msg .= "$ff $aline $ff\n";
            }
        }
    }
    ################################################################
    ### prt(join(" ",@missed)."\n");
    if ($add_missed) {
        $aline = '';
        $msg .= "List of $mcnt 'missing' HGT files\n";
        $msg .= "const char *hgt3missed[] = {\n";
        foreach $file (@missed) {
            $aline .= ', ' if (length($aline));
            $aline .= '"'.$file.'"';
            if (length($aline) > $max_line) {
                $msg .= "$aline,\n";
                $aline = '';
            }
        }
        $msg .= "$aline, 0\n" if (length($aline));
        $msg .= "};\n";
    }
    $msg .= "# Generated by $pgmname on ".lu_get_YYYYMMDD_hhmmss_UTC(time())." UTC\n";
    write2file($msg,$miss_out);
    prt("Missing HGT written to file $miss_out\n");
    ### $load_log = 1;

}

#########################################
### MAIN ###
parse_args(@ARGV);
process_in_dir();
pgm_exit(0,"");
########################################

sub need_arg {
    my ($arg,@av) = @_;
    pgm_exit(1,"ERROR: [$arg] must have a following argument!\n") if (!@av);
}

sub parse_args {
    my (@av) = @_;
    my ($arg,$sarg);
    my $verb = VERB2();
    while (@av) {
        $arg = $av[0];
        if ($arg =~ /^-/) {
            $sarg = substr($arg,1);
            $sarg = substr($sarg,1) while ($sarg =~ /^-/);
            if (($sarg =~ /^h/i)||($sarg eq '?')) {
                give_help();
                pgm_exit(0,"Help exit(0)");
            } elsif ($sarg =~ /^v/) {
                if ($sarg =~ /^v.*(\d+)$/) {
                    $verbosity = $1;
                } else {
                    while ($sarg =~ /^v/) {
                        $verbosity++;
                        $sarg = substr($sarg,1);
                    }
                }
                $verb = VERB2();
                prt("Verbosity = $verbosity\n") if ($verb);
            } elsif ($sarg =~ /^l/) {
                if ($sarg =~ /^ll/) {
                    $load_log = 2;
                } else {
                    $load_log = 1;
                }
                prt("Set to load log at end. ($load_log)\n") if ($verb);
            } elsif ($sarg =~ /^o/) {
                need_arg(@av);
                shift @av;
                $sarg = $av[0];
                $out_file = $sarg;
                prt("Set out file to [$out_file].\n") if ($verb);
            } else {
                pgm_exit(1,"ERROR: Invalid argument [$arg]! Try -?\n");
            }
        } else {
            $in_dir = $arg;
            prt("Set input to [$in_dir]\n") if ($verb);
        }
        shift @av;
    }

    if ($debug_on) {
        prtw("WARNING: DEBUG is ON!\n");
        if (length($in_dir) ==  0) {
            $in_dir = $def_file;
            prt("Set DEFAULT input to [$in_dir]\n");
        }
    }
    if (length($in_dir) ==  0) {
        pgm_exit(1,"ERROR: No input directory found in command!\n");
    }
    if (! -d $in_dir) {
        pgm_exit(1,"ERROR: Unable to find in directory [$in_dir]! Check name, location...\n");
    }
}

sub give_help {
    prt("$pgmname: version $VERS\n");
    prt("Usage: $pgmname [options] [in-dir]\n");
    prt("Options:\n");
    prt(" --help  (-h or -?) = This help, and exit 0.\n");
    prt(" --verb[n]     (-v) = Bump [or set] verbosity. def=$verbosity\n");
    prt(" --load        (-l) = Load LOG at end. ($outfile)\n");
    prt(" --out <file>  (-o) = Write output to this file.\n");
    prt("\n");
    prt("Simple count of the HGT files, in the form [N|S]12[E|W]123.hgt, and\n");
    prt("assess whihc files are missing from the set.\n");
    prt("If no 'in-dir' give will use default '$in_dir'\n");
}

# eof - cnthgt.pl
