+#!/usr/bin/perl -w
+
+package SCX::LogPrinter;
+
+use strict;
+
+use base qw(SCX::Parser);
+
+our $UNIQ_TIMEOUT = 2.0;
+
+sub new {
+ my ($class, $args) = @_;
+
+ my $self = SCX::Parser->new();
+ bless $self, $class;
+
+ $self->{dump_bad_bytes} = 1 if $args->{dump_bad_bytes};
+ $self->{dump_strange} = 1 if $args->{dump_strage};
+ $self->{uniq_only} = 1 if $args->{uniq_only};
+ $self->{skip_types} = $args->{skip_types};
+
+ return $self;
+}
+
+sub cond_print {
+ my ($self, $key, @vals) = @_;
+
+ return if $self->{skip_types}->{$key};
+
+ if ($key !~ /finish_line/ || @vals) {
+ my $val = join('|', @vals);
+ return if $self->{uniq_only}
+ && defined $self->{uniq}->{$key}
+ && $self->{uniq}->{$key} eq $val;
+
+ $self->{uniq}->{$key} = $val;
+ } else {
+ my $time = $self->now;
+ return if $self->{uniq_only}
+ && defined $self->{uniq}->{$key}
+ && $time - $self->{uniq}->{$key} < $UNIQ_TIMEOUT;
+ $self->{uniq}->{$key} = $time;
+ }
+
+ $self->do_print($key, @vals);
+}
+
+sub stringify_data {
+ my (@data) = @_;
+
+ return join(' ', map { sprintf("%02X", $_) } @data);
+}
+
+sub do_print {
+ my ($self, @data) = @_;
+
+ print join(' ', $self->now, @data), "\n";
+}
+
+sub bad_bytes {
+ my ($self, @data) = @_;
+
+ return if !$self->{dump_bad_bytes};
+ $self->do_print('bad_bytes', stringify_data(@data));
+}
+
+sub strange_packet {
+ my ($self, $name, @data) = @_;
+
+ return if !$self->{dump_strage};
+ $self->do_print('strange', $name, stringify_data(@data));
+}
+
+sub unknown_packet {
+ my ($self, @data) = @_;
+
+ $self->do_print('unknown_packet', stringify_data(@data));
+}
+
+sub bus_free_time {
+ my ($self, @data) = @_;
+
+ $self->cond_print('bus_free_time', @data);
+}
+
+sub car_programming {
+ my ($self, @data) = @_;
+
+ $self->cond_print('car_programming', @data);
+}
+
+sub reset {
+ my ($self, @data) = @_;
+
+ $self->cond_print('reset', @data);
+}
+
+sub standings {
+ my ($self, @data) = @_;
+
+ $self->cond_print('standings', @data);
+}
+
+sub car_lap_time {
+ my ($self, $car, @data) = @_;
+
+ $self->cond_print('car_lap_time_' . $car, @data);
+}
+
+sub race_setup {
+ my ($self, @data) = @_;
+
+ $self->cond_print('race_setup', @data);
+}
+
+sub fuel_level {
+ my ($self, @data) = @_;
+
+ my @newdata;
+ if ($self->{prev_fuel_levels}) {
+ for my $i (0..5) {
+ if ($self->{prev_fuel_levels}->[$i] < $data[$i]) {
+ push @newdata, $data[$i] . '+';
+ } else {
+ push @newdata, $data[$i] . ' ';
+ }
+ }
+ }
+ $self->{prev_fuel_levels} = \@data;
+
+ $self->cond_print('fuel_level', @newdata);
+}
+
+sub brake_set {
+ my ($self, @data) = @_;
+
+ $self->cond_print('brake_set', @data);
+}
+
+sub qualification {
+ my ($self, @data) = @_;
+
+ $self->cond_print('qualification', @data);
+}
+
+sub end_of_race {
+ my ($self, @data) = @_;
+
+ $self->cond_print('end_of_race', @data);
+}
+
+sub race_start {
+ my ($self, @data) = @_;
+
+ $self->cond_print('race_start', @data);
+}
+
+sub display_change {
+ my ($self, @data) = @_;
+
+ $self->cond_print('display_change', @data);
+}
+
+sub finish_line {
+ my ($self, $regular, @cars) = @_;
+
+ for my $car (@cars) {
+ $self->cond_print('finish_line_' . $car, $regular);
+ }
+}
+
+sub controller_status {
+ my ($self, @ctrls) = @_;
+
+ my @data;
+ for my $c (@ctrls) {
+ if (!defined $c) {
+ push @data, '-';
+ next;
+ }
+
+ push @data, sprintf('% 2d', $c->{throttle})
+ . ($c->{button} ? '/' : '.');
+ # Ignore lights for now
+ }
+
+ $self->cond_print('controller', @data);
+}
+
+1;