#!/usr/local/bin/perl -w
###########################################
# boom-receiver
# Mike Schilli, 2008 (m@perlmeister.com)
###########################################
use strict;
use POE;
use POE::Component::Server::TCP;
use POE::Wheel::Run;
use File::Basename;
use Log::Log4perl qw(:easy);

my $SOUND_DIR = ".";
my @SOUND_FILES = map { basename $_ } 
                  <$SOUND_DIR/*.wav>;

Log::Log4perl->easy_init($DEBUG);

POE::Component::Server::TCP->new(
  Port  => 8080,

  ClientConnected => sub {
    $_[HEAP]{client}->put("Soundfiles: [".
     join(", ", @SOUND_FILES) . "]" );

    $_[HEAP]{client}->put(
     "Ready when you are.");
  },

  ClientInput => sub {
    my $client_input = $_[ARG0];

    if( $client_input !~ /^[\w.-]+$/ ) {
        $_[HEAP]{client}->put(
          "Illegal input.");
        return;
    }

    if( $client_input eq "q" ) {
        POE::Kernel->yield("shutdown");
        return;
    }

    my $msg = sound_play(
                $_[HEAP],
                basename($client_input));

    $_[HEAP]{client}->put( $msg );
  },

  InlineStates => {
    sound_ended => sub {
      my ($heap, $wid) = @_[HEAP, ARG0];
      DEBUG "Deleting wheel $wid";
      delete $heap->{players}->{$wid};
    },
  },
);

POE::Kernel->run();
exit;

###########################################
sub sound_play {
###########################################
  my($heap, $file) = @_;

  if(! -f "$SOUND_DIR/$file") {
    return "$file doesn't exist";
  }        

  POE::Kernel->sig(CHLD => "reaped");

  my $wheel =
    POE::Wheel::Run->new(
      Program     => "/usr/bin/play",
      ProgramArgs => ["$SOUND_DIR/$file"],
      StderrEvent => 'ignore',
      CloseEvent  => 'sound_ended',
  );

  DEBUG "Creating wheel ", $wheel->ID;
  $heap->{players}->{ $wheel->ID } = $wheel;

  return "Played $file";
}
