package Blue;
###########################################
# Mike Schilli, 2007 (m@perlmeister.com)
###########################################
use Log::Log4perl qw(:easy);
use strict;

my $THRESHOLD = 50;

use Imager;

###########################################
sub detect {
###########################################
    my($img, $debug, $mindist) = @_;

    $mindist = 3 unless defined $mindist;

    LOGDIE "No image given" unless defined $img;

    my $i = Imager->new();
    $i->read(file => $img, type => "jpeg") or 
        LOGDIE "Can't read $img";

    my @l = find_bound($i, "l", $THRESHOLD);
    my($lxfirst, $lyfirst) = @l;

    my $case;

    if($l[-2] > $l[0]) { 
        $case = "A";
    } else {
        $case = "B";
    }

    INFO "Case: $case";

    my @corners = ();
    my($xmin, $ymin);

    while(my($x, $y) = splice @l, 0, 2) {
        #print "L $x $y\n";
        if(!defined $xmin or 
            $x < $xmin - $mindist) {
             $xmin = $x;
             $ymin = $y;
         }
    }

    my @r = find_bound($i, "r", $THRESHOLD);
    my($rxfirst, $ryfirst) = @r;

    my($xmax, $ymax);

    while(my($x, $y) = splice @r, 0, 2) {

        if(!defined $xmax or 
           $x > $xmax + $mindist) {
            $xmax = $x;
            $ymax = $y;
        }
    }

    if($case eq 'A') {
        #print "@l\n";
        push @corners, [$lxfirst, $lyfirst];
        push @corners, [$xmax, $ymax];
    } else {
        push @corners, [$xmin, $ymin];
        push @corners, [$rxfirst, $ryfirst];
    }
    
    return @corners;
}

use Inline C => <<'EOT' => WITH => 'Imager';

#define MO_IV(x) sv_2mortal(newSViv(x))

#define IT_INIT(x,y,xs,ys,xd,yd) \
  x = (xd > 0) ? 0 : xs -1;      \
  y = (yd > 0) ? 0 : ys -1;

#define IT(x,y,xs,ys,xd,yd)      \
    x += xd;                     \
    if(x >= xs || x < 0) {       \
       x = (xd > 0) ? 0 : xs -1; \
       y += yd;                  \
    }                            \
    if(y >= ys || y < 0) {       \
        break;                   \
    }

#define IT_NEXT(x,y,xs,ys,xd,yd) \
    x = (xd > 0) ? 0 : xs -1;    \
    y += yd;                     \
    if(y >= ys || y < 0) {       \
        break;                   \
    }

void
find_bound(Imager im, char direction, int thres) {
    int x, y;
    int br;
    int xd;

    if(direction == 'l') {
        xd = 1;
    } else {
        xd = -1;
    }

    Inline_Stack_Vars;
    Inline_Stack_Reset;

    IT_INIT(x, y, im->xsize, im->ysize, xd, 1);
    while(1) {
        br = blueness(im, x, y);
        if(br > thres) {
            Inline_Stack_Push(MO_IV(x));
            Inline_Stack_Push(MO_IV(y));
            IT_NEXT(x, y, im->xsize, im->ysize, xd, 1);
            continue;
        }
        IT(x, y, im->xsize, im->ysize, xd, 1);
    }

    Inline_Stack_Done;

    return;
}

int blueness(Imager im, int x, int y) {
    i_color val;
    int b;

    i_gpix(im, x, y, &val);
    b = val.channel[2] - val.channel[0] - val.channel[1];
    return b;
}
EOT

1;
