#!/usr/bin/perl
use Tk;
use Tk::ROText;
use Tk::Pane;
use Tk::MListbox;
use Tk::PNG;
use Tk::JPEG;
use POSIX;
use Socket;
use Getopt::Long;
use Pod::Usage;
use strict;
use utf8;
use open ':std', ':encoding(UTF-8)';


my $pjam_version	= '2.2.0';
my $pjam_desc		= "\nRemoteJammer version $pjam_version\nA skinnable graphical remote control for PerlJammer\n";

my $cfgdir		= sprintf('%s/.pjam', $ENV{HOME});
my $cfgfile		= sprintf('%s/config', $cfgdir);
my $iconfile		= '/usr/share/perljammer/RemoteJammer.xpm';

my ($playing, $paused, $elapsed, $waiting) = (0, 0, 0, 0);
my (%opts, $app, $playbutton, $waitbutton, $statusbox, $timebox,
    $laststatus, $laststate);

if (GetOptions(\%opts,
               'skin=s',
               'debug|d',			# undocumented by design; will be removed later
               'layout=s',
               'position=s',
               'help|usage|?',
               'man',
               'version'))
{
    if ($opts{version})
    {
        pod2usage(-message => $pjam_desc,
                  -exitstatus => 0,
                  -verbose => 0);
    }
    elsif ($opts{help})
    {
        pod2usage(-message => $pjam_desc,
                  -exitstatus => 0,
                  -verbose => 1);
    }
    elsif ($opts{man})
    {
        pod2usage(-exitstatus => 0,
                  -verbose => 2);
    }
    elsif (defined $opts{layout} && !($opts{layout} =~ /^(default|horizontal|vertical|ribbon)$/))
    {
        pod2usage(-message => $pjam_desc,
                  -exitstatus => -1,
                  -verbose => 1);
    }
    elsif (defined $opts{position} && !($opts{position} =~ /^([+-](\d+)[+-](\d+))$/))
    {
        pod2usage(-message => $pjam_desc,
                  -exitstatus => -1,
                  -verbose => 1);
    }
    else
    {
        remote();
    }
}
else
{
    pod2usage(-message => $pjam_desc,
              -exitstatus => -1,
              -verbose => 1);
}

exit (0);


sub quit
{
    exit (0);
}


sub remote
{
    if (-d $cfgdir)
    {
        if (-f $cfgfile)
        {
            %opts = get_prefs($cfgfile, %opts);
            apply_defaults(\%opts);

            create_UI();
            chomp(my $data = send_socket_command('status'));
            unless ($data eq 'Inactive')
            {
                $playing = 1;
                $playbutton->configure(-bitmap     => 'pausebutton',
                                       -foreground => $opts{UIforeground});
            }
            $app->repeat(100  => \&state_loop);
            $app->repeat(1000 => \&status_loop) unless ($opts{remotelayout} eq 'vertical');
            MainLoop();

        }
        else
        {
            print "Configuration file $cfgfile not found; cannot continue.\n";
        }
    }
    else
    {
        print "Configuration directory $cfgdir not found; cannot continue.\n";
    }
}


sub get_prefs
{
    my %o;
    my ($cfgfile, %opts) = @_;

    open(PREFS, $cfgfile);
    while (<PREFS>)
    {
        next if (/^#/);
        if (/^(\S+)\s*[:=]\s+(yes|true)$/i)
        {
            $o{$1} = 1;
        }
        elsif (/^(\S+)\s*[:=]\s+(no|false)$/i)
        {
            $o{$1} = 0;
        }
        elsif (/^(\S+)\s*[:=]\s+"?([^"]+)"\s*$/)        # " reset
        {
            $o{$1} = $2;
        }
        elsif (/^(\S+)\s*[:=]\s+(\S.*\S)\s*$/)
        {
            $o{$1} = $2;
        }
        elsif (/^(\S+)\s*[:=]\s+(\d+)\s*$/)
        {
            $o{$1} = $2;
        }
    }

    $o{remoteport} = 16384 unless (defined $o{remoteport});
    $o{remotehost} = 'localhost' unless (defined $o{remotehost});
    foreach my $k (keys %opts)
    {
        $o{$k} = $opts{$k};
    }
    return(%o);
}


sub apply_defaults
{
    my $o = $_[0];
    my $home = $ENV{'HOME'};
    my $geom;

    $o->{datadir} = '/usr/share/perljammer' unless (defined $o->{datadir});
    $o->{skindir} = $o->{datadir}.'/skins';

    $o->{remotelayout}   = $o->{layout} if defined($o->{layout});
    $o->{remotelayout}   = 'default' unless defined($o->{remotelayout});
    $o->{remoteposition} = defined ($o->{position})
                         ? $o->{position}
                         : ($o->{remotelayout} eq 'ribbon' && defined ($o->{ribbonposition}))
                         ? $o->{ribbonposition}
                         : defined ($o->{remoteposition})
                         ? $o->{remoteposition}
                         : '+0+0';

    $geom = ($o->{remotelayout} eq 'horizontal') ? '800x75%s'
          : ($o->{remotelayout} eq 'vertical')   ? '60x480%s'
          : ($o->{remotelayout} eq 'ribbon')   ? '1600x38%s'
          : '160x300%s';

    $o->{geometry} = sprintf($geom, $o->{remoteposition});

    if ($o->{remotelayout} eq 'default')
    {
        if (defined $o->{skin})
        {
            if ($o->{skin} eq 'random')
            {
                $o->{remoteskin} = get_random_skin($o);
            }
            else
            {
                $o->{skin} =~ s/~/$home/;
                $o->{remoteskin} = $o->{skin} if (-f $o->{skin});
            }
        }
        elsif (defined $o->{remoteskin})
        {
            if ($o->{remoteskin} eq 'random')
            {
                $o->{remoteskin} = get_random_skin($o);
            }
            else
            {
                $o->{remoteskin} =~ s/~/$home/;
            }
        }

        $o->{remoteskin}        = sprintf('%s/bluecurve.png', $o->{skindir}) unless (-f $o->{remoteskin});
    }

    $o->{UIforeground}      = 'MidnightBlue' unless (defined $o->{UIforeground});
    $o->{UIbackground}      = 'MidnightBlue' unless (defined $o->{UIbackground});

    $o->{UIforeground}      = '#666699' if ($o->{UIforeground} eq 'SunBlue');		# Easter egg!
    $o->{UIbackground}      = '#666699' if ($o->{UIbackground} eq 'SunBlue');

    $o->{remotefont}        = '-adobe-helvetica-medium-r-normal--*-100-*-*-p-*-iso10646-1' unless (defined $o->{remotefont});
    (($o->{remoteboldfont}  = $o->{remotefont}) =~ s/medium/bold/) unless (defined $o->{remoteboldfont});
    (($o->{remotesmallfont} = $o->{remotefont}) =~ s/100/90/) unless (defined $o->{remotesmallfont});

    $o->{remoteport}        = 16384 unless (defined $o->{remoteport});
    $o->{useWMicon}         = 0 unless (defined $o->{useWMicon});

}


sub get_random_skin
{
    my $o = $_[0];

    srand(time()^($$+($$<<15)));
    opendir(SKINDIR, $o->{skindir});
    my @skins = grep(/\.(png|jpg|jpeg|gif|xpm)$/i, readdir(SKINDIR));
    close (SKINDIR);
    my $i = int(rand(scalar @skins));

    my $skin = sprintf('%s/%s',
                       $o->{skindir},
                       $skins[$i]);

    return ($skin);
}


sub send_socket_command
{
    chomp(my $data = join(' ', @_));
    my ($proto, $iaddr, $paddr);

    if ($opts{remotehost} =~ /:\d+$/)
    {
        ($opts{remotehost}, $opts{remoteport}) = split(/:/, ($opts{remotehost}));
    }

    $proto  = getprotobyname('tcp');
    if ($iaddr  = inet_aton($opts{remotehost}))
    {
        $paddr  = sockaddr_in($opts{remoteport}, $iaddr);

        socket(SOCK, PF_INET, SOCK_STREAM, $proto)  || die "socket: $!";
        connect(SOCK, $paddr)                       || die "connect: $!";
        select((select(SOCK), $| = 1)[0]);
        print SOCK "$data\n";

        my ($rin, $rout);

        $data = '';
        while (!eof(SOCK))
        {
            $rin = '';
            vec($rin, fileno(SOCK), 1) = 1;
            select($rout = $rin, undef, undef, 0.1);
            if (vec($rout, fileno(SOCK), 1))
            {
                $data = $data . <SOCK>;
            }
        }
        close (SOCK);
    }
    else
    {
        printf("pjam-remote: host '%s' is unknown\n",
               $opts{remotehost});
    }

    return ($data);
}


sub status_loop
{
    chomp(my $data = send_socket_command('status'));
    unless ($data eq $laststatus)
    {
        $laststatus = $data;
        $statusbox->delete('1.0', 'end');
        if ($data eq 'Inactive')
        {
            if ($opts{remotelayout} eq 'horizontal' || $opts{remotelayout} eq 'ribbon')
            {
                chomp($data = sprintf('(Inactive)  Next Up:  %s',
                                      send_socket_command('status 1')));
            }
            else
            {
                $data = '(Inactive)';
            }
        }

        if ($opts{remotelayout} eq 'default')
        {
            $data =~ s/ :: /\n/g;
        }
        else
        {
            $data =~ s/ :: /  ::  /g;
        }
        $statusbox->insert('1.0', $data);

        $elapsed = 0;
        $timebox->Contents('00:00:00');
    }
    display_elapsed();
}


sub state_loop
{
    my ($proto, $iaddr, $paddr, $port, $data);

    if ($opts{remotehost} =~ /:\d+$/)
    {
        ($opts{remotehost}, $opts{remoteport}) = split(/:/, ($opts{remotehost}));
    }

    $proto  = getprotobyname('tcp');
    if ($iaddr = inet_aton($opts{remotehost}))
    {
        $port = $opts{remoteport} + 1;
        $paddr = sockaddr_in($port, $iaddr);

        socket(STATE, PF_INET, SOCK_STREAM, $proto)  || die "socket: $!";
        connect(STATE, $paddr)                       || die "connect: $!";

        my ($rin, $rout);
        while (!eof(STATE))
        {
            $rin = '';
            vec($rin, fileno(STATE), 1) = 1;
            select($rout = $rin, undef, undef, 0.1);
            if (vec($rout, fileno(STATE), 1))
            {
                $data = <STATE>;
            }
        }
        close (STATE);
    }
    else
    {
        die "perljammer: host '".$opts{remotehost}."' is unknown\n";
    }

    if (!($data eq $laststate))
    {
        do_button_states($data);
        $laststate = $data;
    }
}


sub do_button_states
{
    ($playing, $waiting, $paused) = split(/\s+/, $_[0]);

    if ($paused)
    {
        $playbutton->configure(-bitmap     => 'playbutton',
                               -foreground => 'red');
        $timebox->configure(-foreground    => 'red') unless ($opts{remotelayout} eq 'vertical');
    }
    elsif ($playing)
    {
        $playbutton->configure(-bitmap     => 'pausebutton',
                               -foreground => $opts{UIforeground});
        $timebox->configure(-foreground    => 'blue') unless ($opts{remotelayout} eq 'vertical');
    }
    else
    {
        $playbutton->configure(-bitmap     => 'playbutton',
                               -foreground => $opts{UIforeground});
        $elapsed = 0;
        unless ($opts{layout} eq 'vertical')
        {
            $timebox->Contents('00:00:00');
            $timebox->configure(-foreground => 'blue');
        }
    }

    if ($waiting)
    {
        $waitbutton->configure(-bitmap	   => 'waitbutton2',
                               -foreground => 'red');
    }
    else
    {
        $waitbutton->configure(-bitmap     => 'waitbutton',
                               -foreground => 'black');
    }
}


sub display_elapsed
{
    if ($playing && !$paused)
    {
        $elapsed++;
        my $t = sprintf("%02d:%02d:%02d",
                        int($elapsed/3600),
                        int($elapsed/60) - 60*int($elapsed/3600),
                        $elapsed % 60);
        $timebox->Contents($t);
    }
}


sub create_UI
{
    if ($opts{remotelayout} eq 'horizontal')
    {
        create_UI_horizontal();
    }
    elsif ($opts{remotelayout} eq 'vertical')
    {
        create_UI_vertical();
    }
    elsif ($opts{remotelayout} eq 'ribbon')
    {
        create_UI_ribbon();
    }
    else
    {
        create_UI_default();
    }
}


sub create_UI_horizontal
{
    my ($stopbutton, $resumebutton, $prevbutton, $nextbutton,
        $firstbutton, $lastbutton, $dropbutton, $killbutton,
        $newbutton, $discbutton, $quitbutton, $helpbutton,
        $addnextbutton, $listbutton);

    $app = MainWindow->new();
    $app -> geometry($opts{geometry});
    $app -> configure(-background => $opts{UIbackground});
    $app -> title("RemoteJammer");
    $app -> formGrid(60,6);

    unless ($opts{useWMicon})
    {
        $app -> Icon(-image => $app->Pixmap(-file => "$iconfile"));
    }

    create_button_bitmaps($app);


    ($statusbox = $app->ROText(-width			=> 120, 
                               -height			=> 2,
                               -padx			=> 8,
                               -pady			=> 4, 
                               -relief			=> 'sunken',
                               -foreground		=> $opts{UIforeground}, 
                               -background		=> 'white', 
                               -selectforeground	=> $opts{UIforeground}, 
                               -selectbackground	=> 'white', 
                               -font			=> $opts{remotefont},
                               -wrap			=> 'none')) -> form(-in		=> $app,
                                                                            -fill	=> 'both',
                                                                            -left	=> ['%0',5],
                                                                            -right	=> ['%53',-3],
                                                               	            -top	=> ['%0',5],
                                                                            -bottom	=> ['%3',0]);

    ($timebox = $app->ROText(-width		=> 30, 
                             -height		=> 2,
                             -padx		=> $opts{remote_timebox_padding} + 8, 
                             -pady		=> 4, 
                             -relief		=> 'groove',
                             -foreground	=> 'blue', 
                             -background	=> 'white', 
                             -selectforeground	=> 'blue', 
                             -selectbackground	=> 'white', 
                             -font		=> $opts{remotefont},
                             -wrap		=> 'none')) -> form(-in		=> $app,
                                                                    -fill	=> 'both',
                                                                    -left	=> ['%53',3],
                                                                    -right	=> ['%60',-5],
                                                                    -top	=> ['%0',5],
                                                                    -bottom	=> ['%3',0]);
    $timebox->Contents('00:00:00');

    ($firstbutton = $app->Button(-bitmap	=> 'startbutton',
                                 -command	=> sub { send_socket_command('first_song'); },
                                 -background	=> 'gainsboro',
                                 -foreground	=> $opts{UIforeground},
                                 -activeforeground	=> 'green2',
                                 -anchor	=> 'center',
                                 -relief	=> 'raised',
                                 -width		=> 2,
                                 -height	=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',5],
                                                               -right	=> ['%4',-2],
                                                               -top	=> ['%3',6],
                                                               -bottom	=> ['%6',-5]);

    ($prevbutton = $app->Button(-bitmap		=> 'prevbutton',
                                -command	=> sub { send_socket_command('prev_song'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%4',2],
                                                               -right	=> ['%8',-2],
                                                               -top	=> ['%3',6],
                                                               -bottom	=> ['%6',-5]);

    ($playbutton = $app->Button(-bitmap		=> 'playbutton',
                                -command	=> sub { send_socket_command('play_or_pause'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%8',2],
                                                               -right	=> ['%12',-2],
                                                               -top	=> ['%3',6],
                                                               -bottom	=> ['%6',-5]);

    ($stopbutton = $app->Button(-bitmap		=> 'stopbutton',
                                -command	=> sub { send_socket_command('stop'); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%12',2],
                                                               -right	=> ['%16',-2],
                                                               -top	=> ['%3',6],
                                                               -bottom	=> ['%6',-5]);

    ($waitbutton = $app->Button(-bitmap		=> 'waitbutton',
                                -command	=> sub { send_socket_command('wait'); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%16',2],
                                                               -right	=> ['%20',-2],
                                                               -top	=> ['%3',6],
                                                               -bottom	=> ['%6',-5]);

    ($nextbutton = $app->Button(-bitmap		=> 'nextbutton',
                                -command	=> sub { send_socket_command('next_song'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%20',2],
                                                               -right	=> ['%24',-2],
                                                               -top	=> ['%3',6],
                                                               -bottom	=> ['%6',-5]);

    ($lastbutton = $app->Button(-bitmap		=> 'endbutton',
                                -command	=> sub { send_socket_command('last_song'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%24',2],
                                                               -right	=> ['%28',-2],
                                                               -top	=> ['%3',6],
                                                               -bottom	=> ['%6',-5]);


    ($addnextbutton = $app->Button(-bitmap	=> 'addnextbutton',
                                   -command	=> sub { send_socket_command('insert_next'); },
                                   -background	=> 'gainsboro',
                                   -foreground	=> $opts{UIforeground},
                                   -activeforeground	=> 'green2',
                                   -anchor	=> 'center',
                                   -relief	=> 'raised',
                                   -width	=> 2,
                                   -height	=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%28',2],
                                                               -right	=> ['%32',-2],
                                                               -top	=> ['%3',6],
                                                               -bottom	=> ['%6',-5]);

    ($discbutton = $app->Button(-bitmap		=> 'discbutton',
                                -command	=> sub { send_socket_command('play_disc'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%32',2],
                                                               -right	=> ['%36',-2],
                                                               -top	=> ['%3',6],
                                                               -bottom	=> ['%6',-5]);

    ($dropbutton = $app->Button(-bitmap		=> 'dropbutton',
                                -command	=> sub { send_socket_command('drop_song'); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%36',2],
                                                               -right	=> ['%40',-2],
                                                               -top	=> ['%3',6],
                                                               -bottom	=> ['%6',-5]);

    ($killbutton = $app->Button(-bitmap		=> 'killbutton',
                                -command	=> sub { confirm_disable(); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%40',2],
                                                               -right	=> ['%44',-2],
                                                               -top	=> ['%3',6],
                                                               -bottom	=> ['%6',-5]);

    ($listbutton = $app->Button(-text		=> 'Next?',
                                -font		=> $opts{remoteboldfont},
                                -command	=> sub { list_ten(); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%44',2],
                                                               -right	=> ['%48',-2],
                                                               -top	=> ['%3',6],
                                                               -bottom	=> ['%6',-5]);

    ($helpbutton = $app->Button(-text		=> 'Help',
                                -font		=> $opts{remoteboldfont},
                                -command	=> sub { help(); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%48',2],
                                                               -right	=> ['%52',-2],
                                                               -top	=> ['%3',6],
                                                               -bottom	=> ['%6',-5]);
    ($newbutton = $app->Button(-text		=> 'NEW',
                                -font		=> $opts{remoteboldfont},
                                -command	=> sub { send_socket_command('new_list'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%52',2],
                                                               -right	=> ['%56',-2],
                                                               -top	=> ['%3',6],
                                                               -bottom	=> ['%6',-5]);

    ($quitbutton = $app->Button(-bitmap		=> 'quitbutton',
                                -command	=> sub { quit(); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%56',2],
                                                               -right	=> ['%60',-5],
                                                               -top	=> ['%3',6],
                                                               -bottom	=> ['%6',-5]);

    $app->bind('<Alt-h>' => \&help);
    $app->bind('<Alt-p>' => \&play);
    $app->bind('<Alt-s>' => \&stop);
    $app->bind('<Alt-q>' => \&quit);
    $app->bind('<Control-q>' => \&quit);
}


sub create_UI_vertical
{
    my ($stopbutton, $resumebutton, $prevbutton, $nextbutton,
        $firstbutton, $lastbutton, $dropbutton, $killbutton,
        $newbutton, $discbutton, $quitbutton, $helpbutton,
        $addnextbutton, $listbutton, $nowbutton);

    $app = MainWindow->new();
    $app -> geometry($opts{geometry});
    $app -> configure(-background => $opts{UIbackground});
    $app -> title("RemoteJammer");
    $app -> formGrid(4,64);

    unless ($opts{useWMicon})
    {
        $app -> Icon(-image => $app->Pixmap(-file => "$iconfile"));
    }

    create_button_bitmaps($app);

    ($firstbutton = $app->Button(-bitmap	=> 'startbutton',
                                 -command	=> sub { send_socket_command('first_song'); },
                                 -background	=> 'gainsboro',
                                 -foreground	=> $opts{UIforeground},
                                 -activeforeground	=> 'green2',
                                 -anchor	=> 'center',
                                 -relief	=> 'raised',
                                 -width		=> 2,
                                 -height	=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',4],
                                                               -right	=> ['%4',-4],
                                                               -top	=> ['%0',4],
                                                               -bottom	=> ['%4',-2]);

    ($prevbutton = $app->Button(-bitmap		=> 'prevbutton',
                                -command	=> sub { send_socket_command('prev_song'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',4],
                                                               -right	=> ['%4',-4],
                                                               -top	=> ['%4',2],
                                                               -bottom	=> ['%8',-2]);

    ($playbutton = $app->Button(-bitmap		=> 'playbutton',
                                -command	=> sub { send_socket_command('play_or_pause'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',4],
                                                               -right	=> ['%4',-4],
                                                               -top	=> ['%8',2],
                                                               -bottom	=> ['%12',-2]);

    ($stopbutton = $app->Button(-bitmap		=> 'stopbutton',
                                -command	=> sub { send_socket_command('stop'); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',4],
                                                               -right	=> ['%4',-4],
                                                               -top	=> ['%12',2],
                                                               -bottom	=> ['%16',-2]);

    ($waitbutton = $app->Button(-bitmap		=> 'waitbutton',
                                -command	=> sub { send_socket_command('wait'); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',4],
                                                               -right	=> ['%4',-4],
                                                               -top	=> ['%16',2],
                                                               -bottom	=> ['%20',-2]);

    ($nextbutton = $app->Button(-bitmap		=> 'nextbutton',
                                -command	=> sub { send_socket_command('next_song'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',4],
                                                               -right	=> ['%4',-4],
                                                               -top	=> ['%20',2],
                                                               -bottom	=> ['%24',-2]);

    ($lastbutton = $app->Button(-bitmap		=> 'endbutton',
                                -command	=> sub { send_socket_command('last_song'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',4],
                                                               -right	=> ['%4',-4],
                                                               -top	=> ['%24',2],
                                                               -bottom	=> ['%28',-2]);


    ($addnextbutton = $app->Button(-bitmap	=> 'addnextbutton',
                                   -command	=> sub { send_socket_command('insert_next'); },
                                   -background	=> 'gainsboro',
                                   -foreground	=> $opts{UIforeground},
                                   -activeforeground	=> 'green2',
                                   -anchor	=> 'center',
                                   -relief	=> 'raised',
                                   -width	=> 2,
                                   -height	=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',4],
                                                               -right	=> ['%4',-4],
                                                               -top	=> ['%28',2],
                                                               -bottom	=> ['%32',-2]);

    ($discbutton = $app->Button(-bitmap		=> 'discbutton',
                                -command	=> sub { send_socket_command('play_disc'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',4],
                                                               -right	=> ['%4',-4],
                                                               -top	=> ['%32',2],
                                                               -bottom	=> ['%36',-2]);

    ($dropbutton = $app->Button(-bitmap		=> 'dropbutton',
                                -command	=> sub { send_socket_command('drop_song'); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',4],
                                                               -right	=> ['%4',-4],
                                                               -top	=> ['%36',2],
                                                               -bottom	=> ['%40',-2]);

    ($killbutton = $app->Button(-bitmap		=> 'killbutton',
                                -command	=> sub { confirm_disable(); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',4],
                                                               -right	=> ['%4',-4],
                                                               -top	=> ['%40',2],
                                                               -bottom	=> ['%44',-2]);

    ($nowbutton = $app->Button(-text		=> 'Now ?',
                                -font		=> $opts{remoteboldfont},
                                -command	=> sub { now_playing(); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',4],
                                                               -right	=> ['%4',-4],
                                                               -top	=> ['%44',2],
                                                               -bottom	=> ['%48',-2]);

    ($listbutton = $app->Button(-text		=> 'Next ?',
                                -font		=> $opts{remoteboldfont},
                                -command	=> sub { list_ten(); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',4],
                                                               -right	=> ['%4',-4],
                                                               -top	=> ['%48',2],
                                                               -bottom	=> ['%52',-2]);

    ($helpbutton = $app->Button(-text		=> 'Help',
                                -font		=> $opts{remoteboldfont},
                                -command	=> sub { help(); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',4],
                                                               -right	=> ['%4',-4],
                                                               -top	=> ['%52',2],
                                                               -bottom	=> ['%56',-2]);
    ($newbutton = $app->Button(-text		=> 'NEW',
                                -font		=> $opts{remoteboldfont},
                                -command	=> sub { send_socket_command('new_list'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',4],
                                                               -right	=> ['%4',-4],
                                                               -top	=> ['%56',2],
                                                               -bottom	=> ['%60',-2]);

    ($quitbutton = $app->Button(-bitmap		=> 'quitbutton',
                                -command	=> sub { quit(); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',4],
                                                               -right	=> ['%4',-4],
                                                               -top	=> ['%60',2],
                                                               -bottom	=> ['%64',-4]);

    $app->bind('<Alt-h>' => \&help);
    $app->bind('<Alt-p>' => \&play);
    $app->bind('<Alt-s>' => \&stop);
    $app->bind('<Alt-q>' => \&quit);
    $app->bind('<Control-q>' => \&quit);
}


sub create_UI_ribbon
{
    my ($stopbutton, $resumebutton, $prevbutton, $nextbutton,
        $firstbutton, $lastbutton, $dropbutton, $killbutton,
        $newbutton, $discbutton, $quitbutton, $helpbutton,
        $addnextbutton, $listbutton);

    $app = MainWindow->new();
    $app -> geometry($opts{geometry});
    $app -> configure(-background => $opts{UIbackground});
    $app -> title("RemoteJammer");
    $app -> formGrid(120,3);

    unless ($opts{useWMicon})
    {
        $app -> Icon(-image => $app->Pixmap(-file => "$iconfile"));
    }

    create_button_bitmaps($app);

    ($firstbutton = $app->Button(-bitmap	=> 'startbutton',
                                 -command	=> sub { send_socket_command('first_song'); },
                                 -background	=> 'gainsboro',
                                 -foreground	=> $opts{UIforeground},
                                 -activeforeground	=> 'green2',
                                 -anchor	=> 'center',
                                 -relief	=> 'raised',
                                 -width		=> 2,
                                 -height	=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',5],
                                                               -right	=> ['%4',-2],
                                                               -top	=> ['%0',6],
                                                               -bottom	=> ['%3',-5]);

    ($prevbutton = $app->Button(-bitmap		=> 'prevbutton',
                                -command	=> sub { send_socket_command('prev_song'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%4',2],
                                                               -right	=> ['%8',-2],
                                                               -top	=> ['%0',6],
                                                               -bottom	=> ['%3',-5]);

    ($playbutton = $app->Button(-bitmap		=> 'playbutton',
                                -command	=> sub { send_socket_command('play_or_pause'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%8',2],
                                                               -right	=> ['%12',-2],
                                                               -top	=> ['%0',6],
                                                               -bottom	=> ['%3',-5]);

    ($stopbutton = $app->Button(-bitmap		=> 'stopbutton',
                                -command	=> sub { send_socket_command('stop'); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%12',2],
                                                               -right	=> ['%16',-2],
                                                               -top	=> ['%0',6],
                                                               -bottom	=> ['%3',-5]);

    ($waitbutton = $app->Button(-bitmap		=> 'waitbutton',
                                -command	=> sub { send_socket_command('wait'); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%16',2],
                                                               -right	=> ['%20',-2],
                                                               -top	=> ['%0',6],
                                                               -bottom	=> ['%3',-5]);

    ($nextbutton = $app->Button(-bitmap		=> 'nextbutton',
                                -command	=> sub { send_socket_command('next_song'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%20',2],
                                                               -right	=> ['%24',-2],
                                                               -top	=> ['%0',6],
                                                               -bottom	=> ['%3',-5]);

    ($lastbutton = $app->Button(-bitmap		=> 'endbutton',
                                -command	=> sub { send_socket_command('last_song'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%24',2],
                                                               -right	=> ['%28',-2],
                                                               -top	=> ['%0',6],
                                                               -bottom	=> ['%3',-5]);


    ($addnextbutton = $app->Button(-bitmap	=> 'addnextbutton',
                                   -command	=> sub { send_socket_command('insert_next'); },
                                   -background	=> 'gainsboro',
                                   -foreground	=> $opts{UIforeground},
                                   -activeforeground	=> 'green2',
                                   -anchor	=> 'center',
                                   -relief	=> 'raised',
                                   -width	=> 2,
                                   -height	=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%28',2],
                                                               -right	=> ['%32',-2],
                                                               -top	=> ['%0',6],
                                                               -bottom	=> ['%3',-5]);

    ($statusbox = $app->ROText(-width			=> 120, 
                               -height			=> 2,
                               -padx			=> 8,
                               -pady			=> 4, 
                               -relief			=> 'sunken',
                               -foreground		=> $opts{UIforeground}, 
                               -background		=> 'white', 
                               -selectforeground	=> $opts{UIforeground}, 
                               -selectbackground	=> 'white', 
                               -font			=> $opts{remotefont},
                               -wrap			=> 'none')) -> form(-in		=> $app,
                                                                            -fill	=> 'both',
                                                                            -left	=> ['%32',5],
                                                                            -right	=> ['%85',-3],
                                                               	            -top	=> ['%0',3],
                                                                            -bottom	=> ['%3',-3]);

    ($timebox = $app->ROText(-width		=> 30, 
                             -height		=> 2,
                             -padx		=> $opts{remote_timebox_padding} + 8, 
                             -pady		=> 4, 
                             -relief		=> 'groove',
                             -foreground	=> 'blue', 
                             -background	=> 'white', 
                             -selectforeground	=> 'blue', 
                             -selectbackground	=> 'white', 
                             -font		=> $opts{remotefont},
                             -wrap		=> 'none')) -> form(-in		=> $app,
                                                                    -fill	=> 'both',
                                                                    -left	=> ['%85',3],
                                                                    -right	=> ['%92',-5],
                                                                    -top	=> ['%0',3],
                                                                    -bottom	=> ['%3',-3]);
    $timebox->Contents('00:00:00');

    ($discbutton = $app->Button(-bitmap		=> 'discbutton',
                                -command	=> sub { send_socket_command('play_disc'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%92',2],
                                                               -right	=> ['%96',-2],
                                                               -top	=> ['%0',6],
                                                               -bottom	=> ['%3',-5]);

    ($dropbutton = $app->Button(-bitmap		=> 'dropbutton',
                                -command	=> sub { send_socket_command('drop_song'); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%96',2],
                                                               -right	=> ['%100',-2],
                                                               -top	=> ['%0',6],
                                                               -bottom	=> ['%3',-5]);

    ($killbutton = $app->Button(-bitmap		=> 'killbutton',
                                -command	=> sub { confirm_disable(); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%100',2],
                                                               -right	=> ['%104',-2],
                                                               -top	=> ['%0',6],
                                                               -bottom	=> ['%3',-5]);

    ($listbutton = $app->Button(-text		=> 'Next?',
                                -font		=> $opts{remoteboldfont},
                                -command	=> sub { list_ten(); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%104',2],
                                                               -right	=> ['%108',-2],
                                                               -top	=> ['%0',6],
                                                               -bottom	=> ['%3',-5]);

    ($helpbutton = $app->Button(-text		=> 'Help',
                                -font		=> $opts{remoteboldfont},
                                -command	=> sub { help(); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%108',2],
                                                               -right	=> ['%112',-2],
                                                               -top	=> ['%0',6],
                                                               -bottom	=> ['%3',-5]);
    ($newbutton = $app->Button(-text		=> 'NEW',
                                -font		=> $opts{remoteboldfont},
                                -command	=> sub { send_socket_command('new_list'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%112',2],
                                                               -right	=> ['%116',-2],
                                                               -top	=> ['%0',6],
                                                               -bottom	=> ['%3',-5]);

    ($quitbutton = $app->Button(-bitmap		=> 'quitbutton',
                                -command	=> sub { quit(); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%116',2],
                                                               -right	=> ['%120',-5],
                                                               -top	=> ['%0',6],
                                                               -bottom	=> ['%3',-5]);

    $app->bind('<Alt-h>' => \&help);
    $app->bind('<Alt-p>' => \&play);
    $app->bind('<Alt-s>' => \&stop);
    $app->bind('<Alt-q>' => \&quit);
    $app->bind('<Control-q>' => \&quit);
}


sub create_UI_default
{
    my ($stopbutton, $resumebutton, $prevbutton, $nextbutton,
        $firstbutton, $lastbutton, $dropbutton, $killbutton,
        $newbutton, $discbutton, $quitbutton, $helpbutton,
        $addnextbutton, $listbutton, $bgimage, $canvas);

    $app = MainWindow->new();
    $app -> geometry($opts{geometry});
    $app -> configure(-background => 'DarkSlateBlue');
    $app -> title("RemoteJammer");
    $app -> formGrid(24,24);

    if (-f $opts{remoteskin})
    {
        ($canvas = $app->Canvas)->form(-in	=> $app,
                                       -fill	=>'both',
                                       -left	=> ['%0',-1],	# necessary to get
                                       -right	=> ['%24',1],	# complete edge to
                                       -top	=> ['%0',-1],	# edge fill of the
                                       -bottom	=> ['%24',1]);	# canvas

        $canvas->createImage(0,0,  
                             -image	=> ($opts{remoteskin} =~ /\.(jpg|jpeg)$/i)
                                        ?  $app->Photo(-file => $opts{remoteskin},
                                                       -format => 'jpeg')
                                        :  $app->Photo(-file => $opts{remoteskin}),
                             -anchor	=> 'nw',
                             -tags	=> ['img']);
    }

    unless ($opts{useWMicon})
    {
        $app -> Icon(-image => $app->Pixmap(-file => "$iconfile"));
    }

    create_button_bitmaps($app);


    ($statusbox = $app->Scrolled('ROText',
                                 -scrollbars		=> 'oe',
                                 -width			=> 8,
                                 -height		=> 2,
                                 -padx			=> 2, 
                                 -pady			=> 2, 
                                 -relief		=> 'sunken',
                                 -spacing3		=> 1,
                                 -foreground		=> $opts{UIforeground}, 
                                 -background		=> 'white', 
                                 -font			=> $opts{remotesmallfont},
                                 -wrap			=> 'word')) -> form(-in		=> $app,
                                                                            -fill	=> 'both',
                                                                            -left	=> ['%2',0],
                                                                            -right	=> ['%22',0],
                                                                            -top	=> ['%2',0],
                                                                            -bottom	=> ['%10',-5]);

    ($timebox = $app->ROText(-width		=> 30, 
                             -height		=> 2,
                             -padx		=> $opts{remote_timebox_padding}, 
                             -pady		=> 0, 
                             -relief		=> 'groove',
                             -foreground	=> 'blue', 
                             -background	=> 'white', 
                             -selectforeground	=> 'blue', 
                             -selectbackground	=> 'white', 
                             -font		=> $opts{remotesmallfont},
                             -wrap		=> 'none')) -> form(-in		=> $app,
                                                                    -fill	=> 'both',
                                                                    -left	=> ['%7',1],
                                                                    -right	=> ['%17',-1],
                                                                    -top	=> ['%10',1],
                                                                    -bottom	=> ['%12',-3]);
    $timebox->Contents('00:00:00');

    ($prevbutton = $app->Button(-bitmap		=> 'prevbutton',
                                -command	=> sub { send_socket_command('prev_song'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',5],
                                                               -right	=> ['%6',-1],
                                                               -top	=> ['%12',1],
                                                               -bottom	=> ['%14',-1]);

    ($playbutton = $app->Button(-bitmap		=> 'playbutton',
                                -command	=> sub { send_socket_command('play_or_pause'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%6',4],
                                                               -right	=> ['%12',-2],
                                                               -top	=> ['%12',1],
                                                               -bottom	=> ['%14',-1]);

    ($stopbutton = $app->Button(-bitmap		=> 'stopbutton',
                                -command	=> sub { send_socket_command('stop'); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%12',2],
                                                               -right	=> ['%18',-4],
                                                               -top	=> ['%12',1],
                                                               -bottom	=> ['%14',-1]);

    ($nextbutton = $app->Button(-bitmap		=> 'nextbutton',
                                -command	=> sub { send_socket_command('next_song'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%18',1],
                                                               -right	=> ['%24',-5],
                                                               -top	=> ['%12',1],
                                                               -bottom	=> ['%14',-1]);

    ($firstbutton = $app->Button(-bitmap	=> 'startbutton',
                                 -command	=> sub { send_socket_command('first_song'); },
                                 -background	=> 'gainsboro',
                                 -foreground	=> $opts{UIforeground},
                                 -activeforeground	=> 'green2',
                                 -anchor	=> 'center',
                                 -relief	=> 'raised',
                                 -width		=> 2,
                                 -height	=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',5],
                                                               -right	=> ['%6',-1],
                                                               -top	=> ['%14',1],
                                                               -bottom	=> ['%16',-1]);

    ($waitbutton = $app->Button(-bitmap		=> 'waitbutton',
                                -command	=> sub { send_socket_command('wait'); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%9',3],
                                                               -right	=> ['%15',-3],
                                                               -top	=> ['%14',1],
                                                               -bottom	=> ['%16',-1]);

    ($lastbutton = $app->Button(-bitmap		=> 'endbutton',
                                -command	=> sub { send_socket_command('last_song'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%18',1],
                                                               -right	=> ['%24',-5],
                                                               -top	=> ['%14',1],
                                                               -bottom	=> ['%16',-1]);


    ($addnextbutton = $app->Button(-bitmap	=> 'addnextbutton',
                                   -command	=> sub { send_socket_command('insert_next'); },
                                   -background	=> 'gainsboro',
                                   -foreground	=> $opts{UIforeground},
                                   -activeforeground	=> 'green2',
                                   -anchor	=> 'center',
                                   -relief	=> 'raised',
                                   -width	=> 2,
                                   -height	=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',5],
                                                               -right	=> ['%6',-1],
                                                               -top	=> ['%17',1],
                                                               -bottom	=> ['%19',-1]);

    ($discbutton = $app->Button(-bitmap		=> 'discbutton',
                                -command	=> sub { send_socket_command('play_disc'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%6',3],
                                                               -right	=> ['%12',-3],
                                                               -top	=> ['%17',1],
                                                               -bottom	=> ['%19',-1]);

    ($dropbutton = $app->Button(-bitmap		=> 'dropbutton',
                                -command	=> sub { send_socket_command('drop_song'); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%12',3],
                                                               -right	=> ['%18',-3],
                                                               -top	=> ['%17',1],
                                                               -bottom	=> ['%19',-1]);

    ($killbutton = $app->Button(-bitmap		=> 'killbutton',
                                -command	=> sub { confirm_disable(); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%18',1],
                                                               -right	=> ['%24',-5],
                                                               -top	=> ['%17',1],
                                                               -bottom	=> ['%19',-1]);

    ($listbutton = $app->Button(-text		=> 'Next Ten',
                                -font		=> $opts{remoteboldfont},
                                -command	=> sub { list_ten(); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%6',3],
                                                               -right	=> ['%18',-3],
                                                               -top	=> ['%19',5],
                                                               -bottom	=> ['%22',-5]);

    ($helpbutton = $app->Button(-text		=> 'Help',
                                -font		=> $opts{remoteboldfont},
                                -command	=> sub { help(); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',5],
                                                               -right	=> ['%8',-1],
                                                               -top	=> ['%22',0],
                                                               -bottom	=> ['%24',-3]);
    ($newbutton = $app->Button(-text		=> 'NEW',
                                -font		=> $opts{remoteboldfont},
                                -command	=> sub { send_socket_command('new_list'); },
                                -background	=> 'gainsboro',
                                -foreground	=> $opts{UIforeground},
                                -activeforeground	=> 'green2',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%8',3],
                                                               -right	=> ['%16',-3],
                                                               -top	=> ['%22',0],
                                                               -bottom	=> ['%24',-3]);

    ($quitbutton = $app->Button(-bitmap		=> 'quitbutton',
                                -command	=> sub { quit(); },
                                -background	=> 'gainsboro',
                                -foreground	=> 'black',
                                -activeforeground	=> 'red',
                                -anchor		=> 'center',
                                -relief		=> 'raised',
                                -width		=> 2,
                                -height		=> 1)) -> form(-in	=> $app,
                                                               -fill	=> 'both',
                                                               -left	=> ['%16',1],
                                                               -right	=> ['%24',-5],
                                                               -top	=> ['%22',0],
                                                               -bottom	=> ['%24',-3]);

    $app->bind('<Alt-h>' => \&help);
    $app->bind('<Alt-p>' => \&play);
    $app->bind('<Alt-s>' => \&stop);
    $app->bind('<Alt-q>' => \&quit);
    $app->bind('<Control-q>' => \&quit);
}


sub now_playing
{
    my ($nowdialog, $title, $play, $okbutton, $timer);
    $nowdialog = MainWindow->new();
    $nowdialog -> title("Now Playing");
    $nowdialog -> configure(-background => $opts{UIbackground});
    $nowdialog -> geometry("200x200");
    $nowdialog -> formGrid(10,10);

    ($play = $nowdialog->ROText(-width			=> 30, 
                                 -height		=> 2,
                                 -padx			=> 5, 
                                 -pady			=> 2, 
                                 -relief		=> 'flat',
                                 -spacing3		=> 3,
                                 -foreground		=> $opts{UIforeground}, 
                                 -background		=> 'white', 
                                 -selectforeground	=> 'blue', 
                                 -selectbackground	=> 'white', 
                                 -font			=> $opts{remotesmallfont},
                                 -wrap			=> 'word')) -> form(-in		=> $nowdialog,
                                                                            -fill	=> 'both',
                                                                            -left	=> ['%0',5],
                                                                            -right	=> ['%10',-5],
                                                                            -top	=> ['%0',5],
                                                                            -bottom	=> ['%10',-40]);

    chomp(my $data = send_socket_command('status'));
    if ($data eq 'Inactive')
    {
        chomp($data = sprintf('(Inactive) :: Next Up: :: %s',
                              send_socket_command('status 1')));
    }

    $data =~ s/ :: /\n/g;
    $play->delete('1.0', 'end');
    $play->insert('1.0', $data);

    ($okbutton = $nowdialog->Button(-text		=> 'OK',
                                 -font			=> $opts{remoteboldfont},
                                 -command		=> sub {
                                                                   $timer = $okbutton->after(10, sub { $nowdialog->destroy(); } );
                                                               },
                                 -background		=> 'gainsboro',
                                 -anchor		=> 'center',
                                 -relief		=> 'raised',
                                 -width			=> 4,
                                 -height		=> 1)) -> form(-in	=> $nowdialog,
                                                                       -fill	=> 'both',
                                                                       -left	=> ['%4',5],
                                                                       -right	=> ['%6',-5],
                                                                       -top	=> ['%10',-30],
                                                                       -bottom	=> ['%10',-5]);

    $nowdialog->bind('<Control-w>' => sub { $nowdialog->destroy(); });
}


sub list_ten
{
    my ($listdialog, $title, $list, $okbutton, $timer);
    $listdialog = MainWindow->new();
    $listdialog -> title("Coming Up Next...");
    $listdialog -> configure(-background => $opts{UIbackground});
    $listdialog -> geometry("400x500");
    $listdialog -> formGrid(10,10);

    ($list = $listdialog->ROText(-width		=> 30, 
                                 -height		=> 2,
                                 -padx			=> 5, 
                                 -pady			=> 2, 
                                 -relief		=> 'flat',
                                 -spacing3		=> 10,
                                 -foreground		=> $opts{UIforeground}, 
                                 -background		=> 'white', 
                                 -selectforeground	=> 'blue', 
                                 -selectbackground	=> 'white', 
                                 -font			=> $opts{remotefont},
                                 -wrap			=> 'word')) -> form(-in		=> $listdialog,
                                                                            -fill	=> 'both',
                                                                            -left	=> ['%0',5],
                                                                            -right	=> ['%10',-5],
                                                                            -top	=> ['%0',5],
                                                                            -bottom	=> ['%10',-40]);

    chomp(my $data = send_socket_command('status 10'));
    $list->delete('1.0', 'end');
    $list->insert('1.0', $data);

    ($okbutton = $listdialog->Button(-text		=> 'OK',
                                 -font			=> $opts{remoteboldfont},
                                 -command		=> sub {
                                                                   $timer = $okbutton->after(10, sub { $listdialog->destroy(); } );
                                                               },
                                 -background		=> 'gainsboro',
                                 -anchor		=> 'center',
                                 -relief		=> 'raised',
                                 -width			=> 4,
                                 -height		=> 1)) -> form(-in	=> $listdialog,
                                                                       -fill	=> 'both',
                                                                       -left	=> ['%4',15],
                                                                       -right	=> ['%6',-15],
                                                                       -top	=> ['%10',-30],
                                                                       -bottom	=> ['%10',-5]);

    $listdialog->bind('<Control-w>' => sub { $listdialog->destroy(); });
}


sub help
{
    my ($dialog, $title, $helptext, $okbutton, $credit, $timer);
    $dialog = MainWindow->new();
    $dialog -> title("About RemoteJammer");
    $dialog -> configure(-background => 'white');
    $dialog -> geometry("450x450");
    $dialog -> formGrid(10,10);

    ($helptext = $dialog->ROText(-width			=> 30, 
                                 -height		=> 2,
                                 -padx			=> 5, 
                                 -pady			=> 2, 
                                 -relief		=> 'flat',
                                 -spacing3		=> 10,
                                 -foreground		=> $opts{UIforeground}, 
                                 -background		=> 'white', 
                                 -selectforeground	=> 'blue', 
                                 -selectbackground	=> 'white', 
                                 -font			=> $opts{remotefont},
                                 -wrap			=> 'word')) -> form(-in		=> $dialog,
                                                                            -fill	=> 'both',
                                                                            -left	=> ['%0',5],
                                                                            -right	=> ['%10',-5],
                                                                            -top	=> ['%0',5],
                                                                            -bottom	=> ['%10',-60]);

    $helptext->insert('1.0', sprintf(
"This is version %s of RemoteJammer, the skinnable graphical remote-control tool for PerlJammer.  If you"
." are already familiar with PerlJammer, all of its functions should be familiar to you.  (If you don't"
." already know PerlJammer's controls, you should probably learn how PerlJammer works locally before trying"
." to use it remotely.)  All control buttons present in PerlJammer's main window are present in RemoteJammer, and"
." work the same way, except for the persistent gain controls.  Persistent gain control is not available remotely.\n"
."Upon startup, RemoteJammer reads PerlJammer's configuration file and extracts the settings it needs to know"
." about.  It will next contact PerlJammer to determine whether anything is playing.  (It does not, at this"
." time check to see whether PerlJammer is running before it does this.)  It will then configure the play/pause"
." button correctly.  From this point onwards, it works just like PerlJammer's control bar, except remotely"
." (with the obvious exception that the Quit button closes only RemoteJammer, not PerlJammer).\n"
."Please run 'remotejammer -man' for information about custom skins for RemoteJammer.",
$pjam_version));

    ($okbutton = $dialog->Button(-text			=> 'OK',
                                 -font			=> $opts{remoteboldfont},
                                 -command		=> sub {
                                                                   $timer = $okbutton->after(10, sub { $dialog->destroy(); } );
                                                               },
                                 -background		=> 'gainsboro',
                                 -anchor		=> 'center',
                                 -relief		=> 'raised',
                                 -width			=> 4,
                                 -height		=> 1)) -> form(-in	=> $dialog,
                                                                       -fill	=> 'both',
                                                                       -left	=> ['%4',15],
                                                                       -right	=> ['%6',-15],
                                                                       -top	=> ['%10',-50],
                                                                       -bottom	=> ['%10',-25]);

    ($credit = $dialog->Label(-text		=> sprintf('RemoteJammer v%s, March 30 2010, Phil V. Stracchino <alaric@caerllewys.net>',
                                                           $pjam_version),
                              -font		=> defined $opts{remotesmallfont} ? $opts{remotesmallfont} : $opts{remotefont},
                              -foreground	=> 'blue', 
                              -background	=> 'white', 
                              -anchor		=> 'center', 
                              -relief		=> 'flat', 
                              -width		=> 50, 
                              -height		=> 1)) -> form(-in	=> $dialog,
                                                               -fill	=> 'both',
                                                               -left	=> ['%0',5],
                                                               -right	=> ['%10',-5],
                                                               -top	=> ['%10',-25],
                                                               -bottom	=> ['%10',-5]);

    $dialog->bind('<Control-w>' => sub { $dialog->destroy(); });
}


sub confirm_disable
{
    my ($dialog, $title, $error, $errortext, $okbutton, $cancelbutton, $timer, $errorfont, @row, $data);
    $dialog = MainWindow->new();
    $dialog -> title("Confirm Disable Song");
    $dialog -> configure(-background => 'white');
    $dialog -> geometry("300x200");
    $dialog -> formGrid(10,1);
    $errorfont = '-misc-fixed-bold-r-normal--15-140-75-75-c-90-iso8859-1';

    ($errortext = $dialog->ROText(-width		=> 30,
                                  -height		=> 2,
                                  -padx			=> 5, 
                                  -pady			=> 5, 
                                  -relief		=> 'flat',
                                  -spacing3		=> 10,
                                  -foreground		=> 'black', 
                                  -background		=> 'gold', 
                                  -font			=> $errorfont,
                                  -wrap			=> 'word')) -> form(-in		=> $dialog,
                                                                            -fill	=> 'both',
                                                                            -left	=> ['%0',15],
                                                                            -right	=> ['%10',-15],
                                                                            -top	=> ['%0',15],
                                                                            -bottom	=> ['%1',-60]);

    chomp($data = send_socket_command('status'));
    @row = split(/ :: /, $data);
    $row[2] =~ s/ \(\d{4}, \d{2}:\d{2}\)$//;
    $errortext->insert('1.0', sprintf("Do you really want to ban '%s', by %s, from appearing in any future playlists?",
                                      $row[2],
                                      $row[0]));

    ($okbutton = $dialog->Button(-text			=> "Yes, I'm sure",
                                 -font			=> $opts{remoteboldfont},
                                 -command		=> sub {
                                                                   $timer = $okbutton->after(10, sub {
                                                                                                         send_socket_command('disable_song');
                                                                                                         $dialog->destroy();
                                                                                                     } );
                                                               },
                                 -background		=> 'gainsboro',
                                 -activeforeground	=> 'red',
                                 -anchor		=> 'center',
                                 -relief		=> 'raised',
                                 -width			=> 4,
                                 -height		=> 1)) -> form(-in	=> $dialog,
                                                                       -fill	=> 'both',
                                                                       -left	=> ['%0',15],
                                                                       -right	=> ['%5',-10],
                                                                       -top	=> ['%1',-45],
                                                                       -bottom	=> ['%1',-15]);

    ($cancelbutton = $dialog->Button(-text		=> 'No, never mind',
                                     -font		=> $opts{remoteboldfont},
                                     -command		=> sub {
                                                                   $timer = $cancelbutton->after(10, sub {
                                                                                                             $dialog->destroy();
                                                                                                         } );
                                                               },
                                     -background	=> 'gainsboro',
                                     -activeforeground	=> 'blue',
                                     -anchor		=> 'center',
                                     -relief		=> 'raised',
                                     -width		=> 4,
                                     -height		=> 1)) -> form(-in	=> $dialog,
                                                                       -fill	=> 'both',
                                                                       -left	=> ['%5',10],
                                                                       -right	=> ['%10',-15],
                                                                       -top	=> ['%1',-45],
                                                                       -bottom	=> ['%1',-15]);

    $dialog->bind('<Control-w>' => sub { $dialog->destroy(); });
}


sub create_button_bitmaps
{
    my $app = $_[0];

    my $playbuttonbits = pack("b12" x 12,
                 "11..........",
                 "1111........",
                 "111111......",
                 "11111111....",
                 "1111111111..",
                 "111111111111",
                 "111111111111",
                 "1111111111..",
                 "11111111....",
                 "111111......",
                 "1111........",
                 "11..........");
    $app->DefineBitmap('playbutton' => 12, 12, $playbuttonbits);

    my $stopbuttonbits = pack("b12" x 12,
                 "111111111111",
                 "111111111111",
                 "111111111111",
                 "111111111111",
                 "111111111111",
                 "111111111111",
                 "111111111111",
                 "111111111111",
                 "111111111111",
                 "111111111111",
                 "111111111111",
                 "111111111111");
    $app->DefineBitmap('stopbutton' => 12, 12, $stopbuttonbits);

    my $pausebuttonbits = pack("b12" x 12,
                 "..111..111..",
                 "..111..111..",
                 "..111..111..",
                 "..111..111..",
                 "..111..111..",
                 "..111..111..",
                 "..111..111..",
                 "..111..111..",
                 "..111..111..",
                 "..111..111..",
                 "..111..111..",
                 "..111..111..");
    $app->DefineBitmap('pausebutton' => 12, 12, $pausebuttonbits);

    my $waitbuttonbits = pack("b24" x 12,
                 "............111111111111",
                 "11..........111111111111",
                 "1111........111111111111",
                 "111111......111111111111",
                 "11111111....111111111111",
                 "1111111111..111111111111",
                 "1111111111..111111111111",
                 "11111111....111111111111",
                 "111111......111111111111",
                 "1111........111111111111",
                 "11..........111111111111",
                 "............111111111111");
    $app->DefineBitmap('waitbutton' => 24, 12, $waitbuttonbits);

    my $waitbutton2bits = pack("b18" x 12,
                 "......111111111111",
                 "11......1111111111",
                 "1111..11..11111111",
                 "111111..11..111111",
                 "11111111..11..1111",
                 "1111111111..11..11",
                 "1111111111..11..11",
                 "11111111..11..1111",
                 "111111..11..111111",
                 "1111..11..11111111",
                 "11......1111111111",
                 "......111111111111");
    $app->DefineBitmap('waitbutton2' => 18, 12, $waitbutton2bits);

    my $startbuttonbits = pack("b20" x 12,
                 "....................",
                 "....................",
                 "11.......11.......11",
                 "11.....1111.....1111",
                 "11...111111...111111",
                 "11.11111111.11111111",
                 "11.11111111.11111111",
                 "11...111111...111111",
                 "11.....1111.....1111",
                 "11.......11.......11",
                 "....................",
                 "....................");
    $app->DefineBitmap('startbutton' => 20, 12, $startbuttonbits);

    my $prevbuttonbits = pack("b18" x 12,
                 "..................",
                 "..................",
                 ".......11.......11",
                 ".....1111.....1111",
                 "...111111...111111",
                 ".11111111.11111111",
                 ".11111111.11111111",
                 "...111111...111111",
                 ".....1111.....1111",
                 ".......11.......11",
                 "..................",
                 "..................");
    $app->DefineBitmap('prevbutton' => 18, 12, $prevbuttonbits);

    my $nextbuttonbits = pack("b18" x 12,
                 "..................",
                 "..................",
                 "11.......11.......",
                 "1111.....1111.....",
                 "111111...111111...",
                 "11111111.11111111.",
                 "11111111.11111111.",
                 "1111111..111111...",
                 "11111....1111.....",
                 "11.......11.......",
                 "..................",
                 "..................");
    $app->DefineBitmap('nextbutton' => 18, 12, $nextbuttonbits);

    my $endbuttonbits = pack("b20" x 12,
                 "....................",
                 "....................",
                 "11.......11.......11",
                 "1111.....1111.....11",
                 "111111...111111...11",
                 "11111111.11111111.11",
                 "11111111.11111111.11",
                 "1111111..111111...11",
                 "11111....1111.....11",
                 "11.......11.......11",
                 "....................",
                 "....................");
    $app->DefineBitmap('endbutton' => 20, 12, $endbuttonbits);

    my $discbuttonbits = pack("b20" x 12,
                 "....................",
                 "...1111.............",
                 ".11111111..11.......",
                 ".11111111..1111.....",
                 "1111111111.111111...",
                 "1111111111.11111111.",
                 "1111111111.11111111.",
                 "1111111111.111111...",
                 ".11111111..1111.....",
                 ".11111111..11.......",
                 "...1111.............",
                 "....................");
    $app->DefineBitmap('discbutton' => 20, 12, $discbuttonbits);

    my $addnextbuttonbits = pack("b20" x 12,
                 "....................",
                 "....................",
                 "....11....11........",
                 "....1111..1111......",
                 "....111111..1111....",
                 "....11111111..1111..",
                 "....11111111..1111..",
                 "....111111..1111....",
                 "....1111..1111......",
                 "....11....11........",
                 "....................",
                 "....................");
    $app->DefineBitmap('addnextbutton' => 20, 12, $addnextbuttonbits);

    my $dropbuttonbits = pack("b20" x 12,
                 "....................",
                 "....111......111....",
                 ".....111....111.....",
                 "......111..111......",
                 ".......111111.......",
                 "111111..1111..111111",
                 "111111..1111..111111",
                 ".......111111.......",
                 "......111..111......",
                 ".....111....111.....",
                 "....111......111....",
                 "....................");
    $app->DefineBitmap('dropbutton' => 20, 12, $dropbuttonbits);

    my $killbuttonbits = pack("b20" x 12,
                 "........1111..111...",
                 ".....111111..111....",
                 "...1111111..111.....",
                 "...111111..111..1...",
                 "..111111..111..111..",
                 "..11111..111..1111..",
                 "..1111..111..11111..",
                 "..111..111..111111..",
                 "...1..111..111111...",
                 ".....111..1111111...",
                 "....111..111111.....",
                 "...111..1111........");
    $app->DefineBitmap('killbutton' => 20, 12, $killbuttonbits);

    my $quitbuttonbits = pack("b12" x 12,
                 "....1111....",
                 "..11111111..",
                 ".111....111.",
                 "111......111",
                 "11........11",
                 "11...11...11",
                 "11...11...11",
                 "111..11..111",
                 ".111.11.111.",
                 "..11.11.11..",
                 ".....11.....",
                 ".....11.....");
    $app->DefineBitmap('quitbutton' => 12, 12, $quitbuttonbits);

    my $upbuttonbits = pack("b12" x 6,
                 ".....11.....",
                 "....1111....",
                 "...111111...",
                 "..11111111..",
                 ".1111111111.",
                 "1111....1111");
    $app->DefineBitmap('upbutton' => 12, 6, $upbuttonbits);

    my $downbuttonbits = pack("b12" x 6,
                 "1111....1111",
                 ".1111111111.",
                 "..11111111..",
                 "...111111...",
                 "....1111....",
                 ".....11.....");
    $app->DefineBitmap('downbutton' => 12, 6, $downbuttonbits);
}

__END__

=head1 NAME

B<RemoteJammer> - A skinnable graphical remote control for B<PerlJammer>

=head1 VERSION

Version 2.2.0

=head1 SYNOPSIS

RemoteJammer [options]

  Options:
    -skin random|skinfile
    -layout horizontal|vertical|ribbon|default
    -position [+-]x[+-]y
    -help, -usage, -?
    -man
    -version

=head1 OPTIONS

=over 4

=item B<-skin>

Specifies the location of the skin to be used, or random skin selection, in default layout only.

=item B<-layout>

Specify horizontal, vertical, ribbon or default layout.  If used, overrides 'remotelayout' in the config file.

=item B<-position>

Specifies the position on screen of the window.  If used, overrides 'remoteposition' or 'ribbonposition'
in the config file, as applicable depending upon whether or not B<--layout ribbon> is in use.

=item B<-help, -usage, -?>

List command-line options and usage, then exit

=item B<-man>

Display full documentation and exit

=item B<-version>

Display version string and exit

=back

=head1 DESCRIPTION

B<RemoteJammer> is the graphical remote-control tool for B<PerlJammer>.  It sends commands to
B<PerlJammer> via its network socket (unless, obviously, B<PerlJammer> was started using
-nonet).  It reads the B<PerlJammer> config file, $HOME/.pjam/config, to determine the 
correct network port (default: 16384) and host (default: localhost) at which to contact
B<PerlJammer>.

=head1 LAYOUTS

B<RemoteJammer> has four interface layout options.  The default is to launch a skinnable UI that
looks like a handheld remote device or music player.  By setting the configuration option
'remotelayout' to 'horizontal', 'ribbon', or 'vertical', B<RemoteJammer> can run as a two-row
horizontal control strip with now-playing and elapsed-time windows, a wider single-row horizontal
control ribbon with now-playing and elapsed-time windows, or the minimalist option, a vertical
control strip with B<ONLY> play control buttons.  It reads the 'remoteposition' X11 geometry
position setting from .pjam/config, except for ribbon mode, which reads the 'ribbonposition'
setting.

'remoteposition: -0+0', for example, will anchor the B<RemoteJammer> window to the top right
corner of the screen, while 'ribbonposition: +480-0' will center the ribbon across the bottom
edge of a 2560-pixel-wide monitor.

In either case, the B<-position> option overrides the config file.  If no position is specified
either on the command line or in the config file, the default position is '+0+0'.

=head1 CONTROLS

B<RemoteJammer> offers all control buttons found on the control bar in B<PerlJammer>'s main
window, except for the persistent gain controls.  (Persistent gain adjustment is not offered
remotely at this time.)  All controls work exactly as they do in the main B<PerlJammer> window.

B<RemoteJammer> also adds a "Next Ten" button.  This button pops up a window containing a list
of the next ten selections in the playlist B<after> the currently-playing selection, or, if
nothing is currently playing, the next ten selections beginning at the current selection
position.

In the vertical and horizontal layouts, the 'Next Ten' button is labelled 'Next?', to save space.
In the vertical layout only, since there is no room for a status panel, B<RemoteJammer> also adds
a 'Now?' button immediately before 'Next?' which pops up a small 'Now Playing' window listing MP3
metadata of the currently playing song.

=head1 SKINS

If run with the default UI, B<RemoteJammer> tries to load a skin at startup.  B<RemoteJammer>
skins are 162x302 images in PNG, JPEG, GIF or XPM format.  By default, it expects to find the
standard skins in B<PerlJammer>'s system shared data directory, which defaults to /usr/share/perljammer.
This location can be changed by setting the B<datadir> option in the configuration file.
A skin can be set manually in the B<remoteskin> option in the configuration file, or by
using the B<-skin> option at the command line.  Either of these may be set to 'random' to
pick a random skin from those found in the shared data directory.  The B<-skin> option, if
used, overrides the B<remoteskin> option in the configuration file.  If both are left blank,
B<RemoteJammer> defaults to trying to use B<datadir>/skins/bluecurve.png, the default skin.  If no
skin file is found, B<RemoteJammer> will fall back to a solid dark slate blue.

=head1 KNOWN BUGS

B<RemoteJammer> does not know if B<PerlJammer> is running until it tries to connect to it,
and will emit many failed-connection warnings if B<PerlJammer> is not in fact running on
the target host.

If started while a song is already playing, B<RemoteJammer>'s elapsed-time display will be
incorrect until the next song begins.

=head1 REPORTING BUGS

Please send all bug reports to the author.

=head1 LICENSE

B<remotejammer>, part of the B<PerlJammer> package, is copyright (C) 2013 Phil Stracchino.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

=head1 OBTAINING PerlJammer

B<PerlJammer> can be downloaded from http://co.ordinate.org/perljammer/.

=head1 AUTHOR

B<PerlJammer> and its supporting tools are written and maintained by Phil Stracchino
(phil@co.ordinate.org).

=cut
 
