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


Rectangle r;
Image *img;
int clear = 0;

typedef struct {
	Point p1;
	Point p2;

	int p1dx;
	int p1dy;
	int p2dx;
	int p2dy;

	uint r, g, b;
	uint dr, dg, db;

} mline;

typedef struct mq mq;
struct mq {
	mline *node;
	mq *next;
};

void
eresized(int new)
{	
	if(new && getwindow(display, Refnone) < 0) {
		fprint(2, "bez: can't reattach to window: %r\n");
		exits("resized");
	}

	draw(screen, screen->r, display->black, nil, ZP);
	r = screen->r;

}

char *buttons[] = 
{
	"more",
	"less",
	"clear",
	"reset",
	"exit",
	0
};

Menu menu = 
{
	buttons
};

void
init(mline *m) {
	m->p1.x = r.min.x + nrand(r.max.x - r.min.x);
	m->p2.x = r.min.x + nrand(r.max.x - r.min.x);
	m->p1.y = r.min.y + nrand(r.max.y - r.min.y);
	m->p2.y = r.min.y + nrand(r.max.y - r.min.y);

	m->p1dx = (int)((frand() - 0.5)*5);
	m->p1dy = (int)((frand() - 0.5)*5);
	m->p2dx = (int)((frand() - 0.5)*5);
	m->p2dy = (int)((frand() - 0.5)*5);

	m->r = nrand(256);
	m->g = nrand(256);
	m->b = nrand(256);

	m->dr = (int)((frand() - 0.5)*5);
	m->dg = (int)((frand() - 0.5)*5);
	m->db = (int)((frand() - 0.5)*5);
}
  
void main(int argc, char **argv) {
	int i, j,k, b = 1, db = 1;
	Mouse ms;
	Point p1, p2;
	mq q;
	mq *p;
	mline *m;
	ulong cnt = 0;

	srand(time(0));

	if(initdraw(nil, nil, "bez") < 0)
		sysfatal("initdraw failed: %r");

	r = screen->r;

	q.node = (mline *)malloc(sizeof (mline));
	q.next = nil;

	init(q.node);



	einit(Emouse);

	eresized(0);
	for(;;) {
		if(!(cnt++ % 10000) || clear)
			draw(screen, screen->r, display->black, nil, ZP);
		if(ecanmouse()) {
			ms = emouse();
			if(ms.buttons&4)
				switch(emenuhit(3, &ms, &menu)) {
					case 0: 	/* more */
						p=&q;
						while(p->next != nil)
							p = p->next;
					
						p->next = (mq *)malloc(sizeof (mq));
						p->next->node = (mline *)malloc(sizeof(mline));
						init(p->next->node);  
						p->next->next = nil;  
						break; 
					case 1:
						if(q.next == nil)
							break;
						p = &q;
						while(p->next->next != nil)
							p = p->next;
						free(p->next->node);
						free(p->next);
						p->next = nil;
						
						break;
					case 2:
						clear = !clear;
						break;
					case 3:
						p=&q;
						do {
							init(p->node);
						} while(p->next != nil && (p = p->next));
						draw(screen, screen->r, display->black, nil, ZP);
						break;
					case 4:
						exits(0);
				}
		}


		

		p = &q;
		while(p != nil) {

			m = p->node;
			m->p1.x += m->p1dx;
			if(m->p1.x < r.min.x || m->p1.x > r.max.x)
				m->p1dx = -m->p1dx;
			m->p1.y += m->p1dy;
			if(m->p1.y < r.min.y || m->p1.y > r.max.y)
				m->p1dy = -m->p1dy;
			m->p2.x += m->p2dx;
			if(m->p2.x < r.min.x || m->p2.x > r.max.x)
				m->p2dx = -m->p2dx;
			m->p2.y += m->p2dy;
			if(m->p2.y < r.min.y || m->p2.y > r.max.y)
				m->p2dy = -m->p2dy;	



			if(m->r <= 1 || m->r >= 254)
				m->dr *= -1;
			m->r+= m->dr;

			if(m->g<= 1 || m->g >= 254)
				m->dg *= -1;
			m->g+= m->dg;

			if(m->b <= 1 || m->b >= 254)
				m->db *= -1;
			m->b+= m->db;

			img = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, (m->r<<24)|(m->g<<16)|(m->b<<8)|0xFF);
			line(screen, m->p1, m->p2, Endsquare, Endsquare,2, img, ZP);
			free(img);
//print("%d, %d, %d\n", m->r, m->g, m->b);
			p = p->next;
		}
	}
}
