#!/usr/bin/perl

# Copyright (c) 2009, Pedro de Oliveira <falso@rdk.homeip.net>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

# this script can never fail!

# o unico modulo que *precisei* de usar, talvez futuramente 
# nem precise dele
use Device::Modem;

# so pra debug, pode ser comentado na *release*
#use Data::Dumper;

# guru faggotry
use warnings;
use strict;

# PIN - Para se autenticar ao modem
my $pin = "2851";

# device a ligar...
#my $device = "/dev/ttyU0"; # OpenBSD
my $device = "/dev/cu.HUAWEIMobile-Modem"; # OSX



# array de hashes que contem todos os dados das sms
my @sms;

my ($rows, $cols);

my $modem = new Device::Modem( port => $device, log => 'Syslog' );

# tenta-se ligar, resultado no $ligado
sub ligar {
	if( !$modem->connect( baudrate => 115200 , parity => 'odd', databits => 8, stopbits => 1) ) {
		die("Erro a ligar ao modem, verifica opcoes no ficheiro");
	}
}

# apanha o tamanho do terminal
# achei isto do stty num site
sub getsize {
	my $data = `stty -a`;
	#print "data: ".$data."\n";

	# lol lunix
	$data =~ /rows (\d+)\; columns (\d+)/;
	($rows, $cols) = ($1, $2);

	# lol bsd hack
	if (!$rows || !$cols) {
		$data =~ /(\d+)\ rows; (\d+)\ columns;/;
		($rows, $cols) = ($1, $2);
	}
}


sub display {

	getsize;

	print &ascii(".","[  sms.pl  ]--.\n","-");
	
	foreach(@sms) {

		# info da sms
		my $info =  $_->{id} . " || " . $_->{remetente} .
		" || " . $_->{data} . " " . $_->{hora} . " || " . $_->{estado};
		print &ascii('| '," |\n"," ",$info);

		# sms..
		my $msg = $_->{mensagem};
		$msg =~ s/[\n\r]//g;
		# pra ver se e' pra cortar...
		#print "#" .length($msg). "#-#" .($cols-5). "#\n";
		#"| MSG: " " |\n"
		my $margem = ($cols - 9);
		if (length($msg) > $margem ) {
			my $primeira = substr($msg,0,$margem);
			my $segunda = substr($msg,$margem,(length($msg)-length($primeira)));
			print &ascii('| MSG: '," |\n"," ",$primeira);
			print &ascii('|      '," |\n"," ",$segunda);
		} else {
			print &ascii('| MSG: '," |\n"," ",$msg);
		}

	}
#|                                                                          |

	print &ascii("`","'\n","-");
}

# ...
sub enviapin {
	$modem->atsend( 'AT^CPIN=' . $pin . "\r\n");
	#sleep(1);
	$modem->wait(250);
}


# parsa a lista de sms raw do modem para um array de hashes @sms
sub getsms {
	&enviapin;

	$modem->atsend( 'AT+CMGF=1' . "\r\n");
	#print $modem->answer()."\n";
	#sleep(1);
	$modem->wait(250);
	$modem->atsend( 'AT+CMGL="all"' . "\r\n");
	my $raw = $modem->answer();
	
	#print $raw;

	my @rawsms = split(/\n/, $raw);

	my $c = 0;
	my %tmp = ();

	while ($c <= (scalar(@rawsms) - 3)) {
		if ($rawsms[$c] =~ m/^\+CMGL: (\d),"REC ([A-Z]*)","(.\d*)",,"([0-9-\/]*)\,([0-9-:+]*)/) {
			%tmp = (id => $1, estado => $2, remetente => $3,
					data => $4, hora => $5);
		} else {
			$tmp{'mensagem'} = $rawsms[$c];
			#print %tmp;
			#push @sms, \%tmp;
			push @sms , {id => $tmp{id}, estado => $tmp{estado},
				remetente => $tmp{remetente},
				data => $tmp{data}, hora => $tmp{hora},
				mensagem => $tmp{mensagem} };
			undef %tmp;
			%tmp = ();
		}

		$c++;
	}
}

sub ascii {
	my $return;

	my $inicio = $_[0];
	my $fim = $_[1];
	my $preenchimento = $_[2];
	my $str = $_[3];
	if (!$str) { $str = ""; }

	&getsize;
	
	$return = $inicio.$str;
	for (my $i = 0; $i <= ($cols-length($inicio.$str)-length($fim)); $i++) {
		$return .= $preenchimento;
	}
	$return .= $fim;
	return $return;
}


&ligar;
&getsms;
&display;
