#!/usr/bin/perl -w
use strict;
use FindBin;
use lib "$FindBin::Bin/lib";

use Tk;
use Joystick;
use Control;
use Servo;
use EFIS::AI;
use EFIS::Needle;

my $version = q$Id: curves,v 1.17 2001/10/31 19:07:56 tramm Exp $;

my $config_file	= shift || 'config-60';
my $curve_size	= 128;
my $ai_size	= 128;


my $mw = MainWindow->new(
	-title		=> 'Control Curve editor',
) or die "Unable to open window on display $ENV{DISPLAY}\n";

my $js = Joystick->new(
) or warn "Unable to open joystick: $!\n";

my $servo	= Servo->new( 0, "/dev/ttyS0" );

$mw->fileevent(
	$js->{dev},
	readable	=> sub { $js->update }
) if $js;

$mw->fileevent(
	$servo->{device},
	readable	=> sub { efis_update( $servo->{device} ) },
) if $servo;

Control->joystick( $js );

my $f = $mw->Frame(
)->pack(
	-side		=> 'top',
	-expand		=> 0,
	-fill		=> 'x',
);


#
# Read in the configuration file and draw the controls
# on the screen.
#
my $controls = do $config_file
	or die "Config file parsing failed: $@\n";

$_->draw(
	$f,
	$curve_size,
	$curve_size
)->pack(
	-side		=> 'left',
)
	for @$controls;


#
# Button 5 is the engine KILL.  The throttle goes to zero and
# stays there.
#
$js->watch_button( 5, sub {
	my $js		= shift;
	my $value	= shift;

	Control->by_name( 'Throttle' )->{servo}->set( -128 );
} ) if $js;

#
# Draw the rest of the interface
#
$f = $mw->Frame(
)->pack(
	-side		=> 'top',
	-expand		=> 1,
	-fill		=> 'both',
);

$f->Button(
	-text		=> 'Exit',
	-command	=> sub { $mw->destroy },
)->pack(
	-side		=> 'top',
	-expand		=> 1,
	-fill		=> 'x',
);

#
# Random instruments go on the bottom of the display
#
$f = $mw->Frame(
)->pack(
	-side		=> 'bottom',
	-expand		=> 0,
	-anchor		=> 'w',
);


#
# Needle gauges for engine and rotor tach
# from the realtime system.
#
my ($n1,$n2) = (30,50);
my $tach = $f->Needle(
	-width		=> $ai_size,
	-label0		=> 'N1',
	-label1		=> 'N2',
)->pack(
	-side		=> 'left',
);

$tach->set( 0 => $n1 );
$tach->set( 1 => $n2 );

for my $axis (qw/0 1/)
{
	$js->watch_axis( $axis => sub {
		my $js		= shift;
		my $value	= shift;

		$tach->set( $axis, (32768 + $value) * 100 / 65536 );
	} ) if $js;
}

#
# EFIS update from the realtime system
#
my ($roll,$pitch,$yaw) = (0) x 3;
my ($roll_hex,$pitch_hex,$yaw_hex) = (0x8000) x 3;
my ($roll_scale,$pitch_scale,$yaw_scale) = (32) x 3;

my $ai = $f->Attitude(
	-width		=> $ai_size,
	-height		=> $ai_size,
)->pack(
	-side		=> 'left',
);

for(
	[ Roll		=> \$roll	],
	[ Pitch		=> \$pitch	],
	[ Yaw		=> \$yaw	],
	[ Hex_Roll	=> \$roll_hex	],
	[ Hex_Pitch	=> \$pitch_hex	],
	[ Hex_Yaw	=> \$yaw_hex	],
) {
	my ($label,$var) = @$_;
	my $f = $f->Frame(
		-border		=> 2,
		-relief		=> 'sunken',
	)->pack(
		-side		=> 'top',
		-anchor		=> 'w',
		-expand		=> 0,
		-fill		=> 'x',
	);

	$f->Label(
		-text		=> "$label:",
		-justify	=> 'left',
		-anchor		=> 'w',
		-width		=> 10,
	)->pack(
		-side		=> 'left',
		-anchor		=> 'w',
	);

	$f->Label(
		-textvariable	=> $var,
		-justify	=> 'right',
		-anchor		=> 'e',
		-width		=> 8,
	)->pack(
		-side		=> 'right',
		-anchor		=> 'e',
	);
}

sub efis_update
{
	my $dev		= shift;
	local $_	= <$dev>;

	($roll_hex,$pitch_hex,$yaw_hex) =
		/R([0-9a-f]+) *P([0-9a-f]+) *Y([0-9a-f]+)/
		or return;

	$roll	= ((hex $roll_hex)  - 0x8000) / $roll_scale;
	$pitch	= ((hex $pitch_hex) - 0x8000) / $pitch_scale;
	$yaw	= ((hex $yaw_hex)   - 0x8000) / $yaw_scale;

	$ai->set_roll( $roll );
	#$ai->set_pitch( $pitch );
	#$efis->set_yaw( $yaw );

	$_ = sprintf "%.2f", $_ for $roll, $pitch, $yaw;
}


$mw->MainLoop;
__END__
