#!/usr/bin/perl

# This shows a slide show on ALL available framebuffers

# The last item on the command line should be the path to the pictures
# other options are "file" for file handle mode, "error" for show
# errors, and 'auto' for autolevel.

use strict;
use threads;
use threads::shared;

use Graphics::Framebuffer;
use Time::HiRes qw(sleep time);
use List::Util qw(shuffle);
# use Data::Dumper::Simple;

my $args = join('',@ARGV);

my $file       = 0;
$file          = 1 if ($args =~ /file/i);
my $errors     = 0;
$errors        = 1 if ($args =~ /errors/i);
my $auto       = 0;
$auto          = 1 if ($args =~ /auto/i);
my $fullscreen = 0;
$fullscreen    = 1 if ($args =~ /full/i);

my @fbs;
foreach my $p (qw(/dev/graphics/fb /dev/fb)) {
    foreach my $b (0..31) {
        push(@fbs,"$p$b") if (-e "$p$b");
    }
}

my @thr;
my $RUNNING : shared = 1;
$SIG{'QUIT'} = sub {
    print STDERR "\nExiting..\n";
    $RUNNING = 0;
    sleep 1;
    $SIG{'QUIT'} = sub {exit(1);};
};
$SIG{'INT'} = sub {
    print STDERR "\nExiting..\n";
    $RUNNING = 0;
    sleep 1;
    $SIG{'INT'} = sub {exit(1);};
};

our @pics;

my @f;
foreach my $fb (@fbs) {
    push(@f,Graphics::Framebuffer->new(
        'FB_DEVICE'   => $fb,
        'SPLASH'      => 0,
        'SHOW_ERRORS' => $errors,
        'FILE_MODE'   => $file
    ));
}

gather($ARGV[-1]);

# print STDERR Dumper(\@pics);exit;


foreach my $F (@f) {
    push(@thr,threads->create(
        sub {
            my $FB = shift;
            my $p  = shift;
            system('clear');
            $FB->cls('OFF');

            show($FB,$p);
            $FB->cls('ON');
        },
        $F,
        scalar(@pics)
    ));
}
while($RUNNING) {
    sleep 1;
}
$f[0]->cls('ON');
foreach my $t (@thr) {
    $t->detach();
}

exit(0);


sub gather {
    my $path = shift;
    chop($path) if ($path =~ /\/$/);
    opendir(my $DIR,$path);
    chomp(my @dir = readdir($DIR));
    closedir($DIR);
    return if (grep(/\.nopmedia/,@dir));
    foreach my $file (@dir) {
        next if ($file =~ /^\.+/);
        if (-d "$path/$file") {
            gather("$path/$file");
        } elsif (-f "$path/$file" && $file =~ /\.(jpg|jpeg|gif|tiff|bmp|png)$/i) {
            push(@pics,"$path/$file");
        }
    }
}

sub show {
    my $FB = shift;
    my $p  = shift;
    my $idx = 0;
    @pics = shuffle(@pics);
    while ($RUNNING) {
        my $name = $pics[$idx];
        print_it($FB,"Loading image $name");
        my $image;
        unless ($fullscreen) {
            $image = $FB->load_image(
                {
                    'file'       => $name,
                    'center'     => $FB->{'CENTER_XY'},
                    'autolevels' => $auto
                }
            );
        } else {
            $image = $FB->load_image(
                {
                    'width'      => $FB->{'XRES'},
                    'height'     => $FB->{'YRES'},
                    'file'       => $name,
                    'center'     => $FB->{'CENTER_XY'},
                    'autolevels' => $auto
                }
            );
        }
#        warn Dumper($image);exit;
        last unless($RUNNING);
        if (defined($image)) {
            $FB->cls();
            if (ref($image) eq 'ARRAY') {
                my $s = time + 8;
                while (time <= $s) {
                    last unless($RUNNING);
                    foreach my $frame (0 .. (scalar(@{$image}) - 1)) {
                        last unless($RUNNING);
                        my $begin = time;
                        $FB->blit_write($image->[$frame]);
                        my $delay = ($image->[$frame]->{'tags'}->{'gif_delay'} / 100) - (time - $begin);
                        sleep $delay if ($delay > 0);
                    }
                }
            } else {
                $FB->cls();
                $FB->blit_write($image);
                sleep 3;
            }
        }
        $idx++;
        $idx = 0 if ($idx >= $p);
    }
}

sub print_it {
    my $fb      = shift;
    my $message = shift;

    unless ($fb->{'XRES'} < 256) {
        $fb->xor_mode();

        my $b = $fb->ttf_print(
            {
                'x'            => 5,
                'y'            => 20,
                'height'       => 20,
                'color'        => 'FFFFFFFF',
                'text'         => $message,
                'bounding_box' => 1,
                'center'       => $fb->{'CENTER_X'},
                'antialias'    => 1
            }
        );
        $fb->ttf_print($b);
    } else {
        print "$message\n";
    }
    $fb->normal_mode();
} ## end sub print_it
