#!/usr/bin/perl
my $GENIMAGES = 1;
my $CONVERTER = "convert -quality 100 -colors 16";


require "parsescript.pl";
require "parsebmp.pl";

my $lev0;
my @obj2room;

sub linkobj($) {
    my $i = $_[0];
    return qq(<a href="lvl$obj2room[$i].html#oid$i">$i</a>);
}

sub linkidx($) {
    my $i = $_[0];
    return qq(<a href="vars.html#var$i">$i</a>);
}

sub linkscript($) {
    my $i = $_[0];
    return qq(<a href="script$i.html">$i</a>);
}
sub linkbidx($) {
    my $i = $_[0];
    my $j = int($i / 16);
    return qq(<a href="vars.html#var$j">$i</a>);
}

sub str_to_html($) {
    $_ = $_[0];
    s/&/&amp;/g;
    s/</&lt;/g;
    s/>/&gt;/g;
    s/ö/&ouml;/g;
    s/Ö/&Ouml;/g;
    s/ä/&auml;/g;
    s/Ä/&Auml;/g;
    s/ü/&uuml;/g;
    s/Ü/&Uuml;/g;
    s/ß/&szlig;/g;
    s/\001(\d*)\002/linkobj($1)/eg;
    s/\003(\d*)\002/linkidx($1)/eg;
    s/\004(\d*)\002/linkbidx($1)/eg;
    s/\005(\d*)\002/linkscript($1)/eg;
    return $_;
}

sub read_level($) {
    my ($num) = @_;
    my $level;
    open LVL, sprintf "%02d.lfl", $num;
    read LVL, $level, 1024*1024;
    close LVL;
    $level =~ s/(.)/chr(ord($1)^0xff)/egs;
    return $level;
}

sub next_char($) {
    local *image = $_[0];
    my $i = ord(substr($image,0,1));
    $image = substr($image,1);
    return $i;
}


$lev0 = &read_level(0);
my $i, $j;

for ($i = 0; $i < 256; $i++) {
    @{$varidx[$i]} = ();
}


foreach $i (@ARGV)
{
    my $lvl = read_level($i);
    $i = sprintf("%02d",$i);

    my $n = unpack("c", substr($lvl,0x14));
    for ($j = 1; $j <= $n; $j++) {
	my $objoff = unpack("v", substr($lvl, 0x1a + 2*($n + $j)));
	my $objlen = unpack "v", substr($lvl, $objoff, 2);
	my $obj = substr($lvl, $objoff, $objlen);
	
	my $oi = unpack "v", substr $obj, 4, 2;
	$obj2room[$oi] = $i;
    }
}

foreach $i (@ARGV)
{
    my $lvl = read_level($i);
    $i = sprintf("%02d",$i);
    my ($w,$h,$dummy, $bmpoffset, $maskoffset) = unpack("v5", substr($lvl, 4));

    open HTML,">lvl$i.html";
    print HTML "<html><head><title>room $i</title></head>\n";
    print HTML "<body><h1>Room $i ($w x $h)</h1>\n";
    print HTML "<img src=\"bmp$i.png\" width=",$w," height=",$h,"><br>\n";
    print HTML "<img src=\"mask$i.png\" width=",$w," height=",$h,"><br>\n";

    if ($GENIMAGES) {
	decode_bmp(substr($lvl, $bmpoffset), $w, $h, "bmp$i.xpm");
	decode_mask(substr($lvl, $maskoffset), $w, $h, "mask$i.pbm");
	system "$CONVERTER bmp$i.xpm bmp$i.png; rm bmp$i.xpm";
	system "$CONVERTER mask$i.pbm mask$i.png; rm mask$i.pbm";
    }

    my $wbinfo = substr($lvl, ord(substr($lvl,0x15)));
    my $wbnr   = ord($wbinfo);
    print HTML "<h2>$wbnr Walkboxes</h2>\n";

    print HTML "<table><tr><td></td><td></td><td></td><td></td><td></td>\n";
    for $j (0..($wbnr-1)) {
	print HTML "<td align=right><b>$j</b></td>";
    }
    print HTML "</tr>\n";

    for $j (0..($wbnr-1)) {
	$yt  = ord substr $wbinfo, 8*$j + 1;
	$yb  = ord substr $wbinfo, 8*$j + 2;
	$xlt = ord substr $wbinfo, 8*$j + 3;
	$xrt = ord substr $wbinfo, 8*$j + 4;
	$xlb = ord substr $wbinfo, 8*$j + 5;
	$xrb = ord substr $wbinfo, 8*$j + 6;
	$u1  = ord substr $wbinfo, 8*$j + 7;
	$flags = ord substr $wbinfo, 8*$j + 8;
	print HTML "<tr><td align=right><b>$j:</b></td>";
	print HTML "<td>($xlt,$yt);($xlb,$yb)</td><td> - ($xrt,$yt);($xrb,$yb)</td><td>$u1</td><td>$flags</td>\n";
	$rowinfo = substr $wbinfo, 1 + 9 * $wbnr + ord(substr($wbinfo,1 + 8*$wbnr + $j));
	for $k (0..($wbnr-1)) {
	    print HTML "<td align=right>".ord($rowinfo)."</td>";
	    $rowinfo = substr $rowinfo,1;
	}
	print HTML "</tr>\n";
    }
    print HTML "</table>\n";


    my $exitscr = unpack("v", substr $lvl, 0x18,2);
    my $entryscr = unpack("v", substr $lvl, 0x1a,2);
    my $end = unpack("v", substr $lvl, 0x0,2);

    if ($entryscr > $exitscr) {
	print HTML "<h2>Exit Script:</h2>";
	print HTML "<pre>\n";
	print HTML str_to_html(parse_script_to_str(substr $lvl, $exitscr, $entryscr-$exitscr));
	print HTML "</pre>\n";
    }
    if ($end > $entryscr) {
	print HTML "<h2>Entry Script:</h2>";
	print HTML "<pre>\n";
	print HTML str_to_html(parse_script_to_str(substr $lvl, $entryscr, $end-$entryscr));
	print HTML "</pre>\n";
    }

    my $n = unpack("c", substr($lvl,0x14));
    print HTML "<h2>$n objects</h2><ul>\n";
    for ($j = 1; $j <= $n; $j++) {
	$j = sprintf("%03d",$j);
	my $objoff = unpack("v", substr($lvl, 0x1a + 2*($n + $j)));
	my $objlen = unpack "v", substr($lvl, $objoff, 2);
	my $bmpoff = unpack("v", substr($lvl, 0x1a + 2*$j));
	my $objbmp = substr($lvl, $bmpoff);
	my $obj = substr($lvl, $objoff, $objlen);
	
	my $oi = unpack "v", substr $obj, 4, 2;
	my $oc = (ord(substr($obj, 6, 1)) & 0xff);
	my $ox = (ord(substr($obj, 7, 1)) & 0xff);
	my $oy = (ord(substr($obj, 8, 1)) & 0x7f);
	my $ou1 = ord(substr($obj, 8, 1)) & 0x80 ? 1 : 0;
	my $ow = (ord(substr($obj, 9, 1)) & 0xff);
	my $odo = ord(substr($obj, 0xa, 1)) & 0xff;
	my $oax = ord(substr($obj, 0xb, 1)) & 0xff;
	my $oay = ord(substr($obj, 0xc, 1)) & 0x1f;
	my $oprep = ord(substr($obj, 0xc, 1)) & 0xe0;
	my $oaf = ord(substr($obj, 0xd, 1)) & 0x07;
	my $oh = ((ord(substr($obj, 0xd, 1)) & 0xff)>>3);
	my $onameoff = ord(substr($obj, 0xe, 1));
	my $odata = substr($obj, $onameoff);
	my $oname = str_to_html(read_strz(\$odata));
	my $sstart = length($obj) - length($odata);

	print HTML "<li><a name=\"oid$oi\">object $j</a>", $oname ? " '$oname'":"", "; id $oi<br>\n";
	if (defined $objbmp && $oh != 0 && $ow != 0) {
	    if ($GENIMAGES) {
		if (decode_bmp($objbmp, $ow*8, $oh*8, "obj$i-$j.xpm\n")) {
		    system "$CONVERTER obj$i-$j.xpm obj$i-$j.png; rm obj$i-$j.xpm";
		}
	    }
	    if (-e "obj$i-$j.png") {
		print HTML "<img src=\"obj$i-$j.png\">\n";
	    }
	}
	printf HTML "class %02x, ", $oc;
	printf HTML "coords: %3d,%3d - %3dx%3d;\n", $ox*8, $oy*8, $ow*8, $oh*8;
	if ($odo) {
	    print HTML "depobj: $odo;\n";
	}
	print HTML "actorxy: $oax $oay; facing $oaf; preposition $oprep; \n";
	print HTML "unknowns: 1:$ou1\n";
	
	my $optr = 0xf;
	printf HTML "<br>verbs: ";
	while (($v = ord(substr($obj, $optr++))) != 0) {
	    print HTML $comma; $comma = ", ";
	    $v = $verbs[$v] if $verbs[$v];
	    $soff = ord(substr($obj, $optr++));
	    printf HTML "$v ->%02x", $soff - $sstart;
	}
	print HTML"\n";
	if (length $odata) {
	    print HTML "<pre>\n";
	    print HTML str_to_html(parse_script_to_str($odata));
	    print HTML "</pre>\n";
	}
	$last = -1;
	@usedvars = 
	    grep { $r = $last != $_; $last = $_; $r } sort {$a<=>$b} @usedvars;
#	print HTML "<p>Used variables: ".join(",", @usedvars)."</p>\n";
	for $_ (@usedvars) {
	    push @{$varidx[$_]}, qq(<a href="lvl$i.html#oid$oi">o$oi(r$i)</a>);
	}
	print HTML "</li>\n";
    }
    print HTML "</ul>\n";
    print HTML "</body></html>\n";
    close HTML
}



### read scripts ####
{
    my $offset = 2;
    # skip objects
    $offset += 2 + unpack "v", substr($lev0, $offset, 2);

    #skip rooms
    $offset += 1 + 3*ord(substr($lev0, $offset, 1));
    
    #skip costumes
    $offset += 1 + 3*ord(substr($lev0, $offset, 1));

    my $n = (unpack "c", substr($lev0, $offset, 1)) & 0xff;
    $offset ++;
    for ($i = 1; $i < $n; $i++) {
	my $rnr = ord(substr($lev0, $offset + $i,1)) & 0xff;
	my $off = unpack "v", substr($lev0, $offset + $n + 2*$i, 2);
	next if $rnr == 255;

	my $level = read_level($rnr);
	$level = substr $level, $off;
	$len = unpack("v", $level) &0xffff;
	if ($len < length($level)) {
	    $level = substr($level, 4, $len-4);
	}

	open HTML,">script$i.html";
	print HTML "<html><head><title>Script $i</title></head>\n";
	print HTML "<body><h1>Script $i</h1>\n";
	print HTML "<pre>\n";
	print HTML str_to_html(parse_script_to_str($level));
	print HTML "</pre>\n";
	print HTML "</body></html>\n";
	close HTML;
	@usedvars = 
	    grep { $r = $last != $_; $last = $_; $r } sort {$a<=>$b} @usedvars;
	for $_ (@usedvars) {
	    push @{$varidx[$_]}, qq(<a href="script$i.html">s$i</a>);
	}
	
	parse_script();
    }
}

{
    open HTML,">vars.html";
    print HTML "<html><head><title>Variable Index</title></head>\n";
    print HTML "<body><h1>Variable Index</h1>\n";
    print HTML "<dl>\n";
    for ($i = 0; $i < 256; $i++) {
	next if !@{$varidx[$i]};
	print HTML "<dt><a name=\"var$i\">$i</a>:</dt>\n";
	print HTML "<dd>".join(", ", @{$varidx[$i]})."</dd>\n";
    }
	
    print HTML "</dl>\n";
    print HTML "</body></html>\n";
    close HTML;
}

