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

int isNew;

int
manage(Client *c, int mapped)
{
	int fixsize, dohide, doreshape, state;
	long msize;
	XClassHint class;
	XWMHints *hints;
	XSetWindowAttributes attrs;

	trace("manage", c, 0);
	XSelectInput(dpy, c->window, ColormapChangeMask | EnterWindowMask | PropertyChangeMask | FocusChangeMask);

	/* Get loads of hints */

	if (XGetClassHint(dpy, c->window, &class) != 0) {	/* ``Success'' */
		c->instance = class.res_name;
		c->class = class.res_class;
		c->is9term = 0;
		if(isNew){
			c->is9term = strstr(c->class, "term") || strstr(c->class, "Term");
			isNew = 0;
		}
	}
	else {
		c->instance = 0;
		c->class = 0;
		c->is9term = 0;
	}
	c->iconname = getprop(c->window, XA_WM_ICON_NAME);
	c->name = getprop(c->window, XA_WM_NAME);
	setlabel(c);

	hints = XGetWMHints(dpy, c->window);
	if (XGetWMNormalHints(dpy, c->window, &c->size, &msize) == 0 || c->size.flags == 0)
		c->size.flags = PSize;		/* not specified - punt */

	getcmaps(c);
	getproto(c);
	gettrans(c);
	if (c->is9term)
		c->hold = getiprop(c->window, _rio_hold_mode);

	/* Figure out what to do with the window from hints */

	if (!getstate(c->window, &state))
		state = hints ? hints->initial_state : NormalState;
	dohide = (state == IconicState);

	fixsize = 0;
	if ((c->size.flags & (USSize|PSize)))
		fixsize = 1;
	if ((c->size.flags & (PMinSize|PMaxSize)) == (PMinSize|PMaxSize) && c->size.min_width == c->size.max_width && c->size.min_height == c->size.max_height)
		fixsize = 1;
	doreshape = !mapped;
	if (fixsize) {
		if (c->size.flags & USPosition)
			doreshape = 0;
		if (dohide && (c->size.flags & PPosition))
			doreshape = 0;
		if (c->trans != None)
			doreshape = 0;
	}
	if (c->is9term)
		fixsize = 0;
	if (c->size.flags & PBaseSize) {
		c->min_dx = c->size.base_width;
		c->min_dy = c->size.base_height;
	}
	else if (c->size.flags & PMinSize) {
		c->min_dx = c->size.min_width;
		c->min_dy = c->size.min_height;
	}
	else if (c->is9term) {
		c->min_dx = 100;
		c->min_dy = 50;
	}
	else
		c->min_dx = c->min_dy = 0;

	if (hints)
		XFree(hints);

	/* Now do it!!! */

	if (doreshape) {
		if(0) fprintf(stderr, "in doreshape is9term=%d fixsize=%d, x=%d, y=%d, min_dx=%d, min_dy=%d, dx=%d, dy=%d\n",
				c->is9term, fixsize, c->x, c->y, c->min_dx, c->min_dy, c->dx, c->dy);
		if (current && current->screen == c->screen)
			cmapnofocus(c->screen);
		if (!c->is9term && c->x==0 && c->y==0) {
			static int nwin;

			c->x = 20*nwin+BORDER;
			c->y = 20*nwin+BORDER;
			nwin++;
			nwin %= 10;
		}

		if (c->is9term && !(fixsize ? drag(c, Button3) : sweep(c, Button3))) {
			XKillClient(dpy, c->window);
			rmclient(c);
			if (current && current->screen == c->screen)
				cmapfocus(current);
			return 0;
		}
	} else
		gravitate(c, 0);


	attrs.border_pixel =  c->screen->black;
	attrs.background_pixel =  c->screen->white;
	attrs.colormap = c->screen->def_cmap;
	c->parent = XCreateWindow(dpy, c->screen->root,
			c->x - BORDER, c->y - BORDER,
			c->dx + 2*BORDER, c->dy + 2*BORDER,
			0,
			c->screen->depth,
			CopyFromParent,
			c->screen->vis,
			CWBackPixel | CWBorderPixel | CWColormap,
			&attrs);

	XSelectInput(dpy, c->parent, SubstructureRedirectMask | SubstructureNotifyMask|ButtonPressMask| PointerMotionMask|LeaveWindowMask);
	if (mapped)
		c->reparenting = 1;
	if (doreshape && !fixsize)
		XResizeWindow(dpy, c->window, c->dx, c->dy);
	XSetWindowBorderWidth(dpy, c->window, 0);

	/*
	  * To have something more than only a big white or black border
	  * XXX should replace this by a pattern in the white or black
	  * such that we can see the border also if all our
	  * windows are black and/or white
	  * (black (or white)  border around black (or white) window
	  *  is not very helpful.
	  */
	if (c->screen->depth <= 8) {
		XSetWindowBorderWidth(dpy, c->parent, 1);
	}

	XReparentWindow(dpy, c->window, c->parent, BORDER, BORDER);
#ifdef	SHAPE
	if (shape) {
		XShapeSelectInput(dpy, c->window, ShapeNotifyMask);
		ignore_badwindow = 1;		/* magic */
		setshape(c);
		ignore_badwindow = 0;
	}
#endif
	XAddToSaveSet(dpy, c->window);
	if (dohide)
		hide(c);
	else {
		XMapWindow(dpy, c->window);
		XMapWindow(dpy, c->parent);
		XUnmapWindow(dpy, c->screen->sweepwin);
		if (nostalgia || doreshape)
			active(c);
		else if (c->trans != None && current && current->window == c->trans)
			active(c);
		else
			setactive(c, 0);
		setstate(c, NormalState);
	}
	if (current && (current != c))
		cmapfocus(current);
	c->init = 1;

	/*
	 * If we swept the window, let's send a resize event to the
	 * guy who just got resized.  It's not clear whether the apps
	 * should notice their new size via other means.  Try as I might,
	 * I can't find a way to have them notice during initdraw, so
	 * I solve the problem this way instead.		-rsc
	 */
	if(c->is9term)
		sendconfig(c);
	return 1;
}

void
scanwins(ScreenInfo *s)
{
	unsigned int i, nwins;
	Client *c;
	Window dw1, dw2, *wins;
	XWindowAttributes attr;

	XQueryTree(dpy, s->root, &dw1, &dw2, &wins, &nwins);
	for (i = 0; i < nwins; i++) {
		XGetWindowAttributes(dpy, wins[i], &attr);
		if (attr.override_redirect || wins[i] == s->menuwin)
			continue;
		c = getclient(wins[i], 1);
		if (c != 0 && c->window == wins[i] && !c->init) {
			c->x = attr.x;
			c->y = attr.y;
			c->dx = attr.width;
			c->dy = attr.height;
			c->border = attr.border_width;
			c->screen = s;
			c->parent = s->root;
			if (attr.map_state == IsViewable)
				manage(c, 1);
		}
	}
	XFree((void *) wins);	/* cast is to shut stoopid compiler up */
}

void
gettrans(Client *c)
{
	Window trans;

	trans = None;
	if (XGetTransientForHint(dpy, c->window, &trans) != 0)
		c->trans = trans;
	else
		c->trans = None;
}

void
withdraw(Client *c)
{
	XUnmapWindow(dpy, c->parent);
	gravitate(c, 1);
	XReparentWindow(dpy, c->window, c->screen->root, c->x, c->y);
	gravitate(c, 0);
	XRemoveFromSaveSet(dpy, c->window);
	setstate(c, WithdrawnState);

	/* flush any errors */
	ignore_badwindow = 1;
	XSync(dpy, False);
	ignore_badwindow = 0;
}

void
gravitate(Client *c, int invert)
{
	int gravity, dx, dy, delta;

	gravity = NorthWestGravity;
	if (c->size.flags & PWinGravity)
		gravity = c->size.win_gravity;

	delta = c->border-BORDER;
	switch (gravity) {
	case NorthWestGravity:
		dx = 0;
		dy = 0;
		break;
	case NorthGravity:
		dx = delta;
		dy = 0;
		break;
	case NorthEastGravity:
		dx = 2*delta;
		dy = 0;
		break;
	case WestGravity:
		dx = 0;
		dy = delta;
		break;
	case CenterGravity:
	case StaticGravity:
		dx = delta;
		dy = delta;
		break;
	case EastGravity:
		dx = 2*delta;
		dy = delta;
		break;
	case SouthWestGravity:
		dx = 0;
		dy = 2*delta;
		break;
	case SouthGravity:
		dx = delta;
		dy = 2*delta;
		break;
	case SouthEastGravity:
		dx = 2*delta;
		dy = 2*delta;
		break;
	default:
		fprintf(stderr, "rio: bad window gravity %d for 0x%x\n", gravity, (int)c->window);
		return;
	}
	dx += BORDER;
	dy += BORDER;
	if (invert) {
		dx = -dx;
		dy = -dy;
	}
	c->x += dx;
	c->y += dy;
}

static void
installcmap(ScreenInfo *s, Colormap cmap)
{
	if (cmap == None)
		XInstallColormap(dpy, s->def_cmap);
	else
		XInstallColormap(dpy, cmap);
}

void
cmapfocus(Client *c)
{
	int i, found;
	Client *cc;

	if (c == 0)
		return;
	else if (c->ncmapwins != 0) {
		found = 0;
		for (i = c->ncmapwins-1; i >= 0; i--) {
			installcmap(c->screen, c->wmcmaps[i]);
			if (c->cmapwins[i] == c->window)
				found++;
		}
		if (!found)
			installcmap(c->screen, c->cmap);
	}
	else if (c->trans != None && (cc = getclient(c->trans, 0)) != 0 && cc->ncmapwins != 0)
		cmapfocus(cc);
	else
		installcmap(c->screen, c->cmap);
}

void
cmapnofocus(ScreenInfo *s)
{
	installcmap(s, None);
}

void
getcmaps(Client *c)
{
	int n, i;
	Window *cw;
	XWindowAttributes attr;

	if (!c->init) {
		ignore_badwindow = 1;
		XGetWindowAttributes(dpy, c->window, &attr);
		c->cmap = attr.colormap;
		XSync(dpy, False);
		ignore_badwindow = 0;
	}

	n = _getprop(c->window, wm_colormaps, XA_WINDOW, 100L, (void*)&cw);
	if (c->ncmapwins != 0) {
		XFree((char *)c->cmapwins);
		free((char *)c->wmcmaps);
	}
	if (n <= 0) {
		c->ncmapwins = 0;
		return;
	}

	c->ncmapwins = n;
	c->cmapwins = cw;

	c->wmcmaps = (Colormap*)malloc(n*sizeof(Colormap));
	for (i = 0; i < n; i++) {
		if (cw[i] == c->window)
			c->wmcmaps[i] = c->cmap;
		else {
			/* flush any errors (e.g., caused by mozilla tabs) */
			ignore_badwindow = 1;
			XSelectInput(dpy, cw[i], ColormapChangeMask);
			XGetWindowAttributes(dpy, cw[i], &attr);
			c->wmcmaps[i] = attr.colormap;
			XSync(dpy, False);
			ignore_badwindow = 0;
		}
	}
}

void
setlabel(Client *c)
{
	char *label, *p;

	if (c->iconname != 0)
		label = c->iconname;
	else if (c->name != 0)
		label = c->name;
	else if (c->instance != 0)
		label = c->instance;
	else if (c->class != 0)
		label = c->class;
	else
		label = "no label";
	if ((p = index(label, ':')) != 0)
		*p = '\0';
	c->label = label;
}

#ifdef	SHAPE
void
setshape(Client *c)
{
	int n, order;
	XRectangle *rect;

	/* don't try to add a border if the window is non-rectangular */
	rect = XShapeGetRectangles(dpy, c->window, ShapeBounding, &n, &order);
	if (n > 1)
		XShapeCombineShape(dpy, c->parent, ShapeBounding, BORDER, BORDER,
			c->window, ShapeBounding, ShapeSet);
	XFree((void*)rect);
}
#endif

int
_getprop(Window w, Atom a, Atom type, long len, unsigned char **p)
{
	Atom real_type;
	int format;
	unsigned long n, extra;
	int status;

	status = XGetWindowProperty(dpy, w, a, 0L, len, False, type, &real_type, &format, &n, &extra, p);
	if (status != Success || *p == 0)
		return -1;
	if (n == 0)
		XFree((void*) *p);
	/* could check real_type, format, extra here... */
	return n;
}

char *
getprop(Window w, Atom a)
{
	unsigned char *p;

	if (_getprop(w, a, XA_STRING, 100L, &p) <= 0)
		return 0;
	return (char *)p;
}

int
get1prop(Window w, Atom a, Atom type)
{
	char **p, *x;

	if (_getprop(w, a, type, 1L, (void*)&p) <= 0)
		return 0;
	x = *p;
	XFree((void*) p);
	return (int)x;
}

Window
getwprop(Window w, Atom a)
{
	return get1prop(w, a, XA_WINDOW);
}

int
getiprop(Window w, Atom a)
{
	return get1prop(w, a, XA_INTEGER);
}

void
setstate(Client *c, int state)
{
	long data[2];

	data[0] = (long) state;
	data[1] = (long) None;

	c->state = state;
	XChangeProperty(dpy, c->window, wm_state, wm_state, 32,
		PropModeReplace, (unsigned char *)data, 2);
}

int
getstate(Window w, int *state)
{
	long *p = 0;

	if (_getprop(w, wm_state, wm_state, 2L, (void*)&p) <= 0)
		return 0;

	*state = (int) *p;
	XFree((char *) p);
	return 1;
}

void
getproto(Client *c)
{
	Atom *p;
	int i;
	long n;
	Window w;

	w = c->window;
	c->proto = 0;
	if ((n = _getprop(w, wm_protocols, XA_ATOM, 20L, (void*)&p)) <= 0)
		return;

	for (i = 0; i < n; i++)
		if (p[i] == wm_delete)
			c->proto |= Pdelete;
		else if (p[i] == wm_take_focus)
			c->proto |= Ptakefocus;
		else if (p[i] == wm_lose_focus)
			c->proto |= Plosefocus;

	XFree((char *) p);
}
