/* 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);
}
