#!/usr/bin/perl
#
# gen_phonebook.pl
#
use strict;
use warnings;
use IO::Zlib;
use IO::File;
use File::Slurp;
use Data::Dumper;

##$FG_AIRPORTS="/usr/local/tmp/apt.dat.gz";
##$FG_NAVAIDS="/usr/local/tmp/nav.dat.gz";
my $FG_AIRPORTS="C:\\FG\\fgdata\\Airports\\apt.dat.gz";
my $FG_NAVAIDS="C:\\FG\\fgdata\\Navaids\\nav.dat.gz";

my $XP_AIRPORTS="D:\\FG\\xplane\\apt.dat";
my $XP_NAVAIDS = "D:\\FG\\xplane\\earth_nav.dat";

my $phonebook_post="ZZZZ                        910.000  0190909090910000  Echo-Box\n".
"ZZZZ                        123.450  0190909090123450  Air2Air\n".
"ZZZZ                        122.750  0190909090122750  Air2Air\n";

my $validate_on_ws = 1;
my $use_xp_files = 1;
my $use_fg_files = 1;

my $read_config = 0;

# counters
my $apt_lines = 0;
my $icao_count = 0;
my $com_count = 0;
my $apts_missed = 0;
my $apts_valid = 0;
my $apts_valid2 = 0;
my $tower_count = 0;
my $missed_tower = 0;
my $missed_freq = 0;
my $missed_icao = 0;

my $freq_added = 0;
my $nav_lines = 0;
my $nav_vordme = 0;
my $nav_others = 0;

my $perl_dir = "C:\\GTools\\perl";
my $temp_pb = $perl_dir."\\temp.phonebook.txt";
my $temp_pos = $perl_dir."\\temp.positions.txt";
my $temp_ext = $perl_dir."\\temp.extensions.txt";

my $temp_pbx = $perl_dir."\\temp.phonebookx.txt";
my $temp_posx = $perl_dir."\\temp.positionsx.txt";
my $temp_extx = $perl_dir."\\temp.extensionsx.txt";

my $temp_notwr = $perl_dir."\\temp.notwr.txt";
my @no_twr = ();
my $temp_nofrq = $perl_dir."\\temp.nofrq.txt";
my @no_frq = ();
my $temp_notwrx = $perl_dir."\\temp.notwrx.txt";
my $temp_nofrqx = $perl_dir."\\temp.nofrqx.txt";

my $config_root = "C:\\FG\\16\\fgcom\\server\\config";
my $conf_ext = $config_root."\\extensions.conf";
#my $conf_iax = $config_root."\\iax.conf";
#my $conf_sip = $config_root."\\sip.conf";

my $verbosity = 0;

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

# program vars
my %CONF = ();
my %APT = ();
my %NAV = ();
my ($positions,$phonebook,$extensions);

my %XAPT = ();
my %XNAV = ();

sub prt($) { print shift; }

sub loc_write2file {
	my ($txt,$fil) = @_;
	open WOF, ">$fil" or mydie("ERROR: Unable to open $fil! $!\n");
	print WOF $txt;
	close WOF;
}

sub loc_trim_leading($) {
    my ($ln) = shift;
	$ln = substr($ln,1) while ($ln =~ /^\s/); # remove all LEADING space
    return $ln;
}

sub loc_trim_tailing($) {
    my ($ln) = shift;
	$ln = substr($ln,0, length($ln) - 1) while ($ln =~ /\s$/g); # remove all TRAILING space
    return $ln;
}

sub loc_trim_ends($) {
    my ($ln) = shift;
    $ln = loc_trim_tailing($ln); # remove all TRAINING space
	$ln = loc_trim_leading($ln); # remove all LEADING space
    return $ln;
}

sub loc_trim_all {
	my ($ln) = shift;
	$ln =~ s/\n/ /gm;	# replace CR (\n)
	$ln =~ s/\r/ /gm;	# replace LF (\r)
	$ln =~ s/\t/ /g;	# TAB(s) to a SPACE
    $ln = loc_trim_ends($ln);
	$ln =~ s/\s{2}/ /g while ($ln =~ /\s{2}/);	# all double space to SINGLE
	return $ln;
}

sub clear_counters() {
    $apt_lines = 0;
    $icao_count = 0;
    $com_count = 0;
    $apts_missed = 0;
    $apts_valid = 0;
    $apts_valid2 = 0;
    $tower_count = 0;
    $missed_tower = 0;
    $missed_freq = 0;
    $missed_icao = 0;
    $freq_added = 0;
    $nav_lines = 0;
    $nav_vordme = 0;
    $nav_others = 0;
}

sub icao2number($) {
	my($icao) = @_;
	my($number,$n,$i);

	$icao=" ".$icao if(length($icao)==3);
	$icao="  ".$icao if(length($icao)==2);
	$icao="   ".$icao if(length($icao)==1);
    $number = "";
	for($i=0;$i<length($icao);$i++)
	{
		$n=ord(substr($icao,$i,1));
        $number.=sprintf("%02d",$n);
	}
	return($number);
}

if ( ! -f $conf_ext ) {
    print "Found no configuration file $conf_ext...\n";
    exit(10);
}

##############################################################################
# Read config
##############################################################################
if ($read_config) {
    if(-e $ENV{'HOME'}."/.fgreg/fgreg.conf")
    {
            $CONF{'CONFIG'}=$ENV{'HOME'}."/.fgreg";
            require $CONF{'CONFIG'}."/fgreg.conf";
    }
    elsif(-e "./fgreg.conf")
    {
            $CONF{'CONFIG'}=".";
            require $CONF{'CONFIG'}."/fgreg.conf";
    }
    else
    {
        print "Found no configuration file...\n";
        exit(10);
    }
}

sub show_apt_count() {
    prt("Processed $apt_lines APT lines, got $icao_count ICAO lines, $apts_valid valid airports, missed $apts_missed\n");
    prt("Of the $com_count COM entires found, only $freq_added were added.\n");
    prt("Of the $apts_missed missed, $missed_tower had no tower, $missed_freq had no freqs, and $missed_icao with no ICAO\n");
    prt("But $apts_valid2 airports added on the basis of the av. location of the WindSock!\n");
}

sub show_nav_count() {
    prt("Processed $nav_lines NAV lines, got $nav_vordme VOR/DME entries, $nav_others others.\n");

}

sub read_airports() {
    my $fh = new IO::Zlib;
    if($fh->open($FG_AIRPORTS, "r"))
    {
        prt("Reading $FG_AIRPORTS file...\n");
        my ($z,$icao,$text,$lat,$lon,$com,$f,$hh,$msg,$ap,$ws_cnt,$wslat,$wslon);
        my %frq = ();
        my @arr = ();
        $hh = 0;    # no header line yet
        $ws_cnt = 0;
        while($z=<$fh>) {
            chop($z);
            $apt_lines++;
            if($z=~/^\s*$/)
            {
                if($icao && scalar(keys(%frq))>0 && $lat && $lon)
                {
                    $APT{$icao}{'text'}=$text;
                    $APT{$icao}{'lat'}=$lat;
                    $APT{$icao}{'lon'}=$lon;
                    foreach $f (keys(%frq)) {
                        $APT{$icao}{'com'}{$f}=$frq{$f};
                        $freq_added++;
                    }
                    $apts_valid++;
                } elsif ($hh) {
                    $apts_missed++;
                    if ($icao) {
                        if (scalar(keys(%frq))>0) {
                            $missed_tower++;
                            if ($validate_on_ws && $ws_cnt) {
                                $lat = $wslat / $ws_cnt;
                                $lon = $wslon / $ws_cnt;
                                $APT{$icao}{'text'}=$text;
                                $APT{$icao}{'lat'}=$lat;
                                $APT{$icao}{'lon'}=$lon;
                                foreach $f (keys(%frq)) {
                                    $APT{$icao}{'com'}{$f}=$frq{$f};
                                    $freq_added++;
                                }
                                $apts_valid2++;
                            } else {
                                push(@no_twr,@arr);
                                push(@no_twr,"");
                            }
                        } else {
                            $missed_freq++;
                            # why not always at least add CTAF
                            # The most common CTAF frequency is 126.7 at non towered aerodromes 
                            push(@no_frq,@arr);
                            push(@no_frq,"");
                        }
                    } else {
                        $missed_icao++;
                        prt("$ap\n");
                    }
                }
                undef($icao);
                undef($text);
                undef($lon);
                undef($lat);
                undef($com);
                %frq=();
                @arr = ();
                $hh = 0;
                $ws_cnt = 0;    # clear the WindSock counter
                next;
            } # elsif($z=~/^1\s+\d+\s+[01]\s+[01]\s+([A-Z0-9]+)\s+(.+)$/)
            elsif($z=~/^1\s+\d+/)
            {
                if($z=~/^1\s+\d+\s+[01]\s+[01]\s+([A-Z0-9]+)\s+(.+)$/)
                {
                    # Airport Header
                    $icao=$1;
                    $text=$2;
                    $icao_count++;
                    $hh = 1;
                    $ap = $z;
                } else {
                    prt("Airport header REJECTED by regex! CHECK ME\n");
                    prt("$ap\n");
                    exit(1);
                }
            }
            elsif($z=~/^14\s+(-?\d+\.\d+)\s+(-?\d+\.\d+)/)
            {
                # TWR Position
                $lat=$1;
                $lon=$2;
                $tower_count++;
            }
            elsif($z=~/^5[0-6]\s+(\d{5})\d*\s+(.+)/)
            {
                # COM data
                $com=sprintf("%3.3f",$1/100);
                $frq{$com}=$2;
                $com_count++;
            }
            elsif ($z=~/^19\s+(-?\d+\.\d+)\s+(-?\d+\.\d+)/)
            {   
                # 19  08.320709 -073.357287 1 WS
                $wslat += $1;
                $wslon += $2;
                $ws_cnt++;
            }
            elsif ($z =~ /^99/)
            {
                last;
            }
            push(@arr,$z);  # keep the lines of this a/p
        }
        prt("Done $apt_lines lines from file...\n");
    }
    else
    {
        die("Cannot open $FG_AIRPORTS :$!\n");
    }
    $fh->close;
}

sub read_airports_XP() {
    if(open INF, "<$XP_AIRPORTS")
    {
        prt("Reading $XP_AIRPORTS file...\n");
        my ($z,$icao,$text,$lat,$lon,$com,$f,$hh,$msg,$ap,$ws_cnt,$wslat,$wslon);
        my %frq = ();
        my @arr = ();
        $hh = 0;    # no header line yet
        $ws_cnt = 0;
        while($z = <INF>) {
            chop($z);
            $apt_lines++;
            if($z=~/^\s*$/)
            {
                if($icao && scalar(keys(%frq))>0 && $lat && $lon)
                {
                    $XAPT{$icao}{'text'}=$text;
                    $XAPT{$icao}{'lat'}=$lat;
                    $XAPT{$icao}{'lon'}=$lon;
                    foreach $f (keys(%frq)) {
                        $XAPT{$icao}{'com'}{$f}=$frq{$f};
                        $freq_added++;
                    }
                    $apts_valid++;
                } elsif ($hh) {
                    $apts_missed++;
                    if ($icao) {
                        if (scalar(keys(%frq))>0) {
                            $missed_tower++;
                            if ($validate_on_ws && $ws_cnt) {
                                $lat = $wslat / $ws_cnt;
                                $lon = $wslon / $ws_cnt;
                                $XAPT{$icao}{'text'}=$text;
                                $XAPT{$icao}{'lat'}=$lat;
                                $XAPT{$icao}{'lon'}=$lon;
                                foreach $f (keys(%frq)) {
                                    $XAPT{$icao}{'com'}{$f}=$frq{$f};
                                    $freq_added++;
                                }
                                $apts_valid2++;
                            } else {
                                push(@no_twr,@arr);
                                push(@no_twr,"");
                            }
                        } else {
                            $missed_freq++;
                            # why not always at least add CTAF
                            # The most common CTAF frequency is 126.7 at non towered aerodromes 
                            push(@no_frq,@arr);
                            push(@no_frq,"");
                        }
                    } else {
                        $missed_icao++;
                        prt("$ap\n");
                    }
                }
                undef($icao);
                undef($text);
                undef($lon);
                undef($lat);
                undef($com);
                %frq=();
                @arr = ();
                $hh = 0;
                $ws_cnt = 0;    # clear the WindSock counter
                next;
            } # elsif($z=~/^1\s+\d+\s+[01]\s+[01]\s+([A-Z0-9]+)\s+(.+)$/)
            elsif($z=~/^1\s+\d+/)
            {
                #        1   596    0      1      EDBC          MAGDEBURG COCHSTEDT
                if($z=~/^1\s+\d+\s+[01]\s+[01]\s+([xA-Z0-9]+)\s+(.+)$/)
                {
                    # Airport Header
                    $icao=$1;
                    $text=$2;
                    $text =~ s/x//g;
                    $icao_count++;
                    $hh = 1;
                    $ap = $z;
                } else {
                    prt("$apt_lines: Airport header REJECTED by regex! CHECK ME\n");
                    prt("$z\n");
                    exit(1);
                }
            }
            elsif($z=~/^14\s+(-?\d+\.\d+)\s+(-?\d+\.\d+)/)
            {
                # TWR Position
                $lat=$1;
                $lon=$2;
                $tower_count++;
            }
            elsif($z=~/^5[0-6]\s+(\d{5})\d*\s+(.+)/)
            {
                # COM data
                $com=sprintf("%3.3f",$1/100);
                $frq{$com}=$2;
                $com_count++;
            }
            elsif ($z=~/^19\s+(-?\d+\.\d+)\s+(-?\d+\.\d+)/)
            {   
                # 19  08.320709 -073.357287 1 WS
                $wslat += $1;
                $wslon += $2;
                $ws_cnt++;
            }
            elsif ($z =~ /^99/)
            {
                last;
            }
            push(@arr,$z);  # keep the lines of this a/p
        }
        prt("Done $apt_lines lines from file...\n");
    }
    else
    {
        die("Cannot open $XP_AIRPORTS :$!\n");
    }
    close INF;
}

# read nav data in hash
sub read_navaids() {
    my $nav=new IO::Zlib;
    if($nav->open($FG_NAVAIDS, "r"))
    {
        prt("Reading $FG_NAVAIDS file...\n");
        my ($z,$lat,$lon,$frq,$code,$text);
        while($z=<$nav>)
        {
            $nav_lines++;
            chop($z);

            if($z=~/^3\s+(-?\d+\.\d+)\s+(-?\d+\.\d+)\s+\d+\s+(\d+)\s+\d+\s+-?\d+\.\d+\s+([A-Z]+)\s+(.*)\s*$/)
            {
                # VOR/DME Nav
                $lat=$1;
                $lon=$2;
                $frq=sprintf("%3.3f",$3/100);
                $code=$4;
                $text=$5;

                $NAV{$code}{'lat'}=$lat;
                $NAV{$code}{'lon'}=$lon;
                $NAV{$code}{'frq'}=$frq;
                $NAV{$code}{'text'}=$text;
                $nav_vordme++;
            } else {
                $nav_others++;
            }
        }
        prt("Done $nav_lines lines from file...\n");
    }
    else
    {
        die("Cannot open $FG_NAVAIDS :$!\n");
    }

    close($nav);
}

# read nav data in hash
sub read_navaids_XP() {
    if(open INF, "<$XP_NAVAIDS")
    {
        prt("Reading $XP_NAVAIDS file...\n");
        my ($z,$lat,$lon,$frq,$code,$text);
        while($z = <INF>)
        {
            $nav_lines++;
            chop($z);
            if($z=~/^3\s+(-?\d+\.\d+)\s+(-?\d+\.\d+)\s+\d+\s+(\d+)\s+\d+\s+-?\d+\.\d+\s+([A-Z]+)\s+(.*)\s*$/)
            {
                # VOR/DME Nav
                $lat=$1;
                $lon=$2;
                $frq=sprintf("%3.3f",$3/100);
                $code=$4;
                $text=$5;

                $XNAV{$code}{'lat'}=$lat;
                $XNAV{$code}{'lon'}=$lon;
                $XNAV{$code}{'frq'}=$frq;
                $XNAV{$code}{'text'}=$text;
                $nav_vordme++;
            } else {
                $nav_others++;
            }
        }
        prt("Done $nav_lines lines from file...\n");
    }
    else
    {
        die("Cannot open $FG_NAVAIDS :$!\n");
    }

    close INF;
}

sub write_fg_data() {
    # open positions file
    $positions=new IO::File;
    # $positions->open("positions.txt", "w") || die("Cannot open positions.txt for writing: $!\n");
    $positions->open($temp_pos, "w") || die("Cannot open $temp_pos for writing: $!\n");
     
    # open phonebook file
    $phonebook=new IO::File;
    #$phonebook->open("phonebook.txt", "w") || die("Cannot open phonebook.txt for writing: $!\n");
    $phonebook->open($temp_pb, "w") || die("Cannot open $temp_pb for writing: $!\n");
    print $phonebook "ICAO  Decription            FRQ      Phone no.          Name\n";
    print $phonebook "-"x79,"\n";

    # open asterisk extensions
    $extensions=new IO::File;
    #$extensions->open($CONF{'ASTERISK_CONFIG_DIR'}."/extensions.conf", "w") || die("Cannot open ".$CONF{'ASTERISK_CONFIG_DIR'}."/extensions.conf for writing: $!\n");
    $extensions->open($temp_ext, "w") || die("Cannot open $temp_ext for writing: $!\n");

    # read pre data for extensions
    #$extensions_pre=read_file($CONF{'CONFIG_DIR'}."/extensions.conf");
    my $extensions_pre = read_file($conf_ext);
    print $extensions $extensions_pre;

    # Print all known airports
    my ($airport);
    foreach $airport (sort(keys(%APT)))
    {
        my ($f,$tmp);
        foreach $f (keys(%{$APT{$airport}{'com'}}))
        {
            my $icao_number=icao2number($airport);

            # write positions APT
            print $positions $airport.",".$f.",".$APT{$airport}{'lat'}.",".$APT{$airport}{'lon'}.",".$APT{$airport}{'com'}{$f}.",".$APT{$airport}{'text'}."\n";
                    
            # write phonebook
            $tmp=sprintf("%4s  %-20s  %3.3f  %-.16s  %-20s\n",$airport,$APT{$airport}{'com'}{$f},$f,"01".$icao_number.$f*1000,$APT{$airport}{'text'});
            print $phonebook $tmp;

            # write extensions.conf
            print $extensions "; $airport $APT{$airport}{'com'}{$f} $f - $APT{$airport}{'text'}\n";
            if($APT{$airport}{'com'}{$f}=~/ATIS$/)
            {
                # ATIS playback extension
                print $extensions "exten => 01$icao_number".($f*1000).",1,SendText($airport ".$APT{$airport}{'text'}." $f ".$APT{$airport}{'com'}{$f}.")\n";
                print $extensions "exten => 01$icao_number".($f*1000).",n,SendURL(http://www.the-airport-guide.com/search.php?by=icao&search=$airport)\n";
                print $extensions "exten => 01$icao_number".($f*1000).",n,Macro(com)\n";

                # ATIS record extension
                print $extensions "exten => 99$icao_number".($f*1000).",1,SendText($airport ".$APT{$airport}{'text'}." $f Record-".$APT{$airport}{'com'}{$f}.")\n";
                print $extensions "exten => 99$icao_number".($f*1000).",n,Macro(com)\n";
            }
            else
            {
                print $extensions "exten => 01$icao_number".($f*1000).",1,SendText($airport ".$APT{$airport}{'text'}." $f ".$APT{$airport}{'com'}{$f}.")\n";
                print $extensions "exten => 01$icao_number".($f*1000).",n,SendURL(http://www.the-airport-guide.com/search.php?by=icao&search=$airport)\n";
                print $extensions "exten => 01$icao_number".($f*1000).",n,Macro(com)\n";

            }

            print $extensions ";\n";

        }
    }

    # write VORs to extensions.conf
    my ($vor);
    foreach $vor (sort(keys(%NAV)))
    {
        my $icao_number=icao2number($vor);

        # write positions NAV
        print $positions $vor.",".$NAV{$vor}{'frq'}.",".$NAV{$vor}{'lat'}.",".$NAV{$vor}{'lon'}.",VOR,".$NAV{$vor}{'text'}."\n";
                    
        # write phonebook
        my $tmp=sprintf("%4s  %-20s  %3.3f  %-.16s  %-20s\n",$vor,"",$NAV{$vor}{'frq'},"01".$icao_number.$NAV{$vor}{'frq'}*1000,$NAV{$vor}{'text'});
        print $phonebook $tmp;

        # write extensions.conf
        print $extensions "; VOR $vor $NAV{$vor}{'frq'} - $NAV{$vor}{'text'}\n";
        print $extensions "exten => 01$icao_number".($NAV{$vor}{'frq'}*1000).",1,SendText($vor ".$NAV{$vor}{'text'}." ".$NAV{$vor}{'frq'}.")\n";
        print $extensions "exten => 01$icao_number".($NAV{$vor}{'frq'}*1000).",n,Macro(vor,$vor)\n";
    }

    # read post data for extensions
    #$extensions_post=read_file($CONF{'CONFIG'}."/extensions.conf");
    #$extensions_post=read_file($conf_ext);
    #print $extensions $extensions_post;

    # close positions
    $positions->close;

    # close extensions
    $extensions->close;

    # close phonebook
    print $phonebook $phonebook_post;
    $phonebook->close;

    prt("Written $temp_pos\n");
    prt("Written $temp_pb\n");
    prt("Written $temp_ext\n");
}

sub write_xp_data() {
    # open positions file
    $positions=new IO::File;
    # $positions->open("positions.txt", "w") || die("Cannot open positions.txt for writing: $!\n");
    $positions->open($temp_posx, "w") || die("Cannot open $temp_posx for writing: $!\n");
     
    # open phonebook file
    $phonebook=new IO::File;
    #$phonebook->open("phonebook.txt", "w") || die("Cannot open phonebook.txt for writing: $!\n");
    $phonebook->open($temp_pbx, "w") || die("Cannot open $temp_pbx for writing: $!\n");
    print $phonebook "ICAO  Decription            FRQ      Phone no.          Name\n";
    print $phonebook "-"x79,"\n";

    # open asterisk extensions
    $extensions=new IO::File;
    #$extensions->open($CONF{'ASTERISK_CONFIG_DIR'}."/extensions.conf", "w") || die("Cannot open ".$CONF{'ASTERISK_CONFIG_DIR'}."/extensions.conf for writing: $!\n");
    $extensions->open($temp_extx, "w") || die("Cannot open $temp_extx for writing: $!\n");

    # read pre data for extensions
    #$extensions_pre=read_file($CONF{'CONFIG_DIR'}."/extensions.conf");
    my $extensions_pre = read_file($conf_ext);
    print $extensions $extensions_pre;

    # Print all known airports
    my ($airport);
    foreach $airport (sort(keys(%XAPT)))
    {
        my ($f,$tmp);
        foreach $f (keys(%{$XAPT{$airport}{'com'}}))
        {
            my $icao_number=icao2number($airport);

            # write positions APT
            print $positions $airport.",".$f.",".$XAPT{$airport}{'lat'}.",".$XAPT{$airport}{'lon'}.",".$XAPT{$airport}{'com'}{$f}.",".$XAPT{$airport}{'text'}."\n";
                    
            # write phonebook
            $tmp=sprintf("%4s  %-20s  %3.3f  %-.16s  %-20s\n",$airport,$XAPT{$airport}{'com'}{$f},$f,"01".$icao_number.$f*1000,$XAPT{$airport}{'text'});
            print $phonebook $tmp;

            # write extensions.conf
            print $extensions "; $airport $XAPT{$airport}{'com'}{$f} $f - $XAPT{$airport}{'text'}\n";
            if($XAPT{$airport}{'com'}{$f}=~/ATIS$/)
            {
                # ATIS playback extension
                print $extensions "exten => 01$icao_number".($f*1000).",1,SendText($airport ".$XAPT{$airport}{'text'}." $f ".$XAPT{$airport}{'com'}{$f}.")\n";
                print $extensions "exten => 01$icao_number".($f*1000).",n,SendURL(http://www.the-airport-guide.com/search.php?by=icao&search=$airport)\n";
                print $extensions "exten => 01$icao_number".($f*1000).",n,Macro(com)\n";

                # ATIS record extension
                print $extensions "exten => 99$icao_number".($f*1000).",1,SendText($airport ".$XAPT{$airport}{'text'}." $f Record-".$XAPT{$airport}{'com'}{$f}.")\n";
                print $extensions "exten => 99$icao_number".($f*1000).",n,Macro(com)\n";
            }
            else
            {
                print $extensions "exten => 01$icao_number".($f*1000).",1,SendText($airport ".$XAPT{$airport}{'text'}." $f ".$XAPT{$airport}{'com'}{$f}.")\n";
                print $extensions "exten => 01$icao_number".($f*1000).",n,SendURL(http://www.the-airport-guide.com/search.php?by=icao&search=$airport)\n";
                print $extensions "exten => 01$icao_number".($f*1000).",n,Macro(com)\n";

            }

            print $extensions ";\n";

        }
    }

    # write VORs to extensions.conf
    my ($vor);
    foreach $vor (sort(keys(%XNAV)))
    {
        my $icao_number=icao2number($vor);

        # write positions NAV
        print $positions $vor.",".$XNAV{$vor}{'frq'}.",".$XNAV{$vor}{'lat'}.",".$XNAV{$vor}{'lon'}.",VOR,".$XNAV{$vor}{'text'}."\n";
                    
        # write phonebook
        my $tmp=sprintf("%4s  %-20s  %3.3f  %-.16s  %-20s\n",$vor,"",$XNAV{$vor}{'frq'},"01".$icao_number.$XNAV{$vor}{'frq'}*1000,$XNAV{$vor}{'text'});
        print $phonebook $tmp;

        # write extensions.conf
        print $extensions "; VOR $vor $XNAV{$vor}{'frq'} - $XNAV{$vor}{'text'}\n";
        print $extensions "exten => 01$icao_number".($XNAV{$vor}{'frq'}*1000).",1,SendText($vor ".$XNAV{$vor}{'text'}." ".$XNAV{$vor}{'frq'}.")\n";
        print $extensions "exten => 01$icao_number".($XNAV{$vor}{'frq'}*1000).",n,Macro(vor,$vor)\n";
    }

    # read post data for extensions
    #$extensions_post=read_file($CONF{'CONFIG'}."/extensions.conf");
    #$extensions_post=read_file($conf_ext);
    #print $extensions $extensions_post;

    # close positions
    $positions->close;

    # close extensions
    $extensions->close;

    # close phonebook
    print $phonebook $phonebook_post;
    $phonebook->close;

    prt("Written $temp_posx\n");
    prt("Written $temp_pbx\n");
    prt("Written $temp_extx\n");
}

sub compare_apt_hashes() {
    my $fgcnt = scalar keys(%APT);
    my $xpcnt = scalar keys(%XAPT);
    prt("Comparing FG $fgcnt, with XP $xpcnt...\n");
}

##############################################################################
# Main program
##############################################################################
clear_counters();
@no_twr = ();
@no_frq = ();
if ($use_xp_files) {
    read_airports_XP();
    read_navaids_XP();

    show_apt_count();
    show_nav_count();

    write_xp_data();
} 

if (@no_twr) {
    loc_write2file(join("\n",@no_twr)."\n",$temp_notwrx);
    my $tmp = $missed_tower - $apts_valid2;
    prt("Written $tmp airports with NO TOWER or WS to $temp_notwrx (".scalar @no_twr.")\n");
}
if (@no_frq) {
    loc_write2file(join("\n",@no_frq)."\n",$temp_nofrqx);
    prt("Written airports with NO FREQUENCY to $temp_nofrqx\n");
}


clear_counters();
@no_twr = ();
@no_frq = ();

if ($use_fg_files) {
    # read airport data in hash
    read_airports();
    read_navaids();

    show_apt_count();
    show_nav_count();

    write_fg_data();
}

if (@no_twr) {
    loc_write2file(join("\n",@no_twr)."\n",$temp_notwr);
    my $tmp = $missed_tower - $apts_valid2;
    prt("Written $tmp airports with NO TOWER or WS to $temp_notwr (".scalar @no_twr.")\n");
}
if (@no_frq) {
    loc_write2file(join("\n",@no_frq)."\n",$temp_nofrq);
    prt("Written airports with NO FREQUENCY to $temp_nofrq\n");
}

if ($use_xp_files && $use_fg_files) {
    compare_apt_hashes();
}


# eof - gen_phonebook.pl
