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

typedef struct Vert{
	Point3 world;
	Point3 screen;
	int color;
}Vert;

int		nocubes;
int		ncolor;
Quaternion	q;
Image		*image;
Image		*bg;
Image		*color[256];
Rectangle	viewrect;
int		prevsel;

int
cmp(Vert *a, Vert *b)
{
	if(a->screen.z>b->screen.z)
		return -1;
	if(a->screen.z<b->screen.z)
		return 1;
	return 0;
}

/* crummy hack */
void
readcolmap(Display *d, RGB *cmap)
{
	int i, rgb, r, g, b;

	for(i=0; i<256; i++){
		rgb = cmap2rgb(i);
		r = rgb>>16;
		g = (rgb>>8)&0xFF;
		b = rgb & 0xFF;
		cmap[i].red = r|(r<<8)|(r<<16)|(r<<24);
		cmap[i].green = g|(g<<8)|(g<<16)|(g<<24);
		cmap[i].blue = b|(b<<8)|(b<<16)|(b<<24);
	}
}

void
colorspace(RGB *cmap, Vert *v)
{
	Space *view;
	int i;

	for(i=0;i!=ncolor;i++){
		v[i].world.x=(cmap[i].red>>24)/255.-.5;
		v[i].world.y=(cmap[i].green>>24)/255.-.5;
		v[i].world.z=(cmap[i].blue>>24)/255.-.5;
		v[i].world.w=1.;
		v[i].color=i;
	}
	view = pushmat(0);
	viewport(view, viewrect, 1.);
	persp(view, 30., 3., 7.);
	look(view, (Point3){0., 0., -5., 1.}, (Point3){0., 0., 0., 1.},
		(Point3){0., 1., 0., 1.});
	qrot(view, q);
	for(i=0;i!=ncolor;i++)
		v[i].screen = xformpointd(v[i].world, 0, view);
	popmat(view);
}

void
line3(Vert a, Vert b)
{
	line(image, Pt(a.screen.x, a.screen.y), Pt(b.screen.x, b.screen.y), 0, 0, 0, display->white, ZP);
}


void
redraw(void)
{
	int i, m;
	RGB cmap[256];
	Vert v[256];

	readcolmap(display, cmap);
	colorspace(cmap, v);
	draw(image, image->r, bg, nil, Pt(0, 0));
	m = Dx(viewrect)/2;
	if(m > Dy(viewrect)/2)
		m = Dy(viewrect)/2;
	ellipse(image, addpt(viewrect.min, divpt(Pt(Dx(viewrect), Dy(viewrect)), 2)),
		m, m, 1, display->white, ZP);

	line3(v[0], v[0x36]);
	line3(v[0x36], v[0x32]);
	line3(v[0x32], v[0x3F]);
	line3(v[0x3F], v[0]);
	
	line3(v[0xF0], v[0xF3]);
	line3(v[0xF3], v[0xFF]);
	line3(v[0xFF], v[0xFC]);
	line3(v[0xFC], v[0xF0]);

	line3(v[0], v[0xF0]);
	line3(v[0x36], v[0xF3]);
	line3(v[0x32], v[0xFF]);
	line3(v[0x3F], v[0xFC]);

	qsort(v, ncolor, sizeof(Vert), (int(*)(const void*, const void*))cmp);
	if(!nocubes)
		for(i=0; i!=ncolor; i++)
			draw(image, rectaddpt(Rect(-3, -3, 4, 4), Pt(v[i].screen.x, v[i].screen.y)),
				color[v[i].color], nil, Pt(0, 0));
	draw(screen, image->r, image, nil, image->r.min);
	flushimage(display, 1);
}

void
eresized(int new)
{
	int dx, dy;

	if(new && getwindow(display, Refnone) < 0){
		fprint(2, "colors: can't reattach to window: %r\n");
		exits("reshaped");
	}
	draw(screen, screen->r, display->black, nil, ZP);
	replclipr(screen, 0, insetrect(screen->r, 3));
	viewrect = screen->clipr;
	viewrect.min.y += stringsize(font, "0i").y + 5;
	if(image)
		freeimage(image);
	image = allocimage(display, viewrect, screen->chan, 0, DNofill);
	dx = viewrect.max.x-viewrect.min.x;
	dy = viewrect.max.y-viewrect.min.y;
	if(dx>dy){
		viewrect.min.x=(viewrect.min.x+viewrect.max.x-dy)/2;
		viewrect.max.x=viewrect.min.x+dy;
	}
	else{
		viewrect.min.y=(viewrect.min.y+viewrect.max.y-dx)/2;
		viewrect.max.y=viewrect.min.y+dx;
	}
	if(image==nil){
		fprint(2, "can't allocate image\n");
		exits("bad allocimage");
	}
	prevsel = -1;
	redraw();
}

void main(int argc, char **argv){
	Vert v[256];
	RGB cmap[256];
	char buf[100];
	Point p;
	Mouse m;
	int i;
	ulong bgcol;

	bgcol = DNofill;
	ARGBEGIN{
	case 'n':
		nocubes = 1;
		break;
	case 'b':
		bgcol = DBlack;
		break;
	case 'w':
		bgcol = DWhite;
		break;
	}ARGEND

	initdraw(0,0,0);
	ncolor=256;
	for(i=0;i!=ncolor;i++)
		color[i] = allocimage(display, Rect(0, 0, 1, 1), CMAP8, 1, cmap2rgba(i));
	if(bgcol==DNofill){
		bg = allocimage(display, Rect(0, 0, 2, 2), screen->chan, 1, DWhite);
		draw(bg, Rect(0, 0, 1, 1), color[0], nil, Pt(0, 0));
		draw(bg, Rect(1, 1, 2, 2), color[0], nil, Pt(0, 0));
	}else
		bg = allocimage(display, Rect(0,0,1,1), screen->chan, 1, bgcol);

	q=(Quaternion){1.,0.,0.,0.};
	einit(Emouse);
	eresized(0);

	for(;;){
		m = emouse();
		if(m.buttons&1)
			qball(viewrect, &m, &q, redraw, 0);
		else if(m.buttons & 2){
			readcolmap(display, cmap);
			colorspace(cmap, v);
			qsort(v, ncolor, sizeof(Vert), (int(*)(const void*, const void*))cmp);
			while(m.buttons){
				for(i=ncolor-1; i!=0; i--){
					if(ptinrect(m.xy, rectaddpt(Rect(-3, -3, 4, 4), Pt(v[i].screen.x, v[i].screen.y)))){
						i = v[i].color;
						if(i == prevsel)
							break;
						sprint(buf, "index %3d r %3ld g %3ld b %3ld",
							i,
							cmap[i].red>>24,
							cmap[i].green>>24,
							cmap[i].blue>>24);
						p = addpt(screen->r.min, Pt(2,2));
						draw(screen, Rpt(p, addpt(p, stringsize(font, buf))), display->black, nil, p);
						string(screen, p, display->white, ZP, font, buf);
						prevsel = i;
						break;
					}
				}
				m = emouse();
			}
		}else if(m.buttons&4){
			do
				m = emouse();
			while(m.buttons);
			exits(0);
		}
	}
}
