/* This file was generated by scramble.py. */
#include "pupil.h"
#include "scramble.h"
int locate_min_x(Image *image)
{
    B *data = image->data.b;
    int w = image->w;
    int h = image->h;
    int x = 0, x_ = 0;
    int minsum = INT_MAX;
    for (int i = 0; i < w; i++)
    {
        V sum = 0;
        for (int j = 0; j < h; j++)
        {
            sum += data[j * w + i];
        }
        if (sum < minsum)
        {
            minsum = sum;
            x = i;
        }
        if (sum == minsum)
        {
            x_ = i;
        }
    }
    return (x + x_) / 2;
}
int locate_min_y(Image *image)
{
    B *data = image->data.b;
    int w = image->w;
    int h = image->h;
    int y = 0, y_ = 0;
    int minsum = INT_MAX;
    for (int j = 0; j < h; j++)
    {
        V sum = 0;
        for (int i = 0; i < h; i++)
        {
            sum += data[j * w + i];
        }
        if (sum < minsum)
        {
            minsum = sum;
            y = j;
        }
        if (sum == minsum)
        {
            y_ = j;
        }
    }
    return (y + y_) / 2;
}
Image * binarize_pupil(Image *image)
/* int x = locate_min_x(image) */
/* int y = locate_min_y(image) */
/* int *histogram = get_histogram(image, w, h) */
/* TODO */
{
    return image;
}
static int count(Image *image, int x, int y, int max_r, int min_c)
{
    int w = image->w;
    int h = image->h;
    int n = 0;
    int s = 0;
    if (image->data.b[x + y * w] >= min_c)
    {
        n++;
    }
    else
    {
        return 0;
    }
    for (int r = 0; r < max_r; r++)
    {
        int on = n;
        s += 2;
        x -= 1;
        y -= 1;
        int dx[4] = {1, 0, -1 ,0};
        int dy[4] = {0, 1, 0, -1};
        for (int j = 0; j < 4; j++)
        {
            for (int i = 0; i < s; i++)
            {
                if (x >= 0 && y >= 0 && x < w && y < h)
                {
                    if (image->data.b[x + y * w] >= min_c)
                    {
                        n++;
                    }
                }
                x += dx[j];
                y += dy[j];
                /* disconnected */
            }
        }
        if (on == n)
        {
            return n;
        }
    }
    return 0;
}
static int fill(Image *image, int x, int y, int max_r, int min_c, int c)
{
    int w = image->w;
    int h = image->h;
    int n = 0;
    int s = 0;
    if (image->data.b[x + y * w] >= min_c)
    {
        n++;
        image->data.b[x + y * w] = c;
    }
    else
    {
        return 0;
    }
    for (int r = 0; r < max_r; r++)
    {
        int on = n;
        s += 2;
        x -= 1;
        y -= 1;
        int dx[4] = {1, 0, -1 ,0};
        int dy[4] = {0, 1, 0, -1};
        for (int j = 0; j < 4; j++)
        {
            for (int i = 0; i < s; i++)
            {
                if (x >= 0 && y >= 0 && x < w && y < h)
                {
                    if (image->data.b[x + y * w] >= min_c)
                    {
                        n++;
                        image->data.b[x + y * w] = c;
                    }
                }
                x += dx[j];
                y += dy[j];
                /* disconnected */
            }
        }
        if (on == n)
        {
            return n;
        }
    }
    return 0;
}
void blackout_reflections(Image *image, int w, int h, int x, int y, int x_, int y_)
{
    int sum = 0;
    int sumc = 0;
    for (int j = y; j < y_; j++)
    {
        for (int i = x; i < x_; i++)
        {
            sum += image->data.b[i + j * w];
            sumc++;
        }
    }
    sum /= sumc;
    for (int j = y; j < y_; j++)
    {
        for (int i = x; i < x_; i++)
        {
            int n = count(image, i, j, 5, 250);
            if (n > 0)
            {
                fill(image, i, j, 5, 150, sum);
            }
        }
    }
}
Image * find_pupil(Image const *orig_image, char const *what, int *px, int *py, int *pr)
{
    Image *image = image_copy(orig_image);
    /* int x = locate_min_x(image) */
    /* int y = locate_min_y(image) */
    int w = image->w;
    int h = image->h;
    int PUPIL_HOUGH_THRESHOLD = 200;
    /* blackout_reflections(image, w, h, x - 60, y - 60, x + 60, y + 60) */
    /* good for ubiris: */
    adjust_luminance(image, w * h * 0.02, w * h * 0.04);
    /* adjust_luminance(image, w * h * 0.04, w * h * 0.9) */
    /* good for casia v3 */
    /* adjust_luminance(image, w * h * 0.04, 0) */
    Image *accum = cumulate(image, 3, 3);
    /* The inverse accum is to reduce shrinking of the pupil. */
    invert(accum);
    Image *accum2 = cumulate(accum, 3, 3);
    invert(accum2);
    image_del(accum);
    accum = accum2;
    accum->name = strdup(image->name);
    int ax, ay, bx, by;
    if (what && hasword(what, "pupilprep"))
    {
        char name[MAX_PATH];
        get_image_name(image, "pupilprep", name);
        save_tiff_luminance(name, accum);
    }
    int hrun = longest_horizontal_run(accum, w * 0.25, 127);
    int vrun = longest_vertical_run(accum, h * 0.25, 127);
    Image *result = canny(accum, 3, 15, 1, 1, what);
    if (what && hasword(what, "pupilcanny"))
    {
        char name[MAX_PATH];
        get_image_name(image, "pupilcanny", name);
        save_tiff_luminance(name, result);
    }
    bool debug = false;
    remove_streaks(result, what, 6, 1, 1, 5, 5, 10, 10, 3, 3, debug);
    if (what && hasword(what, "pupilstreaks"))
    {
        char name[MAX_PATH];
        get_image_name(image, "pupilstreaks", name);
        save_tiff_luminance(name, result);
        /* Can't we do better? The lid has black pixels usually, so this bounds is */
        /* often much too big. */
    }
    bounds_bigger_than_threshold(result, 0, &ax, &ay, &bx, &by);
    /* TODO: Better way for lower and upper bound? */
    /* int min_r = sqrt(black_pixels_count / pi) */
    /* int max_r = (bx - ax) / 2 */
    int min_r = min(hrun / 2, vrun / 2);
    /* This can be far off if there's large reflections on the pupil */
    int max_r = min_r + max(hrun / 2, vrun / 2);
    /* else where would we fit the iris? */
    int border = min_r * 1.5;
    if (ax < border)
    {
        ax = border;
    }
    if (ay < border)
    {
        ay = border;
    }
    if (bx > w - 1 - border)
    {
        bx = w - 1 - border;
    }
    if (by > h - 1 - border)
    {
        by = h - 1 - border;
    }
    printf("%d %d %d %d: [%d/%d] %d - %d\n", ax, ay, bx, by, hrun, vrun, min_r, max_r);
    Vector *circles = hough_circle(result, min_r, max_r, ax, bx, ay, by, PUPIL_HOUGH_THRESHOLD, 0, 0, 0, what, "pupilaccums", "pupilaccums");
    bool debug2 = false;
    int cx = 0, cy = 0, cr = 0;
    find_best_circle(circles, &cx, &cy, &cr, 1, w / 2, h / 2, h / 2, 0, debug2);
    Image *rgb = BtoRGB(orig_image);
    Color red = {255, 0, 0};
    draw_location(rgb, cx, cy, red);
    draw_circle(rgb, cx - cr, cy - cr, cx + cr, cy + cr, red);
    *px = cx;
    *py = cy;
    *pr = cr;
    return rgb;
}
/* This file was generated by scramble.py. */
