#!/usr/bin/perl -w

use strict;

use Graphics::Framebuffer;
use List::Util qw(min max shuffle);
use Time::HiRes qw(sleep time);
# use Data::Dumper::Simple; $Data::Dumper::Sortkeys=1;

system('clear');
$| = 1;

my $file = 0;
my $arg  = join(' ', @ARGV);
my $new_x;
my $new_y;
my $F;
my $dev = 0;
my $s;
my $image;
my $angle;

$file = 1 if ($arg =~ /file/i);    # File Handle drawing mode

if ($arg =~ /X(\d+)/) {
    $new_x = $1;
    $arg =~ s/X\d+//;
}
if ($arg =~ /Y(\d+)/) {
    $new_y = $1;
    $arg =~ s/Y\d+//;
}
if ($arg =~ /(\d+)/) {
    $dev = $1;
}

if (defined($new_x)) {
    $F = Graphics::Framebuffer->new('FB_DEVICE' => "/dev/fb$dev",'FILE_MODE' => $file, 'SHOW_ERRORS' => 1, 'SIMULATED_X' => $new_x,'SIMULATED_Y' => $new_y);
} else {
    $F = Graphics::Framebuffer->new('FB_DEVICE' => "/dev/fb$dev",'FILE_MODE' => $file, 'SHOW_ERRORS' => 1);
}

$SIG{'QUIT'} = sub {$F->clip_reset();$F->cls('ON'); exit(0);};
$SIG{'INT'}  = sub {$F->clip_reset();$F->cls('ON'); exit(0);};

my $screen_width  = $F->{'XRES'};
my $screen_height = $F->{'YRES'};
my $xm            = $F->{'XRES'} / 1920;
my $ym            = $F->{'YRES'} / 1080;
my $XX            = $screen_width;
my $YY            = $screen_height;
my $center_x      = $XX / 2;
my $center_y      = $YY / 2;
my $factor        = 5;
my $images_path   = (-e 'images/GFB.png') ? 'images' : 'examples/images';

$F->cls('OFF');
# if (0){

print_it($F,'Color Mapping Test -> Red-Green-Blue');
{
    $F->rbox(
        {
            'filled' => 1,
            'x'      => 0,
            'y'      => 0,
            'width'  => $XX,
            'height' => $YY,
            'gradient' => {
                'direction' => 'horizontal',
                'colors' => {
                    'red'   => [255,0,0],
                    'green' => [0,255,0],
                    'blue'  => [0,0,255]
                }
            }
        }
    );
#    sleep $factor;
    $image = $F->load_image(
        {
            'x'      => 0,
            'y'      => 0,
            'width'  => $XX * .75,
            'height' => ($YY - $F->{'Y_CLIP'}) * .75,
            'center' => 3,
            'file'   => "$images_path/testpattern.jpg"
        }
    );
    $F->blit_write($image);
    sleep $factor;
}

print_it($F, 'Plotting Test');
$s = time + $factor;
while (time < $s) {
    my $x = int(rand($screen_width));
    my $y = int(rand($screen_height));
    $F->set_color({'alpha' => 255, 'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->plot({'x' => $x, 'y' => $y});
} ## end while (time < $s)

print_it($F, 'Line Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->line({'x' => rand($XX), 'y' => rand($YY), 'xx' => rand($XX), 'yy' => rand($YY)});
} ## end for (my $l = $F->{'Y_CLIP'...})

print_it($F, 'Angle Line Test');
$s = time + $factor;
$angle = 0;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->angle_line({'x' => $center_x, 'y' => $center_y, 'radius' => ($center_y - $F->{'Y_CLIP'}), 'angle' => $angle});
    $angle += 1.1;
    $angle -= 360 if ($angle >= 360);
} ## end for (my $l = $F->{'Y_CLIP'...})

print_it($F, 'Box Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->box({'x' => rand($XX), 'y' => rand($YY), 'xx' => rand($XX), 'yy' => rand($YY)});
}

print_it($F, 'Filled Box Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->box({'x' => rand($XX), 'y' => rand($YY), 'xx' => rand($XX), 'yy' => rand($YY), 'filled' => 1});
}

print_it($F, 'Vertical Gradient Box Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->box(
        {
            'x'        => rand($XX),
              'y'        => rand($YY),
              'xx'       => rand($XX),
              'yy'       => rand($YY),
              'filled'   => 1,
              'gradient' => {
                  'colors' => {
                      'red' => [rand(256),rand(256),rand(256)],
                      'green' => [rand(256),rand(256),rand(256)],
                      'blue' => [rand(256),rand(256),rand(256)],
                  }
              }
        }
    );
} ## end while (time < $s)
print_it($F, 'Horizontal Gradient Box Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->box(
        {
            'x'        => rand($XX),
              'y'        => rand($YY),
              'xx'       => rand($XX),
              'yy'       => rand($YY),
              'filled'   => 1,
              'gradient' => {
                  'direction' => 'horizontal',
                  'colors' => {
                      'red' => [rand(256),rand(256),rand(256)],
                      'green' => [rand(256),rand(256),rand(256)],
                      'blue' => [rand(256),rand(256),rand(256)],
                  }
              }
        }
    );
} ## end while (time < $s)

print_it($F, 'Rounded Box Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->box({'x' => rand($XX), 'y' => rand($YY), 'xx' => rand($XX), 'yy' => rand($YY), 'radius' => rand($XX / 16)});
}

print_it($F, 'Filled Rounded Box Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->box({'x' => rand($XX), 'y' => rand($YY), 'xx' => rand($XX), 'yy' => rand($YY), 'radius' => rand($XX / 16), 'filled' => 1});
}

print_it($F, 'Vertical Gradient Rounded Box Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->box(
        {
            'x'        => rand($XX),
              'y'        => rand($YY),
              'xx'       => rand($XX),
              'yy'       => rand($YY),
              'radius'   => rand($XX / 16),
              'filled'   => 1,
              'gradient' => {
                  'colors' => {
                      'red' => [rand(256),rand(256),rand(256)],
                      'green' => [rand(256),rand(256),rand(256)],
                      'blue' => [rand(256),rand(256),rand(256)],
                  }
              }
        }
    );
} ## end while (time < $s)

print_it($F, 'Horizontal Gradient Rounded Box Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->box(
        {
            'x'        => rand($XX),
            'y'        => rand($YY),
            'xx'       => rand($XX),
            'yy'       => rand($YY),
            'radius'   => rand($XX / 16),
            'filled'   => 1,
            'gradient' => {
                'direction' => 'horizontal',
                'colors' => {
                    'red' => [rand(256),rand(256),rand(256)],
                    'green' => [rand(256),rand(256),rand(256)],
                    'blue' => [rand(256),rand(256),rand(256)],
                }
            }
        }
    );
} ## end while (time < $s)

print_it($F, 'Circle Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->circle({'x' => rand($XX), 'y' => rand($YY), 'radius' => rand($center_y)});
}

print_it($F, 'Filled Circle Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->circle({'x' => rand($XX), 'y' => rand($YY), 'radius' => rand($center_y), 'filled' => 1});
}

print_it($F, 'Vertical Gradient Circle Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->circle(
        {
            'x'        => rand($XX),
            'y'        => rand($YY),
            'radius'   => rand($center_y),
            'filled'   => 1,
            'gradient' => {
                'colors' => {
                    'red' => [rand(256),rand(256),rand(256)],
                    'green' => [rand(256),rand(256),rand(256)],
                    'blue' => [rand(256),rand(256),rand(256)],
                }
            }
        }
    );
} ## end while (time < $s)

print_it($F, 'Horizontal Gradient Circle Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->circle(
        {
            'x'        => rand($XX),
            'y'        => rand($YY),
            'radius'   => rand($center_y),
            'filled'   => 1,
            'gradient' => {
                'direction' => 'horizontal',
                'colors' => {
                    'red' => [rand(256),rand(256),rand(256)],
                    'green' => [rand(256),rand(256),rand(256)],
                    'blue' => [rand(256),rand(256),rand(256)],
                }
            }
        }
    );
} ## end while (time < $s)

print_it($F, 'Arc Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->arc({'x' => rand($XX), 'y' => rand($YY), 'radius' => rand($center_y), 'start_degrees' => rand(360), 'end_degrees' => rand(360)});
}

print_it($F, 'Poly Arc Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->poly_arc({'x' => rand($XX), 'y' => rand($YY), 'radius' => rand($center_y), 'start_degrees' => rand(360), 'end_degrees' => rand(360)});
}

print_it($F, 'Filled Pie Test');
$s = time + ($factor * 2);
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->filled_pie({'x' => rand($XX), 'y' => rand($YY), 'radius' => rand($center_y), 'start_degrees' => rand(360), 'end_degrees' => rand(360)});
}

print_it($F, 'Vertical Gradient Filled Pie Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->filled_pie(
        {
            'x'             => rand($XX),
            'y'             => rand($YY),
            'radius'        => rand($center_y),
            'start_degrees' => rand(360),
            'end_degrees'   => rand(360),
            'gradient'      => {
                'colors' => {
                    'red' => [rand(256),rand(256),rand(256)],
                    'green' => [rand(256),rand(256),rand(256)],
                    'blue' => [rand(256),rand(256),rand(256)],
                }
            }
        }
    );
} ## end while (time < $s)

print_it($F, 'Ellipse Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->ellipse({'x' => rand($XX), 'y' => rand($YY), 'xradius' => rand($center_x), 'yradius' => rand($center_y)});
}

print_it($F, 'Filled Ellipse Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->ellipse({'x' => rand($XX), 'y' => rand($YY), 'xradius' => rand($center_x), 'yradius' => rand($center_y), 'filled' => 1});
}

print_it($F, 'Vertical Gradient Ellipse Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->ellipse(
        {
            'x'        => rand($XX),
            'y'        => rand($YY),
            'xradius'  => rand($center_x),
            'yradius'  => rand($center_y),
            'filled'   => 1,
            'gradient' => {
                'colors' => {
                    'red' => [rand(256),rand(256),rand(256)],
                    'green' => [rand(256),rand(256),rand(256)],
                    'blue' => [rand(256),rand(256),rand(256)],
                }
            }
        }
    );
} ## end while (time < $s)

print_it($F, 'Horizontal Gradient Ellipse Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->ellipse(
        {
            'x'        => rand($XX),
            'y'        => rand($YY),
            'xradius'  => rand($center_x),
            'yradius'  => rand($center_y),
            'filled'   => 1,
            'gradient' => {
                'direction' => 'horizontal',
                'colors' => {
                    'red' => [rand(256),rand(256),rand(256)],
                    'green' => [rand(256),rand(256),rand(256)],
                    'blue' => [rand(256),rand(256),rand(256)],
                }
            }
        }
    );
} ## end while (time < $s)

print_it($F, 'Polygon Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->polygon({'coordinates' => [rand($XX), rand($YY), rand($XX), rand($YY), rand($XX), rand($YY), rand($XX), rand($YY)]});
}

print_it($F, 'Filled Polygon Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->polygon({'coordinates' => [rand($XX), rand($YY), rand($XX), rand($YY), rand($XX), rand($YY), rand($XX), rand($YY)], 'filled' => 1});
}

print_it($F, 'Vertical Gradient Polygon Test');
$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->polygon(
        {
            'coordinates' => [rand($XX), rand($YY), rand($XX), rand($YY), rand($XX), rand($YY), rand($XX), rand($YY)],
            'filled'      => 1,
            'gradient'    => {
                'colors' => {
                    'red' => [rand(256),rand(256),rand(256)],
                    'green' => [rand(256),rand(256),rand(256)],
                    'blue' => [rand(256),rand(256),rand(256)],
                }
            }
        }
    );
} ## end while (time < $s)

print_it($F, 'Testing Bezier Curves');

$s = time + $factor;
while (time < $s) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    my @coords = ();
    foreach my $c (1 .. int(rand(20))) {
        push(@coords, int(rand($XX)), int(rand($YY)));
    }
    $F->bezier({'coordinates' => \@coords, 'points' => 100});
} ## end while (time < $s)

{
    print_it($F, 'Testing TrueType Font Rendering (random height/width)');

    my $g = time + $factor;
    while (time < $g) {
        my $x  = int(rand(600 * $xm));
        my $y  = int(rand(900 * $ym));
        my $h  = ($YY < 128) ? (6 + rand(60)) : (8 + int(rand(300 * $ym)));
        my $ws = ($XX < 256) ? rand(2) : rand(4);

        my $b = $F->ttf_print(
            {
                'x'            => $x,
                'y'            => $y,
                'height'       => $h,
                'wscale'       => $ws,
                'color'        => sprintf('%02x%02x%02x%02x', int(rand(256)), int(rand(256)), int(rand(256)),255),
                'text'         => 'GFB',
                'bounding_box' => 1,
                'center'       => 3
            }
        );
        if (defined($b)) {
            $b->{'x'} = rand($F->{'XX_CLIP'} - $b->{'pwidth'});
            $F->ttf_print($b);
        }
    } ## end while (time < $g)
}

print_it($F, 'Testing flood fill');
if ($XX > 255) {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->polygon({'coordinates' => [220 * $xm, 190 * $ym, 1520 * $xm, 80 * $xm, 1160 * $xm, $YY, 960 * $xm, 540 * $ym, 760 * $xm, 780 * $ym]});
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->polygon({'coordinates' => [1270 * $xm, 570 * $ym, 970 * $xm, 170 * $ym, 600 * $xm, 500 * $ym]});
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->circle({'x' => 500 * $xm, 'y' => 320 * $ym, 'radius' => 100 * $xm});

    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->fill({'x' => 240 * $xm, 'y' => 200 * $ym});

    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->fill({'x' => 960 * $xm, 'y' => 440 * $ym});
} else {
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->polygon({'coordinates' => [$center_x, 3, 3, $YY - 3, $center_x, $center_y, $XX - 3, $YY - 4]});
    $F->set_color({'red' => rand(256), 'green' => rand(256), 'blue' => rand(256)});
    $F->fill({'x' => 3, 'y' => 3});
} ## end else [ if ($XX > 255) ]

print_it($F, 'Testing Color Replace (clipping on)');

my $x = $F->{'XRES'} / 4;
my $y = $F->{'YRES'} / 4;
$F->splash();
$F->clip_set({'x' => $x, 'y' => $y, 'xx' => $x * 3, 'yy' => $y * 3});
my $r = 128;
my $g = 0;
my $b = 0;
$s = time + $factor;
while (time < $s) {
    my $R = int(rand(256));
    my $G = int(rand(256));
    my $B = int(rand(256));
    $F->replace_color(
        {
            'old_red'   => $r,
            'old_green' => $g,
            'old_blue'  => $b,
            'new_red'   => $R,
            'new_green' => $G,
            'new_blue'  => $B
        }
    );
    ($r, $g, $b) = ($R, $G, $B);
} ## end while (time < $s)

print_it($F, 'Testing Color Replace (clipping off)');

$F->splash();

$F->clip_reset();

$r = 128;
$g = 0;
$b = 0;
$s = time + $factor;
while (time < $s) {
    my $R = int(rand(256));
    my $G = int(rand(256));
    my $B = int(rand(256));
    $F->replace_color(
        {
            'old_red'   => $r,
            'old_green' => $g,
            'old_blue'  => $b,
            'new_red'   => $R,
            'new_green' => $G,
            'new_blue'  => $B
        }
    );
    ($r, $g, $b) = ($R, $G, $B);
} ## end while (time < $s)

print_it($F, 'Testing Image load (different sizes)');

{
    my $blank;
    $s = time + $factor;
    while (time < $s) {
        my $image = $F->load_image(
            {
                'x'      => 0,
                'y'      => 0,
                'width'  => rand($XX),
                'height' => rand($YY - $F->{'Y_CLIP'}),
                'center' => 3,
                'file'   => "$images_path/GFB.png"
            }
        );
        if (defined($blank)) {
            $F->xor_mode();
            $F->blit_write($blank);
            $F->normal_mode();
        }
        $F->blit_write($image);
        %{$blank} = %{$image};
    } ## end while (time < $s)
    my $image = $F->load_image(
        {
            'x'      => 0,
            'y'      => 0,
            'width'  => $XX,
            'height' => ($YY - $F->{'Y_CLIP'}),
            'center' => 3,
            'file'   => "$images_path/GFB.png"
        }
    );
    if (defined($blank)) {
        $F->xor_mode();
        $F->blit_write($blank);
        $F->normal_mode();
    }
    $F->blit_write($image);
    sleep $factor;
}

print_it($F, 'Testing Image blitting');

$image = $F->load_image(
    {
        'x'      => 0,
        'y'      => 0,
        'width'  => int($XX/3),
        'height' => int($YY/3),
        'file'   => "$images_path/RWBY_Logo.png"
    }
);
$s = time + $factor;
while (time < $s) {
    $image->{'x'} = abs(rand($XX - $image->{'width'}));
    $image->{'y'} = $F->{'Y_CLIP'} + abs(rand(($YY - $F->{'Y_CLIP'}) - $image->{'height'}));
    $F->blit_write($image);
}

print_it($F, 'Loading "RWBY_Oh_No.jpg" for Rotate Test','FFFF00FF');
if ($YY<=240) {
    $image = $F->load_image(
        {
            'x'      => 0,
            'y'      => 0,
            'width'  => int($YY*.7),
#            'height' => int($YY/3),
            'file'   => "$images_path/RWBY_Oh_No.jpg"
        }
    );
} else {
    $image = $F->load_image(
        {
            'x'      => 0,
            'y'      => 0,
            'width'  => int($XX * .4),
            'height' => int($YY * .4),
            'file'   => "$images_path/RWBY_Oh_No.jpg"
        }
    );
}
$angle = 0;
{
    print_it($F, 'Counter-Clockwise Rotate Test');
    $s = time + ($factor * 2);
    my $count = 0;
    while (time < $s || $count < 6) {
        my $rot = $F->blit_transform(
            {
                'rotate' => {
                    'degrees' => $angle
                },
                'blit_data' => $image
            }
        );
        $rot->{'x'} = abs(($XX - $rot->{'width'})  / 2);
        $rot->{'y'} = $F->{'Y_CLIP'} + abs((($YY - $F->{'Y_CLIP'}) - $rot->{'height'}) / 2);

        $F->blit_write($rot);

        $angle += 5;
        $angle = 0 if ($angle >= 360);
        $count++;
    }
}
$angle = 0;
{
    print_it($F, 'Clockwise Rotate Test');
    $s = time + ($factor * 2);
    my $count = 0;
    while (time < $s || $count < 6) {
        my $rot = $F->blit_transform(
            {
                'rotate' => {
                    'degrees' => $angle
                },
                'blit_data' => $image
            }
        );
        $rot->{'x'} = abs(($XX - $rot->{'width'})  / 2);
        $rot->{'y'} = $F->{'Y_CLIP'} + abs((($YY - $F->{'Y_CLIP'}) - $rot->{'height'}) / 2);

        $F->blit_write($rot);

        $angle -= 5;
        $angle = 0 if ($angle <= -360);
        $count++;
    }
}

print_it($F, 'Loading "RWBY_Faces.png" For Image Flip Tests','FFFF00FF');

$image = $F->load_image(
    {
        'x'      => 0,
        'y'      => $F->{'Y_CLIP'},
        'width'  => $XX,
        'height' => ($YY - $F->{'Y_CLIP'}),
       'file'   => "$images_path/RWBY_Faces.png"
    }
);
$s = time + $factor;
$angle = 0; # Just re-using this variable
while (time < $s) {
    foreach my $dir (qw(normal horizontal vertical both)) {
        my $rot = $F->blit_transform(
            {
                'flip'      => $dir,
                'blit_data' => $image
            }
        );
        $rot->{'x'} = abs(($XX - $rot->{'width'})  / 2);
        $rot->{'y'} = abs((($YY - $F->{'Y_CLIP'}) - $rot->{'height'}) / 2);
        print_it($F, "Testing Image Flip $dir");
        $F->blit_write($rot);
        sleep .3;
    }
}
# sleep $factor;

print_it($F, 'Testing Monochrome Image blitting');

$image = $F->blit_transform(
    {
        'scale' => {
            'width'  => int($XX * .6),
            'height' => int($YY * .6)
        },
        'blit_data' => $image
    }
);
$image->{'image'} = $F->monochrome({'image' => $image->{'image'}, 'bits' => $F->{'BITS'}});
$s = time + $factor;
while (time < $s) {
    $image->{'x'} = abs(rand($XX - $image->{'width'}));
    $image->{'y'} = $F->{'Y_CLIP'} + abs(rand(($YY - $F->{'Y_CLIP'}) - $image->{'height'}));
    $F->blit_write($image);
}

{
    print_it($F,'Testing Animated Images.  Loading...','FFFF00FF');
    opendir(my $DIR,$images_path);
    chomp(my @list = readdir($DIR));
    closedir($DIR);
    @list = shuffle(@list);
    foreach my $info (@list) {
        next unless ($info =~ /\.gif$/i);
        for $angle (0 .. 1) {
            if ($angle || $XX <= 320) {
                print_it($F, "Loading Animated Image '$info' Scaled to Full Screen",'FFFF00FF');
                $image = $F->load_image(
                    {
                        'width'  => $XX,
                        'height' => $YY - $F->{'Y_CLIP'},
                        'file'   => "$images_path/$info",
                        'center' => 3
                    }
                );
            } else {
                print_it($F, "Loading Animated Image '$info' Native Size",'FFFF00FF');
                $image = $F->load_image(
                    {
                        'file'   => "$images_path/$info",
                        'center' => 3
                    }
                );
            }
            foreach my $bench (0 .. 1) {
                if ($angle || $XX <= 320) {
                    print_it($F, $bench ? "Testing Animated Image Display of '$info' Fullscreen Benchmark" : "Testing Animated Image Display of '$info' Fullscreen");
                } else {
                    print_it($F, $bench ? "Testing Animated Image Display of '$info' Native Size Benchmark" : "Testing Animated Image Display of '$info' Native Size");
                }
                if (defined($image)) {
                    $F->cls();
                    my $fps   = 0;
                    my $start = time;
                    $s = time + ($factor);
                    while (time <= $s) {
                        foreach my $frame (0 .. (scalar(@{$image}) - 1)) {
                            if (time > $s * 2) {
                                print_it($F, 'Your System is Too Slow To Complete The Animation','FF9999FF');
                                sleep 2;
                                last;
                            }
                            my $begin = time;
                            $F->blit_write($image->[$frame]);
                            my $delay = (($image->[$frame]->{'tags'}->{'gif_delay'} * .01)) - (time - $begin);
                            if ($delay > 0 && !$bench) {
                                sleep $delay;
                            }
                            $fps++;
                            my $end = time - $start;
                            if ($end >= 1 && $bench) {
                                print STDERR "\r",sprintf('%.02f FPS',(1 / $end) * $fps);$|=1;
                                $fps = 0;
                                $start = time;
                            }
                        }
                    }
                }
            }
            last if ($XX <= 320);
        }
    }
}

{
    print_it($F, 'Testing OR Drawing Mode');

    $F->or_mode();
    my $size = int(($YY - $F->{'Y_CLIP'}) / 3);
    my $mid  = int($XX / 2);

    $F->set_color({'red' => 255, 'green' => 0, 'blue' => 0});
    $F->circle({'x' => $mid - ($size / 2),'y'=> $F->{'Y_CLIP'} + $size*2,'radius' => $size, 'filled' => 1});
    sleep .1;
    $F->set_color({'red' => 0, 'green' => 255, 'blue' => 0});
    $F->circle({'x' => $mid,'y'=> $F->{'Y_CLIP'} + $size,'radius' => $size, 'filled' => 1});
    sleep .1;
    $F->set_color({'red' => 0, 'green' => 0, 'blue' => 255});
    $F->circle({'x' => $mid + ($size / 2),'y'=> $F->{'Y_CLIP'} + $size * 2,'radius' => $size, 'filled' => 1});
    sleep $factor;
}

{
    print_it($F, 'Testing XOR Drawing Mode');

    $F->xor_mode();

    $F->set_color({'red' => 0, 'green' => 255, 'blue' => 255});
    $F->rbox({'x' => 0,'y' => 0, 'width'=> ($XX / 2),'height' => ($YY / 2),'filled' => 1});
    sleep .1;
    $F->set_color({'red' => 255, 'green' => 0, 'blue' => 255});
    $F->rbox({'x' => $XX / 4,'y' => $YY / 4, 'width'=> ($XX / 2),'height' => ($YY / 2),'filled' => 1});
    sleep .1;
    $F->set_color({'red' => 255, 'green' => 255, 'blue' => 0});
    $F->rbox({'x' => ($XX / 2),'y' => ($YY / 2), 'width'=> ($XX / 2),'height' => ($YY / 2),'filled' => 1});
    sleep $factor;
}

{
    print_it($F, 'Testing AND Drawing Mode');

    $F->set_color({'red' => 255, 'green' => 255, 'blue' => 255});
    $F->box({'x' => 0, 'y' => $F->{'Y_CLIP'}, 'xx' => $XX,'yy' => $YY, 'filled' => 1});
    $F->and_mode();
    my $size = int(($YY - $F->{'Y_CLIP'}) / 3);
    my $mid  = int($XX / 2);

    sleep .1;
    $F->set_color({'red' => 255, 'green' => 0, 'blue' => 0});
    $F->circle({'x' => $mid - ($size / 2),'y'=> $F->{'Y_CLIP'} + $size*2,'radius' => $size, 'filled' => 1});
    sleep .1;
    $F->set_color({'red' => 0, 'green' => 255, 'blue' => 0});
    $F->circle({'x' => $mid,'y'=> $F->{'Y_CLIP'} + $size,'radius' => $size, 'filled' => 1});
    sleep .1;
    $F->set_color({'red' => 0, 'green' => 0, 'blue' => 255});
    $F->circle({'x' => $mid + ($size / 2),'y'=> $F->{'Y_CLIP'} + $size * 2,'radius' => $size, 'filled' => 1});
    sleep $factor;
}

{
    print_it($F, 'Testing MASK Drawing Mode (This is SLOOOOW)');
    my $h = int($YY - $F->{'Y_CLIP'});
    my $image1 = $F->load_image(
        {
            'x'      => 0,
            'y'      => $F->{'Y_CLIP'},
            'width'  => ($XX<=320) ? $XX : $XX/2,
            'height' => ($XX<=320) ? $h : $h/2,
            'file'   => "$images_path/GFB.png",
            'center' => 3
        }
    );
    my $image2 = $F->load_image(
        {
            'x'      => 0,
            'y'      => $F->{'Y_CLIP'},
            'width'  => ($XX<=320) ? $XX : $XX/2,
            'height' => ($XX<=320) ? $h : $h/2,
            'file'   => "$images_path/RWBY_beuowolf.jpg",
            'center' => 3,
            'convertalpha' => 1
        }
    );
    $F->blit_write($image1);
    $F->mask_mode();
    $F->blit_write($image2);
    sleep $factor;

    if ($F->{'BITS'} > 16) {
        print_it($F,'Simulating MASK Mode with the much quicker "blit_transform" and "merge"');
        $F->blit_write($image1);
        $F->blit_write(
            $F->blit_transform(
                {
                    'blit_data' => $image2,
                    'merge'     => {
                        'dest_blit_data'=> $F->blit_read($image2)
                    }
                }
            )
        );
        sleep $factor;
    }
}

{
    print_it($F, 'Testing UNMASK Drawing Mode (This is SLOOOW)');
    my $h = int($YY - $F->{'Y_CLIP'});
    my $image1 = $F->load_image(
        {
            'x'      => 0,
            'y'      => $F->{'Y_CLIP'},
            'width'  => ($XX<=320) ? $XX : $XX/2,
            'height' => ($XX<=320) ? $h : $h/2,
            'file'   => "$images_path/RWBY_beuowolf.jpg",
            'center' => 3,
            'convertalpha' => 1
        }
    );
    my $image2 = $F->load_image(
        {
            'x'      => 0,
            'y'      => $F->{'Y_CLIP'},
            'width'  => ($XX<=320) ? $XX : $XX/2,
            'height' => ($XX<=320) ? $h : $h/2,
            'file'   => "$images_path/RWBY_Alternate_Logo.png",
            'center' => 3
        }
    );
    $F->blit_write($image1);
    $F->unmask_mode();
    $F->blit_write($image2);
    sleep $factor;
    if ($F->{'BITS'} > 16) {
        print_it($F,'Simulating UNMASK Mode with the much quicker "blit_transform" and "merge"');
        $F->blit_write($image2);
        $F->blit_write(
            $F->blit_transform(
                {
                    'blit_data' => $image1,
                    'merge'     => {
                        'dest_blit_data'=> $F->blit_read($image1)
                    }
                }
            )
        );
        sleep $factor;
    }
}

$F->clip_reset();
$F->cls('ON');

exit(0);

sub print_it {
    my $fb      = shift;
    my $message = shift;
    my $color   = shift || '00FF00FF';

    $fb->normal_mode();
    $fb->clip_reset();
    $fb->cls();
    unless ($XX <= 320) {
        $fb->or_mode();

        my $b = $fb->ttf_print(
            {
                'x'            => 5 * $xm,
                'y'            => max(9, 15 * $ym),
                'height'       => max(9, 20 * $ym),
                'color'        => $color,
                'text'         => $message,
                'bounding_box' => 1,
                'center'       => $fb->{'CENTER_X'},
                'antialias'    => 1
            }
        );
        $fb->ttf_print($b);
        $fb->clip_set({'x' => 0, 'y' => $b->{'pheight'} * .75, 'xx' => $XX, 'yy' => $YY});
        $center_y = (($YY - $b->{'pheight'}) / 2) + $b->{'pheight'};
        $fb->normal_mode();
    } else {
        system('clear');
        print STDERR "$message\n";
    }
} ## end sub print_it

__END__

