#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);
}
