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

Client	*clients;
Client	*current;

void
setactive(Client *c, int on)
{
//	dbg("setactive client %x %d", c->window, c->on);

	if(c->parent == c->screen->root)
		return;
	
	if(on){
		XUngrabButton(dpy, AnyButton, AnyModifier, c->parent);
		XSetInputFocus(dpy, c->window, RevertToPointerRoot, timestamp());
		if(c->proto & Ptakefocus)
			sendcmessage(c->window, wm_protocols, wm_take_focus, 0, 1);
		cmapfocus(c);
	}else{
		if(c->proto & Plosefocus)
			sendcmessage(c->window, wm_protocols, wm_lose_focus, 0, 1);
		XGrabButton(dpy, AnyButton, AnyModifier, c->parent, False,
			ButtonMask, GrabModeAsync, GrabModeSync, None, None);
	}
	draw_border(c, on);
}

void
draw_border(Client *c, int active)
{
	unsigned long pixel;

	if(active){
		if(c->hold)
			pixel = c->screen->activeholdborder;
		else
			pixel = c->screen->activeborder;
	}else{
		if(c->hold)
			pixel = c->screen->inactiveholdborder;
		else
			pixel = c->screen->inactiveborder;
	}

	if(debug) fprintf(stderr, "draw_border %p pixel %ld active %d hold %d\n", c, pixel, active, c->hold);
	XSetWindowBackground(dpy, c->parent, pixel);
	XClearWindow(dpy, c->parent);
}

void
active(Client *c)
{
	Client *cc;

	if(c == 0){
		fprintf(stderr, "rio: active(c==0)\n");
		return;
	}
	if(c == current)
		return;
	if(current){
		setactive(current, 0);
		if(current->screen != c->screen)
			cmapnofocus(current->screen);
	}
	setactive(c, 1);
	for(cc = clients; cc; cc = cc->next)
		if(cc->revert == c)
			cc->revert = c->revert;
	c->revert = current;
	while(c->revert && !normal(c->revert))
		c->revert = c->revert->revert;
	current = c;
#ifdef	DEBUG
	if(debug)
		dump_revert();
#endif
}

void
nofocus(void)
{
	static Window w = 0;
	int mask;
	XSetWindowAttributes attr;
	Client *c;

	if(current){
		setactive(current, 0);
		for(c = current->revert; c; c = c->revert)
			if(normal(c)){
				active(c);
				return;
			}
		cmapnofocus(current->screen);
		/* if no candidates to revert to, fall through */
	}
	current = 0;
	if(w == 0){
		mask = CWOverrideRedirect/*|CWColormap*/;
		attr.override_redirect = 1;
		/* attr.colormap = screens[0].def_cmap;*/
		w = XCreateWindow(dpy, screens[0].root, 0, 0, 1, 1, 0,
			0 /*screens[0].depth*/, InputOnly, 	screens[0].vis, mask, &attr);
		XMapWindow(dpy, w);
	}
	XSetInputFocus(dpy, w, RevertToPointerRoot, timestamp());
}

void
top(Client *c)
{
	Client **l, *cc;

	l = &clients;
	for(cc = *l; cc; cc = *l){
		if(cc == c){
			*l = c->next;
			c->next = clients;
			clients = c;
			return;
		}
		l = &cc->next;
	}
	fprintf(stderr, "rio: %p not on client list in top()\n", c);
}

Client *
getclient(Window w, int create)
{
	Client *c;

	if(w == 0 || getscreen(w))
		return 0;

	for(c = clients; c; c = c->next)
		if(c->window == w || c->parent == w)
			return c;

	if(!create)
		return 0;

	c = (Client *)malloc(sizeof(Client));
	memset(c, 0, sizeof(Client));
	c->window = w;
	/* c->parent will be set by the caller */
	c->parent = None;
	c->reparenting = 0;
	c->state = WithdrawnState;
	c->init = 0;
	c->cmap = None;
	c->label = c->class = 0;
	c->revert = 0;
	c->is9term = 0;
	c->hold = 0;
	c->ncmapwins = 0;
	c->cmapwins = 0;
	c->wmcmaps = 0;
	c->next = clients;
	c->virt = virt;
	clients = c;
	return c;
}

void
rmclient(Client *c)
{
	Client *cc;

	for(cc = current; cc && cc->revert; cc = cc->revert)
		if(cc->revert == c)
			cc->revert = cc->revert->revert;

	if(c == clients)
		clients = c->next;
	for(cc = clients; cc && cc->next; cc = cc->next)
		if(cc->next == c)
			cc->next = cc->next->next;

	if(hidden(c))
		unhidec(c, 0);

	if(c->parent != c->screen->root)
		XDestroyWindow(dpy, c->parent);

	c->parent = c->window = None;		/* paranoia */
	if(current == c){
		current = c->revert;
		if(current == 0)
			nofocus();
		else {
			if(current->screen != c->screen)
				cmapnofocus(c->screen);
			setactive(current, 1);
		}
	}
	if(c->ncmapwins != 0){
		XFree((char *)c->cmapwins);
		free((char *)c->wmcmaps);
	}
	if(c->iconname != 0)
		XFree((char*) c->iconname);
	if(c->name != 0)
		XFree((char*) c->name);
	if(c->instance != 0)
		XFree((char*) c->instance);
	if(c->class != 0)
		XFree((char*) c->class);
	memset(c, 0, sizeof(Client));		/* paranoia */
	free(c);
}

#ifdef	DEBUG
void
dump_revert(void)
{
	Client *c;
	int i;

	i = 0;
	for(c = current; c; c = c->revert){
		fprintf(stderr, "%s(%x:%d)", c->label ? c->label : "?", (uint)c->window, c->state);
		if(i++ > 100)
			break;
		if(c->revert)
			fprintf(stderr, " -> ");
	}
	if(current == 0)
		fprintf(stderr, "empty");
	fprintf(stderr, "\n");
}

void
dump_clients(void)
{
	Client *c;

	for(c = clients; c; c = c->next)
		fprintf(stderr, "w 0x%x parent 0x%x @ (%d, %d)\n", (uint)c->window, (uint)c->parent, c->x, c->y);
}
#endif

void
shuffle(int up)
{
	Client **l, *c;
	
	if(clients == 0 || clients->next == 0)
		return;
	if(up){
		//for(c=clients; c->next; c=c->next)
		//	;
		for(l=&clients; (*l)->next; l=&(*l)->next)
			;
		c = *l;
		*l = 0;
		c->next = clients;
		clients = c;
		XMapRaised(dpy, c->parent);
		top(c);
		active(c);
	}else{
		c = clients;
		for(l=&clients; *l; l=&(*l)->next)
			;
		clients = c->next;
		*l = c;
		c->next = 0;
		XLowerWindow(dpy, c->window);
	}
//	XMapRaised(dpy, clients->parent);
//	top(clients);	
//	active(clients);
}

