/* Copyright (c) 1994-1996 David Hogan, see README for licence details */
#include <stdio.h>
#include <X11/X.h>
#include <X11/Xos.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "dat.h"
#include "fns.h"

int
nobuttons(XButtonEvent *e)	/* Einstuerzende */
{
	int state;

	state = (e->state & AllButtonMask);
	return (e->type == ButtonRelease) && (state & (state - 1)) == 0;
}

int
grab(Window w, Window constrain, int mask, Cursor curs, int t)
{
	int status;

	if(t == 0)
		t = timestamp();
	status = XGrabPointer(dpy, w, False, mask,
		GrabModeAsync, GrabModeAsync, constrain, curs, t);
	return status;
}

void
ungrab(XButtonEvent *e)
{
	XEvent ev;

	if(!nobuttons(e))
		for(;;){
			XMaskEvent(dpy, ButtonMask | ButtonMotionMask, &ev);
			if(ev.type == MotionNotify)
				continue;
			e = &ev.xbutton;
			if(nobuttons(e))
				break;
		}
	XUngrabPointer(dpy, e->time);
	curtime = e->time;
}

static void
drawstring(Display *dpy, ScreenInfo *s, Menu *m, int wide, int high, int i, int selected)
{
	int tx, ty;

	tx = (wide - XTextWidth(font, m->item[i], strlen(m->item[i])))/2;
	ty = i*high + font->ascent + 1;
	XFillRectangle(dpy, s->menuwin, selected ? s->gcmenubgs : s->gcmenubg, 0, i*high, wide, high);
	XDrawString(dpy, s->menuwin, selected ? s->gcmenufgs : s->gcmenufg, tx, ty, m->item[i], strlen(m->item[i]));
}

int
menuhit(XButtonEvent *e, Menu *m)
{
	XEvent ev;
	int i, n, cur, old, wide, high, status, drawn, warp;
	int x, y, dx, dy, xmax, ymax;
	ScreenInfo *s;

	if(font == 0)
		return -1;
	s = getscreen(e->root);
	if(s == 0 || e->window == s->menuwin)	   /* ugly event mangling */
		return -1;

	dx = 0;
	for(n = 0; m->item[n]; n++){
		wide = XTextWidth(font, m->item[n], strlen(m->item[n])) + 4;
		if(wide > dx)
			dx = wide;
	}
	wide = dx;
	cur = m->lasthit;
	if(cur >= n)
		cur = n - 1;

	high = font->ascent + font->descent + 1;
	dy = n*high;
	x = e->x - wide/2;
	y = e->y - cur*high - high/2;
	warp = 0;
	xmax = DisplayWidth(dpy, s->num);
	ymax = DisplayHeight(dpy, s->num);
	if(x < 0){
		e->x -= x;
		x = 0;
		warp++;
	}
	if(x+wide >= xmax){
		e->x -= x+wide-xmax;
		x = xmax-wide;
		warp++;
	}
	if(y < 0){
		e->y -= y;
		y = 0;
		warp++;
	}
	if(y+dy >= ymax){
		e->y -= y+dy-ymax;
		y = ymax-dy;
		warp++;
	}
	if(warp)
		setmouse(e->x, e->y, s);
	XMoveResizeWindow(dpy, s->menuwin, x, y, dx, dy);
	XSelectInput(dpy, s->menuwin, MenuMask);
	XMapRaised(dpy, s->menuwin);
	status = grab(s->menuwin, None, MenuGrabMask, None, e->time);
	if(status != GrabSuccess){
		/* graberror("menuhit", status); */
		XUnmapWindow(dpy, s->menuwin);
		return -1;
	}
	drawn = 0;
	for(;;){
		XMaskEvent(dpy, MenuMask, &ev);
		switch (ev.type){
		default:
			fprintf(stderr, "rio: menuhit: unknown ev.type %d\n", ev.type);
			break;
		case ButtonPress:
			break;
		case ButtonRelease:
			if(ev.xbutton.button != e->button)
				break;
			x = ev.xbutton.x;
			y = ev.xbutton.y;
			i = y/high;
			if(cur >= 0 && y >= cur*high-3 && y < (cur+1)*high+3)
				i = cur;
			if(x < 0 || x > wide || y < -3)
				i = -1;
			else if(i < 0 || i >= n)
				i = -1;
			else
				m->lasthit = i;
			if(!nobuttons(&ev.xbutton))
				i = -1;
			ungrab(&ev.xbutton);
			XUnmapWindow(dpy, s->menuwin);
			return i;
		case MotionNotify:
			if(!drawn)
				break;
			x = ev.xbutton.x;
			y = ev.xbutton.y;
			old = cur;
			cur = y/high;
			if(old >= 0 && y >= old*high-3 && y < (old+1)*high+3)
				cur = old;
			if(x < 0 || x > wide || y < -3)
				cur = -1;
			else if(cur < 0 || cur >= n)
				cur = -1;
			if(cur == old)
				break;
			if(old >= 0 && old < n)
				drawstring(dpy, s, m, wide, high, old, 0);
			if(cur >= 0 && cur < n)
				drawstring(dpy, s, m, wide, high, cur, 1);
			break;
		case Expose:
			XClearWindow(dpy, s->menuwin);
			for(i = 0; i < n; i++)
				drawstring(dpy, s, m, wide, high, i, cur==i);
			drawn = 1;
		}
	}
}

Client *
selectwin(int release, int *shift, ScreenInfo *s)
{
	XEvent ev;
	XButtonEvent *e;
	int status;
	Window w;
	Client *c;

	status = grab(s->root, s->root, ButtonMask, s->target, 0);
	if(status != GrabSuccess){
		graberror("selectwin", status); /* */
		return 0;
	}
	w = None;
	for(;;){
		XMaskEvent(dpy, ButtonMask, &ev);
		e = &ev.xbutton;
		switch (ev.type){
		case ButtonPress:
			if(e->button != Button3){
				ungrab(e);
				return 0;
			}
			w = e->subwindow;
			if(!release){
				c = getclient(w, 0);
				if(c == 0)
					ungrab(e);
				if(shift != 0)
					*shift = (e->state&ShiftMask) != 0;
				return c;
			}
			break;
		case ButtonRelease:
			ungrab(e);
			if(e->button != Button3 || e->subwindow != w)
				return 0;
			if(shift != 0)
				*shift = (e->state&ShiftMask) != 0;
			return getclient(w, 0);
		}
	}
}

int
sweepcalc(Client *c, int x, int y, BorderOrient bl, int ignored)
{
	int dx, dy, sx, sy;

	dx = x - c->x;
	dy = y - c->y;
	sx = sy = 1;
	x += dx;
	if(dx < 0){
		dx = -dx;
		sx = -1;
	}
	y += dy;
	if(dy < 0){
		dy = -dy;
		sy = -1;
	}

	dx -= 2*BORDER;
	dy -= 2*BORDER;

	if(!c->is9term){
		if(dx < c->min_dx)
			dx = c->min_dx;
		if(dy < c->min_dy)
			dy = c->min_dy;
	}

	if(c->size.flags & PResizeInc){
		dx = c->min_dx + (dx-c->min_dx)/c->size.width_inc*c->size.width_inc;
		dy = c->min_dy + (dy-c->min_dy)/c->size.height_inc*c->size.height_inc;
	}

	if(c->size.flags & PMaxSize){
		if(dx > c->size.max_width)
			dx = c->size.max_width;
		if(dy > c->size.max_height)
			dy = c->size.max_height;
	}
	c->dx = sx*(dx + 2*BORDER);
	c->dy = sy*(dy + 2*BORDER);

	return ignored;
}

int
dragcalc(Client *c, int x, int y, BorderOrient bl, int ignored)
{
	c->x += x;
	c->y += y;

	return ignored;
}

int
pullcalc(Client *c, int x, int y, BorderOrient bl, int init)
{
	int dx, dy, sx, sy, px, py, spx, spy, rdx, rdy, xoff, yoff, xcorn, ycorn;

	px = c->x;
	py = c->y;
	dx = c->dx;
	dy = c->dy;
	sx = sy = 1;
	spx = spy = 0;
 	xoff = yoff = 0;
	xcorn = ycorn = 0;

	switch(bl){
	case BorderN:
		py = y;
		dy = (c->y + c->dy)  - y;
		spy = 1;
		yoff = y - c->y;
		break;
	case BorderS:
		dy = y - c->y;
		yoff =  (c->y + c->dy) - y;
		break;
	case BorderE:
		dx = x - c->x;
		xoff = (c->x + c->dx) - x;
		break;
	case BorderW:
		px = x;
		dx = (c->x + c->dx) - x;
		spx = 1;
		xoff = x - c->x;
		break;
	case BorderNNW:
	case BorderWNW:
		px = x;
		dx = (c->x + c->dx) - x;
		spx = 1;
		py = y;
		dy = (c->y + c->dy)  - y;
		spy = 1;
		xoff = x - c->x;
		yoff = y - c->y;
		break;
	case BorderNNE:
	case BorderENE:
		dx = x - c->x;
		py = y;
		dy = (c->y + c->dy)  - y;
		spy = 1;
		xoff = (c->x + c->dx) - x;
		yoff = y - c->y;
		break;
	case BorderSSE:
	case BorderESE:
		dx = x - c->x;
		dy = y - c->y;
		xoff = (c->x + c->dx) - x;
		yoff =  (c->y + c->dy) - y;
		break;
	case BorderSSW:
	case BorderWSW:
		px = x;
		dx = (c->x + c->dx)  - x;
		spx = 1;
		dy = y - c->y;
		xoff = x - c->x;
		yoff =  (c->y + c->dy) - y;
		break;
	default:
		break;
	}
	switch(bl){
	case BorderNNW:
	case BorderNNE:
	case BorderSSW:
	case BorderSSE:
		xcorn = 1;
		break;
	case BorderWNW:
	case BorderENE:
	case BorderWSW:
	case BorderESE:
		ycorn = 1;
		break;
	}
	if(!init
		|| xoff < 0 || (xcorn && xoff > CORNER) || (!xcorn && xoff > BORDER)
		|| yoff < 0 || (ycorn && yoff > CORNER) || (!ycorn && yoff > BORDER)){
		xoff = 0;
		yoff = 0;
		init = 0;
	}

	if(debug) fprintf(stderr, "c %dx%d+%d+%d m +%d+%d r  %dx%d+%d+%d sp (%d,%d) bl %d\n",
				c->dx, c->dy, c->x, c->y, x, y, dx, dy, px, py, spx, spy, bl);
	if(dx < 0){
		dx = -dx;
		sx = -1;
	}
	if(dy < 0){
		dy = -dy;
		sy = -1;
	}

	/* remember requested size;
	 * after applying size hints we may have to correct position
	 */
	rdx = sx*dx;
	rdy = sy*dy;

	/* apply size hints */
	dx -= (2*BORDER - xoff);
	dy -= (2*BORDER - yoff);

	if(!c->is9term){
		if(dx < c->min_dx)
			dx = c->min_dx;
		if(dy < c->min_dy)
			dy = c->min_dy;
	}

	if(c->size.flags & PResizeInc){
		dx = c->min_dx + (dx-c->min_dx)/c->size.width_inc*c->size.width_inc;
		dy = c->min_dy + (dy-c->min_dy)/c->size.height_inc*c->size.height_inc;
	}

	if(c->size.flags & PMaxSize){
		if(dx > c->size.max_width)
			dx = c->size.max_width;
		if(dy > c->size.max_height)
			dy = c->size.max_height;
	}

	/* set size and position */
	c->dx = sx*(dx + 2*BORDER );
	c->dy = sy*(dy + 2*BORDER );
	c->x = px;
	c->y = py;
	
	/* compensate position for size changed due to size hints */
	if(spx)
		c->x -= c->dx - rdx;
	if(spy)
		c->y -= c->dy - rdy;

	return init;
}

static void
xcopy(int fwd, Display *dpy, Drawable src, Drawable dst, GC gc, int x, int y, int dx, int dy, int x1, int y1)
{
	if(fwd)
		XCopyArea(dpy, src, dst, gc, x, y, dx, dy, x1, y1);
	else
		XCopyArea(dpy, dst, src, gc, x1, y1, dx, dy, x, y);
}

void
drawbound(Client *c, int drawing)
{
	int x, y, dx, dy;
	ScreenInfo *s;

	if(debug) fprintf(stderr, "drawbound %d %dx%d+%d+%d\n", drawing, c->dx, c->dy, c->x, c->y);
	
	s = c->screen;
	x = c->x;
	y = c->y;
	dx = c->dx;
	dy = c->dy;
	if(dx < 0){
		x += dx;
		dx = -dx;
	}
	if(dy < 0){
		y += dy;
		dy = -dy;
	}
	if(dx <= 2 || dy <= 2)
		return;

	if(solidsweep){
		if(drawing == -1){
			XUnmapWindow(dpy, s->sweepwin);
			return;
		}
		
		x += BORDER;
		y += BORDER;
		dx -= 2*BORDER;
		dy -= 2*BORDER;

		if(drawing){
			XMoveResizeWindow(dpy, s->sweepwin, x, y, dx, dy);
			XSelectInput(dpy, s->sweepwin, MenuMask);
			XMapRaised(dpy, s->sweepwin);
		}
		return;
	}

	if(drawing == -1)
		return;

	xcopy(drawing, dpy, s->root, s->bkup[0], s->gccopy, x, y, dx, BORDER, 0, 0);
	xcopy(drawing, dpy, s->root, s->bkup[0], s->gccopy, x, y+dy-BORDER, dx, BORDER, dx, 0);
	xcopy(drawing, dpy, s->root, s->bkup[1], s->gccopy, x, y, BORDER, dy, 0, 0);
	xcopy(drawing, dpy, s->root, s->bkup[1], s->gccopy, x+dx-BORDER, y, BORDER, dy, 0, dy);

	if(drawing){
		XFillRectangle(dpy, s->root, s->gcred, x, y, dx, BORDER);
		XFillRectangle(dpy, s->root, s->gcred, x, y+dy-BORDER, dx, BORDER);
		XFillRectangle(dpy, s->root, s->gcred, x, y, BORDER, dy);
		XFillRectangle(dpy, s->root, s->gcred, x+dx-BORDER, y, BORDER, dy);
	}
}

void
misleep(int msec)
{
	struct timeval t;

	t.tv_sec = msec/1000;
	t.tv_usec = (msec%1000)*1000;
	select(0, 0, 0, 0, &t);
}

int
sweepdrag(Client *c, int but, XButtonEvent *e0, BorderOrient bl, int (*recalc)(Client*, int, int, BorderOrient, int))
{
	XEvent ev;
	int idle;
	int cx, cy, rx, ry;
	int ox, oy, odx, ody;
	XButtonEvent *e;
	int notmoved;

	notmoved = 1;
	ox = c->x;
	oy = c->y;
	odx = c->dx;
	ody = c->dy;
	c->x -= BORDER;
	c->y -= BORDER;
	c->dx += 2*BORDER;
	c->dy += 2*BORDER;
	if(bl != BorderUnknown || e0 == 0)
		getmouse(&cx, &cy, c->screen);
	else
		getmouse(&c->x, &c->y, c->screen);
	XGrabServer(dpy);
	if(bl != BorderUnknown){
		notmoved = recalc(c, cx, cy, bl, notmoved);
	}
	drawbound(c, 1);
	idle = 0;
	for(;;){
		if(XCheckMaskEvent(dpy, ButtonMask, &ev) == 0){
			getmouse(&rx, &ry, c->screen);
			if(rx != cx || ry != cy || ++idle > 300){
				drawbound(c, 0);
				if(rx == cx && ry == cy){
					XUngrabServer(dpy);
					XFlush(dpy);
					misleep(500);
					XGrabServer(dpy);
					idle = 0;
				}
				if(e0 || bl != BorderUnknown)
					notmoved = recalc(c, rx, ry, bl, notmoved);
				else
					notmoved = recalc(c, rx-cx, ry-cy, bl, notmoved);
				cx = rx;
				cy = ry;
				drawbound(c, 1);
				XFlush(dpy);
			}
			misleep(50);
			continue;
		}
		e = &ev.xbutton;
		switch (ev.type){
		case ButtonPress:
		case ButtonRelease:
			drawbound(c, 0);
			ungrab(e);
			XUngrabServer(dpy);
			if(e->button != but && c->init)
				goto bad;
			if(c->dx < 0){
				c->x += c->dx;
				c->dx = -c->dx;
			}
			if(c->dy < 0){
				c->y += c->dy;
				c->dy = -c->dy;
			}
			c->x += BORDER;
			c->y += BORDER;
			c->dx -= 2*BORDER;
			c->dy -= 2*BORDER;
			if(c->dx < 4 || c->dy < 4 || c->dx < c->min_dx || c->dy < c->min_dy)
				goto bad;
			return 1;
		}
	}
bad:
	if(debug) fprintf(stderr, "sweepdrag bad\n");
	c->x = ox;
	c->y = oy;
	c->dx = odx;
	c->dy = ody;
	drawbound(c, -1);
	return 0;
}

int
sweep(Client *c, int but, XButtonEvent *ignored)
{
	XEvent ev;
	int status;
	XButtonEvent *e;
	ScreenInfo *s;

	s = c->screen;
	c->dx = 0;
	c->dy = 0;
	status = grab(s->root, s->root, ButtonMask, s->sweep0, 0);
	if(status != GrabSuccess){
		graberror("sweep", status); /* */
		return 0;
	}

	XMaskEvent(dpy, ButtonMask, &ev);
	e = &ev.xbutton;
	if(e->button != but){
		ungrab(e);
		return 0;
	}
	XChangeActivePointerGrab(dpy, ButtonMask, s->boxcurs, e->time);
	return sweepdrag(c, but, e, BorderUnknown, sweepcalc);
}

int
pull(Client *c, int but, XButtonEvent *e)
{
	int status;
	ScreenInfo *s;
	BorderOrient bl;

	bl = borderorient(c, e->x, e->y);
	/* assert(bl > BorderUnknown && bl < NBorder); */

	s = c->screen;
	status = grab(s->root, s->root, ButtonMask, s->bordcurs[bl], 0);
	if(status != GrabSuccess){
		graberror("pull", status); /* */
		return 0;
	}

	return sweepdrag(c, but, 0, bl, pullcalc);
}

int
drag(Client *c, int but)
{
	int status;
	ScreenInfo *s;

	s = c->screen;
	status = grab(s->root, s->root, ButtonMask, s->boxcurs, 0);
	if(status != GrabSuccess){
		graberror("drag", status); /* */
		return 0;
	}
	return sweepdrag(c, but, 0, BorderUnknown, dragcalc);
}

void
getmouse(int *x, int *y, ScreenInfo *s)
{
	Window dw1, dw2;
	int t1, t2;
	unsigned int t3;

	XQueryPointer(dpy, s->root, &dw1, &dw2, x, y, &t1, &t2, &t3);
	if(debug) fprintf(stderr, "getmouse: %d %d\n", *x, *y);
}

void
setmouse(int x, int y, ScreenInfo *s)
{
	XWarpPointer(dpy, None, s->root, None, None, None, None, x, y);
}
