#!/usr/local/bin/perl -s

# Generate the multi-file HTML representation of the PNG spec
# Usage: makemulti [-rfc] [-w3c] master initial-output-file-name

if ($#ARGV != 1) {
    die "Usage: $0 [-rfc] [-w3c] master initial-output-file-name\n";
}

# table of chapter abbreviations
$cname{"DR"} = "DataRep";
$cname{"C"} = "Chunks";
$cname{"E"} = "Encoders";
$cname{"D"} = "Decoders";
$cname{"R"} = "Rationale";

$Chapter = 0;
$Section = 0;
$Paragraph = 0;

$pre_indent = 0;
$if_nest_ok = 0;
$if_nest_fail = 0;

open(INPUT, "<$ARGV[0]") || die "Couldn't read $ARGV[0]: $!\n";

open(OUTPUT, ">$ARGV[1]") || die "Couldn't write $ARGV[1]: $!\n";

# First, scan for new-file commands and make list of file names
push(@file_names, $ARGV[1]);

while (<INPUT>) {
	&find_files($_);
}

close INPUT;

open(INPUT, "<$ARGV[0]") || die "Couldn't read $ARGV[0]: $!\n";

$cur_file_number = 0;

open(HEADER, ">header-tmp") || die "Couldn't write header-tmp: $!\n";
$header_open = 1;

# Now for the real processing
while (<INPUT>) {
	&process_line($_);
}

&emit_file_bottom;

close OUTPUT;
unlink "header-tmp";
exit;

sub process_line {
	local($line) = @_;

	# Handle conditional exclusion commands, doing nesting correctly
	local($skip_this_line) = 0;

	if ($line =~ /^<!-- IF RFC -->/i) {
	    if ($rfc && !$if_nest_fail) { $if_nest_ok++; }
	    else { $if_nest_fail++; }
	    $skip_this_line = 1;
	}
	if ($line =~ /^<!-- IF !RFC -->/i) {
	    if (!$rfc && !$if_nest_fail) { $if_nest_ok++; }
	    else { $if_nest_fail++; }
	    $skip_this_line = 1;
	}
	if ($line =~ /^<!-- IF W3C -->/i) {
	    if ($w3c && !$if_nest_fail) { $if_nest_ok++; }
	    else { $if_nest_fail++; }
	    $skip_this_line = 1;
	}
	if ($line =~ /^<!-- IF !W3C -->/i) {
	    if (!$w3c && !$if_nest_fail) { $if_nest_ok++; }
	    else { $if_nest_fail++; }
	    $skip_this_line = 1;
	}
	if ($line =~ /^<!-- ENDIF -->/i) {
	    if ($if_nest_fail) { $if_nest_fail--; }
	    else { $if_nest_ok--; }
	    $skip_this_line = 1;
	}
	if ($line =~ /^<!-- NROFF/i) {
	    $if_nest_fail++;
	    $skip_this_line = 1;
	}
	if ($line =~ /^NROFF -->/i) {
	    $if_nest_fail--;
	    $skip_this_line = 1;
	}
	if ($line =~ /^<!-- TEX/i) {
	    $if_nest_fail++;
	    $skip_this_line = 1;
	}
	if ($line =~ /^TEX -->/i) {
	    $if_nest_fail--;
	    $skip_this_line = 1;
	}
	if ($line =~ /^<!-- IF !TEX -->/i) {
	    if (!$if_nest_fail) { $if_nest_ok++; }
	    else { $if_nest_fail++; }
	    $skip_this_line = 1;
	}
	if ($line =~ /^<!-- IF HTML -->/i) {
	    if (!$if_nest_fail) { $if_nest_ok++; }
	    else { $if_nest_fail++; }
	    $skip_this_line = 1;
	}

	if ($if_nest_fail || $skip_this_line) {
	    if ($if_nest_fail < 0 || $if_nest_ok < 0) {
		die "Bogus if/endif matching\n";
	    }
	    return;
	}

	# handle inclusion
	if ($line =~ /<!-- INCLUDE (\S+) -->/i) {
	    if (open(INPUT2, $1)) {
		while (<INPUT2>) {
		    &process_line($_);
		}
		close INPUT2;
	    } else {
		warn "Couldn't open $1: $!\n";
	    }
	    return;
	}

	# handle new-file command
	if ($line =~ /<!-- NEW FILE (\S+) (.+) -->/i) {
	    &emit_file_bottom;
	    close OUTPUT;
	    open(OUTPUT, ">$1") || die "Couldn't write $1: $!\n";
	    $cur_file_number++;
	    if ($1 != $file_names[$cur_file_number]) {
		warn "file_names array out of sync at $1\n";
	    }
	    &emit_file_top($2);
	    return;
	}

	# handle end-header command
	if ($line =~ /<!-- END HEADER -->/i) {
	    if ($header_open) {
		close HEADER;
		$header_open = 0;
	    } else {
		warn "Ignoring duplicate end-header command\n";
	    }
	    return;
	}

	# ignore other special commands
	if ($line =~ /<!-- (.+) -->/) {
	    warn "Ignoring command $line" if $debug;
	    return;
	}

	# handle H2 tag
	if ($line =~ /<H2>.+NAME.+>/i) {
	    $Chapter++;
	    $Section = 0;
	    $Paragraph = 0;
	    $line =~ s|(<H2>[^>]+>)|$1$Chapter. |;
	}

	# handle H3 tag
	if ($line =~ /<H3>.+NAME.+>/i) {
	    $Section++;
	    $Paragraph = 0;
	    $line =~ s|(<H3>[^>]+>)|$1$Chapter.$Section. |;
	}

	# handle H4 tag
	if ($line =~ /<H4>.+NAME.+>/i) {
	    $Paragraph++;
	    $line =~ s|(<H4>[^>]+>)|$1$Chapter.$Section.$Paragraph. |;
	}

	# handle PRE tag
	if ($line =~ m!</PRE>!) {$pre_indent = 0;}
	if ($pre_indent) {$line =~ s|^|   |;}
	if ($line =~ /<PRE>/) {$pre_indent = 1;}

	# suppress /BODY and /HTML at end of master;
	# emit_file_bottom will add those
	if ($line =~ /<\/BODY>/i) {
	    return;
	}
	if ($line =~ /<\/HTML>/i) {
	    return;
	}

	# note: ignore HREFs containing / or @

	# expand abbreviated section crossreferences
	$line =~ s|HREF="([^"/@#\.]+)\.([^"/@#]+)"|HREF="$cname{$1}#$1.$2"|gi;
	# fix general section crossreferences
	$line =~ s|HREF="([^"/@#\.]+)#([^"/@#]+)"|HREF="PNG-$1.html#$2"|gi;
	# fix chapter crossreferences
	$line =~ s|HREF="([^"/@#\.]+)"|HREF="PNG-$1.html"|gi;

	print OUTPUT $line;
	print HEADER $line if $header_open;
}


sub find_files {
	local($line) = @_;

	# look for new-file command, save the file names
	if ($line =~ /<!-- NEW FILE (\S+) (.+) -->/i) {
	    push(@file_names, $1);
	    return;
	}

	# note: we assume included files do not contain NEW FILE commands
}


# Emit extra output added at head of all output files except the initial one

sub emit_file_top {
    local($title) = @_;

    # Duplicate boiler plate from master file, except we substitute local title
    if ($header_open) {
	warn "NEW FILE before END HEADER!?\n";
    } else {
	open(INPUT2, "header-tmp") || die "Couldn't read header-tmp: $!\n";
	while (<INPUT2>) {
	    if (/<TITLE>/i) {
		print OUTPUT "<TITLE>$title</TITLE>\n";
	    } else {
		print OUTPUT $_;
	    }
	}
	close INPUT2;
    }
    # Add navigation buttons
    print OUTPUT "<HR>\n";
    print OUTPUT "<A HREF=\"$file_names[$cur_file_number-1]\">Previous page</A>\n";
    if ($cur_file_number < $#file_names) {
	print OUTPUT "<BR>\n<A HREF=\"$file_names[$cur_file_number+1]\">Next page</A>\n";
    }
    print OUTPUT "<BR>\n<A HREF=\"$file_names[0]\">Table of contents</A>\n";
    print OUTPUT "<HR>\n";
}


# Emit extra output added at end of an output file

sub emit_file_bottom {
    # Add navigation buttons
    print OUTPUT "<HR>\n";
    if ($cur_file_number > 0) {
	print OUTPUT "<A HREF=\"$file_names[$cur_file_number-1]\">Previous page</A>\n";
    }
    if ($cur_file_number < $#file_names) {
	if ($cur_file_number > 0) {
	    print OUTPUT "<BR>\n";
	}
	print OUTPUT "<A HREF=\"$file_names[$cur_file_number+1]\">Next page</A>\n";
    }
    if ($cur_file_number > 0) {
	print OUTPUT "<BR>\n<A HREF=\"$file_names[0]\">Table of contents</A>\n";
    }
    print OUTPUT "<HR>\n";

    # Terminate HTML
    print OUTPUT "\n</BODY>\n</HTML>\n";
}
