#!/Perl
# findap.pl
# AIM: Read FlightGear apt.dat, and find an airport given the name,
# 20061127 - Use gz (gzip) files directly from $FG_ROOT
# geoff mclane - http://geoffmclane.com/mperl/index.htm - 20061127
# Updated 20070405 to parse inputs, added help, 
# updated 20070526 fixes to run from command line
unshift(@INC, 'C:/GTools/perl');
require 'logfile.pl' or die "Error: Unable to locate logfile.pl ...\n";
# =============================================================================
# This NEEDS to be adjusted to YOUR particular default location of these files.
my $FGROOT = (exists $ENV{FG_ROOT})? $FG_ROOT : "C:/FGCVS/FlightGear/data";
my $APTFILE 	  = "$FGROOT/Airports/apt.dat.gz";	# the airports data file
my $NAVFILE 	  = "$FGROOT/Navaids/nav.dat.gz";	# the NAV, NDB, etc. data file
##my $FIXFILE 	  = "$FGROOT/Navaids/fix.dat.gz";	# the FIX data file
# =============================================================================

# log file stuff
my ($LF);
my $pgmname = $0;
my $outfile = 'temp.'.$pgmname.'.txt';
if ($pgmname =~ /\w{1}:\\.*/) {
	my @tmpsp = split(/\\/,$pgmname);
	$pgmname = $tmpsp[-1];
	$outfile = 'temp.'.$pgmname.'.txt';
}
open_log($outfile);
prt( "$pgmname ... Hello, World ... ".scalar localtime(time())."\n" );

# program variables - set during running
# different searches -icao=LFPO, -latlon=1,2, or -name="airport name"
my $aptdat = $APTFILE;
my $navdat = $NAVFILE;

my $SRCHICAO = 0;	# search using icao id ... take precedence
my $SRCHONLL = 0;	# search using lat,lon
my $SRCHNAME = 0;	# search using name
my $SHOWNAVS = 0;	# show navaids around airport found

my $aptname = "strasbourg";
my $apticao = 'KSFO';
my $lat = 37.6;
my $lon = -122.4;
my $maxlatd = 0.5;
my $maxlond = 0.5;
my $nmaxlatd = 1.5;
my $nmaxlond = 1.5;
my $max_cnt = 0;	# maximum airport count - 0 = no limit

# debug tests
# ===================
my $test_name = 0;	# to TEST a NAME search
my $def_name = "hong kong";
my $test_ll = 0;	# to TEST a LAT,LON search
my $def_lat = 37.6;
my $def_lon = -122.4;
my $test_icao = 0;	# to TEST an ICAO search
my $def_icao = 'VHHH'; ## LFPO'; ## 'KSFO';
my $dbg1 = 0;	# show airport during finding ...
my $dbg2 = 0;	# show navaid during finding ...
my $dbg3 = 0;	# show count after finding
# ===================

my $av_apt_lat = 0;	# later will be $tlat / $ac;
my $av_apt_lon = 0; # later $tlon / $ac;

# apt.dat.gz CODES - see http://x-plane.org/home/robinp/Apt810.htm for DETAILS
my $aln =     '1';	# airport line
my $rln =    '10';	# runways/taxiways line
my $sealn =  '16'; # Seaplane base header data.
my $heliln = '17'; # Heliport header data.  
my $twrln =  '14'; # Tower view location. 
my $rampln = '15'; # Ramp startup position(s) 
my $bcnln =  '18'; # Airport light beacons  
my $wsln =   '19'; # windsock
my $minatc = '50';
my $twrfrq = '54';	# like 12210 TWR
my $appfrq = '55';  # like 11970 ROTTERDAM APP
my $maxatc = '56';
my $lastln = '99'; # end of file

# nav.dat.gz CODES
my $navNDB = '2';
my $navVOR = '3';
my $navILS = '4';
my $navLOC = '5';
my $navGS  = '6';
my $navOM  = '7';
my $navMM  = '8';
my $navIM  = '9';
my $navVDME = '12';
my $navNDME = '13';
my @navset = ($navNDB, $navVOR, $navILS, $navLOC, $navGS, $navOM, $navMM, $navIM, $navVDME, $navNDME);
my @navtypes = qw( NDB VOR ILS LOC GS OM NM IM VDME NDME );
my $maxnnlen = 4;
my $actnav = '';
my $line = '';
my $apt = '';
my $alat = 0;
my $alon = 0;
my $glat = 0;
my $glon = 0;
my $rlat = 0;
my $rlon = 0;
my $dlat = 0;
my $dlon = 0;
my $diff = 0;
my $rwycnt = 0;
my $icao = '';
my $name = '';
my @aptlist = ();
my @aptlist2 = ();
my @navlist = ();
my @navlist2 = ();
my $totaptcnt = 0;
my $acnt = 0;
my @lines = ();
my $cnt = 0;
my $loadlog = 0;
my $outcount = 0;
my @tilelist = ();
parse_args(@ARGV);	# collect command line arguments ...

prt("\nLoading $aptdat file ...\n");
mydie("ERROR: Can NOT locate $aptdat ...$!...\n") if ( !( -f $aptdat) );
###open IF, "<$aptdat" or mydie("OOPS, failed to open [$aptdat] ... check name and location ...\n");
open IF, "gzip -d -c $aptdat|" or mydie( "ERROR: CAN NOT OPEN $aptdat...$!...\n" );
@lines = <IF>;
close IF;
$cnt = scalar @lines;
prt( "Processing $cnt lines ...\n" );
if ($SRCHICAO) {
	prt( "Searching for ICAO [$apticao] ...\n" );
} elsif ($SRCHONLL) {
	prt( "Searching for LAT,LON [$lat,$lon], using max. diff. [$maxlatd,$maxlond] ...\n" );
} else {
	prt( "Searching for NAME [$aptname] ...\n" );
}

foreach $line (@lines) {
	$line = trimall($line);
	###prt("$line\n");
	my @arr = split(/ /,$line);
	if ($line =~ /^$aln\s+/) {	# start with '1'
		if (length($apt) && ($rwycnt > 0)) {
			$alat = $glat / $rwycnt;
			$alon = $glon / $rwycnt;
			$dlat = abs( $lat - $alat );
			$dlon = abs( $lon - $alon );
			$diff = int( ($dlat * 10) + ($dlon * 10) );
			my @arr2 = split(/ /,$apt);
			$icao = $arr2[4];
			$name = join(' ', splice(@arr2,5));
			##prt("$diff [$apt] (with $rwycnt runways at [$alat, $alon]) ...\n");
			##prt("$diff [$icao] [$name] ...\n");
			push(@aptlist, [$diff, $icao, $name, $alat, $alon]);
			if ($SRCHICAO) {
				if ($icao =~ /$apticao/) {
						prt("$icao, $name, $alat, $alon \n") if ($dbg1);
						push(@aptlist2, [$diff, $icao, $name, $alat, $alon]);
				}
			} else {
				if ($SRCHONLL) {
					if (($dlat < $maxlatd) && ($dlon < $maxlond)) {
						prt("$icao, $name, $alat, $alon \n") if ($dbg1);
						push(@aptlist2, [$diff, $icao, $name, $alat, $alon]);
					}
				} else {
					if ($name =~ /$aptname/i) {
						prt("$icao, $name, $alat, $alon \n") if ($dbg1);
						push(@aptlist2, [$diff, $icao, $name, $alat, $alon]);
					}
				}
			}
		}
		$apt = $line;
		$rwycnt = 0;
		$glat = 0;
		$glon = 0;
		$totaptcnt++;	# count another AIRPORT
	} elsif ($line =~ /^$rln\s+/) {
		$rlat = $arr[1];
		$rlon = $arr[2];
		###prt( "$line [$rlat, $rlon]\n" );
		$glat += $rlat;
		$glon += $rlon;
		$rwycnt++;
	} elsif ($line =~ /^$lastln\s?/) {	# 99, followed by space, count 0 or more ...
		prt( "Reached END OF FILE ... \n" ) if ($dbg1);
		last;
	}
}

if ($rwycnt > 0) {
	$alat = $glat / $rwycnt;
	$alon = $glon / $rwycnt;
	$dlat = abs( $lat - $alat );
	$dlon = abs( $lon - $alon );
	$diff = int( ($dlat * 10) + ($dlon * 10) );
	my @arr2 = split(/ /,$apt);
	$icao = $arr2[4];
	$name = join(' ', splice(@arr2,5));
	###prt("$diff [$apt] (with $rwycnt runways at [$alat, $alon]) ...\n");
	###prt("$diff [$icao] [$name] ...\n");
	push(@aptlist, [$diff, $icao, $name, $alat, $alon]);
	if ($SRCHICAO) {
		if ($name =~ /$apticao/) {
				prt("$icao, $name, $alat, $alon \n") if ($dbg1);
				push(@aptlist2, [$diff, $icao, $name, $alat, $alon]);
		}
	} else {
		if ($SRCHONLL) {
			if (($dlat < $maxlatd) && ($dlon < $maxlond)) {
				prt("$icao, $name, $alat, $alon \n") if ($dbg1);
				push(@aptlist2, [$diff, $icao, $name, $alat, $alon]);
			}
		} else {
			if ($name =~ /$aptname/i) {
				prt("$icao, $name, $alat, $alon \n") if ($dbg1);
				push(@aptlist2, [$diff, $icao, $name, $alat, $alon]);
			}
		}
	}
}

$acnt = scalar @aptlist2;
prt( "Found $acnt, of $totaptcnt, airports ...\n" ) if ($dbg3);
set_average_apt_latlon();
if ($SRCHICAO) {
	prt( "Found $acnt matching $apticao ...(av. $av_apt_lat,$av_apt_lon)\n" ) if ($dbg3);
} elsif ($SRCHONLL) {
	prt( "Found $acnt matching $lat, $lon ...(av. $av_apt_lat,$av_apt_lon)\n" ) if ($dbg3);
} else {
	prt( "Found $acnt matching $aptname ... (av. $av_apt_lat,$av_apt_lon)\n" ) if ($dbg3);
}
#my @aptsort = sort mycmp_ascend @aptlist;
show_airports_found($max_cnt);
if ($acnt && $SHOWNAVS) {
	search_nav();
	show_navaids_found();
}
$cnt = scalar @tilelist;
if ($cnt) {
	prt( "Scenery Tile" );
	if ($cnt > 1) {
		prt( "s" );
	}
	prt( ": " );
	foreach $name (@tilelist) {
		prt( "$name " );
	}
	prt( "\n" );
}

$loadlog = 1 if ($outcount > 30);
close_log($outfile,$loadlog);
exit(0);

########################################################################
### ONLY SUBS BELOW HERE
sub show_airports_found {
	my ($mx) = shift;	# limit the AIRPORT OUTPUT
	my $scnt = $acnt;
	my $tile = '';
	if ($mx && ($mx < $scnt)) {
		$scnt = $mx;
		prt( "Listing $scnt of $acnt aiports " );
	} else {
		prt( "Listing $scnt aiport(s) " );
	}

	if ($SRCHICAO) {
		prt( "with ICAO [$apticao] ...\n" );
	} elsif ($SRCHONLL) {
		prt( "around lat,lon [$lat,$lon], using diff [$maxlatd,$maxlond] ...\n" );
	} else {
		prt( "matching [$aptname] ...\n" );
	}
	for (my $i = 0; $i < $scnt; $i++) {
		$diff = $aptlist2[$i][0];
		$icao = $aptlist2[$i][1];
		$name = $aptlist2[$i][2];
		$alat = $aptlist2[$i][3];
		$alon = $aptlist2[$i][4];
		$tile = get_tile( $alon, $alat );
		while (length($icao) < 4) {
			$icao .= ' ';
		}
		$line = $diff;
		while (length($line) < 6) {
			$line = ' '.$line;
		}
		$line .= ' '.$icao.' '.$name.' ('.$alat.','.$alon.") tile=$tile";
		prt("$line\n");
		$outcount++;
		add_2_tiles($tile);
	}
	prt( "Done $scnt list ...\n" );
}

sub get_tile { # $alon, $alat
	my ($lon, $lat) = @_;
	my $tile = 'e';
	if ($lon < 0) {
		$tile = 'w';
		$lon = -$lon;
	}
	my $ilon = int($lon / 10) * 10;
	if ($ilon < 10) {
		$tile .= "00$ilon";
	} elsif ($ilon < 100) {
		$tile .= "0$ilon";
	} else {
		$tile .= "$ilon"
	}
	if ($lat < 0) {
		$tile .= 's';
		$lat = -$lat;
	} else {
		$tile .= 'n';
	}
	my $ilat = int($lat / 10) * 10;
	if ($ilat < 10) {
		$tile .= "0$ilat";
	} elsif ($ilon < 100) {
		$tile .= "$ilat";
	} else {
		$tile .= "$ilat"
	}
	return $tile;
}

sub add_2_tiles {	# $tile
	my ($tl) = shift;
	if (@tilelist) {
		foreach my $t (@tilelist) {
			if ($t eq $tl) {
				return 0;
			}
		}
	}
	push(@tilelist, $tl);
	return 1;
}

sub is_valid_nav {
	my ($t) = shift;
	my $cnt = 0;
	foreach my $n (@navset) {
		if ($n == $t) {
			$actnav = $navtypes[$cnt];
			return 1;
		}
		$cnt++;
	}
	return 0;
}

sub set_average_apt_latlon {
	my $ac = scalar @aptlist2;
	my $tlat = 0;
	my $tlon = 0;
	if ($ac) {
		for (my $i = 0; $i < $ac; $i++ ) {
			$alat = $aptlist2[$i][3];
			$alon = $aptlist2[$i][4];
			$tlat += $alat;
			$tlon += $alon;
		}
		$av_apt_lat = $tlat / $ac;
		$av_apt_lon = $tlon / $ac;
	}
}

# push(@aptlist2, [$diff, $icao, $name, $alat, $alon]);
# my $nmaxlatd = 1.5;
# my $nmaxlond = 1.5;
sub near_an_airport {
	my ($lt, $ln) = @_;
	my $ac = scalar @aptlist2;
	for (my $i = 0; $i < $ac; $i++ ) {
		$diff = $aptlist2[$i][0];
		$icao = $aptlist2[$i][1];
		$name = $aptlist2[$i][2];
		$alat = $aptlist2[$i][3];
		$alon = $aptlist2[$i][4];
		my $td = abs($lt - $alat);
		my $nd = abs($ln - $alon);
		if (($td < $nmaxlatd)&&($nd < $nmaxlond)) {
			return ($i + 1);
		}
	}
	return 0;
}

sub show_navaids_found {
	my ($ic, $in, $line, $lcnt, $dnone);
	my ($diff, $icao, $name, $alat, $alon);
	my ($typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name, $off);
	#prt( "$actnav, $typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name ($off)\n");
	#push(@navlist2, [$typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name, $off]);
	my $ac = scalar @aptlist2;
	my $nc = scalar @navlist2;
	prt( "\nFor $ac airports, found $nc NAVAIDS, within [$nmaxlatd,$nmaxlond] ...\n" );
	$lcnt = 0;
	for ($ic = 0; $ic < $ac; $ic++) {
		$diff = $aptlist2[$ic][0];
		$icao = $aptlist2[$ic][1];
		$name = $aptlist2[$ic][2];
		$alat = $aptlist2[$ic][3];
		$alon = $aptlist2[$ic][4];
		while (length($icao) < 4) {
			$icao .= ' ';
		}
		$line = $diff;
		while (length($line) < 6) {
			$line = ' '.$line;
		}
		$line .= ' '.$icao.' '.$name.' ('.$alat.','.$alon.')';
		prt("\n$line\n");
		$outcount++;
		$dnone = 0;
		for ( $in = 0; $in < $nc; $in++ ) {
			$typ = $navlist2[$in][0];
			$nlat = $navlist2[$in][1];
			$nlon = $navlist2[$in][2];
			$nalt = $navlist2[$in][3];
			$nfrq = $navlist2[$in][4];
			$nrng = $navlist2[$in][5];
			$nfrq2 = $navlist2[$in][6];
			$nid = $navlist2[$in][7];
			$name = $navlist2[$in][8];
			$off = $navlist2[$in][9];
			if ($off == ($ic + 1)) {
				# it is FOR this airport
				is_valid_nav($typ);
				#prt( "$actnav, $typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name ($off)\n");
				$line = $actnav;
				while (length($line) < $maxnnlen) {
					$line .= ' ';
				}
				$line .= ' ';
				while (length($nalt) < 5) {
					$nalt = ' '.$nalt;
				}
				while (length($nfrq) < 5) {
					$nfrq = ' '.$nfrq;
				}
				while (length($nrng) < 5) {
					$nrng = ' '.$nrng;
				}
				while (length($nfrq2) < 10) {
					$nfrq2 = ' '.$nfrq2;
				}
				while (length($nid) < 4) {
					$nid = ' '.$nid;
				}

				$line .= "$nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name ($off)";
				if ($dnone == 0) {
					#     NDB  50.049000, 008.328667,   490,   399,    25,      0.000,  WBD, Wiesbaden NDB (2)
					prt( "Type Latitude   Logitude     Alt.  Freq.  Range  Frequency2    ID  Name\n" );
					$dnone = 1;
				}
				prt( "$line\n" );
				$outcount++;
				$lcnt++;
				add_2_tiles( get_tile( $nlon, $nlat ) );
			}
		}
		prt( "Type Latitude   Logitude     Alt.  Freq.  Range  Frequency2    ID  Name\n" ) if ($dnone);

	}
	prt( "Listed $lcnt NAVAIDS ...\n" );
}

sub search_nav {
	my ($typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name, $off);
	prt("\nLoading $navdat file ...\n");
	mydie("ERROR: Can NOT locate $navdat ...$!...\n") if ( !( -f $navdat) );
	open NIF, "gzip -d -c $navdat|" or mydie( "ERROR: CAN NOT OPEN $navdat...$!...\n" );
	my @nav_lines = <NIF>;
	close NIF;
	my $nav_cnt = scalar @nav_lines;
	my $ac = scalar @aptlist2;
	prt("Processing $nav_cnt lines ...\n");
	prt("Using maximum lat,lon deviation of [$nmaxlatd,$nmaxlond] from $ac airport(s).\n" );
	my $vcnt = 0;
	foreach $line (@nav_lines) {
		$line = trimall($line);
		###prt("$line\n");
		my @arr = split(/ /,$line);
		# 0   1 (lat)   2 (lon)        3     4   5           6   7  8++
		# 2   38.087769 -077.324919  284   396  25       0.000 APH  A P Hill NDB
		# 3   57.103719  009.995578   57 11670 100       1.000 AAL  Aalborg VORTAC
		# 4   39.980911 -075.877814  660 10850  18     281.662 IMQS 40N 29 ILS-cat-I
		# 4  -09.458922  147.231225  128 11010  18     148.650 IWG  AYPY 14L ILS-cat-I
		# 5   40.034606 -079.023281 2272 10870  18     236.086 ISOZ 2G9 24 LOC
		# 5   67.018506 -050.682072  165 10955  18      61.600 ISF  BGSF 10 LOC
		# 6   39.977294 -075.860275  655 10850  10  300281.205 ---  40N 29 GS
		# 6  -09.432703  147.216444  128 11010  10  302148.785 ---  AYPY 14L GS
		# 7   39.960719 -075.750778  660     0   0     281.205 ---  40N 29 OM
		# 7  -09.376150  147.176867  146     0   0     148.785 JSN  AYPY 14L OM
		# 8  -09.421875  147.208331   91     0   0     148.785 MM   AYPY 14L MM
		# 8  -09.461050  147.232544  146     0   0     328.777 PY   AYPY 32R MM
		# 9   65.609444 -018.052222   32     0   0      22.093 ---  BIAR 01 IM
		# 9   08.425319  004.475597 1126     0   0      49.252 IL   DNIL 05 IM
		# 12 -09.432703  147.216444   11 11010  18       0.000 IWG  AYPY 14L DME-ILS
		# 12 -09.449222  147.226589   11 10950  18       0.000 IBB  AYPY 32R DME-ILS
		my $nc = scalar @arr;
		$typ = $arr[0];
		if (is_valid_nav($typ)) {
			$vcnt++;
			$nlat = $arr[1];
			$nlon = $arr[2];
			$nalt = $arr[3];
			$nfrq = $arr[4];
			$nrng = $arr[5];
			$nfrq2 = $arr[6];
			$nid = $arr[7];
			$name = '';
			for (my $i = 8; $i < $nc; $i++) {
				$name .= ' ' if length($name);
				$name .= $arr[$i];
			}
			push(@navlist, [$typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name]);
			$off = near_an_airport( $nlat, $nlon );
			if ($off) {
				prt( "$actnav, $typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name ($off)\n") if ($dbg2);
				push(@navlist2, [$typ, $nlat, $nlon, $nalt, $nfrq, $nrng, $nfrq2, $nid, $name, $off]);
			}
		}
	}
	prt("Done - Found ".scalar @navlist2." near NAVAIDS, of $vcnt searched...\n" );
}

# put least first
sub mycmp_ascend {
   if (${$a}[0] < ${$b}[0]) {
      prt( "-[".${$a}[0]."] < [".${$b}[0]."]\n" ) if $verb3;
      return -1;
   }
   if (${$a}[0] > ${$b}[0]) {
      prt( "+[".${$a}[0]."] < [".${$b}[0]."]\n" ) if $verb3;
      return 1;
   }
   prt( "=[".${$a}[0]."] < [".${$b}[0]."]\n" ) if $verb3;
   return 0;
}

sub mycmp_decend {
   if (${$a}[0] < ${$b}[0]) {
      prt( "+[".${$a}[0]."] < [".${$b}[0]."]\n" ) if $verb3;
      return 1;
   }
   if (${$a}[0] > ${$b}[0]) {
      prt( "-[".${$a}[0]."] < [".${$b}[0]."]\n" ) if $verb3;
      return -1;
   }
   prt( "=[".${$a}[0]."] < [".${$b}[0]."]\n" ) if $verb3;
   return 0;
}

sub give_help {
	prt( "FLIGHTGEAR AIRPORT SEARCH UTILITY\n" );
	prt( "Usage: $pgmname options\n" );
	prt( "Options: A ? anywhere for this help.\n" );
	prt( " -icao=$apticao          - Search using icao.\n" );
	prt( " -latlon=$lat,$lon - Search using latitude, longitude.\n" );
	prt( " -maxout=$max_cnt           - Limit the airport output. A 0 for ALL.\n" );
	prt( " -maxll=$maxlatd,$maxlond      - Maximum difference, when searching lat,lon.\n" );
	prt( " -name=\"$aptname\"  - Search using airport name. (A -name=. would match all.)\n" );
	prt( " -shownavs           - Show NAVAIDS around airport found, if any.\n" );
	prt( " -nmaxll=$nmaxlatd,$nmaxlond     - Maximum difference, when searching NAVAID lat,lon.\n" );
	prt( " -aptdata=$aptdat - Use a specific AIRPORT data file.\n" );
	prt( " -navdata=$navdat - Use a specific NAVAID data file.\n" );
	mydie( "                                     Happy Searching.\n" );
}

# set $SRCHICAO on/off
# set $SRCHONLL on/off
sub parse_args {
	my (@av) = @_;
	my (@arr);
	while(@av) {
		my $arg = $av[0]; # shift @av;
		if ($arg =~ /\?/) {
			give_help();
		} elsif ( $arg =~ /-icao=(.+)/i ) {
			$SRCHICAO = 1;
			$SRCHONLL = 0;
			$SRCHNAME = 0;
			$apticao = $1;
			prt( "Search using ICAO of [$apticao] ...\n" );
		} elsif ( lc($arg) eq '-icao' ) {
			require_arg(@av);
			shift @av;
			$SRCHICAO = 1;
			$SRCHONLL = 0;
			$SRCHNAME = 0;
			$apticao = $av[0];
			prt( "Search using ICAO of [$apticao] ...\n" );
		} elsif ( $arg =~ /-latlon=(.+)/i ) {
			$SRCHICAO = 0;
			$SRCHONLL = 1;
			$SRCHNAME = 0;
			@arr = split(',', $1);
			if (scalar @arr == 2) {
				$lat = $arr[0];
				$lon = $arr[1];
				prt( "Search using LAT,LON of [$lat,$lon] ...\n" );
			} else {
				mydie( "ERROR: Failed to find lat,lon in [$arg]...\n" );
			}
		} elsif ( lc($arg) eq '-latlon' ) {
			require_arg(@av);
			shift @av;
			$SRCHICAO = 0;
			$SRCHONLL = 1;
			$SRCHNAME = 0;
			@arr = split(',', $av[0]);
			if (scalar @arr == 2) {
				$lat = $arr[0];
				$lon = $arr[1];
				prt( "Search using LAT,LON of [$lat,$lon] ...\n" );
			} else {
				mydie( "ERROR: Failed to find lat,lon in [$arg]...\n" );
			}
		} elsif ( $arg =~ /-name=(.+)/i ) {
			$SRCHICAO = 0;
			$SRCHONLL = 0;
			$SRCHNAME = 1;
			$aptname = $1;
			prt( "Search using NAME of [$aptname] ...\n" );
		} elsif ( lc($arg) eq '-name' ) {
			require_arg(@av);
			shift @av;
			$SRCHICAO = 0;
			$SRCHONLL = 0;
			$SRCHNAME = 1;
			$aptname = $av[0];
			prt( "Search using NAME of [$aptname] ...\n" );
		} elsif ( $arg =~ /^-shownavs$/i ) {
			$SHOWNAVS = 1;
			prt( "And show NAVAIDS around airport, if any.\n" );
		} elsif ( $arg =~ /-maxll=(.+)/i ) {
			@arr = split(',', $1);
			if (scalar @arr == 2) {
				$maxlatd = $arr[0];
				$maxlond = $arr[1];
				prt( "Search maximum difference LAT,LON of [$maxlatd,$maxlond] ...\n" );
			} else {
				mydie( "ERROR: Failed to find maximum lat,lon difference in [$arg]...\n" );
			}
		} elsif ( lc($arg) eq '-maxll' ) {
			require_arg(@av);
			shift @av;
			@arr = split(',', $av[0]);
			if (scalar @arr == 2) {
				$maxlatd = $arr[0];
				$maxlond = $arr[1];
				prt( "Search maximum difference LAT,LON of [$maxlatd,$maxlond] ...\n" );
			} else {
				mydie( "ERROR: Failed to find maximum lat,lon difference in [$arg]...\n" );
			}
		} elsif ( $arg =~ /-nmaxll=(.+)/i ) {
			@arr = split(',', $1);
			if (scalar @arr == 2) {
				$nmaxlatd = $arr[0];
				$nmaxlond = $arr[1];
				prt( "Search maximum difference LAT,LON of [$nmaxlatd,$nmaxlond] ...\n" );
			} else {
				mydie( "ERROR: Failed to find maximum lat,lon difference in [$arg]...\n" );
			}
		} elsif ( lc($arg) eq '-nmaxll' ) {
			require_arg(@av);
			shift @av;
			@arr = split(',', $av[0]);
			if (scalar @arr == 2) {
				$nmaxlatd = $arr[0];
				$nmaxlond = $arr[1];
				prt( "Search maximum difference LAT,LON of [$nmaxlatd,$nmaxlond] ...\n" );
			} else {
				mydie( "ERROR: Failed to find maximum lat,lon difference in [$arg]...\n" );
			}
		} elsif ( $arg =~ /-aptdata=(.+)/i ) {
			$aptdat = $1;	# the airports data file
			prt( "Using AIRPORT data file [$aptdat] ...\n" );
		} elsif ( lc($arg) eq '-aptdata' ) {
			require_arg(@av);
			shift @av;
			$aptdat = $av[0];	# the airports data file
			prt( "Using AIRPORT data file [$aptdat] ...\n" );
		} elsif ( $arg =~ /-navdata=(.+)/i ) {
			$navdat = $1;
			prt( "Using NAVAID data file [$navdat] ...\n" );
		} elsif ( lc($arg) eq '-navdata' ) {
			require_arg(@av);
			shift @av;
			$navdat = $av[0];
			prt( "Using NAVAID data file [$navdat] ...\n" );
		} elsif ( $arg =~ /-maxout=(.+)/i ) {
			$max_cnt = $1;
			prt( "Airport output limited to $max_cnt. A zero (0), for no limit\n" );
		} elsif ( lc($arg) eq '-maxout' ) {
			require_arg(@av);
			shift @av;
			$max_cnt = $av[0];
			prt( "Airport output limited to $max_cnt. A zero (0), for no limit\n" );
		} else {
			if (substr($arg,0,1) eq '-') {
				mydie( "ERROR: Unknown argument [$arg]. Try ? for HELP ...\n" );
			} else {
				# ASSUME AN AIRPORT NAME
				$SRCHICAO = 0;
				$SRCHONLL = 0;
				$SRCHNAME = 1;
				$aptname = $av[0];
				prt( "Search using NAME of [$aptname] ...\n" );
			}
		}
		shift @av;
	}

	# *** ONLY FOR TESTING ***
	if ($test_name) {
		$SRCHICAO = 0;
		$SRCHONLL = 0;
		$SRCHNAME = 1;
		$SHOWNAVS = 1;
		$aptname = $def_name;
	} elsif ($test_ll) {
		$lat = $def_lat;
		$lon = $def_lon;
		$maxlatd = 0.1;
		$maxlond = 0.1;
		$SRCHICAO = 0;
		$SRCHONLL = 1;
		$SRCHNAME = 0;
	} elsif ($test_icao) {
		$SRCHICAO = 1;
		$SRCHONLL = 0;
		$SRCHNAME = 0;
		$SHOWNAVS = 1;
		#$nmaxlatd = 0.2;
		#$nmaxlond = 0.2;
		$nmaxlatd = 0.1;
		$nmaxlond = 0.1;
		$apticao = $def_icao;
	}

	if ( ($SRCHICAO == 0) && ($SRCHONLL == 0) && ($SRCHNAME == 0) ) {
		prt( "ERROR: Found no valid command found ...\n" );
		give_help();
	}

	###mydie( "Under test ...\n" );
}

# Ensure argument exists, or die.
sub require_arg {
    my ($arg, @arglist) = @_;
    mydie( "ERROR: no argument given for option '$arg' ...\n" ) if ! @arglist;
}

##############
### functions
sub trimall {	# version 20061127
	my ($ln) = shift;
	chomp $ln;			# remove CR (\n)
	$ln =~ s/\r$//;		# remove LF (\r)
	$ln =~ s/\t/ /g;	# TAB(s) to a SPACE
	while ($ln =~ /\s\s/) {
		$ln =~ s/\s\s/ /g;	# all double space to SINGLE
	}
	while ($ln =~ /^\s/) {
		$ln = substr($ln,1); # remove all LEADING space
	}
	while ($ln =~ /\s$/) {
		$ln = substr($ln,0, length($ln) - 1); # remove all TRAILING space
	}
	return $ln;
}

# eof - findap.pl

