/*
 * gui_util.c - GUI helper functions
 *
 * Written 2010 by Werner Almesberger
 * Copyright 2010 by Werner Almesberger
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */


#include <stdint.h>
#include <math.h>
#include <assert.h>
#include <gtk/gtk.h>

#include "gui_util.h"


void hpoint(guchar *rgbbuf, int x, int y, int sx, uint8_t c[3])
{
	guchar *p = rgbbuf+(y*sx+x)*3;

	p[0] = c[0];
	p[1] = c[1];
	p[2] = c[2];
}


void vpoint(guchar *rgbbuf, int y, int x, int sx, uint8_t c[3])
{
	guchar *p = rgbbuf+(y*sx+x)*3;

	p[0] = c[0];
	p[1] = c[1];
	p[2] = c[2];
}


static void alpha(guchar *rgbbuf, int f, int i, int sx, uint8_t c[3], double w,
    void (*point)(guchar *rgbbuf, int f, int i, int sx, uint8_t c[3]))
{
	uint8_t ct[3];
	int n;

	assert(w >= 0);
	assert(w <= 1);
	for (n = 0; n != 3; n++)
		ct[n] = round(c[n]*w);
	point(rgbbuf, f, i, sx, ct);
}


void aa_line(guchar *rgbbuf, int i, double fa, double fb, int max, int sx,
    uint8_t c[3],
    void (*point)(guchar *rgbbuf, int f, int i, int sx, uint8_t c[3]))
{
	int f0, f1;
	int from, to, n;

	assert(max > 0);
	assert(fb >= fa);
	f0 = floor(fa);
	f1 = ceil(fb);
	if (f0 > max || f1 < 0)
		return;
	if (f0 == f1) {
		if (f0 >= 0 && f1 <= max)
			point(rgbbuf, f0, i, sx, c);
		return;
	}
	if (f0 >= 0)
		alpha(rgbbuf, f0, i, sx, c, 1-(fa-f0), point);
	if (f1 <= max)
		alpha(rgbbuf, f1, i, sx, c, 1-(f1-fb), point);
	from = f0+1 > 0 ? f0+1 : 0;
	to = f1-1 < max ? f1-1: max;
	for (n = from; n <= to; n++)
		point(rgbbuf, n, i, sx, c);
}


void draw_circle(GdkDrawable *da, GdkGC *gc, int x, int y, int r)
{
	gdk_draw_arc(da, gc, FALSE, x-r, y-r, 2*r, 2*r, 0, 360*64);
}