#!/usr/bin/perl -w

use strict;

use Graphics::Framebuffer;

$| = 1;

my $mali = 0;
my $file = 0;
my $arg = join('',@ARGV);

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

my $F = Graphics::Framebuffer->new('MALI' => $mali, 'FB_DEVICE' => '/dev/fb0','FILE_MODE' => $file,'SHOW_ERRORS' => 0,'LINE_PADDING'=> 0);

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

my $screen_width  = $F->{'XRES'};
my $screen_height = $F->{'YRES'};
my $XX            = $screen_width;
my $YY            = $screen_height;
my $center_x      = int($screen_width / 2);
my $center_y      = int($screen_height / 2);
my $wait          = 2;
my $factor        = $F->{'BITS'} / 16;

$F->normal_mode();
$F->cls('OFF');

print_it($F,'Plotting Test');
foreach my $p (1..2000) {
    $F->set_color({'red' => rand(256),'green' => rand(256),'blue' => rand(256)});
    $F->plot({'x' => rand($screen_width),'y' => rand($screen_height)});
}
sleep $wait;

print_it($F,'Line Test');
for(my $l=40;$l < $YY;$l += 40) {
    $F->set_color({'red' => rand(256),'green' => rand(256),'blue' => rand(256)});
    $F->line({'x' => 0,'y' => $l,'xx' =>$XX, 'yy' => $l});
    $F->set_color({'red' => rand(256),'green' => rand(256),'blue' => rand(256)});
    $F->line({'x' => 0,'y' => $l,'xx' =>$l, 'yy' => 40});
    $F->set_color({'red' => rand(256),'green' => rand(256),'blue' => rand(256)});
    $F->line({'x' => $XX,'y' => $l,'xx' =>$XX - $l, 'yy' => 40});

    $F->set_color({'red' => rand(256),'green' => rand(256),'blue' => rand(256)});
    $F->line({'x' => $XX,'y' => $YY - $l,'xx' =>$XX - $l, 'yy' => 40});
}
for(my $l=0;$l < $XX;$l += 40) {
    $F->set_color({'red' => rand(256),'green' => rand(256),'blue' => rand(256)});
    $F->line({'x' => $l,'y' => 40,'xx' =>$l, 'yy' => $YY});
}
sleep $wait;

print_it($F,'Box Test');
foreach my $p (1..(50 * $factor)) {
    $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)});
}
sleep $wait;

print_it($F,'Filled Box Test');
foreach my $p (1..(38 * $factor)) {
    $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});
}
sleep $wait;

print_it($F,'Gradient Box Test');
foreach my $p (1..(25 * $factor)) {
    $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' => {
                    'start' => {
                        'red'   => rand(256),
                        'green' => rand(256),
                        'blue'  => rand(256)
                    },
                    'end' => {
                        'red'   => rand(256),
                        'green' => rand(256),
                        'blue'  => rand(256)
                    }
                }
            }
    );
}
sleep $wait;


print_it($F,'Rounded Box Test');
foreach my $p (1..(50 * $factor)) {
    $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(20)+3});
}
sleep $wait;

print_it($F,'Filled Rounded Box Test');
foreach my $p (1..(50 * $factor)) {
    $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(80)+3,'filled' => 1});
}
sleep $wait;

print_it($F,'Gradient Rounded Box Test');
foreach my $p (1..(50 * $factor)) {
    $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(80)+3,'filled' => 1,
                'gradient' => {
                    'start' => {
                        'red'   => rand(256),
                        'green' => rand(256),
                        'blue'  => rand(256)
                    },
                    'end' => {
                        'red'   => rand(256),
                        'green' => rand(256),
                        'blue'  => rand(256)
                    }
                }
                    }
    );
}
sleep $wait;

print_it($F,'Circle Test');
foreach my $p (1..(50 * $factor)) {
    $F->set_color({'red' => rand(256),'green' => rand(256),'blue' => rand(256)});
    $F->circle({'x' => rand($XX),'y' => rand($YY),'radius' => rand($center_y)});
}
sleep $wait;

print_it($F,'Filled Circle Test');
foreach my $p (1..(25 * $factor)) {
    $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});
}
sleep $wait;

print_it($F,'Gradient Circle Test');
foreach my $p (1..(25 * $factor)) {
    $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' => {
                       'start' => {
                           'red'   => rand(256),
                           'green' => rand(256),
                           'blue'  => rand(256)
                       },
                       'end' => {
                           'red'   => rand(256),
                           'green' => rand(256),
                           'blue'  => rand(256)
                       }
                   }
               }
    );
}
sleep $wait;

print_it($F,'Ellipse Test');
foreach my $p (1..(50 * $factor)) {
    $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)});
}
sleep $wait;

print_it($F,'Filled Ellipse Test');
foreach my $p (1..(25 * $factor)) {
    $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});
}
sleep $wait;

print_it($F,'Gradient Ellipse Test');
foreach my $p (1..(25 * $factor)) {
    $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' => {
                       'start' => {
                           'red'   => rand(256),
                           'green' => rand(256),
                           'blue'  => rand(256)
                       },
                       'end' => {
                           'red'   => rand(256),
                           'green' => rand(256),
                           'blue'  => rand(256)
                       }
                   }
               }
    );
}
sleep $wait;

print_it($F,'Polygon Test');
foreach my $p (1..(25 * $factor)) {
    $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)]});
}
sleep $wait;

print_it($F,'Filled Polygon Test');
foreach my $p (1..(20 * $factor)) {
    $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});
}
sleep $wait;

print_it($F,'Gradient Polygon Test');
foreach my $p (1..(20 * $factor)) {
    $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' => {
                        'start' => {
                            'red'   => rand(256),
                           'green' => rand(256),
                            'blue'  => rand(256)
                        },
                        'end' => {
                            'red'   => rand(256),
                            'green' => rand(256),
                            'blue'  => rand(256)
                        }
                    }
                }
    );
}
sleep $wait;

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

foreach my $z (1..(50 * $factor)) {
    $F->set_color({'red' => rand(256),'green' => rand(256),'blue' => rand(256)});
    my @coords = ();
    foreach my $r (1..int(rand(20))) {
        push(@coords,int(rand($XX)),int(rand($YY)));
    }
    $F->bezier({'coordinates' => \@coords, 'points' => 100});
}
sleep $wait;

print_it($F,'Testing TrueType Font Rendering');

for(my $c = 8;$c < 600;$c += (20 * $factor)) {
    my $x  = int(rand(600));
    my $y  = int(rand(900));
    my $h  = int(rand(300)) + 8;
    my $ws = rand(4);

    my $b  = $F->ttf_print(
        {
            'x'            => $x,
            'y'            => $y,
            'height'       => $c,
            'wsize'        => $ws,
            'color'        => sprintf('%x%x%x%x', int(rand(256)), int(rand(256)), int(rand(256)), 255 ),
            'text'         => 'GFB',
            'bounding_box' => 1,
            'center'       => 3
        }
    );
    last unless (defined($b));
    $b->{'x'} = rand($F->{'XX_CLIP'} - $b->{'pwidth'});
    $F->ttf_print($b);
}
sleep $wait;

print_it($F,'Testing flood fill');
$F->set_color({'red' => rand(256),'green' => rand(256),'blue' => rand(256)});
$F->polygon({'coordinates' => [220,190,$XX - 400,90,$center_x + 200,$YY,$center_x,$center_y,$center_x - 200,$YY]});
$F->set_color({'red' => rand(256),'green' => rand(256),'blue' => rand(256)});
$F->polygon({'coordinates' => [$center_x + 310,$center_y + 30, $center_x + 10,180, 600,500]});
$F->set_color({'red' => rand(256),'green' => rand(256),'blue' => rand(256)});
$F->circle({'x' => 500,'y' => 320, 'radius' => 100,'pixel_size' => 3});

$F->set_color({'red' => rand(256),'green' => rand(256),'blue' => rand(256)});
$F->fill({'x' => $center_x+100, 'y' => $center_y + 100});
$F->set_color({'red' => rand(256),'green' => rand(256),'blue' => rand(256)});
$F->fill({'x' => $center_x, 'y' => $center_y - 100});

sleep $wait;

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

$F->clip_set({'x' => 100,'y' => 100,'xx' => $F->{'XRES'} - 100,'yy' => $F->{'YRES'} - 100});

$F->splash();

$F->replace_color(
    {
        'old_red'   => 128,
        'old_green' => 0,
        'old_blue'  => 0,
        'new_red'   => 0,
        'new_green' => 255,
        'new_blue'  => 255
    }
);

sleep $wait;

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

$F->splash();

$F->clip_reset();

my $r = 128;
my $g = 0;
my $b = 0;
foreach my $re (1..(5 * $factor)) {
    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);
}

sleep $wait;

$F->cls('ON');

exit(0);

sub print_it {
    my $fb      = shift;
    my $message = shift;
    $fb->clip_reset();
    $fb->cls();

    my $b = $fb->ttf_print(
        {
            'x'            => 5,
            'y'            => 30,
            'height'       => 30,
            'color'        => '00FF00',
            'text'         => $message,
            'bounding_box' => 1,
            'center'       => 0
        }
    );
    if (defined($b)) {
        $fb->ttf_print($b);
    } else {
        system('clear');
        print "$message\n";
    }
    $fb->clip_set({'x' => 0, 'y' => $b->{'pheight'},'xx' => $XX,'yy' => $YY});
}

__END__

