#!/usr/bin/perl
use strict;

my $debug = 0;
my $total = 0;
my $previous_bitmap;


if($ARGV[0] eq "-d")
{
	$debug = 1;
	shift @ARGV;
}

my $out = pop @ARGV;

unless(@ARGV >= 1 && defined $out)
{
	print STDERR "Usage: $0 [-d] in1 [in2 ...]  out\n";
	exit(1);
}

open(OUT,">$out") || die "$out: $!";

foreach my $in ( @ARGV )
{
	my $gribs = 0;
	my $cnt   = 0;
	open(IN,"<$in")   || die "$in: $!";


	while(1)
	{

		my @sections = ();
# Find header

		print "Looking for GRIB\n" if($debug);
		my $grib;
		while((read(IN,$grib,4) == 4) && ($grib ne "GRIB"))
		{
			seek(IN,-3,1);
		}

		unless($grib eq "GRIB")
		{
			print "No more GRIBs\n" if($debug);
			last;
		}

		my $here = tell(IN);
		my $start = $here - 4;
		$gribs++;

		print "$grib found at offset $start\n" if($debug);

		my ($reserved,$discipline,$edition);

		die "$in: $!" unless(read(IN,$reserved,2) == 2); 
		die "$in: $!" unless(read(IN,$discipline,1) == 1); 
		die "$in: $!" unless(read(IN,$edition,1) == 1); 

		my $grib_edition = ord($edition);
		die "Un-supported edition $grib_edition" unless($grib_edition == 2);


		my ($len1,$len2);
		die "$in: $!" unless(read(IN,$len1,4) == 4); 
		die "$in: $!" unless(read(IN,$len2,4) == 4); 

		my $msglen1 = unpack("N",$len1); die "GRIB too large" if($msglen1);
		my $msglen2 = unpack("N",$len2);
		my $msglen = $msglen2;
		print "Message length $msglen\n" if($debug);

		while(1)
		{
			$here = tell(IN);
			my ($seclen,$section);

			die "$in: $!" unless(read(IN,$seclen,4) == 4); 

			if($seclen eq "7777")
			{
				print "7777 found at offset $here\n" if($debug);
				die "Invalid message lenth $msglen"  
					unless($here+4-$start == $msglen);
				last;
			}

			$seclen = unpack("N",$seclen);
			die "$in: $!" unless(read(IN,$section,1) == 1); 
			$section = ord($section);
			die "Invalid section number $section" unless ($section >= 1 && $section <=7);
			print "Section $section found at offset $here length $seclen\n" if($debug);
			seek(IN,-5,1) or die "$in: $!";

			my $data;
			die "$in: $!" unless(read(IN,$data,$seclen) == $seclen); 


			if($section == 6) 
			{
				# Special case for inherited bitmaps
				if(unpack('C',substr($data,5,1)) == 254)
				{
					die "No previous bitmap" unless(defined $previous_bitmap);
					$data = $previous_bitmap;
				}
				else
				{
					$previous_bitmap = $data;
				}
			}

			splice(@sections,$section+1);
			$sections[$section] = $data;
		

			if($section == 7)
			{
				print OUT "GRIB";
				print OUT $reserved;
				print OUT $discipline;
				print OUT $edition;
				print OUT $len1;

				$len2 = 16 + 4;
				for(my $i = 1; $i <= 7 ; $i++)
				{
					$len2 += length($sections[$i]) 
						if(defined $sections[$i]);
				}

				$cnt++;
				print "GRIB $cnt is $len2\n" if($debug);
				$len2 = pack("N",$len2);
				print OUT $len2;

				for(my $i = 1; $i <= 7 ; $i++)
				{
					next unless(defined $sections[$i]);
					print OUT $sections[$i];
				}
				print OUT "7777";
			}

		}

	}

	print "$in: $cnt field(s) found in $gribs GRIB(s)\n";
	$total += $cnt;
}

close(OUT) or die "$out: $!";

print "$out: $total field(s) written\n";


