/* Copyright (c) 1999 Decklin Foster <fosterd@hartwick.edu>
   Copyright (c) 2000 Linus Nilsson <d96ln@efd.lth.se> */

#include "yawm.h"
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xatom.h>

void handle_keypress_event(XKeyEvent *e) {
	Client myclient;
	Client *c = &myclient;

	if (e->keycode == 
	    XKeysymToKeycode(dpy, XStringToKeysym("F1"))) {
		system(F1_STRING);
	}
	if (e->keycode == 
	    XKeysymToKeycode(dpy, XStringToKeysym("F2"))) {
		/* This should be replaced with fork() and
		   execve() later on */
  		system(F2_STRING);
	}
	if (e->keycode == 
	    XKeysymToKeycode(dpy, XStringToKeysym("F3"))) {
		/* This should be replaced with fork() and
		   execve() later on */
		system(F3_STRING);
	}
	if (e->keycode == 
	    XKeysymToKeycode(dpy, XStringToKeysym("F4"))) {
		for (c = head_client; c && !c->minimized; c=c->next);
		if (c) {
			unhide(c);
		}
	}
	if (e->keycode == 
	    XKeysymToKeycode(dpy, XStringToKeysym("F12"))) {
		/* quit_nicely is currently broken */
		//quit_nicely();
		/* use exit(0) instead for now */
		exit(0);
	}
	if (e->keycode == 
	    XKeysymToKeycode(dpy, XStringToKeysym("Tab")) &&
	    e->state == (Mod1Mask | ShiftMask)) {
		/* move focus to previous client in list */
		if (focused_client) {
			c = focused_client->prev;
		}
		else {
			for (c = head_client; c->next; c = c->next);
		}
		while (c != NULL && !(c && !c->minimized)) {
			c=c->prev;
		}
		if (c == NULL) {
			for (c = head_client; c->next; c = c->next);
			while (c != NULL && !(c && !c->minimized) && 
			       c != focused_client) {
				c=c->prev;
			}
		}
		if (c) { 
			XWarpPointer(dpy, None, c->parent, 
				     0, 0, 0, 0, 0, 0);
			XRaiseWindow(dpy, c->parent); 
		}
	}
	if (e->keycode == 
	    XKeysymToKeycode(dpy, XStringToKeysym("Tab")) &&
	    e->state == Mod1Mask) {
		/* move focus to next client in list */
		if (focused_client) {
			c = focused_client->next;
		}
		else {
			c = head_client;
		}
		while (c != NULL && !(c && !c->minimized)) {
			c=c->next;
		}
		if (c == NULL) {
			c = head_client;
			while (c != NULL && !(c && !c->minimized) && 
			       c != focused_client) {
				c=c->next;
			}
		}
		if (c) {
			XWarpPointer(dpy, None, c->parent, 
				     0, 0, 0, 0, 0, 0);
			XRaiseWindow(dpy, c->parent); 
		}
	}
}

Client * next_non_minimized(Client *c) {
	Client *tmp = (Client *) malloc(sizeof(Client));
	
	tmp = c;
	while (tmp && !tmp->minimized) {
		tmp = tmp->next;
	}
	return tmp;
}

void handle_button_event(XButtonEvent *e) {
	Client *c = find_client(e->window, 1);
	int maxbox;
	int minbox;
	int killbox;

	if (e->window == taskbar) {
		for (c = head_client; c && 
                     (e->x < c->left_offset || e->x > c->right_offset);
                     c = c->next);
        	if (c) {
			if (c->minimized) {
				unhide(c);
			}
			else {
				hide(c);
			}
		}
	}
	else if (e->window == root) {
		switch (e->button) {
		case Button1: 
			system(opt_new1 ? opt_new1 : DEF_NEW1 "&"); 
			break;
		case Button2:
			system("xkill");
			break;
		case Button3: 
#ifdef DEBUG
			dump_clients(); 
#endif
			break;
		}
	} 
	else if (c && c->window != taskbar) {
		maxbox = (e->x >= c->width - theight(c)) && 
			(e->y <= theight(c));
		minbox = (e->x < c->width - theight(c) &&
			  e->x >= c->width - 2*theight(c) + 5 &&
			  e->y <= theight(c));
		killbox = (e->x < 5 - 2 + theight(c) &&
			e->y <= theight(c));
		switch (e->button) {
		case Button1:
			if (maxbox) {
				maximize(c);
			}
			else if (minbox) {
				hide(c);
			}
			else if (killbox) {
				send_wm_delete(c);
			}
			else {
				move(c); 
			}
			break;
		case Button2:
			if (maxbox) {
				maximize_vertically(c); 
			}
			else {
				shade(c);
			}
			break;
		case Button3:
			if (maxbox) {
				resize(c);
			}
			else {
				XLowerWindow(dpy, c->parent); 
			}
			break;
		}
	}
}

void handle_configure_request(XConfigureRequestEvent *e)
{
	Client *c = find_client(e->window, 0);
	XWindowChanges wc;

	if (c) {
		if (e->value_mask & CWX) c->x = e->x;
		if (e->value_mask & CWY) c->y = e->y;
		if (e->value_mask & CWWidth) c->width = e->width;
		if (e->value_mask & CWHeight) c->height = e->height;

		wc.x = c->x;
		wc.y = c->y - theight(c);
		wc.width = c->width;
		wc.height = c->height + theight(c);
		wc.border_width = opt_bw;
		wc.sibling = e->above;
		wc.stack_mode = e->detail;
		XConfigureWindow(dpy, c->parent, e->value_mask, &wc);
		send_config(c);
	}

	wc.x = c ? 0 : e->x;
	wc.y = c ? theight(c) : e->y;
	wc.width = e->width;
	wc.height = e->height;
	wc.sibling = e->above;
	wc.stack_mode = e->detail;
	XConfigureWindow(dpy, e->window, e->value_mask, &wc);
}

void handle_map_request(XMapRequestEvent *e) {
	Client *c = find_client(e->window, 0);

	if (c) {
		XMapWindow(dpy, c->window);
		XMapRaised(dpy, c->parent);
		set_wm_state(c, NormalState);
		c->minimized = 0;
	} else
		make_new_client(e->window);
}

void handle_unmap_event(XUnmapEvent *e)
{
	Client *c = find_client(e->window, 0);
	focused_client = NULL;

	if (c) {
		if (c->ignore_unmap) {
			c->ignore_unmap--;
			draw_tasks();
		}
		else {
			remove_client(c, 0);
			draw_tasks();
		}	
	}
}

void handle_client_message(XClientMessageEvent *e)
{
	Client *c = find_client(e->window, 0);

	if (c && e->message_type == xa_wm_change_state &&
		e->format == 32 && e->data.l[0] == IconicState) hide(c);
}

void handle_colormap_change(XColormapEvent *e)
{
	Client *c = find_client(e->window, 0);

	if (c && e->new) {
		c->cmap = e->colormap;
		XInstallColormap(dpy, c->cmap);
	}
}

void handle_property_change(XPropertyEvent *e) {
	Client *c = find_client(e->window, 0);
	long dummy;

	debug("in handle_property_change\n");
	if (c) {
		focused_client = c;
	}
	if (c) {
		switch (e->atom) {
			case XA_WM_NAME:
				debug("switch1\n");
				if (c->name) XFree(c->name);
				XFetchName(dpy, c->window, &c->name);
				XClearWindow(dpy, c->parent);
				draw_tasks();
				break;
			case XA_WM_NORMAL_HINTS:
				debug("switch2\n");
				XGetWMNormalHints(dpy, c->window, c->size,
						  &dummy);
				redraw(c);
		}
	}
}

void handle_enter_event(XCrossingEvent *e) {
	Client *c = find_client(e->window, 1);

	if (c) {
		if (c->window) {
			focused_client = c;
			XInstallColormap(dpy, c->cmap);
		        XSetInputFocus(dpy, c->window, RevertToPointerRoot, 
			               CurrentTime);
		        if (USE_TASKBAR) draw_tasks();
		}
		for (c = head_client; 
		     c != NULL && c->window != e->window; 
		     c = c->next) {
			redraw(c);
		}
	}
}

void handle_expose_event(XExposeEvent *e) {
	Client *c = find_client(e->window, -1);
	
	if (c && e->count == 0) {
		redraw(c);
	}
}

void handle_reparent_event(XReparentEvent *e) {
	// Client *c = find_client(e->window, 0);
	// Client *dest = find_client(e->parent, 1); 
	// if (c && !dest) remove_client(c, 0); 
}


syntax highlighted by Code2HTML, v. 0.9.1