#include <u.h>
#include "x11-inc.h"
#include <libc.h>
#include <draw.h>
#include <thread.h>
#include <cursor.h>
#include <mouse.h>
#include <memdraw.h>
#include "x11-memdraw.h"

int _windowhasfocus = 1;
int _wantfocuschanges;

void
moveto(Mousectl *m, Point pt)
{
	_xmoveto(pt);
}

void
closemouse(Mousectl *mc)
{
	if(mc == nil)
		return;

/*	postnote(PNPROC, mc->pid, "kill");
*/
	do; while(nbrecv(mc->c, &mc->m) > 0);
	close(mc->mfd);
	close(mc->cfd);
	free(mc->file);
	chanfree(mc->c);
	chanfree(mc->resizec);
	free(mc);
}

int
readmouse(Mousectl *mc)
{
	if(mc->display)
		flushimage(mc->display, 1);
	if(recv(mc->c, &mc->m) < 0){
		fprint(2, "readmouse: %r\n");
		return -1;
	}
	return 0;
}

static
void
_ioproc(void *arg)
{
	int fd, one, buttons;
	Atom a;
	ulong mask;
	Mouse m;
	Mousectl *mc;
	XEvent xevent;

	one = 1;
	mc = arg;
	threadsetname("mouseproc");
	memset(&m, 0, sizeof m);
	mc->pid = getpid();
	mask = MouseMask|ExposureMask|StructureNotifyMask;
	XSelectInput(_x.mousecon, _x.drawable, mask);
	fd = XConnectionNumber(_x.mousecon);
	buttons = 0;
	for(;;){
		XNextEvent(_x.mousecon, &xevent);
		switch(xevent.type){
		case Expose:
			_xexpose(&xevent, _x.mousecon);
			continue;
		case DestroyNotify:
			if(_xdestroy(&xevent, _x.mousecon)){
				/* drain it before sending */
				/* apps that care can notice we sent a 0 */
				/* otherwise we'll have getwindow send SIGHUP */
				nbrecv(mc->resizec, 0);
				nbrecv(mc->resizec, 0);
				send(mc->resizec, 0);
			}
			continue;
		case ConfigureNotify:
			if(_xconfigure(&xevent, _x.mousecon))
				nbsend(mc->resizec, &one);
			continue;
		case SelectionRequest:
			_xselect(&xevent, _x.mousecon);
			continue;
		case ButtonPress:
		case ButtonRelease:
		case MotionNotify:
			/* If the motion notifications are backing up, skip over some. */
			if(0 && xevent.type == MotionNotify){
				while(XCheckWindowEvent(_x.mousecon, _x.drawable, MouseMask, &xevent)){
					if(xevent.type != MotionNotify)
						break;
				}
			}
			m.buttons = buttons;
			if(_xtoplan9mouse(_x.mousecon, &xevent, &m) < 0)
				continue;
			buttons = m.buttons;
			send(mc->c, &m);
			/*
			 * mc->Mouse is updated after send so it doesn't have wrong value if we block during send.
			 * This means that programs should receive into mc->Mouse (see readmouse() above) if
			 * they want full synchrony.
			 */
			mc->m = m;
			break;
		case ClientMessage:
			if(xevent.xclient.message_type == _x.wmprotos){
				a = xevent.xclient.data.l[0];
				if(_wantfocuschanges && a == _x.takefocus){
					_windowhasfocus = 1;
					_x.newscreenr = _x.screenr;
					nbsend(mc->resizec, &one);
				}else if(_wantfocuschanges && a == _x.losefocus){
					_windowhasfocus = 0;
					_x.newscreenr = _x.screenr;
					nbsend(mc->resizec, &one);
				}
			}
			break;
		}
	}
}

Mousectl*
initmouse(char *file, Image *i)
{
	Mousectl *mc;

	mc = mallocz(sizeof(Mousectl), 1);
	if(i)
		mc->display = i->display;
	mc->c = chancreate(sizeof(Mouse), 0);
	chansetname(mc->c, "mousec");
	mc->resizec = chancreate(sizeof(int), 2);
	chansetname(mc->resizec, "resizec");
	proccreate(_ioproc, mc, 32768);
	return mc;
}

void
setcursor(Mousectl *mc, Cursor *c)
{
	_xsetcursor(c);
}

/*
 * Send the mouse event back to the window manager.
 * So that 9term can tell rio to pop up its button3 menu.
 * Note that we're using _x.mousecon in a few places,
 * so we have to be sure that the mouse proc isn't using it
 * when we call!  This is all a bit wonky and should be 
 * avoided unless you know what you're doing.
 */
void
bouncemouse(Mouse *m)
{
	XButtonEvent e;
	XWindow dw;

	e.type = ButtonPress;
	e.state = 0;
	e.button = 0;
	if(m->buttons&1)
		e.button = 1;
	else if(m->buttons&2)
		e.button = 2;
	else if(m->buttons&4)
		e.button = 3;
	e.same_screen = 1;
	XTranslateCoordinates(_x.display, _x.drawable,
		DefaultRootWindow(_x.display),
		m->xy.x, m->xy.y, &e.x_root, &e.y_root, &dw);
	e.root = DefaultRootWindow(_x.mousecon);
	e.window = e.root;
	e.subwindow = None;
	e.x = e.x_root;
	e.y = e.y_root;
#undef time
	e.time = CurrentTime;
	XUngrabPointer(_x.mousecon, m->msec);
	XSendEvent(_x.mousecon, e.root, True, ButtonPressMask, (XEvent*)&e);
	XFlush(_x.mousecon);
}
