#!/Perl

print "Hello, World...\n";

$root_dir = 'C:\\FG0910-1\\source\\';

$debug_on = 0;
# configuration stuff
my $msvc8_dintd = '';
my $msvc8_rintd = '';
# compiler stuff
my @msvc8_dincs = ();
my @msvc8_ddefs = ();
my @msvc8_rincs = ();
my @msvc8_rdefs = ();
# linker stuff
my @msvc8_dlibs = ();
my @msvc8_dpath = ();
my @msvc8_rlibs = ();
my @msvc8_rpath = ();
# other items
my $warn = '';

my ($LOG);
my $outfile = 'tempvcproj01.txt';
open $LOG, ">$outfile" or die "Unable to open $outfile LOG ...\n";
amend_vcproj();
close(LOG);

sub prt_list {
	my (@list) = @_;
	my $ind = '';
	foreach my $line (@list) {
		if ($line =~ /^</) {
			if ($line =~ /\/>/) {
				# end xml same line
			} elsif ($line =~ /^<\//) {
				$ind = substr($ind, 1) if (length($ind));
			} else {
				# $ind .= ' ';
			}
		}
		prt( $ind.$line."\n" );
		if ($line =~ /^</) {
			if ($line =~ /\/>/) {
				# end xml same line
			} elsif ($line =~ /^<\//) {
				# $ind = substr($ind, 1) if (length($ind));
			} else {
				$ind .= ' ';
			}
		}
	}
}

sub trim_line {
	my ($l) = shift;
	chomp $l;
	$l =~ s/\r$//; # and remove CR, if present
	$l =~ s/\t/ /g;
	$l =~ s/\s\s/ /g while ($l =~ /\s\s/);
	$l = substr($l,1) while ($l =~ /^\s/);
	$l = substr($l,0,length($l)-1) while (($l =~ /\s$/)&&(length($l)));
	return $l;
}

sub find_item3 {
	my ($st1, $st2, $st3, $st31, $st3x, $stf, @ll) = @_;
	my @hdrs = ();
	my $ln1 = '';
	my $ln = '';
	my $lb = 0;
	my $le = 0;
	my $lc = 0;
	my $st = 0;
	prt( "Got [".$st1."], [$st2], [$st3], [$st31], [$st3x], [$stf]... \n" ) if $debug_on;
	foreach $ln1 (@ll) {
		chomp $ln1;
		$ln1 =~ s/\r$//; # and remove CR, if present
		$ln .= $ln1;
		if ($ln1 =~ /</) {
			$lb = $lc;
		}
		if ($ln1 =~ />/) {
			$le = $lc;
		}
		if ($ln =~ />/) {
			if ($st == 0) {
				# searching for 'VisualStudioProject'
				#if ($ln =~ /<VisualStudioProject/) {
				if ($ln =~ /$st1/) {
					$st = 1;
				}
			} elsif ($st == 1) {
				# seraching for 'Files'
				if ($ln =~ /$st2/) {
					$st = 2;
				}
			} elsif ($st == 2) {
				# searching for 'Filter'
				if ($ln =~ /$st3/) {
					#if ($ln =~ /Name=\"Header Files\"/) {
					if ($ln =~ /$st31/) {
						prt( "Enter 3 ... found $st31 ... ".trim_line($ln)."\n") if $debug_on;
						$st = 3;
					}
				}
			} elsif ($st == 3) {
				#if ($ln =~ /<\/Filter/) {
				if ($ln =~ /$st3x/) {
					$st = 2;
				#} elsif ( $ln =~ /(<File)+(\s)+(RelativePath=\")+([\.\\\w]+)+(\")+(.)+/ ) {
				} elsif ( $ln =~ /$stf/ ) {
					push(@hdrs, $4 . '|' . $lb . '-' . $le);
					prt( "1[$1] 2[$2] 3[$3] 4[$4] 5[$5] 6[$6] (".trim_line($ln).")\n" ) if $debug_on;
				}
			} 
			$ln = ''; # restart line accumuation
		}
		$lc++; # bump line counter
	}
	return @hdrs;
}



sub find_headers {
	my (@ll) = @_;
	my $st1 = '<VisualStudioProject';
	my $st2 = '<Files';
	my $st3 = '<Filter';
	my $st31 = 'Name="Header Files"';
	my $st3x = '<\/Filter';
	my $stf = '(<File)+(\\s)+(RelativePath=\\")+([\\.\\\\\\w]+)+(\\")+(.)+';
	###prt( "Got [".$st1."], [$st2], [$st3], [$st31], [$st3x], [$stf]... \n" );
	my @hdrs = find_item3( $st1, $st2, $st3, $st31, $st3x, $stf, @ll );
	return @hdrs;
}

sub find_sources {
	my (@ll) = @_;
	my $st1 = '<VisualStudioProject';
	my $st2 = '<Files';
	my $st3 = '<Filter';
	my $st31 = 'Name="Source Files"';
	my $st3x = '<\/Filter';
	my $stf = '(<File)+(\\s)+(RelativePath=\\")+([\\.\\\\\\w]+)+(\\")+(.)+';
	###prt( "Got [".$st1."], [$st2], [$st3], [$st31], [$st3x], [$stf]... \n" );
	my @hdrs = find_item3( $st1, $st2, $st3, $st31, $st3x, $stf, @ll );
	return @hdrs;
}


sub find_hash3 {
	my ($st1, $st2, $st3, $st31, $st3x, $stf1, $stf2, @ll) = @_;
	my %hdrs = ();
	my $ln1 = '';
	my $ln = '';
	my $lb = 0;
	my $le = 0;
	my $lc = 0;
	my $st = 0;
	my $nm = '';
	prt( "Got [".$st1."], [$st2], [$st3], [$st31], [$st3x], [$stf1] [$stf2 ... \n" ) if $debug_on;
	foreach $ln1 (@ll) {
		chomp $ln1;
		$ln1 =~ s/\r$//; # and remove CR, if present
		$ln .= $ln1;
		if ($ln1 =~ /</) {
			$lb = $lc;
		}
		if ($ln1 =~ />/) {
			$le = $lc;
		}
		if ($ln =~ />/) {
			if ($st == 0) {
				# searching for 'VisualStudioProject'
				#if ($ln =~ /<VisualStudioProject/) {
				if ($ln =~ /$st1/) {
					$st = 1;
				}
			} elsif ($st == 1) {
				# searching for 'Configurations'
				if ($ln =~ /$st2/) {
					$st = 2;
				}
			} elsif ($st == 2) {
				# searching for 'Configuration'
				if ($ln =~ /$st3/) {
					#if ($ln =~ /Name=\"Debug|Win32\"/) {
					if ($ln =~ /$st31/) {
						prt( "Enter 3 ... found $st31 1[$1] 2[$2] 3[%3]... ".trim_line($ln)."\n") if $debug_on;
						$nm = $2 . '|'; # set the NAME
						if ($ln =~ /(IntermediateDirectory=\")(\w+?)(\")/) {
							$hdrs{$nm.'IntermediateDirectory'} = '' . $lb . '-' . $le;
							prt( "Got IntDir 1[$1] 2[$2] 3[$3] ...\n" ) if $debug_on;
						}
						$st = 3;
					}
				}
			} elsif ($st == 3) {
				my $tln = trim_line($ln);
				#if ($ln =~ /<\/Configuration/) {
				if ($tln =~ /$st3x/) {
					prt( "Exit 3 ... found $st3x ... ".trim_line($ln)."\n") if $debug_on;
					$st = 2;
				} elsif ( $tln =~ /(^<Tool)+(\s)+(Name=\"VCCLCompilerTool\")+(.+)+(>)/ ) {
				###} elsif ( $ln =~ /$stf/ ) {
					$hdrs{$nm.'VCCLCompilerTool'} = '' . $lb . '-' . $le;
					prt( "1[$1] 2[$2] 3[$3] 4[$4] 5[$5] 6[$6] \n(".trim_line($ln).")\n" ) if $debug_on;
				} elsif ( $tln =~ /(^<Tool)+(\s)+(Name=\"VCLinkerTool\")+(.+)+(>)/ ) {
					$hdrs{$nm.'VCLinkerTool'} = '' . $lb . '-' . $le;
					prt( "1[$1] 2[$2] 3[$3] 4[$4] 5[$5] 6[$6] \n(".trim_line($ln).")\n" ) if $debug_on;
				}
			} 
			$ln = ''; # restart line accumuation
		}
		$lc++; # bump line counter
	}
	return %hdrs;
}

##sub find_debug {
sub find_config {
	my (@ll) = @_;
	my $st1 = '<VisualStudioProject';
	my $st2 = '<Configurations';
	my $st3 = '<Configuration';
	#my $st31 = 'Name="Debug\|Win32"';
	#my $st31 = '(Name=")(Debug\|Win32"|Release\|Win32")';
	my $st31 = '(Name=")(Debug|Release)(\|Win32")';
	my $st3x = '<\/Configuration';
	my $stf1 = '(<Tool)+(\\s)+(Name="VCCLCompilerTool")';
	my $stf2 = '(<Tool)+(\\s)+(Name="VCCLCompilerTool")';
	###prt( "Got [".$st1."], [$st2], [$st3], [$st31], [$st3x], [$stf1] [$stf2] ... \n" );
	my %hdrs = find_hash3( $st1, $st2, $st3, $st31, $st3x, $stf1, $stf2, @ll );
	return %hdrs;
}

# sub get_lines( $configd{$key}, @main_lines );
sub get_lines {
	my ($lns, @arr) = @_;
	my $rln = '';
	my @ft = split( /-/, $lns );
	my $cnt = scalar @arr;
	if (($ft[0] <= $cnt)&&($ft[0] <= $ft[1])&&($ft[1] <= $cnt)) {
		if ($ft[0] == $ft[1]) {
			$rln = trim_line($arr[$ft[0]]);
		} else {
			for (my $i = $ft[0]; $i <= $ft[1]; $i++ ) {
				$rln .= trim_line( $arr[$i] );
				if ($rln =~ /\s$/) {
					# ok, got a space
				} elsif ($i < $ft[1]) {
					$rln .= ' ';
				}
			}
		}
	}
	return trim_line($rln);
}

sub clear_arrays {
	# configuration stuff
	$msvc8_dintd = '';
	$msvc8_rintd = '';
	# compiler stuff
	@msvc8_dincs = ();
	@msvc8_ddefs = ();
	@msvc8_rincs = ();
	@msvc8_rdefs = ();
	# linker stuff
	@msvc8_dlibs = ();
	@msvc8_dpath = ();
	@msvc8_rlibs = ();
	@msvc8_rpath = ();
	# other items
	$warn = '';
}

sub process_lines {
	my (@mlines) = @_;
	my ($key, $line, $nm, $tool, $msg, $item);
	clear_arrays();
	my %configd = find_config(@mlines);
	for my $key (keys %configd) {
		prt( "key = $key => value = " . $configd{$key} . "\n" ) if $debug_on;
		$line = get_lines( $configd{$key}, @mlines );
		my ($nm,$tool) = split( /\|/, $key );
		###prt( "line[$line]nm=$nm tool=$tool\n" );
		if ($tool eq 'VCCLCompilerTool') {
			if ($line =~ /(AdditionalIncludeDirectories)(=)(\")(.+?)(\")(.+)/) {
				$item = $4;
				$msg = "$nm Incs=4[$item] 5[$5] ";
				if ($nm eq 'Debug') {
					@msvc8_dincs = split(/;/, $item);
					$msg .= 'added to msvc8_dincs';
				} elsif ($nm eq 'Release') {
					@msvc8_rincs = split(/;/, $item);
					$msg .= 'added to msvc8_rincs';
				} else {
					prt( "WARNING: Unknown configuration ... $nm ???\n" );
					$warn .= "WARNING: Unknown configuration ... $nm ???\n";
				}
				prt( "$msg\n" ) if $debug_on;
			}
			if ($line =~ /(PreprocessorDefinitions)(=)(\")(.+?)(\")(.+)/) {
				$item = $4;
				$msg = "$nm Defs=4[$item] 5[$5] ";
				if ($nm eq 'Debug') {
					@msvc8_ddefs = split(/;/, $item);
					$msg .= 'added to msvc8_ddefs';
				} elsif ($nm eq 'Release') {
					@msvc8_rdefs = split(/;/, $item);
					$msg .= 'added to msvc8_rdefs';
				} else {
					prt( "WARNING: Unknown configuration ...$nm ???\n" );
					$warn .= "WARNING: Unknown configuration ...$nm ???\n";
				}
				prt( "$msg\n" ) if $debug_on;
			}

		} elsif ($tool eq 'VCLinkerTool') {
			if ($line =~ /(AdditionalDependencies)(=)(\")(.+?)(\")(.+)/) {
				$item = $4;
				$msg = "$nm Libs=4[$item] 5[$5] ";
				if ($nm eq 'Debug') {
					@msvc8_dlibs = split(/ /, $item);
					$msg .= 'added to msvc8_dlibs';
				} elsif ($nm eq 'Release') {
					@msvc8_rlibs = split(/ /, $item);
					$msg .= 'added to msvc8_rlibs';
				} else {
					prt( "WARNING: Unknown configuration ...$nm ???\n" );
					$warn .= "WARNING: Unknown configuration ...$nm ???\n";
				}
				prt( "$msg\n" ) if $debug_on;
			}
			if ($line =~ /(AdditionalLibraryDirectories)(=)(\")(.+?)(\")(.+)/) {
				$item = $4;
				###prt( "Paths=4[$4] 5[$5]\n" );
				$item =~ s/&quot;/\"/g;
				$msg = "$nm Paths=$item 5[$5] ";
				if ($nm eq 'Debug') {
					@msvc8_dpath = split(/;/, $item);
					$msg .= 'added to msvc8_dpath';
				} elsif ($nm eq 'Release') {
					@msvc8_rpath = split(/;/, $item);
					$msg .= 'added to msvc8_rpath';
				} else {
					prt( "WARNING: Unknown configuration ...$nm ???\n" );
					$warn .= "WARNING: Unknown configuration ...$nm ???\n";
				}
				prt( "$msg\n" ) if $debug_on;
			}
		} elsif ($tool = 'IntermediateDirectory') {
			if ($line =~ /(IntermediateDirectory)(=)(\")(.+?)(\")(.+)/) {
				$item = $4;
				$msg = "$nm Paths=$item 5[$5] ";
				if ($nm eq 'Debug') {
					$msvc8_dintd = $item;
					$msg .= 'added to msvc8_dintd';
				} elsif ($nm eq 'Release') {
					$msvc8_rintd = $item;
					$msg .= 'added to msvc8_rintd';
				} else {
					prt( "WARNING: Unknown configuration ...$nm ???\n" );
					$warn .= "WARNING: Unknown configuration ...$nm ???\n";
				}
				prt( "$msg\n" ) if $debug_on;
			}
		} else {
			prt( "WARNING: Unknown Tool [$tool] ...\n" );
			$warn .= "WARNING: Unknown Tool [$tool] ...\n";
		}
	}
}

sub show_arrays {

	prt( "\nDebug IntDir=$msvc8_dintd, and Release IntDir=$msvc8_rintd ...\n" );

	# compiler stuff
	prt( "\nDebug compiler includes ... msvc8_dincs\n" );
	foreach $line (@msvc8_dincs) {
		prt( "$line\n" );
	}
	prt( "\nDebug compiler DEFINES ... msvc8_ddefs\n" );
	foreach $line (@msvc8_ddefs) {
		prt( "$line\n" );
	}
	prt( "\nRelease compiler includes ... msvc8_rincs\n" );
	foreach $line (@msvc8_rincs) {
		prt( "$line\n" );
	}
	prt( "\nRelease compiler DEFINES ... msvc8_rdefs\n" );
	foreach $line (@msvc8_rdefs) {
		prt( "$line\n" );
	}
	# linker stuff
	prt( "\nDebug linker LIBS ... msvc8_dlibs\n" );
	foreach $line (@msvc8_dlibs) {
		prt( "$line\n" );
	}
	prt( "\nDebug linker PATHS ... msvc8_dpath\n" );
	foreach $line (@msvc8_dpath) {
		prt( "$line\n" );
	}
	prt( "\nRelease linker LIBS ... msvc8_rlibs\n" );
	foreach $line (@msvc8_rlibs) {
		prt( "$line\n" );
	}
	prt( "\nRelease linker PATHS ... msvc8_rpath\n" );
	foreach $line (@msvc8_rpath) {
		prt( "$line\n" );
	}

	prt( "\nWARNINGS, if any\n$warn\n" );
}


sub amend_vcproj {
	my $src_lib = $root_dir . 'projects\VC8\FlightGearLib.vcproj';
	my $src_main = $root_dir . 'projects\VC8\FlightGear.vcproj';
	my $line = '';
	my $line1 = '';
	my $cnt = 0;
	if ( ! -f $src_lib ) {
		print "AWK: Unable to locate [$src_lib] file ...\n";
		return 1;
	}
	if ( ! -f $src_main ) {
		print "AWK: Unable to locate [$src_main] file ...\n";
		return 2;
	}

	open IF, "<$src_lib" or die "Can not OPEN $src_lib!\n";
	my @lib_lines = <IF>; # slurp whole file, to an array of lines
	close(IF);

	open IF, "<$src_main" or die "Can not OPEN $src_main!\n";
	my @main_lines = <IF>; # slurp whole file, to an array of lines
	close(IF);

	my $lc_lib = scalar @lib_lines;
	my $lc_main = scalar @main_lines;

	print "Loaded $src_lib of $lc_lib lines ...\n";
	print "Loaded $src_main of $lc_main lines ...\n";

	prt( "Finding headers in main_lines ...\n" );
	my @main_hdrs = find_headers(@main_lines);
	$cnt = 0;
	foreach $line (@main_hdrs) {
		$cnt++;
		prt( $line."\n" );
	}
	prt( "Listed $cnt headers in main_lines ...\n" );

	prt( "Finding source in main_lines ...\n" );
	my @main_srcs = find_sources(@main_lines);
	$cnt = 0;
	foreach $line (@main_srcs) {
		$cnt++;
		prt( $line."\n" );
	}
	prt( "Listed $cnt sources in main_lines ...\n" );

	prt( "Finding headers in lib_lines ...\n" );
	my @lib_hdrs = find_headers(@lib_lines);
	$cnt = 0;
	foreach $line (@lib_hdrs) {
		$cnt++;
		prt( $line."\n" );
	}
	prt( "Listed $cnt headers in lib_lines ...\n" );

	prt( "Finding source in lib_lines ...\n" );
	my @lib_srcs = find_sources(@lib_lines);
	$cnt = 0;
	foreach $line (@lib_srcs) {
		$cnt++;
		prt( $line."\n" );
	}
	prt( "Listed $cnt sources in lib_lines ...\n" );

	process_lines(@main_lines);
	show_arrays();

	process_lines(@lib_lines);
	show_arrays();

	return 0;
}


sub prt {
	my $msg = shift;
	print $msg;
	print $LOG $msg;
}
