#!/perl -w
# dirbydate.pl
# AIM: Read a file output from the DIR command, and order the files in DATE
# order ... drop out the pure <DIR> entries ...
# 10/18/2008 - Account for American MM/DD/YEAR, and inhibit <DIR> listings
# 20061219 - Can NOT use just $0 to get script name, since when directly invoke from
# a command prompt, it becomes C:\GTools\Perl\dirbydate.pl, so added some regex to
# massage the name, and just get the perl script name ... if a DRIVE included /^\w{1}:\\.*/
# AND, to enable it to FIND the logfile.pl, add unshift(@INC, 'C:/GTools/perl');
# OR this can be use lib '/Users/User/perl-lib';, or perl -MC:/GTools/perl -e dirbydate.pl
# and added a $evenspace option ...
use strict;
use warnings;
unshift(@INC, 'C:/GTools/perl');
require 'logfile.pl' or die "Unable to load logfile.pl ...\n";
# options
my $evenspace = 1;
my $excldirs = 1;	# exclude DIRECTORIES from final list
my $maxname = 0;
my $maxsize = 0;
my $loadout = 0;
my $maxlines = 300;	# if greater than ??? lines, $loadout in notepad ...
my $fixtm = 0;
# log file stuff
my ($LF);
my $outfile = 'temp.'.$0.'.txt';
if ($0 =~ /^\w{1}:\\.*/) {
	my @tmpsp = split(/\\/,$0);
	$outfile = 'temp.'.($tmpsp[-1]).'.txt';
}
open_log($outfile);
prt( "$0 ... Hello, World ...\n" );
# debug output
my $dbg01 = 0;	# show each FOLDER as found ...
my $dbg02 = 0;	# show count and bytes as found ...
my $dbg03 = 0;	# show files, as found
my $verb3 = 0;	# show sort compare ...

###my $in_file = 'C:/DTEMP/tempall6.txt';
my $in_file = 'templist';
if (@ARGV) {
	$in_file = pop @ARGV;
}
my @filelist = ();
my @sortlist = ();
my $basedir = '';

sub remdir {
	my ($f) = shift;
	my $b2 = quotemeta($basedir);
	$f =~ s/^$b2\\//; # remove beginning ...
	return $f;
}

# 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;
}

open INF, "<$in_file" or mydie("ERROR: Can NOT open [$in_file] ... $! ...\n" );
my @lines = <INF>;	# slurp it all
close INF;
my $lc = scalar @lines;
prt( "Processing $lc lines from [$in_file] ...\n" );
my $line = '';
my $tln = '';
my $act_folder = '';
$basedir = file_dirname($in_file);
my $dddmmyy = guess_date_order(@lines);
foreach $line (@lines) {
	$tln = trim_all($line);
	next if (length($tln) == 0);
	next if skip_line($tln);
	my @arr = split(/\s/, $tln);
	my $ac = scalar @arr;
	my $pchk = 0;
	#prt( $line );
	if ($ac > 3) {
		if ($arr[2] eq '<DIR>') {
			# ignore
		} else {
			# file names of interest
			my @ar2 = split('/', $arr[0]); # get day/month/year
			my @ar3 = split(':', $arr[1]); # get hour:minutes
			my $sz = $arr[2];
			my $nm = $arr[3];
			#if ($fixtm && (($sz eq 'AM')||($sz eq 'PM'))) {
			if (($sz eq 'AM')||($sz eq 'PM')) {
				# 12 hour clock - have AM or PM
				if ($sz eq 'PM') {
					$ar3[0] += 12;	# bump hour by 12
					$arr[1] = $ar3[0].':'.$ar3[1];
				}
				$sz = $arr[3];
				$nm = $arr[4];
				if ($ac > 5) {
					my $i = 5;
					while($i < $ac) {
						$nm .= ' '.$arr[$i];
						$i++;
					}
				}
			} else {
				# 24 hour clock (no AM/PM)
				if ($ac > 4) {
					my $i = 4;
					while($i < $ac) {
						$nm .= ' '.$arr[$i];
						$i++;
					}
				}
			}
			if ((scalar @ar2 == 3)&&(scalar @ar3 == 2)) {
				my $ft = int($ar2[2].$ar2[1].$ar2[0].$ar3[0].$ar3[1]);
				if ($dddmmyy == 0) {
					$ft = int($ar2[2].$ar2[0].$ar2[1].$ar3[0].$ar3[1]);
				}
				if ($evenspace) {	# get maximum lengths
					$maxname = length($nm) if (length($nm) > $maxname);
					$maxsize = length($sz) if (length($sz) > $maxsize);
				}
				#                 0     1   2    3            4       5
				push(@filelist, [$ft, $nm, $sz, $act_folder, $arr[0], $arr[1]]);
				#prt( "$ft, $nm, $sz, $act_folder $arr[0], $arr[1]\n") if ($dbg03);
				prt( "$ft, $nm, $sz, $arr[0], $arr[1]\n") if ($dbg03);
			} else {
				$pchk = 1;
			}
		}
	} else {
		$pchk = 1;
	}
	if ($pchk) {
		prt( "CHECK: " );
		for (my $i = 0; $i < $ac; $i++) {
			prt( $arr[$i].' ' );
		}
		prt("\n");
	}
}

my $fc = scalar @filelist;
prt( "Got $fc files ... mxsz=$maxsize mxnm=$maxname ...\n" );
###@sortlist = sort mycmp_decend @filelist;
@sortlist = sort mycmp_ascend @filelist;
my $fcs = scalar @sortlist;
$loadout = 1 if ($fcs > $maxlines);	# if greater than ??? lines, $loadout in notepad ...
prt( "Got $fcs sorted files ...\n" );
my $msg = '';
for (my $i = 0; $i < $fcs; $i++) {
	my $reldir = remdir( $sortlist[$i][3] );
	#                   0    1    2    3            4        5 
	# push(@filelist, [$ft, $nm, $sz, $act_folder, $arr[0], $arr[1]]);
	my $flsz = $sortlist[$i][2];
	if ($excldirs) {	# exclude DIRECTORIES from final list
		next if ($flsz =~ /<DIR>/i);
	}
	if ($evenspace) {
		my $sz = $sortlist[$i][2];
		while (length($sz) < $maxsize) {
			$sz = ' ' . $sz;
		}
		my $nm = $sortlist[$i][1];
		while (length($nm) < $maxname) {
			$nm = ' ' . $nm;
		}
		$msg = $sortlist[$i][4] . ' ' . $sortlist[$i][5] . ' ' . $sz . ' ' . $nm . ' ' . $reldir;
	} else {
		$msg = $sortlist[$i][4] . ' ' . $sortlist[$i][5] . ' ' . $sortlist[$i][1] . ' ' . $reldir;
	}
	prt( "$msg\n" );
}
close_log($outfile,$loadout);
exit(0);


sub skip_line {
	my ($l) = shift;
	#  Volume in drive C has no label.
	#  Volume Serial Number is D833-AEFA
	if ($l =~ /Volume in drive (.*)/ ) {
		return 1;	# ignore
	} elsif ($l =~ /Volume Serial Number is (.*)/ ) {
		return 1;	# ignore
	} elsif ($l =~ /Total Files Listed/ ) {
		return 1;	# ignore
	} elsif ($l =~ /Directory of (.*)/ ) {
		$act_folder = $1;
		prt( "Folder [$act_folder] ...\n" ) if ($dbg01);
		return 1;
	} elsif ($l =~ /\d+\s+File\(s\)\s+[\d,]+\s+bytes/ ) {
		prt( $l ) if ($dbg02);
		return 1;
	} elsif ($l =~ /\d+\s+Dir\(s\)\s+[\d,]+\s+bytes/ ) {
		prt( $l ) if ($dbg02);
		return 1;
	}
	return 0;
}

########################################
sub guess_date_order {
	my (@lns) = @_;
	my ($ln, @ar, $c);
	my $badmths = 0;
	my $daysgt12 = 0;
	my $checked = 0;
	foreach $ln (@lns) {
		$ln = trim_all($ln);
		next if (length($ln) == 0);
		next if skip_line($ln);
		@ar = split(/\s/, $ln);
		$c = scalar @ar;
		#prt( $line );
		if ($c > 3) {
			if ($ar[2] eq '<DIR>') {
				# ignore
			} else {
				# file names of interest
				my @arr2 = split('/', $ar[0]); # get day/month/year OR month/day/year
				if (scalar @arr2 >= 3) {
					$checked++;
					if ($arr2[1] > 12) {
						if ($badmths) {
							$badmths++;
							if ($badmths > 10) {
								prt( "Got $badmths months GT 12 [$ln]... $arr2[1] ... assume American MM/DD/YEAR ...\n" );
								return 0;
							}
						} else {
							prt( "Got month GT 12 [$ln]... $arr2[1] ...\n" );
							$badmths++;
						}
					}
					if ($arr2[0] > 12) {
						if ($daysgt12) {
							$daysgt12++;
						} else {
							prt( "Got day GT 12 [$ln]... $arr2[0] ...\n" );
							$daysgt12++;
						}
					}
				}
			}
		}
	}
	if ($badmths > 2) {
		return 0;
	}
	return 1;
}

# eof
