#define CONCAT_I(a, b) a ## b
#define CONCAT(a, b) CONCAT_I(a, b)
#define pixel_t CONCAT(uint, CONCAT(BPP, _t))
#ifdef GENERIC
#define NAME CONCAT(generic_, BPP)
#else
#define NAME BPP
#endif

static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
                                             int x, int y, int w, int h,
                                             void *last_bg_,
                                             void *last_fg_,
                                             int *has_bg, int *has_fg)
{
    VncDisplay *vd = vs->vd;
    uint8_t *row = vnc_server_fb_ptr(vd, x, y);
    pixel_t *irow = (pixel_t *)row;
    int j, i;
    pixel_t *last_bg = (pixel_t *)last_bg_;
    pixel_t *last_fg = (pixel_t *)last_fg_;
    pixel_t bg = 0;
    pixel_t fg = 0;
    int n_colors = 0;
    int bg_count = 0;
    int fg_count = 0;
    int flags = 0;
    uint8_t data[(vs->client_pf.bytes_per_pixel + 2) * 16 * 16];
    int n_data = 0;
    int n_subtiles = 0;

    for (j = 0; j < h; j++) {
        for (i = 0; i < w; i++) {
            switch (n_colors) {
            case 0:
                bg = irow[i];
                n_colors = 1;
                break;
            case 1:
                if (irow[i] != bg) {
                    fg = irow[i];
                    n_colors = 2;
                }
                break;
            case 2:
                if (irow[i] != bg && irow[i] != fg) {
                    n_colors = 3;
                } else {
                    if (irow[i] == bg)
                        bg_count++;
                    else if (irow[i] == fg)
                        fg_count++;
                }
                break;
            default:
                break;
            }
        }
        if (n_colors > 2)
            break;
        irow += vnc_server_fb_stride(vd) / sizeof(pixel_t);
    }

    if (n_colors > 1 && fg_count > bg_count) {
        pixel_t tmp = fg;
        fg = bg;
        bg = tmp;
    }

    if (!*has_bg || *last_bg != bg) {
        flags |= 0x02;
        *has_bg = 1;
        *last_bg = bg;
    }

    if (n_colors < 3 && (!*has_fg || *last_fg != fg)) {
        flags |= 0x04;
        *has_fg = 1;
        *last_fg = fg;
    }

    switch (n_colors) {
    case 1:
        n_data = 0;
        break;
    case 2:
        flags |= 0x08;

        irow = (pixel_t *)row;

        for (j = 0; j < h; j++) {
            int min_x = -1;
            for (i = 0; i < w; i++) {
                if (irow[i] == fg) {
                    if (min_x == -1)
                        min_x = i;
                } else if (min_x != -1) {
                    hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
                    n_data += 2;
                    n_subtiles++;
                    min_x = -1;
                }
            }
            if (min_x != -1) {
                hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
                n_data += 2;
                n_subtiles++;
            }
            irow += vnc_server_fb_stride(vd) / sizeof(pixel_t);
        }
        break;
    case 3:
        flags |= 0x18;

        irow = (pixel_t *)row;

        if (!*has_bg || *last_bg != bg)
            flags |= 0x02;

        for (j = 0; j < h; j++) {
            int has_color = 0;
            int min_x = -1;
            pixel_t color = 0; /* shut up gcc */

            for (i = 0; i < w; i++) {
                if (!has_color) {
                    if (irow[i] == bg)
                        continue;
                    color = irow[i];
                    min_x = i;
                    has_color = 1;
                } else if (irow[i] != color) {
                    has_color = 0;
#ifdef GENERIC
                    vnc_convert_pixel(vs, data + n_data, color);
                    n_data += vs->client_pf.bytes_per_pixel;
#else
                    memcpy(data + n_data, &color, sizeof(color));
                    n_data += sizeof(pixel_t);
#endif
                    hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
                    n_data += 2;
                    n_subtiles++;

                    min_x = -1;
                    if (irow[i] != bg) {
                        color = irow[i];
                        min_x = i;
                        has_color = 1;
                    }
                }
            }
            if (has_color) {
#ifdef GENERIC
                vnc_convert_pixel(vs, data + n_data, color);
                n_data += vs->client_pf.bytes_per_pixel;
#else
                memcpy(data + n_data, &color, sizeof(color));
                n_data += sizeof(pixel_t);
#endif
                hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
                n_data += 2;
                n_subtiles++;
            }
            irow += vnc_server_fb_stride(vd) / sizeof(pixel_t);
        }

        /* A SubrectsColoured subtile invalidates the foreground color */
        *has_fg = 0;
        if (n_data > (w * h * sizeof(pixel_t))) {
            n_colors = 4;
            flags = 0x01;
            *has_bg = 0;

            /* we really don't have to invalidate either the bg or fg
               but we've lost the old values.  oh well. */
        }
        break;
    default:
        break;
    }

    if (n_colors > 3) {
        flags = 0x01;
        *has_fg = 0;
        *has_bg = 0;
        n_colors = 4;
    }

    vnc_write_u8(vs, flags);
    if (n_colors < 4) {
        if (flags & 0x02)
            vs->write_pixels(vs, last_bg, sizeof(pixel_t));
        if (flags & 0x04)
            vs->write_pixels(vs, last_fg, sizeof(pixel_t));
        if (n_subtiles) {
            vnc_write_u8(vs, n_subtiles);
            vnc_write(vs, data, n_data);
        }
    } else {
        for (j = 0; j < h; j++) {
            vs->write_pixels(vs, row, w * 4);
            row += vnc_server_fb_stride(vd);
        }
    }
}

#undef NAME
#undef pixel_t
#undef CONCAT_I
#undef CONCAT
