/* 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", (void*)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", (void*)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 : "?", (int)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", (int)c->window, (int)c->parent, c->x, c->y);
}
#endif

void
shuffle(int up)
{
	Client **l, *c;
	
	if(clients == 0 || clients->next == 0)
		return;
	if(!up){
		c = 0;
		/*for(c=clients; c->next; c=c->next) */
		/*	; */
		for(l=&clients; (*l)->next; l=&(*l)->next)
			if ((*l)->state == 1)
				c = *l;
		if (c == 0)
			return;
		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); */
}

