#!/usr/bin/perl -w
# NAME: fg-ac2.pl
# AIM: Given an input folder, enumerate ALL *.ac files found
# Also see fg-ac.pl which tries to do the same using parsing the *-set.xml
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-10-24";
my $load_log = 0;
my $in_dir = '';
my $verbosity = 0;
my $out_file = $temp_dir.$PATH_SEP."tempac.txt";
#my $out_file = $temp_dir.$PATH_SEP."tempaiac.txt";
my $exclude_none = 0;
my $ai_model = 'F:\Projects\aircraft\AIModels.txt';
my $def_ai_dir = 'X:\fgdata\AI\Aircraft';

# ### DEBUG ###
my $debug_on = 1;
#my $def_file = 'X:\fgdata\AI\Aircraft';
#my $def_file = 'F:\fgdata\AI\Aircraft';
my $def_file = 'X:\fgdata\Aircraft';

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

### excluded directories
my @excluded_dirs = qw( lights Effects Instruments light Lights Light Cockpit
    Flightdeck FlightDeck Pushback Interior Operations Stores Interior Pilot Engines
    LandingGears Wings Textures Submodels Immat Seats interior Remb Rescue
    Instruments-3d compass nd pfd torque weapons instruments Ropes Guns weapons Weapons
    Interiour Loads armament Propellers refueling effects propeller
    Instruments3d Instruments(original) Stickers Handles Exterior 
    Cabine Engine Details Crew instrumentation Human Panels Armament
    loads instruments Instrumentation GroundCrew seats Wakes
    ControlHandle Exhausts Illuminators Seat Resources Instruments-de );

sub is_excluded_dir($) {
    my $dir = shift;
    my ($tmp);
    return 0 if ($exclude_none);
    foreach $tmp (@excluded_dirs) {
        return 1 if ($tmp eq $dir);
    }
    return 0;
}

sub is_excluded_file($) {
    my $file = shift;
    return 1 if ($file =~ /shadow/i);
    return 1 if (defined $excluded_files{$file});
    return 0;
}

sub is_excluded_type($) {
    my $file = shift;
    return 1 if ($file =~ /panel/i);
    return 1 if ($file =~ /gear/i);
    return 1 if ($file =~ /wing/i);
    return 1 if ($file =~ /engine/i);
    return 1 if ($file =~ /cabin/i);
    return 1 if ($file =~ /switch/i);
    return 1 if ($file =~ /light/i);
    return 1 if ($file =~ /stab/i);
    return 1 if ($file =~ /beacon/i);
    return 1 if ($file =~ /blackout/i);
    return 1 if ($file =~ /pilot/i);
    return 1 if ($file =~ /wheel/i);
    return 1 if ($file =~ /cabin/i);
    return 1 if ($file =~ /gauge/i);
    return 1 if ($file =~ /pedal/i);
    return 1 if ($file =~ /compass/i);
    return 1 if ($file =~ /landing/i);
    return 0;
}

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");
        }
    }
}

my @ac_files = ();
my $dir_count = 0;
my $file_count = 0;
my $excl_dir_cnt = 0;
my $excl_files = 0;
my $act_dir = '';

sub process_in_dir($$);



sub process_in_dir($$) {
    my ($dir,$lev) = @_;
    if (!opendir(DIR,"$dir")) {
        prt("Failed to open dir $dir!\n");
        return;
    }
    $dir_count++;
    my @files = readdir(DIR);
    close(DIR);
    my ($i,$file,$ff,$ra,$cnt,$n,$d,$e,$xf);
    if ($lev == 1) {
        ($file,$ff) = fileparse($dir);
        $act_dir = $file;
        prt("Active directory = '$act_dir'\n");
    }
    ut_fix_directory(\$dir);
    my @dirs = ();
    my @ac = ();
    $xf = 0;
    foreach $file (@files) {
        next if ($file eq '.');
        next if ($file eq '..');
        $ff = $dir.$file;
        if (-d $ff) {
            if (is_excluded_dir($file)) {
                $excl_dir_cnt++;
            } else {
                push(@dirs,$ff)
            }
        } elsif (-f $ff) {
            $file_count++;
            if ($file =~ /\.ac$/) {
                if (is_excluded_file($file)) {
                    $excl_files++;
                    $xf++;
                } else {
                    push(@ac,[$act_dir,$ff]);
                }
            }
        } else {
            pgm_exit(1,"What is this $ff!\n");
        }
    }

    if ($xf == 0) {
        $cnt = scalar @ac;
        if ($cnt == 1) {
            push(@ac_files, $ac[0]);
        } elsif ($cnt > 1) {
            # try to choose one
            my $fnd = 0;
            for ($i = 0; $i < $cnt; $i++) {
                $ra = $ac[$i];
                $dir = ${$ra}[0];
                $file = ${$ra}[1];
                ($n,$d,$e) = fileparse($file, qr/\.[^.]*/);
                if (lc($dir) eq lc($n)) {
                    push(@ac_files, $ra);
                    $fnd = 1;
                }
            }
            if (!$fnd) {
                for ($i = 0; $i < $cnt; $i++) {
                    $ra = $ac[$i];
                    $dir = ${$ra}[0];
                    $file = ${$ra}[1];
                    ($n,$d,$e) = fileparse($file, qr/\.[^.]*/);
                    if (is_excluded_type($n)) {
                        $excl_files++;
                    } else {
                        push(@ac_files, $ra);
                        $fnd++;
                    }
                }
            }
            if (!$fnd) {
                for ($i = 0; $i < $cnt; $i++) {
                    $ra = $ac[$i];
                    push(@ac_files, $ra);
                }
            }
        }
    }

    foreach $dir (@dirs) {
        process_in_dir($dir,($lev + 1));
    }
}

sub show_ac_files() {
    my ($cnt,$fil,$dir,$i,$ra);
    my $txt = '';
    $cnt = scalar @ac_files;
    prt("Processed $dir_count dirs, $excl_dir_cnt excluded, $file_count files, $excl_files excluded, and found $cnt .ac files...\n");
    for ($i = 0; $i < $cnt; $i++) {
        $ra = $ac_files[$i];
        $dir = ${$ra}[0];
        $fil = ${$ra}[1];
        $txt .= "$dir,$fil\n";
    }
    write2file($txt,$out_file);
    prt("List written to $out_file...\n");
}

sub load_ai_models() {
    my $file = $ai_model;
    if (! -f $file) {
        pgm_exit(1,"ERROR: file $file does NOT exist!\n");
        return;
    }
    if (!open FIL, "<$file") {
        pgm_exit(1,"ERROR: Can NOT open file $file!\n");
        return;
    }
    my @lines = <FIL>;
    close FIL;
    my ($line,$len,$name,$dir,@arr,$dcnt,$cnt,$adir);
    my $ai_dir = path_u2d($def_ai_dir);
    my @darr = split(/\\/,$ai_dir);
    $dcnt = scalar @darr;
    foreach $line (@lines) {
        chomp $line;
        $line = trim_all($line);
        $len = length($line);
        next if ($len == 0);
        $line = path_u2d($line);
        ($name,$dir) = fileparse($line);
        @arr = split(/\\/,$dir);
        $cnt = scalar @arr;
        if ($cnt < $dcnt) {
            pgm_exit(1,"ERROR: Count too small $cnt! Expect GTT $dcnt\n");
        }
        $adir = $arr[$dcnt];
        prt("file '$name', dir '$adir'\n") if (VERB9());
        $excluded_files{$name} = $adir;
    }
    $cnt = scalar keys %excluded_files;
    prt("Got $cnt AI files to exclude...\n");
    ###pgm_exit(1,"TEMP EXIT\n");
}



#########################################
### MAIN ###
parse_args(@ARGV);
load_ai_models();
process_in_dir($in_dir,0);
show_ac_files();
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-file\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(" --xclude <dir> (-x) = Exclude this directory.\n");
}

# eof - template.pl
