package dash_lib;

# this file should be named dash_lib.pm

# dash_lib is a library intended to interface with a motec dash that has had
# a configuration loaded onto it as follows

# first channel 0-100 = % bargraph at top
# second channel 0-9999 = /10 left display
# third channel 0-9999 = /10 right display
# forth channel 0-100 = upper left display
# fifth channel 0-9 = big single digit
# sixth channel = error codes

use IO::Socket;
use IO::Select;

sub new {
	my $type = shift;
	my $self = {};
	bless($self, $type);
}

sub fork {
	# this function forks off the communications thread
	# it takes one argument, a comm handler to the dash
	# it creates a unix domain socket in /tmp
	# to handle receiving input

	my $self = shift;
	my $ob = shift;

	my $mainsock;
	my $select;
	my $sock;
	my @chan = (0,0,0,0,0,0);
	my $chn, $val;


	if(fork()) {
		return;
	} else {
		$SIG{'CHLD'} = IGNORE;
		$SIG{'INT'} = IGNORE;
		close(STDIN);
		close(STDOUT);
		close(STDERR);

		# we are the child thread
		# we basically run in circles, screaming
		# and shouting
		# we write the dash, and poll the
		# tcp socket for updates

		$mainsock = IO::Socket::INET->new(Listen => 5, 
						  LocalPort => 6556,
						  Proto => 'tcp',
						  Reuse => 1,
						  );
	
		die "Failed!" if(!$mainsock);

		$select = new IO::Select();
	
		$select->add($mainsock);

		$alive = 1;

		while($alive) {
			@readable = $select->can_read(0.20);
			foreach $sock (@readable) {
				if($sock eq $mainsock) {
					# new connection
					$sock = $mainsock->accept();
					print $sock "DASH>";
					$select->add($sock);
				} else {
					$sock->recv($in,255,0);

					if($in == undef) {
						$select->remove($sock);
					} else {
						($chn, $val) = $in =~ /^(\d*)\D*(\d*)\D*$/;

						$alive = 0 if(($chn) == 42 && ($val == 69));
						$chan[$chn] = $val;
					}
					print $sock "DASH>";
				}
			}
			$str = sprintf("%4d,%4d,%4d,%4d,%4d,%d\n",$chan[1],$chan[2],$chan[3],$chan[4],$chan[5],$chan[6]);
			$ob->write($str);
		}
		die;
	}
}

1;
