#!/usr/bin/perl

$first = 1;
while (<>) {
    if (/^Motion notify ([\d]+) ([\d]+) (\-?[\d]+)/) {
	$x = $1;
	$y = $2;
	push @x, $x;
	push @y, $y;
	push @press, $3;
	if ($first) {
	    $xmin = $x;
	    $xmax = $x;
	    $ymin = $y;
	    $ymax = $y;
	} else {
	    $xmin = $x if $xmin > $x;
	    $xmax = $x if $xmax < $x;
	    $ymin = $y if $ymin > $y;
	    $ymax = $y if $ymax < $y;
	}
	$first = 0;
    }
}

$scalex = 540 / ($xmax - $xmin);
$scaley = 720 / ($ymax - $ymin);
if ($scalex < $scaley) {
    $scale = $scalex;
} else {
    $scale = $scaley;
}

print "%!PS-Adobe-1.0\n";
print "36 756 translate\n";
printf "%g %g scale\n", $scale, -$scale;
printf "%d %d translate\n", -$xmin, -$ymin;
print "1 setlinejoin\n";

print ".75 .75 .75 setrgbcolor\n";

printf "%g setlinewidth\n", 5 / $scale;

$str = "moveto";
for ($i = 0; $i < @x; $i++) {
    if ($press[$i] > -480) {
	print "$x[$i] $y[$i] $str % $press[$i]\n";
	$str = "lineto";
    } else {
	if ($str eq "lineto") {
	    print "stroke\n";
	    $str = "moveto";
	}
	print "% $x[$i] $y[$i] $press[$i]\n";
    }
}

if ($str eq "lineto") {
    print "stroke\n";
    $str = "moveto";
}

if (1) {
print "1 0 0 setrgbcolor\n";
printf "%g setlinewidth\n", 0.25 / $scale;

$str = "moveto";
for ($i = 0; $i < @x; $i++) {
    print "$x[$i] $y[$i] $str % $press[$i]\n";
    $str = "lineto";
}

print "stroke\n";
}

if (1) {
print "0.5 0.5 1 setrgbcolor\n";
printf "%g setlinewidth\n", 0.25 / $scale;

$sz = 2;
$sz2 = 2 * $sz;
for ($i = 0; $i < @x; $i++) {
    print "$x[$i] $y[$i] moveto -$sz -$sz rmoveto 0 $sz2 rlineto $sz2 0 rlineto 0 -$sz2 rlineto closepath fill\n";
    $str = "lineto";
}

print "stroke\n";
}

printf "%g setlinewidth\n", 0.25 / $scale;

print "0 0 0 setrgbcolor\n";

sub predict {
    ($state, $i, $xx) = @_;
    my ($x0, $x1, $x2, $x3) =
	($$xx[$i], $$xx[$i - 1], $$xx[$i - 2], $$xx[$i - 3]);
    my ($x0_pred, $x1_noncausal, $x1_causal);
    my ($x);

    if ($state == 0) {
	$x0_pred = 2 * $x1 - $x2;
	$x0_pred1 = 3 * $x2 - 2 * $x2;
	if (($x0 - $x0_pred) > 8 &&
	    ($x0 - $x0_pred1) > 8) {
	    if (0 && abs ($x0_pred - $x0) > 1.5 * abs ($x0_pred1 - $x0)) {
		$state = 2;
		$x = ($x0 + $x2) * 0.5;
	    } else {
		$state = 1;
		$x = $x1;
	    }
	} else {
	    $x = ($x0 + $x1 + $x2) / 3.0;
	}
    } elsif ($state == 1) {
	$x1_noncausal = ($x0 + $x2) * 0.5;
	$x1_causal = 2 * $x2 - $x3;
	$x = $x1_noncausal * 0.75 + $x1_causal * 0.25;
	$state = 2;
    } elsif ($state == 2) {
	# $x2 is suspect
	$x = $x1;
	$state = 0;
    }

    return ($x, $state);
}

$show_predict = 0;

$str = "moveto";
$ystate = 0;
$xforce = 0;
$yforce = 0;
for ($i = 0; $i < @x; $i++) {
    ($x, $xstate) = predict ($xstate, $i, \@x);
    ($y, $ystate) = predict ($ystate, $i, \@y);

    if ($i >= 3) {
	print "$x $y $str % $press[$i]\n";
	$str = "lineto";
    }
}

print "stroke\n";

print "showpage";
