#!/usr/bin/perl -w
use strict;
use Data::Dumper;
use POSIX;
use Ackis2 qw(logit);

$|=1;

sysopen(my $serial, "/dev/ttyLight", O_RDWR | O_NOCTTY) or logit 0, "No arduino found" and die;
my $termios = POSIX::Termios->new();
$termios->getattr($serial->fileno());
$termios->setispeed(POSIX::B9600);
$termios->setospeed(POSIX::B9600);

my $cflag = $termios->getcflag();
my $iflag = $termios->getiflag();
my $lflag = $termios->getlflag();
my $oflag = $termios->getoflag();

# 8N1
$cflag &= ~PARENB;
$cflag &= ~CSTOPB;
$cflag &= ~CSIZE;
$cflag |= CS8;
# no flow control
#$cflag &= ~CRTSCTS;

$cflag |= CREAD | CLOCAL;  #turn on READ & ignore ctrl lines
$iflag &= ~(IXON | IXOFF ); #turn off s/w flow ctrl

$lflag &= ~(ICANON | ECHO | ECHOE | ISIG); #make raw
$oflag &= ~OPOST; #make raw


$termios->setcflag($cflag);
$termios->setlflag($lflag);
$termios->setiflag($iflag);
$termios->setoflag($oflag);

$termios->setcc(VMIN, 0);
$termios->setcc(VTIME, 20);

$termios->setattr($serial->fileno(), TCSANOW);

my $state = "off";
my $laston = time();

sub do_msg {
	my $msg = shift;
	open MSG, ">", "../sign/msg.txt";
	print MSG $msg;
	close MSG;

	chdir "..";	
	system("./graph.bash");
	chdir "ackis";
}

sub do_alert {
	my $self = shift;
	my $packet = shift;

	return if ($packet->{'type'} ne "triggered");

	my $msg = $packet->{'data'};
	$msg =~ s/alert *//;
	$msg = substr($msg, 0, 32);

	# if we're off, turn us on
	if ($state eq "off") {
		logit 0, "Alerting";
		&do_msg($msg);
		$self->return_message($packet->{'responseid'}, "Activating the light!");
		syswrite($serial, "on", 2);
		$state = "on";
		$laston = time();
	}
	# if we're on, turn us off and reset the counter
	else {
		logit 0, "User request to stop";
		&do_msg("");
		$self->return_message($packet->{'responseid'}, "Activating the light!");
		$self->return_message($packet->{'responseid'}, "Deactivating the light.");
		syswrite($serial, "off", 3);
		$state = "off";
	}
}

sub turn_cam {
	my $degree = shift;
	syswrite($serial, $degree, length($degree));
}

sub do_turn {
	my $self = shift;
	my $packet = shift;

	return if ($packet->{'type'} ne "triggered");
	my $degree = $packet->{'data'};
	$degree =~ s/turn *//;
	$degree += 0;
	if ($degree < 0 or $degree > 180) {
		return;
	}
	&turn_cam($degree);
}

sub center_cam {
	&turn_cam(90);
}

sub turnoff_light {
	# if we're on, turn us off
	if ($state eq "on" and $laston + 30 < time()) {
		logit 0, "Timing out, turning off";
		&do_msg("");
		syswrite($serial, "off", 3);
		$state = "off";
	}
}

my $ackis = Ackis2->new();
$ackis->register(server => "24.96.165.228",
		port => 16668,
		type => "mod",
		username => "makers",
		password => "local",
		loglevel => 5,
		callbacks => [
			["message", "^alert", \&do_alert],
			["message", "^turn", \&do_turn]
		],
		socks => [
				{ sock => $serial, callback => \&serial, len => 1 }
		],
		timers => [
			{
				timeout => 2,
				callback => \&turnoff_light
			},
			{
				timeout => 600,
				callback => \&center_cam
			}
		]
);

$ackis->run;
