#! @PERLPATH@

use strict;

sub usage () {
	print "Usage: javaconst.pl <initobj.c> <ifcserver.h> <package> <Message class> <Object class> <outdir>\n";
}

sub gen ($$$$$$\@\%) {
	my ($orig, $outdir, $package, $class, $base, $type, $ref1, $ref2) = @_;
	my @const = @{ $ref1 };
	my %strings = %{ $ref2 };
	

	# Check the output directory
	die "$outdir is not a directory" if ((-e $outdir) && (!-d $outdir));
	if (! -d $outdir) {
		die "Can't create $outdir: $!" unless mkdir($outdir, 0755);
	}

	# Create the intermediate directories
	my $realdir = $outdir;
	foreach (split /\./, $package) {
		$realdir .= "/$_";
		next if (-d $realdir);
		die "$realdir is not a directory." if (-e $realdir);
		die "Can't create intermediate directory $realdir: $!" unless mkdir($realdir, 0775);
	}

	# Find out the longest identifier
	my $max = 0;
	map {
		if (length($_) > $max) { $max = length($_); }
	} (@const);

	# Create the output file
	die "Can't create output file $realdir/$class.java: $!" unless open F, ">$realdir/".$class.".java";

	print F "package $package;\n";
	print F "\n";
	print F "/**\n";
	print F " * Generated from $orig at ".scalar(localtime())."\n";
	print F " */\n";
	print F "public class $class {\n";
	print F "\n";
	my ($key, $val);
	while ($key = shift(@const)) {
		my $val = shift(@const);
		$val =~ s/^0+//;
		if ((!defined $val) || ($val eq "")) { $val = "0"; }
		print F "\tpublic static final $type ", $base, $key;
		print F " "x($max-length($key)), " = ", $val, ";\n";
	};
	print F "\n";
	if ((keys %strings) > 0) {
		# Add the string array constants
		my $arr;
		foreach $arr (sort keys %strings) {
			my @vals = @{ $strings{$arr} };
			print F "\tpublic static final String[] $arr = new String[] {\n";
			map {
				print F "\t\t\"$_\",\n";
			} (@vals);
			print F "\t};\n\n";	
		}
	}
	print F "}";
	
	close F;
}

my $ifcserver = shift(@ARGV);
my $inito = shift(@ARGV);
my $pack = shift(@ARGV);
my $mestypes = shift(@ARGV);
my $objtypes = shift(@ARGV);
my $outdir = shift(@ARGV);

if (!defined $outdir) {
	usage();
	exit(1);
}

my $line;
my @consts;
my %strings;

die "Can't open $ifcserver : $!" unless open F, $ifcserver;
while ($line = <F>) {
	if ($line =~ /\#define\s+IFC_(MSG_\S+?)_STRINGS\s+(.*)/) {
		my $name = $1;
		my $val = $2;
		chomp($val);
		my @vals = split(/\s+/, $val);
		@{ $strings{$name} } = @vals;
	} elsif ($line =~ /\#define\s+IFC_(MSG._\S+)\s+(\d+)/) {
		push @consts, $1, $2;
	}
}
close F;

gen($ifcserver, $outdir, $pack, $mestypes, "", "int", @consts, %strings);

@consts = ();
%strings = ();

die "Can't open initobj file: $!" unless open F, $inito;
while ($line = <F>) {
	if ($line =~ /\/\*\s*(\d+)\s*\*\/\s*\{\s*(\S+?)_NAME/) {
		push @consts, $2, $1;
	}
}
close F;

gen($inito, $outdir, $pack, $objtypes, "OBJ_", "int", @consts, %strings);
