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

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*1000LL;
	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 <= 0){
				tv.tv_sec = 0;
				tv.tv_usec = 0;
			}else{
				tv.tv_sec = (t0-eslave[i].nexttick)/1000000000;
				tv.tv_usec = (t0-eslave[i].nexttick)%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));
				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 > 0){
				eslave[i].nexttick += eslave[i].n*1000LL;
				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;
}

