#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>

/*
 * ellipse(dst, c, a, b, t, src, sp)
 *   draws an ellipse centered at c with semiaxes a,b>=0
 *   and semithickness t>=0, or filled if t<0.  point sp
 *   in src maps to c in dst
 *
 *   very thick skinny ellipses are brushed with circles (slow)
 *   others are approximated by filling between 2 ellipses
 *   criterion for very thick when b<a: t/b > 0.5*x/(1-x)
 *   where x = b/a
 */

typedef struct Param	Param;
typedef struct State	State;

static	void	bellipse(int, State*, Param*);
static	void	erect(int, int, int, int, Param*);
static	void	eline(int, int, int, int, Param*);

struct Param {
	Memimage	*dst;
	Memimage	*src;
	Point			c;
	int			t;
	Point			sp;
	Memimage	*disc;
	int			op;
};

/*
 * denote residual error by e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2
 * e(x,y) = 0 on ellipse, e(x,y) < 0 inside, e(x,y) > 0 outside
 */

struct State {
	int	a;
	int	x;
	vlong	a2;	/* a^2 */
	vlong	b2;	/* b^2 */
	vlong	b2x;	/* b^2 * x */
	vlong	a2y;	/* a^2 * y */
	vlong	c1;
	vlong	c2;	/* test criteria */
	vlong	ee;	/* ee = e(x+1/2,y-1/2) - (a^2+b^2)/4 */
	vlong	dxe;
	vlong	dye;
	vlong	d2xe;
	vlong	d2ye;
};

static
State*
newstate(State *s, int a, int b)
{
	s->x = 0;
	s->a = a;
	s->a2 = (vlong)(a*a);
	s->b2 = (vlong)(b*b);
	s->b2x = (vlong)0;
	s->a2y = s->a2*(vlong)b;
	s->c1 = -((s->a2>>2) + (vlong)(a&1) + s->b2);
	s->c2 = -((s->b2>>2) + (vlong)(b&1));
	s->ee = -s->a2y;
	s->dxe = (vlong)0;
	s->dye = s->ee<<1;
	s->d2xe = s->b2<<1;
	s->d2ye = s->a2<<1;
	return s;
}

/*
 * return x coord of rightmost pixel on next scan line
 */
static
int
step(State *s)
{
	while(s->x < s->a) {
		if(s->ee+s->b2x <= s->c1 ||	/* e(x+1,y-1/2) <= 0 */
		   s->ee+s->a2y <= s->c2) {	/* e(x+1/2,y) <= 0 (rare) */
			s->dxe += s->d2xe;	  
			s->ee += s->dxe;	  
			s->b2x += s->b2;
			s->x++;	  
			continue;
		}
		s->dye += s->d2ye;	  
		s->ee += s->dye;	  
		s->a2y -= s->a2;
		if(s->ee-s->a2y <= s->c2) {	/* e(x+1/2,y-1) <= 0 */
			s->dxe += s->d2xe;	  
			s->ee += s->dxe;	  
			s->b2x += s->b2;
			return s->x++;
		}
		break;
	}
	return s->x;	  
}

void
memellipse(Memimage *dst, Point c, int a, int b, int t, Memimage *src, Point sp, int op)
{
	State in, out;
	int y, inb, inx, outx, u;
	Param p;

	if(a < 0)
		a = -a;
	if(b < 0)
		b = -b;
	p.dst = dst;
	p.src = src;
	p.c = c;
	p.t = t;
	p.sp = subpt(sp, c);
	p.disc = nil;
	p.op = op;

	u = (t<<1)*(a-b);
	if(b<a && u>b*b || a<b && -u>a*a) {
/*	if(b<a&&(t<<1)>b*b/a || a<b&&(t<<1)>a*a/b)	# very thick */
		bellipse(b, newstate(&in, a, b), &p);
		return;
	}

	if(t < 0) {
		inb = -1;
		newstate(&out, a, y = b);
	} else {	
		inb = b - t;
		newstate(&out, a+t, y = b+t);
	}
	if(t > 0)
		newstate(&in, a-t, inb);
	inx = 0;
	for( ; y>=0; y--) {
		outx = step(&out);
		if(y > inb) {
			erect(-outx, y, outx, y, &p);
			if(y != 0)
				erect(-outx, -y, outx, -y, &p);
			continue;
		}
		if(t > 0) {
			inx = step(&in);
			if(y == inb)
				inx = 0;
		} else if(inx > outx)
			inx = outx;
		erect(inx, y, outx, y, &p);
		if(y != 0)
			erect(inx, -y, outx, -y, &p);
		erect(-outx, y, -inx, y, &p);
		if(y != 0)
			erect(-outx, -y, -inx, -y, &p);
		inx = outx + 1;
	}
}

static Point p00 = {0, 0};

/*
 * a brushed ellipse
 */
static
void
bellipse(int y, State *s, Param *p)
{
	int t, ox, oy, x, nx;

	t = p->t;
	p->disc = allocmemimage(Rect(-t,-t,t+1,t+1), GREY1);
	if(p->disc == nil)
		return;
	memfillcolor(p->disc, DTransparent);
	memellipse(p->disc, p00, t, t, -1, memopaque, p00, p->op);
	oy = y;
	ox = 0;
	nx = x = step(s);
	do {
		while(nx==x && y-->0)
			nx = step(s);
		y++;
		eline(-x,-oy,-ox, -y, p);
		eline(ox,-oy,  x, -y, p);
		eline(-x,  y,-ox, oy, p);
		eline(ox,  y,  x, oy, p);
		ox = x+1;
		x = nx;
		y--;
		oy = y;
	} while(oy > 0);
}

/*
 * a rectangle with closed (not half-open) coordinates expressed
 * relative to the center of the ellipse
 */
static
void
erect(int x0, int y0, int x1, int y1, Param *p)
{
	Rectangle r;

/*	print("R %d,%d %d,%d\n", x0, y0, x1, y1); */
	r = Rect(p->c.x+x0, p->c.y+y0, p->c.x+x1+1, p->c.y+y1+1);
	memdraw(p->dst, r, p->src, addpt(p->sp, r.min), memopaque, p00, p->op);
}

/*
 * a brushed point similarly specified
 */
static
void
epoint(int x, int y, Param *p)
{
	Point p0;
	Rectangle r;

/*	print("P%d %d,%d\n", p->t, x, y);	*/
	p0 = Pt(p->c.x+x, p->c.y+y);
	r = Rpt(addpt(p0, p->disc->r.min), addpt(p0, p->disc->r.max));
	memdraw(p->dst, r, p->src, addpt(p->sp, r.min), p->disc, p->disc->r.min, p->op);
}

/* 
 * a brushed horizontal or vertical line similarly specified
 */
static
void
eline(int x0, int y0, int x1, int y1, Param *p)
{
/*	print("L%d %d,%d %d,%d\n", p->t, x0, y0, x1, y1); */
	if(x1 > x0+1)
		erect(x0+1, y0-p->t, x1-1, y1+p->t, p);
	else if(y1 > y0+1)
		erect(x0-p->t, y0+1, x1+p->t, y1-1, p);
	epoint(x0, y0, p);
	if(x1-x0 || y1-y0)
		epoint(x1, y1, p);
}
