#!/perl -w
# NAME: xmlfgair.pl
# AIM: Read FG AirCraft -set.xml file, and show details...
use strict;
use warnings;
# References
# http://www.perl.com/lpt/a/3 # http://www.xml.com/pub/a/98/09/xml-perl.html
# use XML::Parser
# Install
# shell> perl -MCPAN -e shell
# cpan> install XML::Simple
#   require XML::Parser::Expat;
#  $VERSION = '2.36';
#  die "Parser.pm and Expat.pm versions don't match"
#    unless $VERSION eq $XML::Parser::Expat::VERSION;
# http://sourceforge.net/projects/expat/
# References
# http://search.cpan.org/dist/XML-Simple/lib/XML/Simple.pm
use XML::Simple;
use File::Basename;     # to split path into ($name, $dir) = fileparse($ff); or ($nm,$dir,$ext) = fileparse( $fil, qr/\.[^.]*/ );
unshift(@INC,'C:\GTools\perl');
require 'logfile.pl' or die "Unable to load logfile.pl ...\n";
# log file stuff
my ($LF);
my $pgmname = $0;
if ($pgmname =~ /\w{1}:\\.*/) {
   my @tmpsp = split(/\\/,$pgmname);
   $pgmname = $tmpsp[-1];
}
my $perl_root = 'C:\GTools\perl';
my $outfile = $perl_root."\\temp.$pgmname.txt";
open_log($outfile);

# features
my $load_log = 0;
my $def_file = 'C:\FG\27\data\Aircraft\A380\A380-set.xml';
my @in_files = ();
my @in_dirs = ();
my %exclude_files = ();
my $temp_file_list = $perl_root.'\temp_list.txt';
my $temp_xclude_list = $perl_root.'\temp_xclude.txt';

# debug
my $dbg_01 = 0; # prt("[dbg_01] Processing directory [$dir]...\n") if ($dbg_01);


sub process_dir($);

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

sub is_in_excluded($) {
   my ($fil) = shift;
   foreach my $test (keys %exclude_files) {
      if ($fil eq $test) {
         return 1;
      }
   }
   return 0;
}

sub show_fg_xml_data($$) {
   my ($fil,$rha) = @_;
   my ($msg,$v);
   my %hash = ();
   prt("FG Information: for [$fil]...\n");
   if (defined $rha->{'sim'}) {
      $msg = "Aero        :";
      if (defined $rha->{'sim'}->{'aero'}) {
         $v = $rha->{'sim'}->{'aero'};
         prt("$msg $v\n" );
         $hash{'aero'} = $v;
      } else {
         prt("$msg <not found>\n");
      }
      $msg = "Status      :";
      if (defined $rha->{'sim'}->{'status'}) {
         $v = $rha->{'sim'}->{'status'};
         prt("$msg $v\n" );
         $hash{'status'} = $v;
      } else {
         prt("$msg <not found>\n");
      }

      $msg = "Flight Model:";
      if (defined $rha->{'sim'}->{'flight-model'}) {
         $v = $rha->{'sim'}->{'flight-model'};
         prt("$msg $v\n");
         $hash{'flight-model'} = $v;
      } else {
         prt("$msg <not found>\n");
      }

      $msg = "Description :";
      if (defined $rha->{'sim'}->{'description'}) {
         $v = $rha->{'sim'}->{'description'};
         prt("$msg $v\n");
         $hash{'description'} = $v;
      } else {
         prt("$msg <not found>\n");
      }

      $msg = "Version     :";
      if (defined $rha->{'sim'}->{'aircraft-version'}) {
         $v = $rha->{'sim'}->{'aircraft-version'};
         prt("$msg $v\n" );
         $hash{'aircraft-version'} = $v;
      } else {
         prt("$msg <not found>\n");
      }
   } else {
      prt("Error: Can not locate 'sim' entry. Maybe NOT an aricraft set file!\n");
   }
   return \%hash;
}

sub process_file($) {
   my ($fil) = shift;
   my $rh = undef;
   if (! -f $fil) {
      prt("ERROR: Can NOT locate file [$fil]!\n");
      return $rh;
   }
   my ($nm,$dir) = fileparse($fil);
   if (is_in_excluded($nm) ) {
      prt("Excluding file [$fil]...\n");
   } else {
      prt("Loading file [$fil]...\n");
      my $xml = new XML::Simple (ForceArray => 0);
      my $data = $xml->XMLin($fil);
      $rh = show_fg_xml_data($fil,$data);
   }
   return $rh;
}

sub process_files($$$) {
   my ($rfa,$tfl,$txl) = @_;
   my ($file,$msg,$cnt,$rh);
   my %hash = ();
   if (length($tfl)) {
      $msg = '';
      $cnt =0;
      foreach $file (@{$rfa}) {
         $msg .= "$file\n";
         $cnt++;
      }
      write2file($msg,$tfl);
      prt("File list $cnt, written to $tfl...\n");
   }

   if (length($txl)) {
      $msg = '';
      $cnt =0;
      foreach $file (keys %exclude_files) {
         $msg .= "$file\n";
         $cnt++;
      }
      write2file($msg,$txl);
      prt("File list $cnt, written to $txl...\n");
   }

   foreach $file (@{$rfa}) {
      $rh = process_file($file);
      $hash{$file} = $rh;
   }
   return \%hash;
}

sub process_dir($) {
   my ($dir) = shift;
   my @dirs = ();
   prt("[dbg_01] Processing directory [$dir]...\n") if ($dbg_01);
   if (opendir(DIR,$dir)) {
      my @fils = readdir(DIR);
      closedir(DIR);
      foreach my $fil (@fils) {
         next if (($fil eq '.')||($fil eq '..'));
         my $ff = $dir;
         $ff .= "/" if (!($ff =~ /(\\|\/)$/));
         $ff .= $fil;
         if (-d $ff) {
            push(@dirs,$ff);
         } elsif ($fil =~ /-set\.xml$/) {
            push(@in_files,$ff);
         }
      }
      foreach my $d (@dirs) {
         process_dir($d);
      }
   } else {
      prt("WARNING: Unable to open directory [$dir]\n");
   }
}

sub process_dirs($) {
   my ($rda) = shift;
   my ($dir);
   my $cnt = scalar @in_files;
   foreach $dir (@{$rda}) {
      process_dir($dir);
   }
   my $ncnt = scalar @in_files;
   if ($ncnt > $cnt) {
      prt("Directory processing added ".($ncnt - $cnt)." files...\n");
   }
}

sub show_ref_hash($) {
   my ($rh) = shift;
   my ($fil,$key,$msg,$val,$cnt,$rh2);
   $cnt = 0;
   foreach $fil (keys %{$rh}) {
      $rh2 = $rh->{$fil};
      #$rh2 = ${$rh}{$fil};
      $cnt++;
      $msg = "";
      foreach $key (keys %{$rh2}) {
         $val = ${$rh2}{$key};
         $msg .= ", " if length($msg);
         $msg .= "$key=$val";
      }
      $msg = "$cnt: File: $fil\n$msg";
      prt("$msg\n");
   }
}

# #####################################
# ### MAIN ###
parse_args(@ARGV);
process_dirs(\@in_dirs);   # process directory input...
my $ref_hash = process_files(\@in_files,$temp_file_list,$temp_xclude_list);
show_ref_hash($ref_hash);
pgm_exit(0,"Normal exit");
# #####################################

sub parse_args {
   my (@av) = @_;
   my ($arg,$cnt,@arr,$tmp);
   $cnt = scalar @av;
   #prt("Processing $cnt arguments...\n");
   while (@av) {
      my $arg = $av[0];
      if ($arg =~ /^-/) {
         my $sarg = substr($arg,1);
         $sarg = substr($sarg,1) while ($sarg =~ /^-/);
         if ($sarg =~ /^l/i) {
            $load_log = 1;
            prt("Set load log at end.\n");
         } elsif ($sarg =~ /^x:(.+)$/) {
            $sarg = $1;
            @arr = split(":",$sarg);
            foreach $tmp (@arr) {
               if ( defined $exclude_files{$tmp} ) {
                  prt("File $tmp already excluded!\n");
               } else {
                  $exclude_files{$tmp} = 1;
                  prt("Added file [$tmp] to excluded.\n");
               }
            }
         }
         # options???
      } else {
         if (-d $arg) {
            push(@in_dirs,$arg);
            prt("Added input directory [$arg]...\n");
         } elsif (-f $arg) {
            push(@in_files,$arg);
            prt("Added input file [$arg]...\n");
         } else {
            pgm_exit(1,"ERROR: [$arg] NOT directory or file! Aborting.");
         }
      }
      shift @av;
   }
   if ( !@in_files && !@in_dirs ) {
      if (-f $def_file) {
         push(@in_files,$def_file);
         prt("Added DEFAULT input file [$def_file]...\n");
      } else {
         pgm_exit(1,"Error: No input file to process! Aborting.\n");
      }
   }
}

# eof - xmlfgair.pl
