#!/usr/bin/env perl

use strict;

use Time::HiRes qw(time);
use Graphics::Framebuffer;
use List::Util qw(max);

$SIG{'QUIT'} = sub { exec('reset'); };
$SIG{'INT'}  = sub { exec('reset'); };

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

my $dev = 0;
if ($args =~ /(\d+)/) {
    $dev = $1;
}

my $f = Graphics::Framebuffer->new('FILE_MODE' => 0, 'FB_DEVICE' => "/dev/fb$dev");

my $fm = Graphics::Framebuffer->new('FILE_MODE' => 1, 'FB_DEVICE' => "/dev/fb$dev", 'SPLASH' => 0);

$f->cls('OFF');
my @t;
my $x     = $f->{'XRES'} / 2;
my $y     = $f->{'YRES'} / 2;
my $start = time;

$f->set_color({'red' => 255, 'green' => 0, 'blue' => 0});
my $step = max(1,$f->{'YRES'}/50);
for (my $radius = 10 ; $radius < $y ; $radius += $step) {
    $f->circle({'x' => $x, 'y' => $y, 'radius' => $radius, 'filled' => 1});
}

push(@t, time - $start);

$start = time;

$fm->set_color({'red' => 0, 'green' => 0, 'blue' => 255});
for (my $radius = 10 ; $radius < $y ; $radius += $step) {
    $fm->circle({'x' => $x, 'y' => $y, 'radius' => $radius, 'filled' => 1});
}

push(@t, sprintf('%.02f', time - $start));

$f->set_color({'red' => 255, 'green' => 255, 'blue' => 0});
$start = time;
for (my $xx = $y ; $xx >= 0 ; $xx-=$step) {
    $f->box({'x' => $xx, 'y' => $xx, 'xx' => $f->{'XRES'} - $xx, 'yy' => $f->{'YRES'} - $xx, 'filled' => 1});
}

push(@t, time - $start);

$fm->set_color({'red' => 0, 'green' => 255, 'blue' => 255});
$start = time;

for (my $xx = $y ; $xx >= 0 ; $xx-=$step) {
    $fm->box({'x' => $xx, 'y' => $xx, 'xx' => $fm->{'XRES'} - $xx, 'yy' => $fm->{'YRES'} - $xx, 'filled' => 1});
}

push(@t, time - $start);

$start = time;
$f->set_color({'red' => 0, 'green' => 255, 'blue' => 0});
$step = max(1,$f->{'XRES'}/25);

for (my $xx=0; $xx < $f->{'XRES'}; $xx += $step) {
    $f->line({'x' => $xx, 'y' => 0, 'xx' => $xx, 'yy' => $f->{'YRES'}});
}
push(@t, time - $start);

$start = time;
$fm->set_color({'red' => 255, 'green' => 0, 'blue' => 255});

for (my $xx=0; $xx < $fm->{'XRES'}; $xx += $step) {
    $fm->line({'x' => $xx, 'y' => 0, 'xx' => $xx, 'yy' => $f->{'YRES'},'filled' => 1});
}
push(@t, time - $start);
$f->cls('ON');
my @names = ('CIRCLE','CIRCLE','   BOX','   BOX','  LINE','  LINE');

my $file_average   = 0;
my $string_average = 0;
for (my $idx=0;$idx<6;$idx+=2) {
    if ($t[$idx] < $t[$idx+1]) {
        print STDERR sprintf('%s MMAP:  %.03f (fastest)',$names[$idx],$t[$idx]),"\n";
        print STDERR sprintf('%s FILE:  %.03f',$names[$idx+1],$t[$idx+1]),"\n\n";
    } elsif ($t[$idx] > $t[$idx+1]) {
        print STDERR sprintf('%s MMAP:  %.03f',$names[$idx],$t[$idx]),"\n";
        print STDERR sprintf('%s FILE:  %.03f (fastest)',$names[$idx+1],$t[$idx+1]),"\n\n";
    } else {
        print STDERR sprintf('%s MMAP:  %.03f',$names[$idx],$t[$idx]),"\n";
        print STDERR sprintf('%s FILE:  %.03f',$names[$idx+1],$t[$idx+1]),"\n\n";
    }
    $string_average += $t[$idx];
    $file_average   += $t[$idx+1];
}

$file_average   /= 3;
$string_average /= 3;

print STDERR sprintf('Memory Mapped String Mode Average: %.03f',$string_average),"\n";
print STDERR sprintf('         File Handle Mode Average: %.03f',$file_average),"\n\n";

if ($file_average > $string_average) {
    print STDERR "It is recommended you use the default Mmap string mode for your framebuffer device.\n";
} else {
    print STDERR "It is recommend you use the File Handle mode for your framebuffer device, UNLESS you will be using the 'replace_color' method a lot\n";
}
