#!/usr/bin/perl -w

use IO::Socket;
use Fcntl;
use Xmms::Remote ();
use File::Basename qw(basename dirname);

##################
$timeout = 0.2;         # how often to update when visible
$scroll_speed = 1;      # how fast to scroll the filename (1 is fastest)
$xmms_wait = 5;         # seconds between checking xmms is running
$duration_stopped = 2;  # seconds to show for when song is stopped
$duration_playing = 6;  # seconds to show for when song is playing
$priority_running = 128; # 128 to share, 16 to be a bitch
$debug = 0;
##################

# Connect to the server...
$remote = IO::Socket::INET->new(
        Proto     => "tcp",
        PeerAddr  => "localhost",
        PeerPort  => "13666",
    )
    || die "Cannot connect to LCDproc port\n";

# Make sure our messages get there right away
$remote->autoflush(1);

sleep 1;    # Give server plenty of time to notice us...

print $remote "hello\n";
my $connected=0;
my $listen = 0;

$rin = '';
# repeat next line for all filehandles to poll
vec($rin, fileno($remote), 1) = 1;


my $xmms = Xmms::Remote->new;
my $curr_timeout = undef;

while(1)
{
  $nfound = select($rout=$rin, undef, undef, $curr_timeout);
  if ($nfound) {
    if (vec($rout,fileno($remote),1)) { 
       # read data
       $rt = sysread($remote, $input, 1024);
       if($rt > 0)
       {
          @lines = split(/\n/, $input);
          foreach $line (@lines)
          {
            if($line =~ /listen.*/)
            {
               # start doing updates
               print STDERR "visible\n" if ($debug);
               $listen = 1;
               $curr_timeout = $timeout;
               &update_text();
            }
            elsif($line =~ /ignore.*/)
            {
               # no more updates, we're hidden
               print STDERR "hidden\n" if ($debug);
               $listen = 0;
               $curr_timeout = undef;
            }
            elsif($line =~ /connect.*/)
            {
              print STDERR "connected\n" if ($debug);
              $connected = 1;
              # Set up some screen widgets...
              print $remote "client_set name {xmms.pl}\n";
              print $remote "screen_add xmms\n";
              print $remote "screen_set xmms name {xmms}\n";
              print $remote "widget_add xmms title title\n";
              print $remote "widget_set xmms title {xmms}\n";
              print $remote "screen_set xmms priority " . $priority_running . "\n";
              print $remote "widget_add xmms filename scroller\n";
              print $remote "widget_add xmms info string\n";
              print $remote "widget_add xmms info2 string\n";
              &update_text();
            }
            elsif($line =~ /bye.*/)
            {
              print STDERR "got a \"bye\"\n" if ($debug);
              exit(0);
            }
          }
       }
    }
  }
  elsif($curr_timeout == $xmms_wait)
  {
    # try and reconnect to xmms
    print STDERR "timed out waiting for xmms to be running\n" if ($debug);
    undef $xmms;
    $xmms = Xmms::Remote->new();
    if($xmms->is_running)
    {
      print STDERR "xmms has just been started up\n" if ($debug);
      if($listen)
      {
        print $remote "screen_set xmms priority " . $priority_running . "\n";
        $curr_timeout = $timeout;
        &update_text();
      }
      else
      {
        $curr_timeout = undef;
      }
    }
  }
  else
  {
    # timed out during visible phase.
    print STDERR "timed out when visible\n" if ($debug);
    &update_text();
  }
}

close ($remote) || die "close: $!";
exit;

sub update_text {
 if($connected)
 {
    print STDERR "in update_text\n" if ($debug);
    if($xmms->is_running)
    {
      print STDERR "xmms is running, drawing filename\n" if ($debug);
      my $pos = $xmms->get_playlist_pos;
      $filename = basename($xmms->get_playlist_file($pos));
      $filename =~ s/\.mp.$//;
      print $remote "widget_set xmms filename 1 2 20 2 h $scroll_speed {$filename}\n";
      if($xmms->is_playing)
      {
        print STDERR "xmms is playing, drawing everything\n" if ($debug);
        my $time = $xmms->get_output_timestr;
        my($rate, $freq, $nch) = $xmms->get_info;
        my $info = sprintf "[%s]", $xmms->get_output_timestr;
        my $info2 = sprintf "[%d kbps] [%d kHz] [%s]",  ($rate / 1000),
                ($freq / 1000), $nch == 2 ? "stereo" : "mono";

        print $remote "widget_set xmms info 1 3 {$info}\n";
        print $remote "widget_set xmms info2 1 4 {$info2}\n";
        print $remote "screen_set xmms duration " . ($duration_playing * 8)  ."\n";
      }
      else
      {
        print STDERR "xmms is stopped, drawing \"STOPPED\"\n" if ($debug);
        print $remote "widget_set xmms info 1 3 {      STOPPED}\n";
        print $remote "widget_set xmms info2 1 4 { }\n";
        print $remote "screen_set xmms duration " . ($duration_stopped * 8)  . "\n";
      }
    }
    else
    {
      print STDERR "xmms is not running - hiding\n" if ($debug);
      # hide and wait for xmms to come back to life.
      print $remote "widget_set xmms filename 1 2 20 2 h $scroll_speed { }\n";
      print $remote "widget_set xmms info 1 3 { Not Running}\n";
      print $remote "widget_set xmms info2 1 4 { }\n";
      print $remote "screen_set xmms duration 2\n";
      print $remote "screen_set xmms priority 255\n";
      $curr_timeout = $xmms_wait;
    }
 }
}
