#include <u.h>
#include <libc.h>
#include <draw.h>
#include <plumb.h>
#include <regexp.h>
#include <bio.h>
#include <thread.h>
#include <mouse.h>
#include <cursor.h>
#include <9pclient.h>
#include "faces.h"

int	history = 0;	/* use old interface, showing history of mailbox rather than current state */
int	initload = 0;	/* initialize program with contents of mail box */

enum
{
	Facesep = 6,	/* must be even to avoid damaging background stipple */
	Infolines = 9,

	HhmmTime = 18*60*60,	/* max age of face to display hh:mm time */
	
	STACK = 32768
};

enum
{
	Mainp,
	Timep,
	Mousep,
	Resizep,
	NPROC
};

char *procnames[] = {
	"main",
	"time",
	"mouse",
	"resize"
};

Rectangle leftright = {0, 0, 20, 15};

uchar leftdata[] = {
	0x00, 0x80, 0x00, 0x01, 0x80, 0x00, 0x03, 0x80,
	0x00, 0x07, 0x80, 0x00, 0x0f, 0x00, 0x00, 0x1f,
	0xff, 0xf0, 0x3f, 0xff, 0xf0, 0xff, 0xff, 0xf0,
	0x3f, 0xff, 0xf0, 0x1f, 0xff, 0xf0, 0x0f, 0x00,
	0x00, 0x07, 0x80, 0x00, 0x03, 0x80, 0x00, 0x01,
	0x80, 0x00, 0x00, 0x80, 0x00
};

uchar rightdata[] = {
	0x00, 0x10, 0x00, 0x00, 0x18, 0x00, 0x00, 0x1c,
	0x00, 0x00, 0x1e, 0x00, 0x00, 0x0f, 0x00, 0xff,
	0xff, 0x80, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xf0,
	0xff, 0xff, 0xc0, 0xff, 0xff, 0x80, 0x00, 0x0f,
	0x00, 0x00, 0x1e, 0x00, 0x00, 0x1c, 0x00, 0x00,
	0x18, 0x00, 0x00, 0x10, 0x00
};

CFsys	*mailfs;
Mousectl	*mousectl;
Image	*blue;		/* full arrow */
Image	*bgrnd;		/* pale blue background color */
Image	*left;		/* left-pointing arrow mask */
Image	*right;		/* right-pointing arrow mask */
Font	*tinyfont;
Font	*mediumfont;
Font	*datefont;
int	first, last;	/* first and last visible face; last is first invisible */
int	nfaces;
int	mousefd;
int	nacross;
int	ndown;

char	date[64];
Face	**faces;
char	*maildir = "mbox";
ulong	now;

Point	datep = { 8, 6 };
Point	facep = { 8, 6+0+4 };	/* 0 updated to datefont->height in init() */
Point	enddate;			/* where date ends on display; used to place arrows */
Rectangle	leftr;			/* location of left arrow on display */
Rectangle	rightr;		/* location of right arrow on display */
void updatetimes(void);
void eresized(int);

void
setdate(void)
{
	now = time(nil);
	strcpy(date, ctime(now));
	date[4+4+3+5] = '\0';	/* change from Thu Jul 22 14:28:43 EDT 1999\n to Thu Jul 22 14:28 */
}

void
init(void)
{
	mailfs = nsmount("mail", nil);
	if(mailfs == nil)
		sysfatal("mount mail: %r");
	mousectl = initmouse(nil, screen);
	if(mousectl == nil)
		sysfatal("initmouse: %r");
	initplumb();

	/* make background color */
	bgrnd = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DWhite);
	blue = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x008888FF);	/* blue-green */
	left = allocimage(display, leftright, GREY1, 0, DWhite);
	right = allocimage(display, leftright, GREY1, 0, DWhite);
	if(bgrnd==nil || blue==nil || left==nil || right==nil){
		fprint(2, "faces: can't create images: %r\n");
		threadexitsall("image");
	}

	loadimage(left, leftright, leftdata, sizeof leftdata);
	loadimage(right, leftright, rightdata, sizeof rightdata);

	/* initialize little fonts */
	tinyfont = openfont(display, "/lib/font/bit/misc/ascii.5x7.font");
	if(tinyfont == nil)
		tinyfont = font;
	mediumfont = openfont(display, "/lib/font/bit/pelm/latin1.8.font");
	if(mediumfont == nil)
		mediumfont = font;
	datefont = font;

	facep.y += datefont->height;
	if(datefont->height & 1)	/* stipple parity */
		facep.y++;
	faces = nil;
}

void
drawtime(void)
{
	Rectangle r;

	r.min = addpt(screen->r.min, datep);
	if(eqpt(enddate, ZP)){
		enddate = r.min;
		enddate.x += stringwidth(datefont, "Wed May 30 22:54");	/* nice wide string */
		enddate.x += Facesep;	/* for safety */
	}
	r.max.x = enddate.x;
	r.max.y = enddate.y+datefont->height;
	draw(screen, r, bgrnd, nil, ZP);
	string(screen, r.min, display->black, ZP, datefont, date);
}

void
timeproc(void *dummy)
{
	for(;;){
		lockdisplay(display);
		drawtime();
		updatetimes();
		flushimage(display, 1);
		unlockdisplay(display);
		sleep(60000);
		setdate();
	}
}

int
alreadyseen(char *digest)
{
	int i;
	Face *f;

	if(!digest)
		return 0;

	/* can do accurate check */
	for(i=0; i<nfaces; i++){
		f = faces[i];
		if(f->str[Sdigest]!=nil && strcmp(digest, f->str[Sdigest])==0)
			return 1;
	}
	return 0;
}

int
torune(Rune *r, char *s, int nr)
{
	int i;

	for(i=0; i<nr-1 && *s!='\0'; i++)
		s += chartorune(r+i, s);
	r[i] = L'\0';
	return i;
}

void
center(Font *f, Point p, char *s, Image *color)
{
	int i, n, dx;
	Rune rbuf[32];
	char sbuf[32*UTFmax+1];

	dx = stringwidth(f, s);
	if(dx > Facesize){
		n = torune(rbuf, s, nelem(rbuf));
		for(i=0; i<n; i++){
			dx = runestringnwidth(f, rbuf, i+1);
			if(dx > Facesize)
				break;
		}
		sprint(sbuf, "%.*S", i, rbuf);
		s = sbuf;
		dx = stringwidth(f, s);
	}
	p.x += (Facesize-dx)/2;
	string(screen, p, color, ZP, f, s);
}

Rectangle
facerect(int index)	/* index is geometric; 0 is always upper left face */
{
	Rectangle r;
	int x, y;

	x = index % nacross;
	y = index / nacross;
	r.min = addpt(screen->r.min, facep);
	r.min.x += x*(Facesize+Facesep);
	r.min.y += y*(Facesize+Facesep+2*mediumfont->height);
	r.max = addpt(r.min, Pt(Facesize, Facesize));
	r.max.y += 2*mediumfont->height;
	/* simple fix to avoid drawing off screen, allowing customers to use position */
	if(index<0 || index>=nacross*ndown)
		r.max.x = r.min.x;
	return r;
}

static char *mon = "JanFebMarAprMayJunJulAugSepOctNovDec";
char*
facetime(Face *f, int *recent)
{
	static char buf[30];

	if((long)(now - f->time) > HhmmTime){
		*recent = 0;
		sprint(buf, "%.3s %2d", mon+3*f->tm.mon, f->tm.mday);
		return buf;
	}else{
		*recent = 1;
		sprint(buf, "%02d:%02d", f->tm.hour, f->tm.min);
		return buf;
	}
}

void
drawface(Face *f, int i)
{
	char *tstr;
	Rectangle r;
	Point p;

	if(f == nil)
		return;
	if(i<first || i>=last)
		return;
	r = facerect(i-first);
	draw(screen, r, bgrnd, nil, ZP);
	draw(screen, r, f->bit, f->mask, ZP);
	r.min.y += Facesize;
	center(mediumfont, r.min, f->str[Suser], display->black);
	r.min.y += mediumfont->height;
	tstr = facetime(f, &f->recent);
	center(mediumfont, r.min, tstr, display->black);
	if(f->unknown){
		r.min.y -= mediumfont->height + tinyfont->height + 2;
		for(p.x=-1; p.x<=1; p.x++)
			for(p.y=-1; p.y<=1; p.y++)
				center(tinyfont, addpt(r.min, p), f->str[Sdomain], display->white);
		center(tinyfont, r.min, f->str[Sdomain], display->black);
	}
}

void
updatetimes(void)
{
	int i;
	Face *f;

	for(i=0; i<nfaces; i++){
		f = faces[i];
		if(f == nil)
			continue;
		if(((long)(now - f->time) <= HhmmTime) != f->recent)
			drawface(f, i);
	}	
}

void
setlast(void)
{
	last = first+nacross*ndown;
	if(last > nfaces)
		last = nfaces;
}

void
drawarrows(void)
{
	Point p;

	p = enddate;
	p.x += Facesep;
	if(p.x & 1)
		p.x++;	/* align background texture */
	leftr = rectaddpt(leftright, p);
	p.x += Dx(leftright) + Facesep;
	rightr = rectaddpt(leftright, p);
	draw(screen, leftr, first>0? blue : bgrnd, left, leftright.min);
	draw(screen, rightr, last<nfaces? blue : bgrnd, right, leftright.min);
}

void
addface(Face *f)	/* always adds at 0 */
{
	Face **ofaces;
	Rectangle r0, r1, r;
	int y, nx, ny;

	if(f == nil)
		return;
	if(first != 0){
		first = 0;
		eresized(0);
	}
	findbit(f);

	nx = nacross;
	ny = (nfaces+(nx-1)) / nx;

	lockdisplay(display);
	for(y=ny; y>=0; y--){
		/* move them along */
		r0 = facerect(y*nx+0);
		r1 = facerect(y*nx+1);
		r = r1;
		r.max.x = r.min.x + (nx - 1)*(Facesize+Facesep);
		draw(screen, r, screen, nil, r0.min);
		/* copy one down from row above */
		if(y != 0){
			r = facerect((y-1)*nx+nx-1);
			draw(screen, r0, screen, nil, r.min);
		}
	}

	ofaces = faces;
	faces = emalloc((nfaces+1)*sizeof(Face*));
	memmove(faces+1, ofaces, nfaces*(sizeof(Face*)));
	free(ofaces);
	nfaces++;
	setlast();
	drawarrows();
	faces[0] = f;
	drawface(f, 0);
	flushimage(display, 1);
	unlockdisplay(display);
}

void
loadmboxfaces(char *maildir)
{
	CFid *dirfd;
	Dir *d;
	int i, n;

	dirfd = fsopen(mailfs, maildir, OREAD);
	if(dirfd != nil){
		while((n = fsdirread(dirfd, &d)) > 0){
			for(i=0; i<n; i++)
				addface(dirface(maildir, d[i].name));
			free(d);
		}
		fsclose(dirfd);
	}else
		sysfatal("open %s: %r", maildir);
}

void
freeface(Face *f)
{
	int i;

	if(f->file!=nil && f->bit!=f->file->image)
		freeimage(f->bit);
	freefacefile(f->file);
	for(i=0; i<Nstring; i++)
		free(f->str[i]);
	free(f);
}

void
delface(int j)
{
	Rectangle r0, r1, r;
	int nx, ny, x, y;

	if(j < first)
		first--;
	else if(j < last){
		nx = nacross;
		ny = (nfaces+(nx-1)) / nx;
		x = (j-first)%nx;
		for(y=(j-first)/nx; y<ny; y++){
			if(x != nx-1){
				/* move them along */
				r0 = facerect(y*nx+x);
				r1 = facerect(y*nx+x+1);
				r = r0;
				r.max.x = r.min.x + (nx - x - 1)*(Facesize+Facesep);
				draw(screen, r, screen, nil, r1.min);
			}
			if(y != ny-1){
				/* copy one up from row below */
				r = facerect((y+1)*nx);
				draw(screen, facerect(y*nx+nx-1), screen, nil, r.min);
			}
			x = 0;
		}
		if(last < nfaces)	/* first off-screen becomes visible */
			drawface(faces[last], last-1);
		else{
			/* clear final spot */
			r = facerect(last-first-1);
			draw(screen, r, bgrnd, nil, r.min);
		}
	}
	freeface(faces[j]);
	memmove(faces+j, faces+j+1, (nfaces-(j+1))*sizeof(Face*));
	nfaces--;
	setlast();
	drawarrows();
}

void
dodelete(int i)
{
	Face *f;

	f = faces[i];
	if(history){
		free(f->str[Sshow]);
		f->str[Sshow] = estrdup("");
	}else{
		delface(i);
		flushimage(display, 1);
	}
}

void
delete(char *s, char *digest)
{
	int i;
	Face *f;

	lockdisplay(display);
	for(i=0; i<nfaces; i++){
		f = faces[i];
		if(digest != nil){
			if(f->str[Sdigest]!=nil && strcmp(digest, f->str[Sdigest]) == 0){
				dodelete(i);
				break;
			}
		}else{
			if(f->str[Sshow] && strcmp(s, f->str[Sshow]) == 0){
				dodelete(i);
				break;
			}
		}
	}
	unlockdisplay(display);
}

void
faceproc(void)
{
	for(;;)
		addface(nextface());
}

void
resized(void)
{
	int i;

	nacross = (Dx(screen->r)-2*facep.x+Facesep)/(Facesize+Facesep);
	for(ndown=1; rectinrect(facerect(ndown*nacross), screen->r); ndown++)
		;
	setlast();
	draw(screen, screen->r, bgrnd, nil, ZP);
	enddate = ZP;
	drawtime();
	for(i=0; i<nfaces; i++)
		drawface(faces[i], i);
	drawarrows();
	flushimage(display, 1);
}

void
eresized(int new)
{
	lockdisplay(display);
	if(new && getwindow(display, Refnone) < 0) {
		fprint(2, "can't reattach to window\n");
		killall("reattach");
	}
	resized();
	unlockdisplay(display);
}

void
resizeproc(void *v)
{
	USED(v);

	while(recv(mousectl->resizec, 0) == 1)
		eresized(1);
}

int
getmouse(Mouse *m)
{
	static int eof;

	if(eof)
		return 0;
	if(readmouse(mousectl) < 0){
		eof = 1;
		m->buttons = 0;
		return 0;
	}
	*m = mousectl->m;
	return 1;
}

enum
{
	Clicksize	= 3,		/* pixels */
};

int
scroll(int but, Point p)
{
	int delta;

	delta = 0;
	lockdisplay(display);
	if(ptinrect(p, leftr) && first>0){
		if(but == 2)
			delta = -first;
		else{
			delta = nacross;
			if(delta > first)
				delta = first;
			delta = -delta;
		}
	}else if(ptinrect(p, rightr) && last<nfaces){
		if(but == 2)
			delta = (nfaces-nacross*ndown) - first;
		else{
			delta = nacross;
			if(delta > nfaces-last)
				delta = nfaces-last;
		}
	}
	first += delta;
	last += delta;
	unlockdisplay(display);
	if(delta)
		eresized(0);
	return delta;
}

void
click(int button, Mouse *m)
{
	Point p;
	int i;

	p = m->xy;
	while(m->buttons == (1<<(button-1)))
		getmouse(m);
	if(m->buttons)
		return;
	if(abs(p.x-m->xy.x)>Clicksize || abs(p.y-m->xy.y)>Clicksize)
		return;
	switch(button){
	case 1:
		if(scroll(1, p))
			break;
		if(history){
			/* click clears display */
			lockdisplay(display);
			for(i=0; i<nfaces; i++)
				freeface(faces[i]);
			free(faces);
			faces=nil;
			nfaces = 0;
			unlockdisplay(display);
			eresized(0);
			return;
		}else{
			for(i=first; i<last; i++)	/* clear vwhois faces */
				if(ptinrect(p, facerect(i-first)) 
				&& strstr(faces[i]->str[Sshow], "/XXXvwhois")){
					lockdisplay(display);
					delface(i);
					flushimage(display, 1);
					unlockdisplay(display);
					break;
				}
		}
		break;
	case 2:
		scroll(2, p);
		break;
	case 3:
		scroll(3, p);
		lockdisplay(display);
		for(i=first; i<last; i++)
			if(ptinrect(p, facerect(i-first))){
				showmail(faces[i]);
				break;
			}
		unlockdisplay(display);
		break;
	}
}

void
mouseproc(void *v)
{
	Mouse mouse;
	USED(v);

	while(getmouse(&mouse)){
		if(mouse.buttons == 1)
			click(1, &mouse);
		else if(mouse.buttons == 2)
			click(2, &mouse);
		else if(mouse.buttons == 4)
			click(3, &mouse);

		while(mouse.buttons)
			getmouse(&mouse);
	}
}

void
killall(char *s)
{
	threadexitsall(s);
}

void
usage(void)
{
	fprint(2, "usage: faces [-hi] [-m maildir] -W winsize\n");
	threadexitsall("usage");
}

void
threadmain(int argc, char *argv[])
{
	int i;

	rfork(RFNOTEG);

	ARGBEGIN{
	case 'h':
		history++;
		break;
	case 'i':
		initload++;
		break;
	case 'm':
		addmaildir(EARGF(usage()));
		maildir = nil;
		break;
	case 'W':
		winsize = EARGF(usage());
		break;
	default:
		usage();
	}ARGEND

	if(initdraw(nil, nil, "faces") < 0){
		fprint(2, "faces: initdraw failed: %r\n");
		threadexitsall("initdraw");
	}
	if(maildir)
		addmaildir(maildir);
	init();
	unlockdisplay(display);	/* initdraw leaves it locked */
	display->locking = 1;	/* tell library we're using the display lock */
	setdate();
	eresized(0);

	proccreate(timeproc, nil, STACK);
	proccreate(mouseproc, nil, STACK);
	proccreate(resizeproc, nil, STACK);
	if(initload)
		for(i = 0; i < nmaildirs; i++)
			loadmboxfaces(maildirs[i]);
	faceproc();
	killall(nil);
}
