#!/usr/bin/perl -w

use Curses;
use IO::Select;
use strict;

my @matrices;

sub rnd_str {
	my $length = $_[0] || 12;
	my $chars = $_[1] || join('', (('a' .. 'z'), ('A' .. 'Z'), (0 .. 9), '.', '#', '!', '?', '>', '<'));
	my $str = '';

	for (0 .. $length) { $str .= substr($chars, int(rand()*length($chars))-1, 1); }

	return $str;
}

sub gen_matrix {
	my $mtrx;

	$mtrx->{'y'} = int(rand()*$Curses::COLS)-1;
	$mtrx->{'speed'} = int(rand()*9)+1;
	$mtrx->{'text'} = $_[0] || rnd_str(int(rand()*15)+5);
	$mtrx->{'brightness'} = int(rand()*2)+1;
	$mtrx->{'time'} = time();

	return $mtrx;
}

unless (@ARGV) { print "\nUsage: $0 file-to-watch\n\n"; exit(); }
open(our $fh, $ARGV[0]) || die "Couldn't open $ARGV[0]: '$!'!";
seek($fh, 0, 2);
my $select = IO::Select->new();
$select->add($fh);

initscr;

my $win = new Curses;

while (1) {
	while ($select->can_read) {
		if (defined(my $line = <$fh>)) {
			chomp($line);
			push(@matrices, gen_matrix($line));
		} else {
			last;
		}
	}

	$win->clear;

	for(my $i=0;$i<scalar(@matrices);$i++) {
		my $mtrx = $matrices[$i];
		my $time = time();

		for (0 .. length($mtrx->{'text'})) {
			my $x = ($_+($time-$mtrx->{'time'})*$mtrx->{'speed'})-length($mtrx->{'text'});
			if ($x >= 0) { $win->addstr($x, $mtrx->{'y'}, substr($mtrx->{'text'}, $_, 1)); }
		}

		if ((($time-$mtrx->{'time'})*$mtrx->{'speed'})-length($mtrx->{'text'}) > $Curses::LINES) { splice(@matrices, $i, 1); }
	}

	$win->refresh;

	sleep 1;
}

close($fh);

endwin;

