#include <u.h>
#include <sys/select.h>
#include <libc.h>
#include <draw.h>
#include <cursor.h>
#include <event.h>
#include <mux.h>
#include <drawfcall.h>

typedef struct	Slave Slave;
typedef struct	Ebuf Ebuf;
extern Mouse _drawmouse;

struct Slave
{
	int	inuse;
	Ebuf	*head;		/* queue of messages for this descriptor */
	Ebuf	*tail;
	int	(*fn)(int, Event*, uchar*, int);
	Muxrpc *rpc;
	vlong nexttick;
	int fd;
	int n;
};

struct Ebuf
{
	Ebuf	*next;
	int	n;		/* number of bytes in buf */
	union {
		uchar	buf[EMAXMSG];
		Rune	rune;
		Mouse	mouse;
	} u;
};

static	Slave	eslave[MAXSLAVE];
static	int	Skeyboard = -1;
static	int	Smouse = -1;
static	int	Stimer = -1;

static	int	nslave;
static	int	newkey(ulong);
static	int	extract(int canblock);

static
Ebuf*
ebread(Slave *s)
{
	Ebuf *eb;

	while(!s->head)
		extract(1);
	eb = s->head;
	s->head = s->head->next;
	if(s->head == 0)
		s->tail = 0;
	return eb;
}

ulong
event(Event *e)
{
	return eread(~0UL, e);
}

ulong
eread(ulong keys, Event *e)
{
	Ebuf *eb;
	int i, id;

	if(keys == 0)
		return 0;
	for(;;){
		for(i=0; i<nslave; i++)
			if((keys & (1<<i)) && eslave[i].head){
				id = 1<<i;
				if(i == Smouse)
					e->mouse = emouse();
				else if(i == Skeyboard)
					e->kbdc = ekbd();
				else if(i == Stimer)
					eslave[i].head = 0;
				else{
					eb = ebread(&eslave[i]);
					e->n = eb->n;
					if(eslave[i].fn)
						id = (*eslave[i].fn)(id, e, eb->u.buf, eb->n);
					else
						memmove(e->data, eb->u.buf, eb->n);
					free(eb);
				}
				return id;
			}
		extract(1);
	}
	return 0;
}

int
ecanmouse(void)
{
	if(Smouse < 0)
		drawerror(display, "events: mouse not initialized");
	return ecanread(Emouse);
}

int
ecankbd(void)
{
	if(Skeyboard < 0)
		drawerror(display, "events: keyboard not initialzed");
	return ecanread(Ekeyboard);
}

int
ecanread(ulong keys)
{
	int i;

	for(;;){
		for(i=0; i<nslave; i++)
			if((keys & (1<<i)) && eslave[i].head)
				return 1;
		if(!extract(0))
			return 0;
	}
	return -1;
}

ulong
estartfn(ulong key, int fd, int n, int (*fn)(int, Event*, uchar*, int))
{
	int i;

	if(fd < 0)
		drawerror(display, "events: bad file descriptor");
	if(n <= 0 || n > EMAXMSG)
		n = EMAXMSG;
	i = newkey(key);
	eslave[i].fn = fn;
	eslave[i].fd = fd;
	eslave[i].n = n;
	return 1<<i;
}

ulong
estart(ulong key, int fd, int n)
{
	return estartfn(key, fd, n, nil);
}

ulong
etimer(ulong key, int n)
{
	if(Stimer != -1)
		drawerror(display, "events: timer started twice");
	Stimer = newkey(key);
	if(n <= 0)
		n = 1000;
	eslave[Stimer].n = n;
	eslave[Stimer].nexttick = nsec()+n*1000000LL;
	return 1<<Stimer;
}

void
einit(ulong keys)
{
	if(keys&Ekeyboard){
		for(Skeyboard=0; Ekeyboard & ~(1<<Skeyboard); Skeyboard++)
			;
		eslave[Skeyboard].inuse = 1;
		if(nslave <= Skeyboard)
			nslave = Skeyboard+1;
	}
	if(keys&Emouse){
		for(Smouse=0; Emouse & ~(1<<Smouse); Smouse++)
			;
		eslave[Smouse].inuse = 1;
		if(nslave <= Smouse)
			nslave = Smouse+1;
	}
}

static Ebuf*
newebuf(Slave *s, int n)
{
	Ebuf *eb;
	
	eb = malloc(sizeof(*eb) - sizeof(eb->u.buf) + n);
	if(eb == nil)
		drawerror(display, "events: out of memory");
	eb->n = n;
	eb->next = 0;
	if(s->head)
		s->tail = s->tail->next = eb;
	else
		s->head = s->tail = eb;
	return eb;
}

static Muxrpc*
startrpc(int type)
{
	uchar buf[100];
	Wsysmsg w;
	
	w.type = type;
	convW2M(&w, buf, sizeof buf);
	return muxrpcstart(display->mux, buf);
}

static int
finishrpc(Muxrpc *r, Wsysmsg *w)
{
	uchar *p;
	void *v;
	int n;
	
	if(!muxrpccanfinish(r, &v))
		return 0;
	p = v;
	if(p == nil)	/* eof on connection */
		exit(0);
	GET(p, n);
	convM2W(p, n, w);
	free(p);
	return 1;
}

static int
extract(int canblock)
{
	Ebuf *eb;
	int i, n, max;
	fd_set rset, wset, xset;
	struct timeval tv, *timeout;
	Wsysmsg w;
	vlong t0;

	/*
	 * Flush draw buffer before waiting for responses.
	 * Avoid doing so if buffer is empty.
	 * Also make sure that we don't interfere with app-specific locking.
	 */
	if(display->locking){
		/* 
		 * if locking is being done by program, 
		 * this means it can't depend on automatic 
		 * flush in emouse() etc.
		 */
		if(canqlock(&display->qlock)){
			if(display->bufp > display->buf)
				flushimage(display, 1);
			unlockdisplay(display);
		}
	}else
		if(display->bufp > display->buf)
			flushimage(display, 1);

	/*
	 * Set up for select.
	 */
	FD_ZERO(&rset);
	FD_ZERO(&wset);
	FD_ZERO(&xset);
	max = -1;
	timeout = nil;
	for(i=0; i<nslave; i++){
		if(!eslave[i].inuse)
			continue;
		if(i == Smouse){
			if(eslave[i].rpc == nil)
				eslave[i].rpc = startrpc(Trdmouse);
			if(eslave[i].rpc){
				/* if ready, don't block in select */
				if(eslave[i].rpc->p)
					canblock = 0;
				FD_SET(display->srvfd, &rset);
				FD_SET(display->srvfd, &xset);
				if(display->srvfd > max)
					max = display->srvfd;
			}
		}else if(i == Skeyboard){
			if(eslave[i].rpc == nil)
				eslave[i].rpc = startrpc(Trdkbd);
			if(eslave[i].rpc){
				/* if ready, don't block in select */
				if(eslave[i].rpc->p)
					canblock = 0;
				FD_SET(display->srvfd, &rset);
				FD_SET(display->srvfd, &xset);
				if(display->srvfd > max)
					max = display->srvfd;
			}
		}else if(i == Stimer){
			t0 = nsec();
			if(t0 >= eslave[i].nexttick){
				tv.tv_sec = 0;
				tv.tv_usec = 0;
			}else{
				tv.tv_sec = (eslave[i].nexttick-t0)/1000000000;
				tv.tv_usec = (eslave[i].nexttick-t0)%1000000000 / 1000;
			}
			timeout = &tv;
		}else{
			FD_SET(eslave[i].fd, &rset);
			FD_SET(eslave[i].fd, &xset);
			if(eslave[i].fd > max)
				max = eslave[i].fd;
		}
	}
	
	if(!canblock){
		tv.tv_sec = 0;
		tv.tv_usec = 0;
		timeout = &tv;
	}

	if(select(max+1, &rset, &wset, &xset, timeout) < 0)
		drawerror(display, "select failure");

	/*
	 * Look to see what can proceed.
	 */
	n = 0;
	for(i=0; i<nslave; i++){
		if(!eslave[i].inuse)
			continue;
		if(i == Smouse){
			if(finishrpc(eslave[i].rpc, &w)){
				eslave[i].rpc = nil;
				eb = newebuf(&eslave[i], sizeof(Mouse));
				_drawmouse = w.mouse;
				eb->u.mouse = w.mouse;
				if(w.resized)
					eresized(1);
				n++;
			}
		}else if(i == Skeyboard){
			if(finishrpc(eslave[i].rpc, &w)){
				eslave[i].rpc = nil;
				eb = newebuf(&eslave[i], sizeof(Rune)+2);	/* +8: alignment */
				eb->u.rune = w.rune;
				n++;
			}
		}else if(i == Stimer){
			t0 = nsec();
			while(t0 > eslave[i].nexttick){
				eslave[i].nexttick += eslave[i].n*1000000LL;
				eslave[i].head = (Ebuf*)1;
				n++;
			}
		}else{
			if(FD_ISSET(eslave[i].fd, &rset)){
				eb = newebuf(&eslave[i], eslave[i].n);
				eb->n = read(eslave[i].fd, eb->u.buf, eslave[i].n);
				n++;
			}
		}
	}
	return n;
}

static int
newkey(ulong key)
{
	int i;

	for(i=0; i<MAXSLAVE; i++)
		if((key & ~(1<<i)) == 0 && eslave[i].inuse == 0){
			if(nslave <= i)
				nslave = i + 1;
			eslave[i].inuse = 1;
			return i;
		}
	drawerror(display, "events: bad slave assignment");
	return 0;
}

Mouse
emouse(void)
{
	Mouse m;
	Ebuf *eb;

	if(Smouse < 0)
		drawerror(display, "events: mouse not initialized");
	eb = ebread(&eslave[Smouse]);
	m = eb->u.mouse;
	free(eb);
	return m;
}

int
ekbd(void)
{
	Ebuf *eb;
	int c;

	if(Skeyboard < 0)
		drawerror(display, "events: keyboard not initialzed");
	eb = ebread(&eslave[Skeyboard]);
	c = eb->u.rune;
	free(eb);
	return c;
}

void
emoveto(Point pt)
{
	_displaymoveto(display, pt);
}

void
esetcursor(Cursor *c)
{
	_displaycursor(display, c);
}

int
ereadmouse(Mouse *m)
{
	int resized;

	resized = 0;
	if(_displayrdmouse(display, m, &resized) < 0)
		return -1;
	if(resized)
		eresized(1);
	return 1;
}

