#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
